4 #include "EVENT/LCCollection.h"
5 #include "UTIL/PIDHandler.h"
10 #include "marlinutil/GeometryUtil.h"
12 #include "EVENT/SimTrackerHit.h"
13 #include "UTIL/LCRelationNavigator.h"
14 #include "CLHEP/Random/Randomize.h"
16 using namespace TOFUtils;
19 using EVENT::LCCollection;
20 using EVENT::ReconstructedParticle;
21 using EVENT::TrackerHit;
23 using EVENT::SimTrackerHit;
25 using EVENT::CalorimeterHit;
26 using EVENT::TrackState;
27 using EVENT::LCObject;
28 using UTIL::LCRelationNavigator;
29 using CLHEP::RandGauss;
36 _description =
"TOFEstimators processor computes time-of-flight of the chosen ReconstructedParticle to the \
37 specified end point (SET hit or Ecal surface). To be used for a further particle ID";
39 registerInputCollection(LCIO::RECONSTRUCTEDPARTICLE,
40 "ReconstructedParticleCollection",
41 "Name of the ReconstructedParticle collection",
45 registerProcessorParameter(
"ExtrapolateToEcal",
46 "If true, track is extrapolated to the Ecal surface for track length calculation, \
47 time of flight estimated using Ecal hits. If false, track length calculated to the last tracker hit.\
48 Time of flight estimated using SET hit if exists.",
52 registerProcessorParameter(
"TofMethod",
53 "name of the algorithm which estimates time of flight\
54 to the Ecal surface based on Ecal hits time information.\
55 Available options are: closest, frankAvg, frankFit.\
56 In case of _extrapolateToEcal==false is ignored",
60 registerProcessorParameter(
"TimeResolution",
61 "Time resolution of individual SET strips or Ecal hits in ps",
65 registerProcessorParameter(
"MaxEcalLayer",
66 "Time of flight is calculated using Ecal hits only up to MaxLayer",
76 throw EVENT::Exception(
"Invalid steering parameter for TofMethod is passed: " +
_tofMethod +
"\n Available options are: closest, frankAvg, frankFit" );
82 _bField = MarlinUtil::getBzAtOrigin();
95 LCCollection* setRelations = evt->getCollection(
"SETSpacePointRelations");
97 LCRelationNavigator navigatorSET = LCRelationNavigator( setRelations );
99 PIDHandler pidHandler( pfos );
103 for (
int i=0; i<pfos->getNumberOfElements(); ++i){
104 streamlog_out(DEBUG9)<<std::endl<<
"Starting to analyze "<<i+1<<
" PFO"<<
std::endl;
105 ReconstructedParticle* pfo = static_cast <ReconstructedParticle*> ( pfos->getElementAt(i) );
107 int nClusters = pfo->getClusters().size();
108 int nTracks = pfo->getTracks().size();
110 if( nClusters != 1 || nTracks != 1){
113 pidHandler.setParticleID(pfo , 0, 0, 0., algoID, results);
116 Track* track = pfo->getTracks()[0];
117 Cluster* cluster = pfo->getClusters()[0];
119 double timeOfFlight = 0.;
137 if ( hitSET !=
nullptr ){
138 const vector<LCObject*>& simHitsSET = navigatorSET.getRelatedToObjects( hitSET );
139 if ( simHitsSET.
size() >= 2 ){
141 if (simHitsSET.
size() > 2) streamlog_out(WARNING)<<
"Found more than two SET strip hits! Writing TOF as an average of the first two elements in the array."<<
std::endl;
143 SimTrackerHit* simHitSETFront = static_cast <SimTrackerHit*>( simHitsSET[0] );
144 SimTrackerHit* simHitSETBack = static_cast <SimTrackerHit*>( simHitsSET[1] );
145 double timeFront = RandGauss::shoot(simHitSETFront->getTime(),
_timeResolution);
146 double timeBack = RandGauss::shoot(simHitSETBack->getTime(),
_timeResolution);
147 timeOfFlight = (timeFront + timeBack)/2.;
149 else if (simHitsSET.
size() == 1){
150 streamlog_out(WARNING)<<
"Found only one SET strip hit! Writing TOF from a single strip."<<
std::endl;
151 SimTrackerHit* simHitSET = static_cast <SimTrackerHit*>(simHitsSET[0]);
152 timeOfFlight = RandGauss::shoot(simHitSET->getTime(),
_timeResolution);
156 streamlog_out(WARNING)<<
"Found NO simHits associated with the found SET hit! Writing TOF as 0."<<
std::endl;
161 pidHandler.setParticleID(pfo , 0, 0, 0., algoID, results);
162 streamlog_out(DEBUG9)<<
"Final results for the "<<i+1<<
" PFO"<<
std::endl;
163 streamlog_out(DEBUG9)<<
"time-of-flight: "<< float(timeOfFlight)<<
" ns"<<
std::endl;
164 streamlog_out(DEBUG9)<<std::endl<<
std::endl;
double getTofFrankAvg(std::vector< EVENT::CalorimeterHit * > selectedHits, EVENT::Track *track, double timeResolution)
Get the time-of-flight using average of the Frank ECal hits.
double getTofClosest(EVENT::Cluster *cluster, EVENT::Track *track, double timeResolution)
Get the time-of-flight using the closest ECal hit.
TOFEstimators()
Default constructor.
std::string _pfoCollectionName
Stores ReconstructedParticleCollection steering parameter.
TOFEstimators aTOFEstimators
int _maxEcalLayer
Stores MaxEcalLayer steering parameter.
EVENT::TrackerHit * getSETHit(EVENT::Track *track, double tpcOuterR)
Returns SET hit.
int _nEvent
Stores current event number.
double getTPCOuterR()
Returns TPC outer radius from the DD4hep detector geometry.
Marlin processor that calculates time-of-flight for charged particles.
static ProcessorEventSeeder * EVENTSEEDER
void processEvent(EVENT::LCEvent *evt)
Called for every event - the working horse.
double _bField
Stores z component of the magnetic field at the origin in Tesla.
std::string _tofMethod
Stores TofMethod steering parameter.
bool _extrapolateToEcal
Stores ExtrapolateToEcal steering parameter.
double getTofFrankFit(std::vector< EVENT::CalorimeterHit * > selectedHits, EVENT::Track *track, double timeResolution)
Get the time-of-flight using fit of the Frank ECal hits.
void registerProcessor(Processor *proc)
std::vector< EVENT::CalorimeterHit * > selectFrankEcalHits(EVENT::Cluster *cluster, EVENT::Track *track, int maxEcalLayer, double bField)
Get a subset of the cluster calorimeter hits.
void init()
Called at the begin of the job before anything is read.
std::vector< std::string > _outputParNames
Stores names of the output parameter - "timeOfFlight".
double _timeResolution
Stores TimeResolution steering parameter.
double _tpcOuterR
Stores outer TPC radius in mm.