3 #include <EVENT/LCCollection.h>
4 #include <EVENT/MCParticle.h>
5 #include <EVENT/SimTrackerHit.h>
6 #include <EVENT/Track.h>
7 #include <EVENT/TrackerHit.h>
9 #include <IMPL/LCCollectionVec.h>
11 #include <CalorimeterHitType.h>
12 #include <marlinutil/GeometryUtil.h>
18 using namespace marlin;
27 _description =
"Selects Pfos from full PFO list using timing cuts";
31 registerInputCollection(LCIO::RECONSTRUCTEDPARTICLE,
"InputPfoCollection",
"Input PFO Collection",
m_inputPfoCollection,
32 std::string(
"PandoraPFANewPFOs"));
35 registerOutputCollection(LCIO::RECONSTRUCTEDPARTICLE,
"SelectedPfoCollection",
"Selected pfo collection name",
38 registerProcessorParameter(
"Monitoring",
"Monitoring",
m_monitoring,
int(0));
40 registerProcessorParameter(
"DisplaySelectedPfos",
"DisplaySelectedPfos",
m_displaySelectedPfos,
int(0));
42 registerProcessorParameter(
"DisplayRejectedPfos",
"DisplayRejectedPfos",
m_displayRejectedPfos,
int(0));
44 registerProcessorParameter(
"CorrectHitTimesForTimeOfFlight",
"CorrectHitTimesForTimeOfFlight",
52 registerProcessorParameter(
"CheckKaonCorrection",
"CheckKaonCorrection",
m_checkKaonCorrection,
int(0));
54 registerProcessorParameter(
"KeepKShorts",
"KeepKShorts",
m_keepKShorts,
int(1));
56 registerProcessorParameter(
"UseNeutronTiming",
"UseNeutronTiming",
m_useNeutronTiming,
int(0));
58 registerProcessorParameter(
"MinimumEnergyForNeutronTiming",
"MinimumEnergyForNeutronTiming",
61 registerProcessorParameter(
"ForwardCosThetaForHighEnergyNeutralHadrons",
"ForwardCosThetaForHighEnergyNeutralHadrons",
64 registerProcessorParameter(
"ForwardHighEnergyNeutralHadronsEnergy",
"ForwardHighEnergyNeutralHadronsEnergy",
67 registerProcessorParameter(
"FarForwardCosTheta",
"FarForwardCosTheta",
m_farForwardCosTheta,
float(0.975));
69 registerProcessorParameter(
"PtCutForTightTiming",
"PtCutForTightTiming",
m_ptCutForTightTiming,
float(0.75));
71 registerProcessorParameter(
"PhotonPtCut",
"PhotonPtCut",
m_photonPtCut,
float(0.0));
76 registerProcessorParameter(
"PhotonLooseTimingCut",
"PhotonLooseTimingCut",
m_photonLooseTimingCut,
float(2.0));
78 registerProcessorParameter(
"PhotonTightTimingCut",
"PhotonTightTimingCut",
m_photonTightTimingCut,
float(1.0));
80 registerProcessorParameter(
"ChargedPfoPtCut",
"ChargedPfoPtCut",
m_chargedPfoPtCut,
float(0.0));
82 registerProcessorParameter(
"ChargedPfoPtCutForLooseTiming",
"ChargedPfoPtCutForLooseTiming",
89 registerProcessorParameter(
"ChargedPfoNegativeLooseTimingCut",
"ChargedPfoNegativeLooseTimingCut",
92 registerProcessorParameter(
"ChargedPfoNegativeTightTimingCut",
"ChargedPfoNegativeTightTimingCut",
95 registerProcessorParameter(
"NeutralHadronPtCut",
"NeutralHadronPtCut",
m_neutralHadronPtCut,
float(0.0));
97 registerProcessorParameter(
"NeutralHadronPtCutForLooseTiming",
"NeutralHadronPtCutForLooseTiming",
106 registerProcessorParameter(
"NeutralFarForwardLooseTimingCut",
"NeutralFarForwardLooseTimingCut",
109 registerProcessorParameter(
"NeutralFarForwardTightTimingCut",
"NeutralFarForwardTightTimingCut",
112 registerProcessorParameter(
"PhotonFarForwardLooseTimingCut",
"PhotonFarForwardLooseTimingCut",
115 registerProcessorParameter(
"PhotonFarForwardTightTimingCut",
"PhotonFarForwardTightTimingCut",
124 registerProcessorParameter(
"HCalEndCapTimingFactor",
"HCalEndCapTimingFactor",
m_hCalEndCapTimingFactor,
float(1.0));
126 registerProcessorParameter(
"NeutralHadronBarrelPtCutForLooseTiming",
"NeutralHadronBarrelPtCutForLooseTiming",
129 registerProcessorParameter(
"MinECalHitsForTiming",
"MinECalHitsForTiming",
m_minECalHitsForTiming,
int(5));
134 registerProcessorParameter(
"UseClusterLessPfos",
"UseClusterLessPfos",
m_useClusterLessPfos,
int(1));
136 registerProcessorParameter(
"MinMomentumForClusterLessPfos",
"MinMomentumForClusterLessPfos",
139 registerProcessorParameter(
"MaxMomentumForClusterLessPfos",
"MaxMomentumForClusterLessPfos",
153 _bField = MarlinUtil::getBzAtOrigin();
159 streamlog_out(DEBUG) << std::endl;
160 streamlog_out(DEBUG) <<
"CLICPfoSelector ---> new run : run number = " <<
_nRun << std::endl;
164 streamlog_out(DEBUG) <<
"CLICPfoSelector -> run = " <<
_nRun <<
" event = " <<
_nEvt << std::endl;
167 colPFO->setSubset(
true);
175 int nelem = col->getNumberOfElements();
178 for (
int iPfo = 0; iPfo < nelem; ++iPfo)
179 pfos.push_back(static_cast<ReconstructedParticle*>(col->getElementAt(iPfo)));
183 streamlog_out(MESSAGE) << std::endl;
184 streamlog_out(MESSAGE) <<
"Number of Input Pfos = " << nelem << std::endl;
185 streamlog_out(MESSAGE) <<
" Type PDG E Pt cosTheta #trk time #Clu time ecal hcal "
190 float eTotalInput(0.);
191 float eTotalOutput(0.);
193 for (
int iPfo = 0; iPfo < nelem; ++iPfo) {
194 bool passPfoSelection =
true;
195 ReconstructedParticle* pPfo = pfos[iPfo];
197 const int type = pPfo->getType();
200 for (
unsigned int i = 0; i < 3; i++)
201 momentum[i] = pPfo->getMomentum()[i];
202 const float pT_pfo = sqrt(momentum[0] * momentum[0] + momentum[1] * momentum[1]);
203 const float p_pfo = sqrt(pT_pfo * pT_pfo + momentum[2] * momentum[2]);
204 const float cosTheta = fabs(momentum[2]) / p_pfo;
205 const float energy = pPfo->getEnergy();
206 eTotalInput += energy;
208 const ClusterVec clusters = pPfo->getClusters();
209 const TrackVec tracks = pPfo->getTracks();
212 float trackTime = std::numeric_limits<float>::max();
213 float clusterTime = 999.;
214 float clusterTimeEcal = 999.;
215 float clusterTimeHcalEndcap = 999.;
217 int nHcalEndCapHits(0);
222 for (
unsigned int i = 0; i < tracks.size(); i++) {
223 const Track* track = tracks[i];
224 const float d0 = track->getD0();
225 const float z0 = track->getZ0();
226 const float omega = track->getOmega();
227 const float tanL = track->getTanLambda();
228 const float phi0 = track->getPhi();
231 helix.Initialize_Canonical(phi0, d0, z0, omega, tanL,
_bField);
232 const float px = helix.getMomentum()[0];
233 const float py = helix.getMomentum()[1];
234 const float pz = helix.getMomentum()[2];
235 const float p = sqrt(px * px + py * py + pz * pz);
238 if (fabs(time) < trackTime) {
240 const float cproton = sqrt((p * p + 0.94 * 0.94) / (p * p + 0.14 * 0.14));
241 const float ckaon = sqrt((p * p + 0.49 * 0.49) / (p * p + 0.14 * 0.14));
242 tproton = (trackTime + tof) * (cproton - 1);
243 tkaon = (trackTime + tof) * (ckaon - 1);
247 for (
unsigned int i = 0; i < clusters.size(); i++) {
248 float meanTime(999.);
249 float meanTimeEcal(999.);
250 float meanTimeHcalEndcap(999.);
253 int nCaloHitsUsed(0);
255 const Cluster* cluster = clusters[i];
260 if (!tracks.empty()) {
261 meanTime -= trackTime;
262 meanTimeEcal -= trackTime;
263 meanTimeHcalEndcap -= trackTime;
266 if (fabs(meanTime) < clusterTime) {
267 clusterTime = meanTime;
268 nCaloHits = nCaloHitsUsed;
270 if (fabs(meanTimeEcal) < clusterTimeEcal) {
271 clusterTimeEcal = meanTimeEcal;
274 if (fabs(meanTimeHcalEndcap) < clusterTimeHcalEndcap) {
275 clusterTimeHcalEndcap = meanTimeHcalEndcap;
276 nHcalEndCapHits = nHcalEnd;
284 float timingCutLow(0.);
314 if (!tracks.empty()) {
326 if (pT_pfo < ptCut) {
327 passPfoSelection =
false;
332 passPfoSelection =
false;
338 bool applyTimingCuts =
343 if (passPfoSelection && applyTimingCuts) {
345 bool selectPfo(
false);
347 if (!clusters.empty()) {
350 if ((clusterTimeEcal >= timingCutLow) && (clusterTimeEcal <= timingCutHigh))
352 }
else if (type == 22) {
353 if ((clusterTime >= timingCutLow) && (clusterTime <= timingCutHigh))
356 if ((clusterTimeHcalEndcap >= timingCutLow) &&
360 if ((clusterTime >= timingCutLow) && (clusterTime < hCalBarrelTimingCut))
370 streamlog_out(MESSAGE) <<
" Recovered KS : " << energy << std::endl;
376 (clusterTimeEcal - tproton <= timingCutHigh)) {
378 streamlog_out(MESSAGE) <<
" Recovered proton : " << energy << std::endl;
382 (clusterTimeEcal - tkaon <= timingCutHigh)) {
384 streamlog_out(MESSAGE) <<
" Recovered kaon : " << energy << std::endl;
396 passPfoSelection =
false;
401 std::stringstream output;
402 output << std::fixed;
404 if (passPfoSelection) {
405 output <<
" Selected PFO : ";
407 output <<
" Rejected PFO : ";
409 if (clusters.size() == 0)
412 if (tracks.size() == 0)
414 clusterTime, clusterTimeEcal, clusterTimeHcalEndcap);
415 if (tracks.size() > 0 && clusters.size() > 0)
417 clusters.size(), clusterTime, clusterTimeEcal, clusterTimeHcalEndcap);
418 streamlog_out(MESSAGE) << output.str();
421 if (passPfoSelection) {
422 eTotalOutput += energy;
423 colPFO->addElement(pPfo);
430 streamlog_out(MESSAGE) <<
" Total PFO energy in = " << eTotalInput <<
" GeV " << std::endl;
431 streamlog_out(MESSAGE) <<
" Total PFO energy out = " << eTotalOutput <<
" GeV " << std::endl;
433 }
catch (DataNotAvailableException&
e) {
434 streamlog_out(MESSAGE) <<
m_inputPfoCollection.c_str() <<
" collection is unavailable" << std::endl;
float m_chargedPfoNegativeTightTimingCut
The charged hadron tight low timing cut.
#define FORMATTED_OUTPUT_TRACK_CLUSTER_full(out, N1, E1, E2, E3, N2, E4, N3, E5, E6, E7)
std::string m_selectedPfoCollection
Output PFO collection name.
virtual void check(LCEvent *evt)
float m_farForwardCosTheta
Value of cos theta identifying the detector forward region.
float m_neutralHadronTightTimingCut
The neutral hadron tight high timing cut.
float m_neutralHadronBarrelPtCutForLooseTiming
pt above which loose timing cuts are applied to neutral hadrons in barrel
int m_checkProtonCorrection
Check proton hypothesis.
int m_checkKaonCorrection
Check charged hypothesis.
float m_ptCutForTightTiming
The pt value below which tight timing cuts are used.
CLICPfoSelector aCLICPfoSelector
int m_monitoring
Whether to display monitoring information.
float m_clusterLessPfoTrackTimeCut
Maximum arrival time at Ecal for cluster-less pfo.
float TimeAtEcal(const Track *pTrack, float &tof)
float m_photonFarForwardLooseTimingCut
The photon loose high timing cut for the forward region.
float m_minimumEnergyForNeutronTiming
Minimum energy for attempted neutron timing correction.
int m_useNeutronTiming
Attempt to make a (dubious) neutron timing correction.
float m_chargedPfoPtCut
The basic pt cut for a charged hadron pfo.
std::vector< EVENT::ReconstructedParticle * > PfoList
int m_minHCalEndCapHitsForTiming
Minimum hcal endcap hits in order to use hcal endcap timing info.
int m_useClusterLessPfos
Whether to accept any cluster-less pfos.
float m_neutralHadronLooseTimingCut
The neutral hadron loose high timing cut.
float m_chargedPfoPtCutForLooseTiming
The charged hadron pt value below which tight timing cuts are used.
float m_maxMomentumForClusterLessPfos
Minimum momentum for a cluster-less pfo.
float m_neutralFarForwardLooseTimingCut
The neutral hadron loose high timing cut for the forward region.
int m_correctHitTimesForTimeOfFlight
Correct hit times for straight line time of flight.
float m_chargedPfoLooseTimingCut
The charged hadron loose high timing cut.
virtual void processEvent(LCEvent *evt)
float m_neutralHadronPtCut
The basic pt cut for a neutral hadron pfo.
float m_photonPtCutForLooseTiming
The photon pt value below which tight timing cuts are used.
=== CLICPfoSelector Processor === Processor to select good pfos based on timing ...
float m_hCalBarrelLooseTimingCut
The loose timing cut for hits predominantly in hcal barrel.
float m_chargedPfoTightTimingCut
The charged hadron tight high timing cut.
float m_minMomentumForClusterLessPfos
Minimum momentum for a cluster-less pfo.
int m_minECalHitsForTiming
Minimum ecal hits in order to use ecal timing info.
float m_hCalBarrelTightTimingCut
The tight timing cut for hits predominantly in hcal barrel.
float m_forwardCosThetaForHighEnergyNeutralHadrons
Forward region of HCAL where timing cuts will be applied to all neutral hadrons.
int m_displaySelectedPfos
Whether to display monitoring information concerning selected pfos.
static bool PfoSortFunction(EVENT::ReconstructedParticle *lhs, EVENT::ReconstructedParticle *rhs)
std::vector< LCCollection * > LCCollectionVec
void GetClusterTimes(const Cluster *cluster, float &meanTime, int &nCaloHitsUsed, float &meanTimeEcal, int &nEcal, float &meanTimeHcalEndcap, int &nHcalEnd, bool correctHitTimesForTimeOfFlight)
float m_neutralFarForwardTightTimingCut
The neutral hadron tight high timing cut for the forward region.
int m_displayRejectedPfos
Whether to display monitoring information concerning rejected pfos.
float m_photonPtCut
The basic pt cut for a photon pfo.
float m_minPtForClusterLessPfos
Minimum pT for a cluster-less pfo.
float m_forwardHighEnergyNeutralHadronsEnergy
Energy cut for specific HCAL timing requirements cuts for neutral hadrons.
float m_neutralHadronPtCutForLooseTiming
The neutral hadron pt value below which tight timing cuts are used.
float m_monitoringPfoEnergyToDisplay
Minimum pfo energy in order to display monitoring information.
std::string m_inputPfoCollection
Input PFO collection name.
float m_hCalEndCapTimingFactor
Factor by which high timing cut is multiplied for hcal barrel hits.
float m_photonTightTimingCut
The photon tight high timing cut.
int m_keepKShorts
Keep kshorts.
virtual void processRunHeader(LCRunHeader *run)
float m_photonFarForwardTightTimingCut
The photon tight high timing cut for the forward region.
float m_chargedPfoNegativeLooseTimingCut
The charged hadron loose low timing cut.
float m_photonLooseTimingCut
The photon loose high timing cut.