All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
reco_truth_matching.cxx
Go to the documentation of this file.
2 
6 
7 namespace single_photon
8 {
10  std::vector<PandoraPFParticle> all_PPFPs,
11  const std::vector<art::Ptr<recob::Track>>& tracks,
12  std::map<art::Ptr<recob::Track>, art::Ptr<simb::MCParticle> > & trackToMCParticleMap,
13  std::map< art::Ptr<simb::MCParticle>, art::Ptr<simb::MCTruth>> & MCParticleToMCTruthMap,
14  std::vector<art::Ptr<simb::MCParticle>> & mcParticleVector,
15  std::map< int, art::Ptr<simb::MCParticle> > & MCParticleToTrackIdMap,
16  std::vector<double> & vfrac,
17  var_all& vars
18  ){
19 
20 
21  //if(g_is_verbose)
22  std::cout<<"RecoMCTracks()\t||\t Begininning recob::Track Reco-MC suite on: "<<tracks.size()<<" tracks."<<std::endl;
23 
24  int i_trk = 0;
25 
26  for(size_t k =0; k< tracks.size();++k){
27  const art::Ptr<recob::Track> track = tracks[k];
28  vars.m_sim_track_matched[i_trk] = 0;
29 
30  if(trackToMCParticleMap.count(track)>0){
31 
32  const art::Ptr<simb::MCParticle> mcparticle = trackToMCParticleMap[track];
33  std::cout<<"count2: "<<MCParticleToMCTruthMap.count(mcparticle)<<std::endl;
34  const art::Ptr<simb::MCTruth> mctruth = MCParticleToMCTruthMap[mcparticle];
35 
36  PandoraPFParticle* ppfp = PPFP_GetPPFPFromTrack(all_PPFPs, track);
37  // const art::Ptr<recob::PFParticle> pfp = ppfp->pPFParticle;
38  // const art::Ptr<recob::PFParticle> pfp = //trackToPFParticleMap[track];
39 
40  std::vector<double> correctedstart(3);
41  std::vector<double> correctedend(3);
42  std::vector<double> raw_End ={mcparticle->EndX(), mcparticle->EndY(), mcparticle->EndZ()};
43  // std::cout<<"the raw end of this mcparticle is "<<raw_End[0]<<", "<<raw_End[1]<<", "<<raw_End[2]<<std::endl;
44  spacecharge_correction(mcparticle, correctedstart);
45  spacecharge_correction(mcparticle, correctedend, raw_End);
46 
47  //std::cout<<"the corrected end of this mcparticle is "<<correctedend[0]<<", "<<correctedend[1]<<", "<<correctedend[2]<<std::endl;
48 
49 
50  vars.m_sim_track_matched[i_trk] = 1;
51  vars.m_sim_track_energy[i_trk] = mcparticle->E();
52  vars.m_sim_track_mass[i_trk] = mcparticle->Mass();
53  vars.m_sim_track_kinetic_energy[i_trk] = vars.m_sim_track_energy[i_trk]-vars.m_sim_track_mass[i_trk];
54  vars.m_sim_track_pdg[i_trk] = mcparticle->PdgCode();
55  vars.m_sim_track_process[i_trk] = mcparticle->Process();
56  vars.m_sim_track_startx[i_trk] = correctedstart[0];
57  vars.m_sim_track_starty[i_trk] = correctedstart[1];
58  vars.m_sim_track_startz[i_trk] = correctedstart[2];
59 
60  vars.m_sim_track_endx[i_trk]= correctedend[0];
61  vars.m_sim_track_endy[i_trk]= correctedend[1];
62  vars.m_sim_track_endz[i_trk]= correctedend[2];
63 
64  vars.m_sim_track_length[i_trk]= sqrt(pow( vars.m_sim_track_endx[i_trk] - vars.m_sim_track_startx[i_trk], 2)+ pow( vars.m_sim_track_endy[i_trk] - vars.m_sim_track_starty[i_trk], 2) + pow( vars.m_sim_track_endz[i_trk] - vars.m_sim_track_startz[i_trk], 2));
65 
66  vars.m_sim_track_px[i_trk]= mcparticle->Px();
67  vars.m_sim_track_py[i_trk]= mcparticle->Py();
68  vars.m_sim_track_pz[i_trk]= mcparticle->Pz();
69 
70 
71  vars.m_sim_track_origin[i_trk] = mctruth->Origin();
72  vars.m_sim_track_trackID[i_trk] = mcparticle->TrackId();
73  vars.m_sim_track_overlay_fraction[i_trk] = vfrac[i_trk];
74 
75  vars.m_sim_track_sliceId[i_trk] = ppfp->get_SliceID();//PFPToSliceIdMap[pfp];
76  vars.m_sim_track_nuscore[i_trk] = ppfp->get_NuScore();//sliceIdToNuScoreMap[ vars.m_sim_track_sliceId[i_trk]] ;
77  vars.m_sim_track_isclearcosmic[i_trk] = ppfp->get_IsClearCosmic();//PFPToClearCosmicMap[pfp];
78 
79 
80  if(mcparticle->Mother()>=(int)mcParticleVector.size()){
81  vars.m_sim_track_parent_pdg[i_trk] = -1;
82  }else{
83  vars.m_sim_track_parent_pdg[i_trk] = mcParticleVector[mcparticle->Mother()]->PdgCode();
84  }
85 
86  }
87  i_trk++;
88  }
89 
90  return;
91  }
92 
93  //recoMCmatching but specifically for recob::showers
95  std::vector<PandoraPFParticle> all_PPFPs,
96  std::vector<art::Ptr<recob::Shower>>& showerVector,
97  std::map<art::Ptr<recob::Shower>,art::Ptr<simb::MCParticle>>& showerToMCParticleMap,
98  art::FindManyP<simb::MCParticle,anab::BackTrackerHitMatchingData>& mcparticles_per_hit,
99  std::vector<art::Ptr<simb::MCParticle>>& mcParticleVector,
100  std::map< int ,art::Ptr<simb::MCParticle> > & MCParticleToTrackIdMap,
101  var_all& vars){
102 
103  std::vector<double> vec_fraction_matched;
104  //processes that are "showery"
105  std::map<std::string,bool> map_is_shower_process = {{"compt",true},
106  {"FastScintillation",true},
107  {"eBrem",true},
108  {"phot",true},
109  {"eIoni",true},
110  {"conv",true},
111  {"annihil",true}};
112 
113  std::vector<int> spacers = Printer_header({"pfpID", " matched_#simb", " pdg"," E_plane0"," E_plane1"," E_plane2"," cosmic?"});
114  //for each recob::track/shower in the event
115  for(size_t i=0; i<showerVector.size();++i){
116  auto shower = showerVector[i];
117 
118  //get the associated reco PFP
119  // if(g_is_verbose)std::cout<<"We have "<<showerToPFParticleMap.count(shower)<<" matches in map"<<std::endl;
120 
121  PandoraPFParticle* ppfp = PPFP_GetPPFPFromShower(all_PPFPs, shower);
122  const art::Ptr<recob::PFParticle> pfp = ppfp->pPFParticle;
123 
124  //putting in the PFP pdg code as a check
125 
126  //and get the hits associated to the reco PFP
127  std::vector< art::Ptr<recob::Hit> > obj_hits_ptrs = ppfp->pPFPHits; //pfParticleToHitsMap[pfp];
128 
129  /**
130  *
131  * Loop over hits associated with the reco PFP to find MCParticles which contribute energy to the reco shower
132  *
133  **/
134 
135  std::unordered_map<int,double> objide; //map between the MCParticle track ID and the backtracker energy
136 
137  //energy for an MCParticle that comprises the most energy when sum over associated hits in PFP
138  //total energy of the reco PFP taken from the sum of the hits associated to an MCParticle
139  double maxe=-1, tote=0;
140 
141  std::vector<double> total_energy_on_plane = {0.0,0.0,0.0};
142  //simb::MCParticle const * best_matched_mcparticle = NULL; //pointer for the particle match we will calculate
143  art::Ptr<simb::MCParticle> best_matched_mcparticle; //pointer for the MCParticle match we will calculate
144 
145  // std::vector<simb::MCParticle const *> particle_vec;
146  // std::vector<anab::BackTrackerHitMatchingData const *> match_vec;
147 
148  std::vector<art::Ptr<simb::MCParticle>> particle_vec; //vector of all MCParticles associated with a given hit in the reco PFP
149  std::vector<anab::BackTrackerHitMatchingData const *> match_vec; //vector of some backtracker thing
150 
151  int n_associated_mcparticle_hits = 0;
152  int n_not_associated_hits = 0;
153 
154  //this is the vector that will store the associated MC paritcles, as well as a MAP to the amount of energy associated
155  std::vector<art::Ptr<simb::MCParticle>> asso_mcparticles_vec;
156  std::map<art::Ptr<simb::MCParticle>, std::vector<double>> map_asso_mcparticles_energy;
157 
158  bool found_a_match = false;
159 
160  //std::cout<<"RecoMC()\t||\t On shower: "<<i<<" with pfp "<< pfp->Self() <<"and slice id "<<PFPToSliceIdMap[pfp]<<". This shower has "<<obj_hits_ptrs.size()<<" hits associated with it"<<std::endl;
161 
162  //loop only over hits associated to this reco PFP
163  for(size_t i_h=0; i_h < obj_hits_ptrs.size(); ++i_h){
164 
165  int which_plane = (int)obj_hits_ptrs[i_h]->View();
166 
167  particle_vec.clear(); match_vec.clear(); //only store per hit
168 
169  //for the hit, fill the backtracker info
170  mcparticles_per_hit.get(obj_hits_ptrs[i_h].key(), particle_vec, match_vec);
171  // std::cout<<"for hit "<< i_h <<" particle_vec.size() = "<< particle_vec.size()<< " and match_vec.size() = "<< match_vec.size()<<std::endl;
172 
173 
174  //mcparticles_per_hit.get(obj_hits_ptrs[i_h].key(),particle_vec,match_vec);
175  //the .key() gives us the index in the original collection
176  //std::cout<<"REC: hit "<<i_h<<" has "<<particle_vec.size()<<" MCparticles assocaied: "<<std::endl;
177 
178  //if there is an MCParticle associated to this hit
179  if(particle_vec.size()>0) n_associated_mcparticle_hits++;
180 
181  if(particle_vec.size()==0) n_not_associated_hits++;
182 
183 
184 
185  //for each MCParticle associated with this hit
186  for(size_t i_p=0; i_p<particle_vec.size(); ++i_p){
187  //add the energy of the back tracked hit for this MCParticle to the track id for the MCParticle in the map
188  objide[ particle_vec[i_p]->TrackId()] += match_vec[i_p]->energy; //store energy per track id
189 
190  //if the id isn't already in the map, store it in the vector of all associated MCParticles
191  if(std::find(asso_mcparticles_vec.begin(), asso_mcparticles_vec.end(), particle_vec[i_p]) == asso_mcparticles_vec.end()){
192  asso_mcparticles_vec.push_back(particle_vec[i_p]);
193  map_asso_mcparticles_energy[particle_vec[i_p]] = {0.0,0.0,0.0};
194  map_asso_mcparticles_energy[particle_vec[i_p]][which_plane] = match_vec[i_p]->energy;
195  }else{
196  map_asso_mcparticles_energy[particle_vec[i_p]][which_plane] += match_vec[i_p]->energy;
197  }
198 
199  //add the energy of the back tracked hit to the total energy for the PFP
200  tote += match_vec[i_p]->energy; //calculate total energy deposited
201  total_energy_on_plane[which_plane]+=match_vec[i_p]->energy;
202 
203 
204  //want the MCParticle with the max total energy summed from the back tracker hit energy from hits in PFP
205  //TODO: this part will change once the parts below are fully implemented
206  if( objide[ particle_vec[i_p]->TrackId()] > maxe ){ //keep track of maximum
207  maxe = objide[ particle_vec[i_p]->TrackId() ];
208  best_matched_mcparticle = particle_vec[i_p]; //we will now define the best match as a source MCP rather than the max single energy contributor
209  found_a_match = true;//will be false for showers from overlay
210  }
211  }//end loop over particles per hit
212 
213 
214  } // end loop over hits
215 
216  double fraction_num_hits_overlay = (double)n_not_associated_hits/(double)obj_hits_ptrs.size();
217 
218  if(g_is_verbose)std::cout << "recoMC()\t||\t On Object "<<i<<". The number of MCParticles associated with this PFP is "<<objide.size()<<std::endl;
219  if(g_is_verbose) std::cout<<"recoMC()\t||\t the fraction of hits from overlay is is "<<fraction_num_hits_overlay<<" ("<<n_not_associated_hits<<"/"<<obj_hits_ptrs.size()<<")"<<std::endl;
220 
221 
222  if(n_associated_mcparticle_hits == 0){
223  //This will only occur if the whole recob::PFParticle is PURELY associated with an overlay shower
224  found_a_match =false;
225  if(!found_a_match){
226  }
227  //Here we will fill every sivars.m_shower_XXX variable with -999 or something like that
228 
229  vars.m_sim_shower_matched[i] = 0;
230  vars.m_sim_shower_energy[i] = -999;
231  vars.m_sim_shower_mass[i] = -999;
232  vars.m_sim_shower_kinetic_energy[i] = -999;
233  vars.m_sim_shower_pdg[i] = -999;
234  vars.m_sim_shower_trackID[i] = -999;
235  vars.m_sim_shower_process[i] = "overlay";
236  vars.m_sim_shower_end_process[i] = "overlay";
237  vars.m_sim_shower_parent_pdg[i] = -999;
238  vars.m_sim_shower_parent_trackID[i] = -999;
239  vars.m_sim_shower_vertex_x[i] = -9999;
240  vars.m_sim_shower_vertex_y[i] = -9999;
241  vars.m_sim_shower_vertex_z[i] = -9999;
242 
243  vars.m_sim_shower_start_x[i] = -9999;
244  vars.m_sim_shower_start_y[i] = -9999;
245  vars.m_sim_shower_start_z[i] = -9999;
246  vars.m_sim_shower_px[i] = -9999;
247  vars.m_sim_shower_py[i] = -9999;
248  vars.m_sim_shower_pz[i] = -9999;
249 
250  vars.m_sim_shower_is_true_shower[i] = -999;
251  vars.m_sim_shower_best_matched_plane[i] = -999;
255 
256  vars.m_sim_shower_overlay_fraction[i] = fraction_num_hits_overlay;
257  vars.m_sim_shower_sliceId[i] = -999;
258  vars.m_sim_shower_nuscore[i] = -999;
259  vars.m_sim_shower_isclearcosmic[i] = -999;
260  vars.m_sim_shower_is_nuslice[i] = -999;
261 
262 
263  continue;
264  }
265 
266 
267  /* ********** if shower has been matched to MCParticle ************************* */
268 
269  /*
270  *
271  * Loop over each MCParticle associated to the reco shower to find the source particle
272  *
273  */
274 
275  std::map<int, art::Ptr<simb::MCParticle>> mother_MCP_map; //map between MCP track id and the source MCP
276 
277  std::vector<art::Ptr<simb::MCParticle>> marks_mother_vector; // a vector of mother MCP
278  std::map<art::Ptr<simb::MCParticle>, std::vector<double>> marks_mother_energy_fraction_map; // map of mother MCP and its energy on 3 planes
279 
280  int this_mcp_id = -1; //the track id for the current MCP in parent tree
281  int last_mcp_id = -1; //the track id for the previous MCP in parent tree
282  int i_mcp = 0;
283 
284  int num_bt_mothers =0; // number of associated MCP that has mothers
285 
286  //g_is_verbose = false;
287  //for each MCP that's associated to the reco shower
288  for(auto mcp:asso_mcparticles_vec){
289 
290  if(g_is_verbose) std::cout<<"-----------------------------Start L1 Loop --------------------------------------------------"<<std::endl;
291  if(g_is_verbose) std::cout<<"L1: ("<<i<<" <-> "<<i_mcp<<") Start by Looking at an MCP with pdg code "<<mcp->PdgCode()<<" and status code "<<mcp->StatusCode()<<" TrackID: "<<mcp->TrackId()<<std::endl;
292  if(g_is_verbose) std::cout<<"L1: ("<<i<<" <-> "<<i_mcp<<") This MCP gave "<< map_asso_mcparticles_energy[mcp][0] <<" | "<<map_asso_mcparticles_energy[mcp][1]<<" | "<<map_asso_mcparticles_energy[mcp][2]<<" energy to the recob::Object on each plane"<<std::endl;
293  // std::cout<<"L1: the mother of this MCP is track id "<<mcp->Mother()<<" and there are "<<mcp->NumberDaughters()<<" daughters"<<std::endl;
294 
295  //get the track ID for the current MCP
296  this_mcp_id = mcp->TrackId();
297  last_mcp_id = this_mcp_id;//initialize the previous one
298 
299  //while the track id is valid, move up the parent tree for the MCP that contributes to the reco shower
300  //currently it keeps going until it hits the top of the interaction chain, but this is likely too far
301  //to do a proper match you need to check for different cases and stop once one is fulfilled
302  while(this_mcp_id >= 0 ){
303  art::Ptr<simb::MCParticle> this_mcp = MCParticleToTrackIdMap[this_mcp_id];//get the MCP associated to the track ID
304  // std::cout<<"going up the tree got mother particle"<<std::endl;
305 
306  //check if it's a valid MCP
307  if (this_mcp.isNull()){
308  if(g_is_verbose) std::cout<<"L1: ("<<i<<" <-> "<<i_mcp<<") null pointer at id "<<this_mcp_id<<std::endl;
309  this_mcp_id = last_mcp_id; //if invalid, move back a level to the previous MCP in parent tree and break the loop
310  break;
311  }
312 
313  //If primary particle will have process "primary"
314  if(g_is_verbose) std::cout<<"L1: ("<<i<<" <-> "<<i_mcp<<") going up the tree at an MCP with track id "<<this_mcp_id<<", pdg code "<<this_mcp->PdgCode()<<", and status code "<<this_mcp->StatusCode()<<" and Mother: "<<this_mcp->Mother()<<" Process: "<<this_mcp->Process()<<" EndProcess: "<<this_mcp->EndProcess()<<std::endl;
315 
316  //if it is a valid particle, iterate forward to the mother
317  last_mcp_id = this_mcp_id;
318  this_mcp_id = this_mcp->Mother();
319 
320  //Check to see if this MCP was created in a "showery" process
321  if(map_is_shower_process.count(this_mcp->Process()) > 0){
322  //if it was, keep going,
323 
324  }else if(this_mcp->Process()=="primary"){
325  //if its primary, great! Note it.
326  if(g_is_verbose) std::cout<<"L1: Backtracked to primary! breaking"<<std::endl;
327  this_mcp_id = last_mcp_id; //if invalid, move back a level to the previous MCP in parent tree and break the loop
328  break;
329  }else{
330  if(g_is_verbose) std::cout<<"L1: Backtracked to a particle created in "<<this_mcp->EndProcess()<<"! breaking"<<std::endl;
331  this_mcp_id = last_mcp_id; //if invalid, move back a level to the previous MCP in parent tree and break the loop
332  break;
333  }
334  }
335 
336  //if the MCP at the top of the interaction chain has a valid track id store this in the mother map
337  if (this_mcp_id >= 0){
338 
339  //Guanqun: this line here doesn't really cosider other break cases than finding primary particle
340  if(g_is_verbose) std::cout<<"L1: ("<<i<<" <-> "<<i_mcp<<") Storing the mother mother particle with track id "<<this_mcp_id<<" and pdg code "<<MCParticleToTrackIdMap[this_mcp_id]->PdgCode()<<" and status code "<<MCParticleToTrackIdMap[this_mcp_id]->StatusCode()<<std::endl;
341 
342  mother_MCP_map[this_mcp_id] = MCParticleToTrackIdMap[this_mcp_id];//putting it in a map allows for multiple contributing MCP's in the reco shower to have the same mother MCP
343 
344  bool is_old = false;
345 
346  for(size_t k=0; k< marks_mother_vector.size(); k++){
347  //if its in it before, just run with it
348  if(marks_mother_vector[k]==MCParticleToTrackIdMap[this_mcp_id]){
349  marks_mother_energy_fraction_map[marks_mother_vector[k]][0] += map_asso_mcparticles_energy[mcp][0];
350  marks_mother_energy_fraction_map[marks_mother_vector[k]][1] += map_asso_mcparticles_energy[mcp][1];
351  marks_mother_energy_fraction_map[marks_mother_vector[k]][2] += map_asso_mcparticles_energy[mcp][2];
352  is_old = true;
353  break;
354  }
355  }
356  if(is_old==false){//add one element in marks_mother_vector
357  marks_mother_vector.push_back(MCParticleToTrackIdMap[this_mcp_id]);
358  marks_mother_energy_fraction_map[marks_mother_vector.back()] = {0.0,0.0,0.0};
359  marks_mother_energy_fraction_map[marks_mother_vector.back()][0] = map_asso_mcparticles_energy[mcp][0];
360  marks_mother_energy_fraction_map[marks_mother_vector.back()][1] = map_asso_mcparticles_energy[mcp][1];
361  marks_mother_energy_fraction_map[marks_mother_vector.back()][2] = map_asso_mcparticles_energy[mcp][2];
362  }
363 
364 
365  num_bt_mothers++;
366  } else{
367  if(g_is_verbose) std::cout<<"L1: error, the mother mother id was "<<this_mcp_id <<std::endl;
368 
369  }
370 
371  if(g_is_verbose) std::cout<<"-----------------------------End L1 Loop --------------------------------------------------"<<std::endl;
372  i_mcp++;
373  }//for each MCParticle that's associated to a the recob::Shower
374 
375  //g_is_verbose = true;
376  //there should be at least 1 mother MCP
377  if(g_is_verbose) std::cout<<"recoMC()\t||\t the number of source mother particles is "<<mother_MCP_map.size()<<" of which : "<<marks_mother_vector.size()<<" are unique!"<<std::endl;
378 
379  if(g_is_verbose) std::cout<<"---------------------------- L2-------------------------------"<<std::endl;
380 
381  double best_mother_index = 0;
382  double best_mother_energy = -9999;
383  // int best_mother_plane = -99;
384 
385  for(size_t p=0; p< marks_mother_vector.size(); p++){
386  art::Ptr<simb::MCParticle> mother = marks_mother_vector[p];
387  std::vector<double> mother_energy_recod = marks_mother_energy_fraction_map[mother];
388  if(g_is_verbose) std::cout<<"L2: Mother candidate "<<p<<" TrackID "<<mother->TrackId()<<" Process: "<<mother->Process()<<" EndProcess: "<<mother->EndProcess()<<std::endl;
389  if(g_is_verbose) std::cout<<"L2: Mother candidate "<<p<<" Energy "<<mother->E()<<" Reco'd Energy: "<<mother_energy_recod[0]<<" | "<<mother_energy_recod[1]<<" | "<<mother_energy_recod[2]<<" Fraction: ("<<mother_energy_recod[0]/(1000*mother->E())*100.0<<"% , "<<mother_energy_recod[1]/(1000*mother->E())*100.0<<"% , "<<mother_energy_recod[2]/(1000*mother->E())*100.0<<"% )"<<std::endl;
390 
391  if( mother_energy_recod[0] > best_mother_energy){
392  best_mother_index = p;
393  best_mother_energy = mother_energy_recod[0];
394  // best_mother_plane = 0;
395  }
396 
397  if( mother_energy_recod[1] > best_mother_energy){
398  best_mother_index = p;
399  best_mother_energy = mother_energy_recod[1];
400  // best_mother_plane = 1;
401  }
402 
403  if( mother_energy_recod[2] > best_mother_energy){
404  best_mother_index = p;
405  best_mother_energy = mother_energy_recod[2];
406  // best_mother_plane = 2;
407  }
408 
409  }
410 
411 
412 
413  // now have found the best mother of the shower
414  if(g_is_verbose) std::cout<<"---------------------------- L2-------------------------------"<<std::endl;
415  const art::Ptr<simb::MCParticle> match = marks_mother_vector[best_mother_index];
416 
417  std::vector<double> corrected_vertex(3), corrected_start(3);
418  spacecharge_correction(match, corrected_vertex);
419 
420 
421  if(match->PdgCode()==22){ // if it's a gamma
422  std::vector<double> tmp ={match->EndX(), match->EndY(), match->EndZ()};
423  spacecharge_correction(match, corrected_start, tmp );
424  vars.m_sim_shower_is_true_shower[i] = 1;
425  }else if(abs(match->PdgCode())==11){ // if it's e+/e-
426  spacecharge_correction(match, corrected_start);
427  vars.m_sim_shower_is_true_shower[i] = 1;
428  }else{
429  corrected_start = {-999,-999,-999};
430  vars.m_sim_shower_is_true_shower[i] = 0;
431  }
432 
433  art::Ptr<simb::MCParticle> match_mother = MCParticleToTrackIdMap[match->Mother()];
434 
435  if (match_mother.isNull()){
436  vars.m_sim_shower_parent_pdg[i] = -1;
437  vars.m_sim_shower_parent_trackID[i] = -1;
438 
439  }else{
440  vars.m_sim_shower_parent_pdg[i] = match_mother->PdgCode();
441  vars.m_sim_shower_parent_trackID[i] = match_mother->TrackId();
442  }
443 
444 
445 
446  vars.m_sim_shower_matched[i] = 1;
447  vars.m_sim_shower_energy[i] = match->E();
448  vars.m_sim_shower_mass[i] = match->Mass();
449  vars.m_sim_shower_kinetic_energy[i] = match->E()-match->Mass();
450  vars.m_sim_shower_pdg[i] = match->PdgCode();
451  vars.m_sim_shower_trackID[i] = match->TrackId();
452  vars.m_sim_shower_process[i] = match->Process();
453  vars.m_sim_shower_end_process[i] = match->EndProcess();
454  vars.m_sim_shower_vertex_x[i] = corrected_vertex[0];
455  vars.m_sim_shower_vertex_y[i] = corrected_vertex[1];
456  vars.m_sim_shower_vertex_z[i] =corrected_vertex[2];
457 
458  vars.m_sim_shower_start_x[i] = corrected_start[0];
459  vars.m_sim_shower_start_y[i] = corrected_start[1];
460  vars.m_sim_shower_start_z[i] =corrected_start[2];
461 
462  vars.m_sim_shower_px[i] = match->Px();
463  vars.m_sim_shower_py[i] = match->Py();
464  vars.m_sim_shower_pz[i] = match->Pz();
465 
466  // should've use 'best_mother_plane' here
467  vars.m_sim_shower_best_matched_plane[i] = best_mother_index;
468  vars.m_sim_shower_matched_energy_fraction_plane0[i] = marks_mother_energy_fraction_map[marks_mother_vector[best_mother_index]][0]/total_energy_on_plane[0];
469  vars.m_sim_shower_matched_energy_fraction_plane1[i] = marks_mother_energy_fraction_map[marks_mother_vector[best_mother_index]][1]/total_energy_on_plane[1];
470  vars.m_sim_shower_matched_energy_fraction_plane2[i] = marks_mother_energy_fraction_map[marks_mother_vector[best_mother_index]][2]/total_energy_on_plane[2];
471 
472  vars.m_sim_shower_overlay_fraction[i] = fraction_num_hits_overlay;
473 
474  mcParticleVector.push_back(match);
475  showerToMCParticleMap[shower] = mcParticleVector.back();
476 
477  vars.m_sim_shower_sliceId[i] = ppfp->get_SliceID();//PFPToSliceIdMap[pfp];
478  vars.m_sim_shower_nuscore[i] = ppfp->get_NuScore();//sliceIdToNuScoreMap[ vars.m_sim_shower_sliceId[i]] ;
479  vars.m_sim_shower_isclearcosmic[i] = ppfp->get_IsClearCosmic();//PFPToClearCosmicMap[pfp];
480  vars.m_sim_shower_is_nuslice[i] = ppfp->get_IsNuSlice();//PFPToNuSliceMap[pfp];
481 
482  // if(marks_mother_vector.size()!=0){
483  // //if(g_is_verbose) std::cout<<"recoMC()\t||\t The `BEST` mother is a "<<marks_mother_vector[best_mother_index]->PdgCode()<<" at "<<best_mother_index<<" on plane: "<<best_mother_plane<<std::endl;
484  // //std::vector<int> spacers = Printer_header({"pfpID", " matched_#simb", " pdg"," E_plane0"," E_plane1"," E_plane2"," cosmic?"});
485  // std::cout<<"recoMC()\t||\t The `BEST` mother is a "<<marks_mother_vector[best_mother_index]->PdgCode()<<" at "<<best_mother_index<<" on plane: "<<best_mother_plane<<std::endl;
486  // for(int l=0; l<3; l++){
487  // std::cout<<"recoMC()\t||\t It represents "<<marks_mother_energy_fraction_map[marks_mother_vector[best_mother_index]][l]/total_energy_on_plane[l]*100.0<<"% of the energy on plane: "<<l<<" which is "<<total_energy_on_plane[l] <<std::endl;
488  // }
489  // }
490  //
491  //
492  // if (vars.m_sim_shower_isclearcosmic[i]== false){
493  // std::cout<<"sim shower is matched to non-clear cosmic PFP "<<pfp->Self()<<std::endl;
494  // }
495  Printer_content({std::to_string(pfp->Self()),
496  std::to_string(best_mother_index),
497  std::to_string(marks_mother_vector[best_mother_index]->PdgCode()),
498  std::to_string(total_energy_on_plane[0]),
499  std::to_string(total_energy_on_plane[1]),
500  std::to_string(total_energy_on_plane[2]),
502  },spacers);
503 
504  if (g_is_verbose) std::cout<<"looking at pfp "<< pfp->Self()<<" with is matched to true particle with pdg vars.m_sim_shower_pdg[i]= "<< vars.m_sim_shower_pdg[i]<< ". is_nuslice = "<< vars.m_sim_shower_is_nuslice[i]<<" in slice "<< vars.m_sim_shower_sliceId[i]<<". The matched energy for this shower from mark's mother particle with pdg "<<marks_mother_vector[best_mother_index]->PdgCode()<< " is "<<vars.m_sim_shower_matched_energy_fraction_plane0[i]<<"/"<<vars.m_sim_shower_matched_energy_fraction_plane1[i]<<"/" <<vars.m_sim_shower_matched_energy_fraction_plane2[i]<<std::endl;
505 
506  }//end vector loop.
507  }//end showerRecoMCmatching
508 
509 
510 
511  /* @brief: a simpler MCmatching function for track and shower
512  * @argument to be filled in function body:
513  * objectToMCParticleMap: map of object (track, shower) to its best-matching MCParticle
514  * mcParticleVector: a vector of best-matching MCParticle corresponding to objectVector
515  * @return: a vector of fraction number, which is the fraction of unassociated hits in all reco hits of PFParticle
516  */
517  //Typenamed for recob::Track and recob::Shower
518  std::vector<double> trackRecoMCmatching(std::vector<art::Ptr<recob::Track>>& objectVector,
519  std::map<art::Ptr<recob::Track>,art::Ptr<simb::MCParticle>>& objectToMCParticleMap,
520  std::map<art::Ptr<recob::Track>,art::Ptr<recob::PFParticle>>& objectToPFParticleMap,
521  std::map<art::Ptr<recob::PFParticle>, std::vector<art::Ptr<recob::Hit>> >& pfParticleToHitsMap,
522  art::FindManyP<simb::MCParticle,anab::BackTrackerHitMatchingData>& mcparticles_per_hit,
523  std::vector<art::Ptr<simb::MCParticle>>& mcParticleVector,
524  var_all& vars ){
525 
526  std::vector<double> trk_overlay_vec;
527  std::vector<double> vec_fraction_matched;
528  bool reco_verbose = false;
529  //for each recob::track/shower in the event
530  for(size_t i=0; i<objectVector.size();++i){
531  auto object = objectVector[i];
532 
533  //get the associated reco PFP
534  const art::Ptr<recob::PFParticle> pfp = objectToPFParticleMap[object];
535 
536  // std::cout<<"recoMCmatching()\t||\t looking for a track match to pfp"<< pfp->Self()<<std::endl;
537 
538 
539  int pdg = pfp->PdgCode();
540  //and get the hits associated to the reco PFP
541  std::vector< art::Ptr<recob::Hit> > obj_hits_ptrs = pfParticleToHitsMap[pfp];
542 
543  std::unordered_map<int,double> objide; //map between the MCParticle track ID and the backtracker energy
544 
545  //energy for an MCParticle that comprises the most energy when sum over associated hits in PFP
546  //total energy of the reco PFP taken from the sum of the hits associated to an MCParticle
547  double maxe=-1, tote=0;
548 
549  //simb::MCParticle const * best_matched_mcparticle = NULL; //pointer for the particle match we will calculate
550  art::Ptr<simb::MCParticle> best_matched_mcparticle; //pointer for the MCParticle match we will calculate
551 
552  // std::vector<simb::MCParticle const *> particle_vec;
553  // std::vector<anab::BackTrackerHitMatchingData const *> match_vec;
554 
555  std::vector<art::Ptr<simb::MCParticle>> particle_vec; //vector of all MCParticles associated with a given hit in the reco PFP
556  std::vector<anab::BackTrackerHitMatchingData const *> match_vec; //vector of some backtracker thing
557 
558  bool found_a_match = false;
559  int n_associated_mcparticle_hits = 0;
560  int n_not_associated_hits = 0;
561 
562  // std::cout<<"REC: This object with pfp "<< pfp->Self() <<" in slice "<<PFPToSliceIdMap[pfp] <<" has "<<obj_hits_ptrs.size()<<" hits associated with it"<<std::endl;
563 
564  //loop only over hits associated to this reco PFP
565  for(size_t i_h=0; i_h < obj_hits_ptrs.size(); ++i_h){
566 
567  particle_vec.clear(); match_vec.clear(); //only store per hit
568 
569  //for the hit, fill the backtracker info
570 
571  mcparticles_per_hit.get(obj_hits_ptrs[i_h].key(), particle_vec, match_vec);
572  // std::cout<<"for hit "<< i_h <<" particle_vec.size() = "<< particle_vec.size()<< " and match_vec.size() = "<< match_vec.size()<<std::endl;
573 
574  //mcparticles_per_hit.get(obj_hits_ptrs[i_h].key(),particle_vec,match_vec);
575  //the .key() gives us the index in the original collection
576  //std::cout<<"REC: hit "<<i_h<<" has "<<particle_vec.size()<<" MCparticles assocaied: "<<std::endl;
577 
578  //if there is an MCParticle associated to this hit
579 
580  //if there is an MCParticle associated to this hit
581  if(particle_vec.size()>0) n_associated_mcparticle_hits++;
582 
583  if(particle_vec.size()==0) n_not_associated_hits++;
584 
585 
586  //loop over MCparticles finding which is the MCparticle with most "energy" matched correctly
587  //for each MCParticle associated with this hit
588  for(size_t i_p=0; i_p<particle_vec.size(); ++i_p){
589  //add the energy of the back tracked hit for this MCParticle to the track id for the MCParticle in the map
590  objide[ particle_vec[i_p]->TrackId()] += match_vec[i_p]->energy; //store energy per track id
591 
592  //add the energy of the back tracked hit to the total energy for the PFP
593  tote += match_vec[i_p]->energy; //calculate total energy deposited
594 
595  //want the MCParticle with the max total energy summed from the back tracker hit energy from hits in PFP
596  if( objide[ particle_vec[i_p]->TrackId() ] > maxe ){ //keep track of maximum
597  maxe = objide[ particle_vec[i_p]->TrackId() ];
598  best_matched_mcparticle = particle_vec[i_p];
599  found_a_match = true;
600  }
601  }//end loop over particles per hit
602  }
603 
604 
605  double fraction_num_hits_overlay = (double)n_not_associated_hits/(double)obj_hits_ptrs.size();
606 
607  trk_overlay_vec.push_back(fraction_num_hits_overlay);
608  if(n_associated_mcparticle_hits == 0){
609  //This will only occur if the whole recob::PFParticle is associated with an overlay object
610  //std::cout<<fraction_num_hits_overlay<<std::endl;
611  }//for each recob::track/shower in the event
612 
613  //std::cout << "recoMC()\t||\t the number of MCParticles associated with this PFP is "<<objide.size()<<std::endl;
614 
615  if(found_a_match){
616  mcParticleVector.push_back(best_matched_mcparticle);
617  objectToMCParticleMap[object] = mcParticleVector.back();
618  }else{
619  // mcParticleVector.push_back(0);
620  }
621  vec_fraction_matched.push_back(maxe/tote);
622  // if(g_is_verbose){
623  // std::cout << "recoMC()\t||\t the fracrion matched is "<<maxe/tote<<std::endl;
624  // }
625 
626 
627  if(!found_a_match){
628  if(reco_verbose) std::cout << "recoMC()\t||\t NO MATCH NO MATCH (from my loop) for PFP with pdg "<<pdg<<std::endl;
629  if(reco_verbose)std::cout<<" count "<<objectToMCParticleMap.count(object)<<std::endl;
630  }else{
631  //if(reco_verbose)
632  std::cout << "recoMC()\t||\t Final Match (from my loop) for PFP with pdg "<<pdg<<" is " << best_matched_mcparticle->TrackId() << " with energy " << maxe << " over " << tote << " (" << maxe/tote << ")"
633  << " pdg=" << best_matched_mcparticle->PdgCode()
634  << " trkid=" << best_matched_mcparticle->TrackId()
635  << " ke=" << best_matched_mcparticle->E()-best_matched_mcparticle->Mass()<< "\n";
636  }
637 
638  }//end vector loop.
639  //return vec_fraction_matched;
640  return trk_overlay_vec;
641  }
642 
643 
644  int photoNuclearTesting(std::vector<art::Ptr<simb::MCParticle>>& mcParticleVector){
645 
646 
647  for(auto &mcp: mcParticleVector){
648  int pdg = mcp->PdgCode();
649  std::string end_process = mcp->EndProcess();
650  int status = mcp->StatusCode() ;
651 
652 
653  if(pdg==22){
654  std::cout<<"PHOTO: "<<status<<" "<<end_process<<std::endl;
655  }
656  }
657 
658 
659  return 0;
660 
661  }
662 
663 }//namespace end
std::vector< double > m_sim_shower_vertex_x
Definition: variables.h:870
std::vector< double > m_sim_track_startx
Definition: variables.h:702
std::vector< double > m_sim_shower_py
Definition: variables.h:875
var pdg
Definition: selectors.fcl:14
std::vector< int > m_sim_track_origin
Definition: variables.h:701
ClusterModuleLabel join with tracks
std::vector< double > trackRecoMCmatching(std::vector< art::Ptr< recob::Track >> &objectVector, std::map< art::Ptr< recob::Track >, art::Ptr< simb::MCParticle >> &objectToMCParticleMap, std::map< art::Ptr< recob::Track >, art::Ptr< recob::PFParticle >> &objectToPFParticleMap, std::map< art::Ptr< recob::PFParticle >, std::vector< art::Ptr< recob::Hit >> > &pfParticleToHitsMap, art::FindManyP< simb::MCParticle, anab::BackTrackerHitMatchingData > &mcparticles_per_hit, std::vector< art::Ptr< simb::MCParticle >> &mcParticleVector, var_all &vars)
std::vector< bool > m_sim_shower_is_nuslice
Definition: variables.h:887
std::vector< double > m_sim_shower_pz
Definition: variables.h:876
pdgs p
Definition: selectors.fcl:22
std::vector< double > m_sim_shower_vertex_z
Definition: variables.h:872
std::vector< double > m_sim_track_energy
Definition: variables.h:694
std::vector< int > m_sim_track_parent_pdg
Definition: variables.h:698
std::vector< std::string > m_sim_track_process
Definition: variables.h:700
art::Ptr< recob::PFParticle > pPFParticle
process_name use argoneut_mc_hitfinder track
std::vector< int > m_sim_track_trackID
Definition: variables.h:713
std::vector< int > m_sim_track_sliceId
Definition: variables.h:718
std::vector< double > m_sim_track_py
Definition: variables.h:706
void RecoMCTracks(std::vector< PandoraPFParticle > all_PPFPs, const std::vector< art::Ptr< recob::Track >> &tracks, std::map< art::Ptr< recob::Track >, art::Ptr< simb::MCParticle > > &trackToMCParticleMap, std::map< art::Ptr< simb::MCParticle >, art::Ptr< simb::MCTruth >> &MCParticleToMCTruthMap, std::vector< art::Ptr< simb::MCParticle >> &mcParticleVector, std::map< int, art::Ptr< simb::MCParticle > > &MCParticleToTrackIdMap, std::vector< double > &vfrac, var_all &vars)
process_name shower
Definition: cheaterreco.fcl:51
std::vector< double > m_sim_shower_matched_energy_fraction_plane2
Definition: variables.h:882
void showerRecoMCmatching(std::vector< PandoraPFParticle > all_PPFPs, std::vector< art::Ptr< recob::Shower >> &showerVector, std::map< art::Ptr< recob::Shower >, art::Ptr< simb::MCParticle >> &showerToMCParticleMap, art::FindManyP< simb::MCParticle, anab::BackTrackerHitMatchingData > &mcparticles_per_hit, std::vector< art::Ptr< simb::MCParticle >> &mcParticleVector, std::map< int, art::Ptr< simb::MCParticle > > &MCParticleToTrackIdMap, var_all &vars)
std::vector< double > m_sim_track_endy
Definition: variables.h:709
std::vector< double > m_sim_shower_vertex_y
Definition: variables.h:871
std::vector< double > m_sim_shower_matched_energy_fraction_plane0
Definition: variables.h:879
std::vector< art::Ptr< recob::Hit > > pPFPHits
std::vector< double > m_sim_shower_start_z
Definition: variables.h:869
std::vector< double > m_sim_track_kinetic_energy
Definition: variables.h:696
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::vector< double > m_sim_shower_kinetic_energy
Definition: variables.h:856
std::vector< int > m_sim_shower_best_matched_plane
Definition: variables.h:878
T abs(T value)
std::vector< double > m_sim_track_endx
Definition: variables.h:708
std::vector< double > m_sim_track_endz
Definition: variables.h:710
std::vector< int > Printer_header(std::vector< std::string > headings)
std::vector< double > m_sim_shower_energy
Definition: variables.h:855
std::vector< int > m_sim_shower_matched
Definition: variables.h:853
std::vector< double > m_sim_shower_matched_energy_fraction_plane1
Definition: variables.h:881
std::vector< double > m_sim_shower_px
Definition: variables.h:874
std::vector< double > m_sim_track_startz
Definition: variables.h:704
std::vector< int > m_sim_track_pdg
Definition: variables.h:697
std::vector< double > m_sim_shower_mass
Definition: variables.h:857
int photoNuclearTesting(std::vector< art::Ptr< simb::MCParticle >> &mcParticleVector)
PandoraPFParticle * PPFP_GetPPFPFromTrack(std::vector< PandoraPFParticle > &PPFPs, art::Ptr< recob::Track > pTrack)
std::vector< double > m_sim_shower_nuscore
Definition: variables.h:885
std::vector< double > m_sim_track_pz
Definition: variables.h:707
int spacecharge_correction(const art::Ptr< simb::MCParticle > &mcparticle, std::vector< double > &corrected, std::vector< double > &input)
Definition: Processors.cxx:25
std::vector< double > m_sim_shower_start_y
Definition: variables.h:868
std::vector< int > m_sim_shower_sliceId
Definition: variables.h:884
std::vector< double > m_sim_shower_overlay_fraction
Definition: variables.h:883
std::vector< std::string > m_sim_shower_end_process
Definition: variables.h:864
std::vector< int > m_sim_shower_trackID
Definition: variables.h:859
std::vector< std::string > m_sim_shower_process
Definition: variables.h:863
std::vector< double > m_sim_track_starty
Definition: variables.h:703
std::vector< double > m_sim_shower_start_x
Definition: variables.h:867
std::vector< int > m_sim_shower_parent_pdg
Definition: variables.h:860
void Printer_content(std::vector< std::string > nums, std::vector< int > spacers)
std::vector< double > m_sim_track_nuscore
Definition: variables.h:719
std::string to_string(WindowPattern const &pattern)
PandoraPFParticle * PPFP_GetPPFPFromShower(std::vector< PandoraPFParticle > &PPFPs, art::Ptr< recob::Shower > pShower)
std::vector< int > m_sim_track_matched
Definition: variables.h:690
std::vector< int > m_sim_shower_pdg
Definition: variables.h:858
std::vector< bool > m_sim_track_isclearcosmic
Definition: variables.h:720
std::vector< int > m_sim_shower_is_true_shower
Definition: variables.h:877
pdgs k
Definition: selectors.fcl:22
std::vector< double > m_sim_track_length
Definition: variables.h:711
std::vector< double > m_sim_track_overlay_fraction
Definition: variables.h:693
std::vector< double > m_sim_track_mass
Definition: variables.h:695
std::vector< bool > m_sim_shower_isclearcosmic
Definition: variables.h:886
BEGIN_PROLOG could also be cout
std::vector< int > m_sim_shower_parent_trackID
Definition: variables.h:861
std::vector< double > m_sim_track_px
Definition: variables.h:705