hpstr
The Heavy Photon Search Toolkit for Reconstruction (hpstr) provides an interface to physics data from the HPS experiment saved in the LCIO format and converts it into an ROOT based format.
All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
TrackEfficiencyProcessor.cxx
Go to the documentation of this file.
1
9#include <iostream>
10#include <utility>
11TrackEfficiencyProcessor::TrackEfficiencyProcessor(const std::string& name, Process& process) : Processor(name,process) {
12
13}
14
15//TODO Check this destructor
16
18
20 std::cout << "Configuring TrackEfficiencyProcessor" <<std::endl;
21 try
22 {
23 debug_ = parameters.getInteger("debug");
24 anaName_ = parameters.getString("anaName");
25 // cluColl_ = parameters.getString("cluColl");
26 fspartColl_ = parameters.getString("fspartColl");
27 // trkColl_ = parameters.getString("trkColl");
28 // trkSelCfg_ = parameters.getString("trkSelectionjson");
29 cluSelCfg_ = parameters.getString("cluSelectionjson");
30 cluHistoCfg_ = parameters.getString("cluHistoCfg");
31 histoCfg_ = parameters.getString("histoCfg");
32 thrProngCfg_ = parameters.getString("thrProngCfg");
33 timeOffset_ = parameters.getDouble("CalTimeOffset");
34 beamE_ = parameters.getDouble("beamE");
35 isData = parameters.getInteger("isData");
36
37 //region definitions
38 regionSelections_ = parameters.getVString("regionDefinitions");
39 threeProngSelections_ = parameters.getVString("threeProngDefinitions");
40
41
42 }
43 catch (std::runtime_error& error)
44 {
45 std::cout<<error.what()<<std::endl;
46 }
47}
48
50 tree_ = tree;
51 _ah = std::make_shared<AnaHelpers>();
52
53 // trkSelector = std::make_shared<BaseSelector>("trkSelection",trkSelCfg_);
54 //trkSelector->setDebug(debug_);
55 // trkSelector->LoadSelection();
56 std::cout<<"Setting up cluster selector and trkeff histos"<<std::endl;
57 cluSelector = std::make_shared<BaseSelector>("cluSelection",cluSelCfg_);
58 cluSelector->setDebug(debug_);
59 cluSelector->LoadSelection();
60 std::cout<<"Setting up cluster selection"<<std::endl;
61 _trkeff_histos = std::make_shared<TrackEfficHistos>("clusterSelection",_ah);
62 _trkeff_histos->loadHistoConfig(cluHistoCfg_);
63 std::cout<<"Setting cal time offset in histograms to "<<timeOffset_<<std::endl;
64 _trkeff_histos->SetCalTimeOffset(timeOffset_);
65 _trkeff_histos->DefineHistos();
66
67
68 // //For each region initialize plots
69 std::cout<<"Number of regions = "<<regionSelections_.size()<<std::endl;
70 for (unsigned int i_reg = 0; i_reg < regionSelections_.size(); i_reg++) {
71 std::string regname = AnaHelpers::getFileName(regionSelections_[i_reg],false);
72 std::cout<<"Setting up region:: " << regname <<std::endl;
73 _reg_trkeff_selectors[regname] = std::make_shared<BaseSelector>(regname, regionSelections_[i_reg]);
74 _reg_trkeff_selectors[regname]->setDebug(debug_);
75 _reg_trkeff_selectors[regname]->LoadSelection();
76
77 _reg_trkeff_histos[regname] = std::make_shared<TrackEfficHistos>(regname,_ah);
78 _reg_trkeff_histos[regname]->loadHistoConfig(histoCfg_);
79 _reg_trkeff_histos[regname]->DefineHistos();
80
81 _regions.push_back(regname);
82 }
83 // //For each three-prong region initialize plots
84 std::cout<<"Number of regions = "<<threeProngSelections_.size()<<std::endl;
85 for (unsigned int i_reg = 0; i_reg < threeProngSelections_.size(); i_reg++) {
86 std::string regname = AnaHelpers::getFileName(threeProngSelections_[i_reg],false);
87 std::cout<<"Setting up region:: " << regname <<std::endl;
88 _reg_three_prong_trkeff_selectors[regname] = std::make_shared<BaseSelector>(regname, threeProngSelections_[i_reg]);
89 _reg_three_prong_trkeff_selectors[regname]->setDebug(debug_);
90 _reg_three_prong_trkeff_selectors[regname]->LoadSelection();
91 std::cout<<"Configuring histos with:: " << thrProngCfg_ <<std::endl;
92 _reg_three_prong_trkeff_histos[regname] = std::make_shared<ThreeProngHistos>(regname);
93 _reg_three_prong_trkeff_histos[regname]->loadHistoConfig(thrProngCfg_);
94 _reg_three_prong_trkeff_histos[regname]->DefineHistos();
95 _reg_three_prong_trkeff_histos[regname]->setBeamEnergy(beamE_);
96
97 _three_prong_regions.push_back(regname);
98 }
99
100
101 //init Reading Tree
102 tree_->SetBranchAddress(fspartColl_.c_str(), &fspart_ , &bfspart_);
103 tree_->SetBranchAddress("EventHeader",&evth_ , &bevth_);
104
105 //If track and/or cluster collection name is empty take the tracks from the particles.
106 if (!cluColl_.empty())
107 tree_->SetBranchAddress(cluColl_.c_str(),&clus_, &bclus_);
108 if (!trkColl_.empty())
109 tree_->SetBranchAddress(trkColl_.c_str(),&trks_, &btrks_);
110}
111
113
114 HpsEvent* hps_evt = (HpsEvent*) ievent;
115 double weight = 1.;
116
117 //Store processed number of events
118 //std::vector<std::pair<CalCluster*,Track*> > goodEleSide;
119 //std::vector<std::pair<CalCluster*,Track*> > goodPosSide;
120 std::vector<Particle*> goodEleSide;
121 std::vector<Particle*> goodPosSide;
122 std::vector<Particle*> goodAll;
123
124
125 // std::cout<<"Number of final state particles = "<<fspart_->size()<<std::endl;
126 // std::cout<<"Number of clusters = "<<clus_->size()<<std::endl;
127 int n_pass_clus_time=0;
128 int n_clusters_event=0;
129 for(int i_part=0;i_part<fspart_->size();i_part++){
130 Particle* part=fspart_->at(i_part);
131 CalCluster cluster=part->getCluster();
132 //std::cout<<"Number of hits in cluster = "<<cluster.getNHits()<<std::endl;
133 if(cluster.getNHits()>0)
134 n_clusters_event++;
135
136 // loose cuts on the cluster energy and time...
137 // these will also select only those particles with clusters
138 // unmatched clusters are ok, no unmatched tracks though
139 // std::cout<<"cluster time = "<<cluster.getTime()<<"; offset is "<<timeOffset_<<std::endl;
140 if (!cluSelector->passCutGt("cluEne_gt",cluster.getEnergy(),weight))
141 continue;
142 if (!cluSelector->passCutLt("cluTime_lt",cluster.getTime()-timeOffset_,weight))
143 continue;
144 if (!cluSelector->passCutGt("cluTime_gt",cluster.getTime()-timeOffset_,weight))
145 continue;
146 //found a good cluster...check if ele or pos side and match to particle if there is one
147 // if(cluster->getPosition().at(0)<-270.0){
148 //std::cout<<"Cluster passed! "<<std::endl;
149 //std::cout<<"GOOD cluster: clX = "<<cluster.getPosition().at(0)<<std::endl;
150 // }
151 goodAll.push_back(part);
152 double clX=cluster.getPosition().at(0);
153 if(clX>0){
154 goodPosSide.push_back(part);
155 } else {
156 goodEleSide.push_back(part);
157 }
158 n_pass_clus_time++;
159 _trkeff_histos->FillPreSelectionPlots(&cluster,weight);
160
161 }
162 _trkeff_histos->Fill1DHisto("nClusters_all_h",n_clusters_event);
163
164 /*
165 for (int i_clu=0;i_clu<clus_->size(); i_clu++){
166 CalCluster* cluster=clus_->at(i_clu);
167 std::pair<CalCluster*, Track*> clTrkPair=_trkeff_histos->getClusterTrackPair(cluster,*trks_);
168 // if(cluster->getPosition().at(0)<-270.0){
169 // std::cout<<"large -X cluster: clX = "<<cluster->getPosition().at(0)<<std::endl;
170 //}
171 if (!cluSelector->passCutGt("cluEne_gt",cluster->getEnergy(),weight))
172 continue;
173 if (!cluSelector->passCutLt("cluTime_lt",cluster->getTime()-timeOffset_,weight))
174 continue;
175 if (!cluSelector->passCutGt("cluTime_gt",cluster->getTime()-timeOffset_,weight))
176 continue;
177 // found a good cluster...check if ele or pos side and match to particle if there is one
178 // if(cluster->getPosition().at(0)<-270.0){
179 //std::cout<<"GOOD large -X cluster: clX = "<<cluster->getPosition().at(0)<<std::endl;
180 // }
181 double clX=cluster->getPosition().at(0);
182 if(clX>0){
183 goodPosSide.push_back(clTrkPair);
184 } else {
185 goodEleSide.push_back(clTrkPair);
186 }
187 n_pass_trig_time++;
188 _trkeff_histos->FillPreSelectionPlots(cluster,weight);
189 }
190 */
191 _trkeff_histos->Fill1DHisto("nClusters_pass_trig_time_h",n_pass_clus_time);
192
193 //cluster pair candidates
194 std::vector<TridentCand> triPairs;
195 for (int i_part=0; i_part<goodEleSide.size();i_part++){
196 Particle* partEle=goodEleSide.at(i_part);
197 CalCluster cluEle=partEle->getCluster();//this already for sure exists
198 //std::cout<<"Got electron cluster"<<std::endl;
199 for (int j_part=0; j_part<goodPosSide.size();j_part++){
200 Particle* partPos=goodPosSide.at(j_part);
201 CalCluster cluPos=partPos->getCluster();//this already for sure exists
202 double cluEleY=cluEle.getPosition().at(1);
203 double cluPosY=cluPos.getPosition().at(1);
204 double cluEleTime=cluEle.getTime();
205 double cluPosTime=cluPos.getTime();
206 // if(cluEle->getPosition().at(0)<-265.0){
207 // std::cout<<"large -X cluster: clX = "<<cluEle->getPosition().at(0)<<" time = "<<cluEleTime<<" diff = "<<abs(cluEleTime-cluPosTime)<<std::endl;
208 //}
209 if(cluEleY*cluPosY>0) { //just want top/bottom tracks
210 // std::cout<<"Both top or bottom"<<std::endl;
211 continue;
212 }
213
214 if (!cluSelector->passCutLt("cluTimeDiff_lt",abs(cluEleTime-cluPosTime),weight)){
215 // std::cout<<"Cluster time difference too big "<<abs(cluEleTime-cluPosTime)<<std::endl;
216 continue;
217 }
218 _trkeff_histos->FillPairSelectionPlots(&cluEle,&cluPos,weight);
219 TridentCand epemPair={partEle,partPos};
220 triPairs.push_back(epemPair);
221
222 }
223 }
224 _trkeff_histos->Fill1DHisto("nClusterPairs_pass_bunch_time_h",triPairs.size());
225
226
227 //make a 3-prong candidate by looping over 2-prong (trident) pairs
228 //and adding another particle from "goodAll" list
229 //I am allowing the "recoil" to be on either electron or positron side...
230 //I can require that recoil is in electron side in region cuts if I want to
231 std::vector<ThreeProngCand> threeProngers;
232 // std::cout<<"Looking for 3-prongers from triPairs n = "<<triPairs.size()<<std::endl;
233 for (int i_pair=0; i_pair<triPairs.size();i_pair++){
234 TridentCand epemPair(triPairs.at(i_pair));
235 Particle* partEle=epemPair.ele;
236 Particle* partPos=epemPair.pos;
237 CalCluster cluEle=partEle->getCluster();
238 CalCluster cluPos=partPos->getCluster();
239 double cluEleTime=cluEle.getTime();
240 double cluPosTime=cluPos.getTime();
241 double cluEleEne=cluEle.getEnergy();
242 double cluPosEne=cluPos.getEnergy();
243 /*
244 std::cout<<"Electron Cluster Time = "<<cluEleTime<<std::endl;
245 std::cout<<"Positron Cluster Time = "<<cluPosTime<<std::endl;
246 std::cout<<"looping over all good particles = "<<goodAll.size()<<std::endl;
247 */
248 for (int k_all=0; k_all<goodAll.size(); k_all++){
249 Particle* partRec=goodAll.at(k_all);
250 CalCluster cluRec=partRec->getCluster();//this already for sure exists
251 double cluRecTime=cluRec.getTime();
252 double cluRecEne=cluRec.getEnergy();
253 // std::cout<<"Checking new particle with cluster time = "<<cluRecTime<<std::endl;
254 if(partRec == partEle || partRec==partPos){
255 // std::cout<<"in 3-prong finder::Found an overlapping ele or pos...skip it"<<std::endl;
256 continue;
257 }
258 //check if it's in the cluster dt of both ele and pos...if so, it's good for now
259 if (!cluSelector->passCutLt("cluTimeDiff_lt",abs(cluEleTime-cluRecTime),weight))
260 continue;
261 if (!cluSelector->passCutLt("cluTimeDiff_lt",abs(cluPosTime-cluRecTime),weight))
262 continue;
263
264 //ok...let's make sure we haven't added this one already in a different combination...
265 //to do...make a function for this.
266 bool foundExistingPronger=false;
267 for(int j_3p=0;j_3p<threeProngers.size();j_3p++){
268 ThreeProngCand check3Pronger=threeProngers.at(j_3p);
269 Particle* checkPos=check3Pronger.pos;
270 Particle* checkEle=check3Pronger.ele;
271 Particle* checkRec=check3Pronger.recoil;
272 bool eleMatches=false;
273 bool recMatches=false;
274 bool posMatches=false;
275 if(checkEle==partEle ||checkEle==partRec)
276 eleMatches=true;
277 if(checkPos==partPos ||checkPos==partRec)
278 posMatches=true;
279 if(checkRec==partRec ||checkEle==partRec ||checkPos==partRec)
280 recMatches=true;
281 if(eleMatches && posMatches && recMatches)
282 foundExistingPronger=true;
283 // std::cout<<"found an exising pronger...."<<std::endl;
284 }
285 if(!foundExistingPronger){
286 ThreeProngCand this3Pronger={partEle,partPos,partRec};
287 if(cluRecEne>cluEleEne)//flip the order so highest energy "electron" is labeled "ele" and lowest is "recoil"
288 this3Pronger={partRec,partPos,partEle};
289 threeProngers.push_back(this3Pronger);
290 }
291 }
292 }
293 if(threeProngers.size()>0)
294 std::cout<<"Number of 3-prongers found = "<<threeProngers.size()<<std::endl;
295
296 // std::cout<<"#Good cluster pairs = "<<triPairs.size()<<std::endl;
297 for (auto region : _regions ) {
298 for (int i_pair=0; i_pair<triPairs.size();i_pair++){
299 TridentCand epemPair(triPairs.at(i_pair));
300 // std::pair<CalCluster*,Track*> electron=epemPair.ele;
301 // std::pair<CalCluster*,Track*> positron=epemPair.pos;
302 Particle* partEle=epemPair.ele;
303 Particle* partPos=epemPair.pos;
304 CalCluster electron=partEle->getCluster();
305 CalCluster positron=partPos->getCluster();
306 bool isFiducialElectron=_ah->IsECalFiducial(&electron);
307 bool isFiducialPositron=_ah->IsECalFiducial(&positron);
308 double clusterESum=electron.getEnergy()+positron.getEnergy();
309
310 if (!_reg_trkeff_selectors[region]->passCutLt("nClustersCut",n_clusters_event,weight))
311 continue;
312 if (!_reg_trkeff_selectors[region]->passCutLt("nClustersTrigTimeCut",n_pass_clus_time,weight))
313 continue;
314 if (!_reg_trkeff_selectors[region]->passCutGt("cluESum",clusterESum,weight))
315 continue;
316 if (!_reg_trkeff_selectors[region]->passCutLt("cluESumLt",clusterESum,weight))
317 continue;
318 if (!_reg_trkeff_selectors[region]->passCutEq("cluFiducialElectron",isFiducialElectron,weight))
319 continue;
320 if (!_reg_trkeff_selectors[region]->passCutEq("cluFiducialPositron",isFiducialPositron,weight))
321 continue;
322
323 // double coplan=_ah->GetClusterCoplanarity(electron.first, positron.first);
324
325 //if(!_reg_trkeff_selectors[region]->passCutLt("cluCoplan",abs(coplan-180.0),weight))
326 //continue;
327
328 _reg_trkeff_histos[region]->FillEffPlots(partEle,partPos,weight);
329
330 }
331 }
332
333
334 for (auto region : _three_prong_regions ) {
335 for (int i_pair=0; i_pair<threeProngers.size();i_pair++){
336 ThreeProngCand threeProng(threeProngers.at(i_pair));
337 // std::pair<CalCluster*,Track*> electron=epemPair.ele;
338 // std::pair<CalCluster*,Track*> positron=epemPair.pos;
339 std::cout<<"analyzing a three pronger"<<std::endl;
340 Particle* partEle=threeProng.ele;
341 Particle* partRec=threeProng.recoil;
342 Particle* partPos=threeProng.pos;
343 CalCluster electron=partEle->getCluster();
344 CalCluster positron=partPos->getCluster();
345 CalCluster recoil=partRec->getCluster();
346 bool isFiducialElectron=_ah->IsECalFiducial(&electron);
347 bool isFiducialPositron=_ah->IsECalFiducial(&positron);
348 bool isFiducialRecoil=_ah->IsECalFiducial(&recoil);
349 double clusterESum=electron.getEnergy()+positron.getEnergy()+recoil.getEnergy();
350 std::cout<<"three pronger eSum = "<<clusterESum<<std::endl;
351
352 if (!_reg_three_prong_trkeff_selectors[region]->passCutLt("nClustersCut",n_clusters_event,weight))
353 continue;
354 if (!_reg_three_prong_trkeff_selectors[region]->passCutLt("nClustersTrigTimeCut",n_pass_clus_time,weight))
355 continue;
356 if (!_reg_three_prong_trkeff_selectors[region]->passCutGt("cluESum",clusterESum,weight))
357 continue;
358 if (!_reg_three_prong_trkeff_selectors[region]->passCutLt("cluESumLt",clusterESum,weight))
359 continue;
360 if (!_reg_three_prong_trkeff_selectors[region]->passCutEq("cluFiducialElectron",isFiducialElectron,weight))
361 continue;
362 if (!_reg_three_prong_trkeff_selectors[region]->passCutEq("cluFiducialPositron",isFiducialPositron,weight))
363 continue;
364
365 // double coplan=_ah->GetClusterCoplanarity(electron.first, positron.first);
366
367 //if(!_reg_three_prong_trkeff_selectors[region]->passCutLt("cluCoplan",abs(coplan-180.0),weight))
368 //continue;
369 std::cout<<"Filling histos for three pronger"<<std::endl;
370
371 _reg_three_prong_trkeff_histos[region]->FillThreeProngPlots(partEle,partPos,partRec,weight);
372
373 }
374 }
375
376 return true;
377}
378
380
381 //TODO clean this up a little.
382 outF_->cd();
383 _trkeff_histos->saveHistos(outF_,_trkeff_histos->getName());
384 outF_->cd(_trkeff_histos->getName().c_str());
385 // trkSelector->getCutFlowHisto()->Write();
386
387
388 for (reg_it it = _reg_trkeff_histos.begin(); it!=_reg_trkeff_histos.end(); ++it) {
389 (it->second)->saveHistos(outF_,it->first);
390 outF_->cd((it->first).c_str());
391 _reg_trkeff_selectors[it->first]->getCutFlowHisto()->Write();
392 //Save tuples
393 // _reg_tuples[it->first]->writeTree();
394 }
396 (it->second)->saveHistos(outF_,it->first);
397 outF_->cd((it->first).c_str());
398 _reg_three_prong_trkeff_selectors[it->first]->getCutFlowHisto()->Write();
399 //Save tuples
400 // _reg_tuples[it->first]->writeTree();
401 }
402
403 outF_->Close();
404
405}
406
#define DECLARE_PROCESSOR(CLASS)
Macro which allows the framework to construct a producer given its name during configuration.
Definition Processor.h:139
static std::string getFileName(std::string filePath, bool withExtension)
Definition AnaHelpers.cxx:5
double getEnergy() const
Definition CalCluster.h:73
std::vector< double > getPosition() const
Definition CalCluster.h:63
int getNHits() const
Definition CalCluster.h:53
double getTime() const
Definition CalCluster.h:83
Definition IEvent.h:7
description
CalCluster getCluster() const
Definition Particle.h:62
Base class for all event processing components.
Definition Processor.h:34
TFile * outF_
Definition Processor.h:125
virtual bool process()
Process the histograms and generate analysis output.
Definition Processor.h:95
std::shared_ptr< TrackEfficHistos > _trkeff_histos
virtual void configure(const ParameterSet &parameters)
Callback for the Processor to configure itself from the given set of parameters.
std::map< std::string, std::shared_ptr< TrackEfficHistos > >::iterator reg_it
virtual void finalize()
Callback for the Processor to take any necessary action when the processing of events finishes,...
TrackEfficiencyProcessor(const std::string &name, Process &process)
std::vector< std::string > regionSelections_
virtual void initialize(TTree *tree)
Callback for the Processor to take any necessary action when the processing of events starts,...
std::vector< Track * > * trks_
std::vector< CalCluster * > * clus_
std::map< std::string, std::shared_ptr< TrackEfficHistos > > _reg_trkeff_histos
std::vector< std::string > threeProngSelections_
std::map< std::string, std::shared_ptr< BaseSelector > > _reg_three_prong_trkeff_selectors
std::vector< std::string > _three_prong_regions
std::map< std::string, std::shared_ptr< ThreeProngHistos > >::iterator three_prong_reg_it
std::map< std::string, std::shared_ptr< ThreeProngHistos > > _reg_three_prong_trkeff_histos
std::shared_ptr< AnaHelpers > _ah
std::map< std::string, std::shared_ptr< BaseSelector > > _reg_trkeff_selectors
std::shared_ptr< BaseSelector > cluSelector
std::vector< Particle * > * fspart_
std::vector< std::string > _regions