4 #include <EVENT/LCCollection.h>
6 #include "marlin/VerbosityLevels.h"
8 #include <marlin/AIDAProcessor.h>
11 using namespace marlin;
25 "CLICPfoSelectorAnalysis produces a tree and scatter plots using PFO variables defined in the CLICPfoSelector.";
28 registerInputCollection(LCIO::RECONSTRUCTEDPARTICLE,
"PFOCollectionName",
"Name of the PFO collection",
colNamePFOs,
29 string(
"PandoraPFOs"));
31 registerProcessorParameter(
"TreeName",
"Name of output tree",
treeName,
string(
"PfoTree"));
33 registerProcessorParameter(
"CosThetaCut",
"Cut on the PFO cosTheta to define central/forward region",
cutCosTheta,
36 registerProcessorParameter(
37 "MinECalHitsForHadrons",
38 "Min number of Ecal hits to use clusterTime info from Ecal (for neutral and charged hadrons only)",
minECalHits,
41 registerProcessorParameter(
42 "MinHcalEndcapHitsForHadrons",
43 "Min number of Hcal Endcap hits to use clusterTime info from Hcal Endcap (for neutral and charged hadrons only)",
46 registerProcessorParameter(
"ForwardCosThetaForHighEnergyNeutralHadrons",
"ForwardCosThetaForHighEnergyNeutralHadrons",
49 registerProcessorParameter(
"ForwardHighEnergyNeutralHadronsEnergy",
"ForwardHighEnergyNeutralHadronsEnergy",
52 registerProcessorParameter(
"AnalyzePhotons",
"Boolean factor to decide if perform the analysis on photons",
analyzePhotons,
55 registerProcessorParameter(
"AnalyzeChargedPfos",
"Boolean factor to decide if perform the analysis on charged PFOs",
58 registerProcessorParameter(
"AnalyzeNeutralHadrons",
"Boolean factor to decide if perform the analysis on neutral hadrons",
61 registerProcessorParameter(
"AnalyzeAll",
"Boolean factor to decide if perform the analysis on all PFOs",
analyzeAll,
64 registerProcessorParameter(
"AnalyzeSignal",
65 "Boolean factor to decide if perform the analysis only on PFOs belonging to the signal",
68 registerProcessorParameter(
"AnalyzeOverlay",
69 "Boolean factor to decide if perform the analysis on only on PFOs belonging to the overlay",
72 registerProcessorParameter(
"MinEnergy",
"Minimum energy (needed for the energy histos)",
en_min,
float(0));
74 registerProcessorParameter(
"MaxEnergy",
"Maximum energy (needed for the energy histos)",
en_max,
float(500));
76 registerInputCollection(LCIO::MCPARTICLE,
"MCPhysicsParticleCollectionName",
78 std::string(
"MCPhysicsParticles"));
80 registerInputCollection(LCIO::LCRELATION,
"RecoMCTruthLink",
"Name of the RecoMCTruthLink input collection",
83 registerInputCollection(LCIO::LCRELATION,
"SiTracksMCTruthLink",
"Name of the SiTracksMCTruthLink input collection",
86 registerInputCollection(LCIO::LCRELATION,
"ClusterMCTruthLink",
"Name of the ClusterMCTruthLink input collection",
96 AIDAProcessor::histogramFactory(
this);
127 streamlog_out(DEBUG) <<
"CLICPfoSelectorAnalysis ---> set up ttree " << std::endl;
153 std::string graphLabel =
"";
156 graphLabel = ipc +
"_" + igc;
157 streamlog_out(DEBUG) <<
"Analysing followig particle category: " << graphLabel << endl;
162 new TH1F((graphLabel +
"_energy").c_str(), (graphLabel +
"_energy").c_str(), 1000,
en_min,
en_max);
164 new TH1F((graphLabel +
"_energy_central").c_str(), (graphLabel +
"_energy_central").c_str(), 1000,
en_min,
en_max);
166 new TH1F((graphLabel +
"_energy_forward").c_str(), (graphLabel +
"_energy_forward").c_str(), 1000,
en_min,
en_max);
175 streamlog_out(DEBUG) << std::endl;
176 streamlog_out(DEBUG) <<
"CLICPfoSelectorAnalysis ---> new run : run number = " <<
_nRun << std::endl;
180 streamlog_out(DEBUG) <<
"CLICPfoSelectorAnalysis ---> processing run = " <<
_nRun <<
" event = " <<
_nEvt << std::endl;
186 LCCollection* physicsParticleCollection = NULL;
189 }
catch (lcio::DataNotAvailableException&
e) {
191 physicsParticleCollection = NULL;
193 for (
int ipart = 0; ipart < physicsParticleCollection->getNumberOfElements(); ipart++) {
194 MCParticle* signal =
static_cast<MCParticle*
>(physicsParticleCollection->getElementAt(ipart));
197 streamlog_out(DEBUG) <<
physicsParticles.size() <<
" MC Particles belong to the signal." << endl;
200 LCCollection* rmclcol = NULL;
203 }
catch (lcio::DataNotAvailableException& e) {
204 streamlog_out(WARNING) <<
m_recoMCTruthLink <<
" collection not available" << std::endl;
207 if (rmclcol != NULL) {
208 m_reltrue =
new LCRelationNavigator(rmclcol);
212 LCCollection* rtrkclcol = NULL;
215 }
catch (lcio::DataNotAvailableException& e) {
219 if (rtrkclcol != NULL) {
224 LCCollection* rclulcol = NULL;
227 }
catch (lcio::DataNotAvailableException& e) {
231 if (rclulcol != NULL) {
237 streamlog_out(DEBUG) <<
" finished event: " << evt->getEventNumber() <<
" in run: " <<
_nRun << endl;
247 AIDAProcessor::histogramFactory(
this);
248 std::string graphLabel =
"";
251 graphLabel = ipc +
"_" + igc;
252 g_timeVsPt[graphLabel]->Write((graphLabel +
"_timeVsPt").c_str());
258 streamlog_out(DEBUG) <<
"CLICPfoSelectorAnalysis ---> finished " << name() <<
" processed " <<
_nEvt <<
" events in "
259 <<
_nRun <<
" runs " << endl;
263 streamlog_out(DEBUG) <<
"CLICPfoSelectorAnalysis ---> filling TTree " << std::endl;
265 LCCollection* col = evt->getCollection(collName);
268 double en_tot_signal = 0.0;
269 double en_tot_background = 0.0;
271 std::string graphLabel =
"";
274 graphLabel = ipc +
"_" + igc;
283 int nelem = col->getNumberOfElements();
284 streamlog_out(DEBUG) <<
"Number of Input Pfos = " << nelem << endl;
287 for (
int i = 0; i < nelem; i++) {
288 streamlog_out(DEBUG) <<
" --- " << std::endl;
290 ReconstructedParticle* pPfo =
static_cast<ReconstructedParticle*
>(col->getElementAt(i));
291 type = pPfo->getType();
292 px = pPfo->getMomentum()[0];
293 py = pPfo->getMomentum()[1];
294 pz = pPfo->getMomentum()[2];
298 energy = pPfo->getEnergy();
299 mass = pPfo->getMass();
300 charge = pPfo->getCharge();
304 mcvec =
m_reltrue->getRelatedToObjects(pPfo);
307 streamlog_out(DEBUG) <<
" PFO with number of linked MC particles = " << mcvec.size() << endl;
310 if (mcvec.size() > 0) {
311 for (
auto imcp : mcvec) {
312 MCParticle* mc_part =
dynamic_cast<MCParticle*
>(imcp);
314 streamlog_out(DEBUG) <<
" MC Type PDG Energy" << endl;
318 if (mc_part != NULL) {
320 streamlog_out(DEBUG) << output.str();
325 streamlog_out(DEBUG) <<
" -> belongs to the PhysicsParticle (skip the others)" << std::endl;
328 streamlog_out(DEBUG) <<
"-> does not belong to the PhysicsParticle" << std::endl;
337 en_tot_background +=
energy;
340 const TrackVec tracks = pPfo->getTracks();
341 const ClusterVec clusters = pPfo->getClusters();
346 float trackTime = numeric_limits<float>::max();
351 streamlog_out(DEBUG) <<
" PFO with number of tracks = " << tracks.size() << endl;
352 for (
unsigned int trk = 0; trk < tracks.size(); trk++) {
353 const Track* track = tracks[trk];
356 if (fabs(time) < trackTime) {
362 streamlog_out(DEBUG) <<
" PFO with number of clusters = " << clusters.size() << endl;
363 for (
unsigned int clu = 0; clu < clusters.size(); clu++) {
364 float meanTime(999.);
365 float meanTimeEcal(999.);
366 float meanTimeHcalEndcap(999.);
369 int nCaloHitsUsed(0);
371 const Cluster* cluster = clusters[clu];
372 PfoUtil::GetClusterTimes(cluster, meanTime, nCaloHitsUsed, meanTimeEcal, nEcal, meanTimeHcalEndcap, nHcalEnd,
false);
375 if (!tracks.empty()) {
376 meanTime -= trackTime;
377 meanTimeEcal -= trackTime;
378 meanTimeHcalEndcap -= trackTime;
397 for (
unsigned int it = 0; it < tracks.size(); it++) {
399 Track* track = tracks[it];
400 LCObjectVec mctrkvec;
403 if (mctrkvec.size() > 0) {
404 for (
unsigned int ic = 0; ic < clusters.size(); ic++) {
406 Cluster* cluster = clusters[ic];
407 LCObjectVec mccluvec;
412 if (mccluvec.size() > 0) {
413 for (
auto imctrk : mctrkvec) {
416 for (
auto imcclu : mccluvec) {
418 streamlog_out(DEBUG) <<
" -> PFO track and cluster have same MCParticle" << std::endl;
430 streamlog_out(DEBUG) <<
" -> PFO track and cluster have NOT same MCParticle" << std::endl;
435 std::find(particleCategories.begin(), particleCategories.end(),
"photons") != particleCategories.end()) {
438 std::find(particleCategories.begin(), particleCategories.end(),
"neutralHadrons") !=
439 particleCategories.end()) {
440 h_label =
"neutralHadrons";
442 std::find(particleCategories.begin(), particleCategories.end(),
"chargedPfos") !=
443 particleCategories.end()) {
444 h_label =
"chargedPfos";
474 streamlog_out(DEBUG) <<
" Type PDG E Pt cosTheta #trk time #Clu time ecal hcal " << endl;
480 if (clusters.size() == 0)
481 FORMATTED_OUTPUT_TRACK_CLUSTER_full(output,
type,
energy,
pT,
costheta, tracks.size(), trackTime,
"-",
"-",
"-",
483 if (tracks.size() == 0)
486 if (tracks.size() > 0 && clusters.size() > 0)
490 streamlog_out(DEBUG) << output.str();
494 streamlog_out(DEBUG) <<
" " << std::endl;
501 streamlog_out(DEBUG) <<
" Energy: TOTAL = " << en_tot <<
", SIGNAL = " << en_tot_signal
502 <<
", OVERLAY = " << en_tot_background << std::endl;
504 for (
auto ipc : particleCategories) {
506 graphLabel = ipc +
"_" + igc;
510 streamlog_out(DEBUG) <<
" Energy (" << graphLabel <<
" - all ): " <<
energy_tot[graphLabel] << std::endl;
511 streamlog_out(DEBUG) <<
" Energy (" << graphLabel <<
" - central): " <<
energy_tot_central[graphLabel] << std::endl;
512 streamlog_out(DEBUG) <<
" Energy (" << graphLabel <<
" - forward): " <<
energy_tot_forward[graphLabel] << std::endl;
518 Int_t nEntries =
pfo_tree->GetEntries();
519 streamlog_out(DEBUG) <<
"CLICPfoSelectorAnalysis ---> filling plots with TTree (nEntries = " << nEntries <<
")"
522 for (
int ie = 0; ie < nEntries; ie++) {
563 streamlog_out(ERROR) <<
"Cannot fill scatter plots because TGraph for photons was not created. " << endl;
580 g_timeVsPt[
"neutralHadrons_all"]->SetPoint(
g_timeVsPt[
"neutralHadrons_all"]->GetN(),
pT, currentClusterTime);
588 g_timeVsPt[
"neutralHadrons_signal"]->SetPoint(
g_timeVsPt[
"neutralHadrons_signal"]->GetN(),
pT, currentClusterTime);
597 g_timeVsPt[
"neutralHadrons_overlay"]->SetPoint(
g_timeVsPt[
"neutralHadrons_overlay"]->GetN(),
pT, currentClusterTime);
605 streamlog_out(ERROR) <<
"Cannot fill scatter plots because TGraph for neutralHadrons was not created. " << endl;
630 g_timeVsPt[
"chargedPfos_signal"]->SetPoint(
g_timeVsPt[
"chargedPfos_signal"]->GetN(),
pT, currentClusterTime);
639 g_timeVsPt[
"chargedPfos_overlay"]->SetPoint(
g_timeVsPt[
"chargedPfos_overlay"]->GetN(),
pT, currentClusterTime);
647 streamlog_out(ERROR) <<
"Cannot fill scatter plots because TGraph for chargedPfos was not created. " << endl;
CLICPfoSelectorAnalysis()
#define FORMATTED_OUTPUT_MC(out, N1, E1)
LCRelationNavigator * m_clureltrue
TH1F * h_energy_tot_signal
virtual void processEvent(LCEvent *evt)
#define FORMATTED_OUTPUT_TRACK_CLUSTER_full(out, N1, E1, E2, E3, N2, E4, N3, E5, E6, E7)
float forwardCosThetaForHighEnergyNeutralHadrons
double clusterTimeHcalEndcap
map< string, double > energy_tot_central
float forwardHighEnergyNeutralHadronsEnergy
float TimeAtEcal(const Track *pTrack, float &tof)
string m_inputPhysicsParticleCollection
map< string, TH1F * > h_energy_central
vector< string > generationCategories
map< string, TH1F * > h_energy
vector< string > particleCategories
void fillTree(LCEvent *evt, string collName)
map< string, double > energy_tot_forward
map< string, TH1F * > h_energy_forward
string m_ClusterMCTruthLink
LCRelationNavigator * m_reltrue
string m_SiTracksMCTruthLink
void GetClusterTimes(const Cluster *cluster, float &meanTime, int &nCaloHitsUsed, float &meanTimeEcal, int &nEcal, float &meanTimeHcalEndcap, int &nHcalEnd, bool correctHitTimesForTimeOfFlight)
virtual void processRunHeader(LCRunHeader *run)
vector< MCParticle * > physicsParticles
bool analyzeNeutralHadrons
map< string, TGraph * > g_timeVsPt
LCRelationNavigator * m_trackreltrue
map< string, double > energy_tot
map< string, TGraph * > g_timeVsPt_forward
CLICPfoSelectorAnalysis processor.
TH1F * h_energy_tot_background
CLICPfoSelectorAnalysis aCLICPfoSelectorAnalysis
map< string, TGraph * > g_timeVsPt_central