4 #include <marlin/Global.h>
5 #include <marlin/Exceptions.h>
6 #include <EVENT/LCCollection.h>
7 #include <IMPL/LCCollectionVec.h>
8 #include <IMPL/CalorimeterHitImpl.h>
9 #include <IMPL/LCRelationImpl.h>
10 #include <CalorimeterHitType.h>
11 #include <EVENT/LCParameters.h>
12 #include <UTIL/CellIDDecoder.h>
13 #include <marlin/ProcessorEventSeeder.h>
21 #include "CLHEP/Random/Random.h"
22 #include "CLHEP/Random/RandGauss.h"
23 #include "CLHEP/Random/RandFlat.h"
24 #include "CLHEP/Units/PhysicalConstants.h"
26 #define RELATIONFROMTYPESTR "FromType"
27 #define RELATIONTOTYPESTR "ToType"
30 using namespace lcio ;
31 using namespace marlin ;
32 using namespace std::placeholders;
41 _description =
"Performs digitization of sim calo hits. Virtual class." ;
44 std::vector<std::string> inputCollections;
45 inputCollections.push_back(
"SimCalorimeterHits");
47 registerInputCollections( LCIO::SIMCALORIMETERHIT,
48 "inputHitCollections" ,
49 "input simcalhit Collection Names" ,
55 std::vector<std::string> outputCollections;
56 registerProcessorParameter(
"outputHitCollections",
57 "output calorimeterhit Collection Names" ,
62 std::vector<std::string> outputRelCollections;
63 registerProcessorParameter(
"outputRelationCollections",
64 "output hit relatiob Collection Names" ,
66 outputRelCollections );
69 registerProcessorParameter(
"threshold" ,
74 registerProcessorParameter(
"thresholdUnit" ,
75 "Unit for threshold. Can be \"GeV\", \"MIP\" or \"px\". MIP and px need properly set calibration constants" ,
80 registerProcessorParameter(
"timingCut" ,
85 registerProcessorParameter(
"timingCorrectForPropagation" ,
86 "Correct hit times for propagation: radial distance/c" ,
90 registerProcessorParameter(
"timingWindowMin" ,
91 "Time Window minimum time in ns" ,
95 registerProcessorParameter(
"timingWindowMax" ,
96 "Time Window maximum time in ns" ,
100 registerProcessorParameter(
"integrationMethod" ,
101 "Energy integration and time calculation method. Options: Standard, ROC" ,
103 std::string(
"Standard"));
105 registerProcessorParameter(
"fastShaper" ,
106 "Fast shaper value. Unit in ns" ,
110 registerProcessorParameter(
"slowShaper" ,
111 "Slow shaper value. Unit in ns" ,
115 registerProcessorParameter(
"timingResolution" ,
116 "Time resolution to apply (gaussian smearing). Unit in ns" ,
123 registerProcessorParameter(
"calibration_mip" ,
124 "average G4 deposited energy by MIP for calibration" ,
128 registerProcessorParameter(
"miscalibration_uncorrel" ,
129 "uncorrelated random gaussian miscalibration (as a fraction: 1.0 = 100%) " ,
133 registerProcessorParameter(
"miscalibration_uncorrel_memorise" ,
134 "store oncorrelated miscalbrations in memory? (i.e. use same miscalibrations in each event. WARNING: can take a lot of memory if used...) " ,
138 registerProcessorParameter(
"miscalibration_correl" ,
139 "correlated random gaussian miscalibration (as a fraction: 1.0 = 100%) " ,
143 registerProcessorParameter(
"deadCell_fraction" ,
144 "random dead cell fraction (as a fraction: 0->1) " ,
148 registerProcessorParameter(
"deadCell_memorise" ,
149 "store dead cells in memory? (i.e. use same dead cells in each event. WARNING: can take a lot of memory if used...) " ,
154 registerProcessorParameter(
"elec_noise_mip",
155 "typical electronics noise (in MIP units)",
159 registerProcessorParameter(
"elec_range_mip",
160 "maximum of dynamic range of electronics (in MIPs)",
165 registerProcessorParameter(
"CellIDLayerString" ,
166 "name of the part of the cellID that holds the layer" ,
201 streamlog_out(ERROR) <<
"could not identify threshold unit. Please use \"GeV\", \"MIP\" or \"px\"! Aborting." << std::endl;
202 marlin::StopProcessingException(
this);
209 std::map<std::string, integr_function> integrations = {
214 if(integrations.end() == findIter) {
215 streamlog_out(ERROR) <<
"Could not guess timing calculation method!" << std::endl;
216 streamlog_out(ERROR) <<
"Available are: Standard, ROC. Provided: " <<
_integration_method << std::endl;
217 streamlog_out(ERROR) <<
"Aborting..." << std::endl;
218 marlin::StopProcessingException(
this);
224 if(!parameterSet(
"fastShaper") || !parameterSet(
"slowShaper")) {
225 streamlog_out(ERROR) <<
"Fast/slow shaper parameter(s) not set. Required for ROC integration!" << std::endl;
226 streamlog_out(ERROR) <<
"Aborting..." << std::endl;
227 marlin::StopProcessingException(
this);
231 _flag.setBit(LCIO::CHBIT_LONG);
232 _flag.setBit(LCIO::RCHBIT_TIME);
236 marlin::Global::EVENTSEEDER->registerProcessor(
this);
246 CLHEP::HepRandom::setTheSeed( marlin::Global::EVENTSEEDER->getSeed(
this) );
257 streamlog_out ( DEBUG1 ) <<
"looking for collection: " << colName << endl;
259 LCCollection * col = evt->getCollection( colName.c_str() ) ;
260 string initString = col->getParameters().getStringVal(LCIO::CellIDEncoding);
261 CHT::CaloType cht_type = caloTypeFromString(colName);
262 CHT::CaloID cht_id = caloIDFromString(colName);
263 CHT::Layout cht_lay = layoutFromString(colName);
265 CellIDDecoder<SimCalorimeterHit> idDecoder( col );
267 int numElements = col->getNumberOfElements();
268 streamlog_out ( DEBUG1 ) << colName <<
" number of elements = " << numElements << endl;
270 if ( numElements==0 )
continue;
274 newcol->setFlag(
_flag.getFlag());
283 for (
int j=0; j < numElements; ++j) {
284 SimCalorimeterHit * simhit =
dynamic_cast<SimCalorimeterHit*
>( col->getElementAt( j ) ) ;
287 auto integrationResult =
Integrate(simhit);
288 if( ! integrationResult.has_value() ) {
291 float time = integrationResult.value().first;
292 float energyDep = integrationResult.value().second;
294 float energyDig =
EnergyDigi(energyDep, simhit->getCellID0() , simhit->getCellID1() );
297 CalorimeterHitImpl* newhit =
new CalorimeterHitImpl();
298 newhit->setCellID0( simhit->getCellID0() );
299 newhit->setCellID1( simhit->getCellID1() );
300 newhit->setTime( time );
301 newhit->setPosition( simhit->getPosition() );
302 newhit->setEnergy( energyDig );
304 newhit->setType( CHT( cht_type, cht_id, cht_lay, layer ) );
305 newhit->setRawHit( simhit );
306 newcol->addElement( newhit );
308 streamlog_out ( DEBUG1 ) <<
"orig/new hit energy: " << simhit->getEnergy() <<
" " << newhit->getEnergy() << endl;
310 LCRelationImpl *rel =
new LCRelationImpl(newhit,simhit,1.0);
311 relcol->addElement( rel );
317 newcol->parameters().setValue(LCIO::CellIDEncoding,initString);
323 }
catch(DataNotAvailableException &
e){
324 streamlog_out(DEBUG1) <<
"could not find input collection " << colName << std::endl;
367 std::pair <int, int> id(id0, id1);
392 std::pair <int, int> id(id0, id1);
400 if (thisDead ==
true){
416 float timeCorrection(0);
419 for (
int i=0; i<3; i++)
420 r+=pow(hit->getPosition()[i],2);
421 timeCorrection = sqrt(r)/CLHEP::c_light;
427 float earliestTime=std::numeric_limits<float>::max();
428 for(
int i = 0; i<hit->getNMCContributions(); i++){
429 float timei = hit->getTimeCont(i);
430 float energyi = hit->getEnergyCont(i);
431 float relativetime = timei - timeCorrection;
433 energySum += energyi;
434 if (relativetime<earliestTime){
435 earliestTime = relativetime;
448 const unsigned int ncontrib = hit->getNMCContributions() ;
450 std::vector<MCC> mcconts{ncontrib};
451 for(
unsigned int i = 0; i<ncontrib; i++){
452 mcconts[i].energy = hit->getEnergyCont(i);
453 mcconts[i].time = hit->getTimeCont(i);
455 std::sort(mcconts.begin(), mcconts.end(), [](
auto lhs,
auto rhs){
456 return (lhs.time < rhs.time);
460 bool passThreshold =
false;
461 float epar=0.f, hitTime=0.f;
462 unsigned int thresholdIndex=0;
465 for(
unsigned int i=0; i<ncontrib ; ++i) {
466 const auto timei = mcconts[i].time;
469 for(
unsigned int j=i; j<ncontrib ; ++j) {
470 const auto timej = mcconts[j].time;
472 epar += mcconts[j].energy;
479 passThreshold = true ;
488 const float thresholdTime = mcconts[thresholdIndex].time;
495 float energySum = 0.f ;
496 for(
unsigned int i=thresholdIndex ; i<ncontrib ; ++i) {
498 energySum += mcconts[i].energy;
std::map< std::pair< int, int >, bool > _cell_dead
virtual float EnergyDigi(float energy, int id0, int id1)
integr_function _integr_function
virtual integr_res_opt Integrate(const SimCalorimeterHit *hit) const
bool _misCalib_uncorrel_keep
#define RELATIONTOTYPESTR
virtual float digitiseDetectorEnergy(float energy) const =0
std::string _integration_method
std::string _cellIDLayerString
virtual float convertEnergy(float energy, int inScale) const =0
int _time_correctForPropagation
std::vector< std::string > _outputCollections
float _event_correl_miscalib
std::map< std::pair< int, int >, float > _cell_miscalibs
float SmearTime(float time) const
integr_res_opt StandardIntegration(const SimCalorimeterHit *hit) const
std::vector< std::string > _outputRelCollections
virtual void processRunHeader(LCRunHeader *run)
std::string _threshold_unit
std::optional< integr_res > integr_res_opt
virtual void check(LCEvent *evt)
std::vector< LCCollection * > LCCollectionVec
integr_res_opt ROCIntegration(const SimCalorimeterHit *hit) const
std::vector< std::string > _inputCollections
virtual void processEvent(LCEvent *evt)
#define RELATIONFROMTYPESTR
std::pair< float, float > integr_res