6 #include "EVENT/LCCollection.h"
7 #include "UTIL/PIDHandler.h"
9 #include "marlin/Global.h"
10 #include "marlin/ProcessorEventSeeder.h"
11 #include "marlin/VerbosityLevels.h"
12 #include "marlinutil/GeometryUtil.h"
13 #include "MarlinTrk/Factory.h"
14 #include "EVENT/SimTrackerHit.h"
15 #include "UTIL/LCRelationNavigator.h"
16 #include "CLHEP/Random/Randomize.h"
18 using namespace TOFUtils;
21 using EVENT::LCCollection;
22 using EVENT::ReconstructedParticle;
23 using EVENT::TrackerHit;
25 using EVENT::SimTrackerHit;
27 using EVENT::CalorimeterHit;
28 using EVENT::TrackState;
29 using EVENT::LCObject;
30 using UTIL::LCRelationNavigator;
31 using CLHEP::RandGauss;
38 _description =
"TOFEstimators processor computes momentum harmonic mean, track length \
39 and time-of-flight of the chosen ReconstructedParticle to the \
40 specified end point (SET hit or Ecal surface). To be used for a further particle ID";
42 registerInputCollection(LCIO::RECONSTRUCTEDPARTICLE,
43 "ReconstructedParticleCollection",
44 "Name of the ReconstructedParticle collection",
46 std::string(
"PandoraPFOs") );
48 registerProcessorParameter(
"ExtrapolateToEcal",
49 "If true, track is extrapolated to the Ecal surface for track length calculation, \
50 time of flight estimated using Ecal hits. If false, track length calculated to the last tracker hit.\
51 Time of flight estimated using SET hit if exists.",
55 registerProcessorParameter(
"TofMethod",
56 "name of the algorithm which estimates time of flight\
57 to the Ecal surface based on Ecal hits time information.\
58 Available options are: closest, frankAvg, frankFit.\
59 In case of _extrapolateToEcal==false is ignored",
61 std::string(
"closest") );
63 registerProcessorParameter(
"TimeResolution",
64 "Time resolution of individual SET strips or Ecal hits in ps",
68 registerProcessorParameter(
"MaxEcalLayer",
69 "Time of flight is calculated using Ecal hits only up to MaxLayer",
79 throw EVENT::Exception(
"Invalid steering parameter for TofMethod is passed: " +
_tofMethod +
"\n Available options are: closest, frankAvg, frankFit" );
82 marlin::Global::EVENTSEEDER->registerProcessor(
this);
85 _bField = MarlinUtil::getBzAtOrigin();
90 _trkSystem = MarlinTrk::Factory::createMarlinTrkSystem(
"DDKalTest",
nullptr,
"");
91 _trkSystem->setOption( MarlinTrk::IMarlinTrkSystem::CFG::useQMS,
true);
92 _trkSystem->setOption( MarlinTrk::IMarlinTrkSystem::CFG::usedEdx,
true);
93 _trkSystem->setOption( MarlinTrk::IMarlinTrkSystem::CFG::useSmoothing,
true);
99 RandGauss::setTheSeed( marlin::Global::EVENTSEEDER->getSeed(
this) );
101 streamlog_out(DEBUG9)<<std::endl<<
"==========Event========== "<<
_nEvent<<std::endl;
102 auto startTime = std::chrono::steady_clock::now();
105 LCCollection* setRelations = evt->getCollection(
"SETSpacePointRelations");
107 LCRelationNavigator navigatorSET = LCRelationNavigator( setRelations );
109 PIDHandler pidHandler( pfos );
113 for (
int i=0; i<pfos->getNumberOfElements(); ++i){
114 streamlog_out(DEBUG9)<<std::endl<<
"Starting to analyze "<<i+1<<
" PFO"<<std::endl;
115 ReconstructedParticle* pfo = static_cast <ReconstructedParticle*> ( pfos->getElementAt(i) );
117 int nClusters = pfo->getClusters().size();
118 int nTracks = pfo->getTracks().size();
120 if( nClusters != 1 || nTracks != 1){
122 vector<float> results{0., 0., 0.};
123 pidHandler.setParticleID(pfo , 0, 0, 0., algoID, results);
126 Track* track = pfo->getTracks()[0];
127 Cluster* cluster = pfo->getClusters()[0];
135 double trackLength = 0.;
136 double harmonicMom = 0.;
137 int nTrackStates = trackStates.size();
138 for(
int j=1; j < nTrackStates; ++j ){
143 if ( nTurns <= 0.5 ) arcLength =
getHelixArcLength( trackStates[j-1], trackStates[j] );
147 trackLength += arcLength;
148 harmonicMom += arcLength/mom.r2();
150 harmonicMom = std::sqrt(trackLength/harmonicMom);
155 double timeOfFlight = 0.;
173 if ( hitSET !=
nullptr ){
174 const vector<LCObject*>& simHitsSET = navigatorSET.getRelatedToObjects( hitSET );
175 if ( simHitsSET.size() >= 2 ){
177 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;
179 SimTrackerHit* simHitSETFront = static_cast <SimTrackerHit*>( simHitsSET[0] );
180 SimTrackerHit* simHitSETBack = static_cast <SimTrackerHit*>( simHitsSET[1] );
181 double timeFront = RandGauss::shoot(simHitSETFront->getTime(),
_timeResolution);
182 double timeBack = RandGauss::shoot(simHitSETBack->getTime(),
_timeResolution);
183 timeOfFlight = (timeFront + timeBack)/2.;
185 else if (simHitsSET.size() == 1){
186 streamlog_out(WARNING)<<
"Found only one SET strip hit! Writing TOF from a single strip."<<std::endl;
187 SimTrackerHit* simHitSET = static_cast <SimTrackerHit*>(simHitsSET[0]);
188 timeOfFlight = RandGauss::shoot(simHitSET->getTime(),
_timeResolution);
192 streamlog_out(WARNING)<<
"Found NO simHits associated with the found SET hit! Writing TOF as 0."<<std::endl;
196 vector<float> results{float(harmonicMom), float(trackLength), float(timeOfFlight)};
197 pidHandler.setParticleID(pfo , 0, 0, 0., algoID, results);
198 streamlog_out(DEBUG9)<<
"Final results for the "<<i+1<<
" PFO"<<std::endl;
199 streamlog_out(DEBUG9)<<
"momentum: "<< float(harmonicMom)<<
" Gev"<<std::endl;
200 streamlog_out(DEBUG9)<<
"track length: "<< float(trackLength)<<
" mm"<<std::endl;
201 streamlog_out(DEBUG9)<<
"time-of-flight: "<< float(timeOfFlight)<<
" ns"<<std::endl;
202 streamlog_out(DEBUG9)<<std::endl<<std::endl;
205 auto endTime = std::chrono::steady_clock::now();
206 std::chrono::duration<double> duration = endTime - startTime;
207 streamlog_out(DEBUG9)<<
"Time spent (sec): "<<duration.count()<<std::endl;
double getHelixLengthAlongZ(const EVENT::TrackState &ts1, const EVENT::TrackState &ts2)
Get track length.
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.
double getHelixNRevolutions(const EVENT::TrackState &ts1, const EVENT::TrackState &ts2)
Get number of helix revolutions.
MarlinTrk::IMarlinTrkSystem * _trkSystem
Kalman Filter System.
double _bField
Stores z component of the magnetic field at the origin in Tesla.
CLHEP::Hep3Vector Vector3D
void init()
Called at the begin of the job before anything is read.
TOFEstimators aTOFEstimators
std::string _pfoCollectionName
Stores ReconstructedParticleCollection steering parameter.
std::vector< std::string > _outputParNames
Stores names of the output parameters.
EVENT::TrackerHit * getSETHit(EVENT::Track *track, double tpcOuterR)
Returns SET hit.
double getTPCOuterR()
Returns TPC outer radius from the DD4hep detector geometry.
std::string _tofMethod
Stores TofMethod steering parameter.
double _tpcOuterR
Stores outer TPC radius in mm.
bool _extrapolateToEcal
Stores ExtrapolateToEcal steering parameter.
std::vector< IMPL::TrackStateImpl > getTrackStatesPerHit(std::vector< EVENT::Track * > tracks, MarlinTrk::IMarlinTrkSystem *trkSystem, bool extrapolateToEcal, double bField)
Get list of track states.
double _timeResolution
Stores TimeResolution 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.
int _maxEcalLayer
Stores MaxEcalLayer steering parameter.
std::vector< EVENT::CalorimeterHit * > selectFrankEcalHits(EVENT::Cluster *cluster, EVENT::Track *track, int maxEcalLayer, double bField)
Get a subset of the cluster calorimeter hits.
double getHelixArcLength(const EVENT::TrackState &ts1, const EVENT::TrackState &ts2)
Get track length.
TOFEstimators()
Default constructor.
std::vector< EVENT::Track * > getSubTracks(EVENT::Track *track)
Get all subtracks of the Track.
void processEvent(EVENT::LCEvent *evt)
Called for every event - the working horse.
dd4hep::rec::Vector3D getHelixMomAtTrackState(const EVENT::TrackState &ts, double bField)
Get track momentum at the track state.
int _nEvent
Stores current event number.