All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
second_shower_search.cxx
Go to the documentation of this file.
2 
3 #include "art/Framework/Principal/Event.h"
4 
5 #include "TPrincipal.h"
6 #include "TCanvas.h"
7 #include "TH1.h"
8 #include "TAxis.h"
9 #include "TLegend.h"
10 #include "TLine.h"
11 #include "TLatex.h"
12 
15 
17 
18 namespace single_photon
19 {
20 
21  TGraph* GetNearestNpts(int p, int cl, std::vector<art::Ptr<recob::Hit>> &hitz, double vertex_wire, double vertex_tick, int Npts){
22 
23  std::vector<double>t_wire;
24  std::vector<double>t_tick;
25  // std::vector<double>t_dist;
26 
27  std::vector<double>all_wire; // wire of all hits
28  std::vector<double>all_tick;
29  std::vector<double>all_dist; // distance to vertex of all hits
30 
31 
32  for(size_t h = 0; h< hitz.size(); h++){
33  auto hit = hitz[h];
34  double h_wire = (double)hit->WireID().Wire;
35  double h_tick = (double)hit->PeakTime();
36 
37  double dd =sqrt(pow(h_wire*0.3-vertex_wire*0.3,2)+pow(h_tick/25.0- vertex_tick/25.0,2));
38  all_wire.push_back(h_wire);
39  all_tick.push_back(h_tick);
40  all_dist.push_back(dd);
41  }
42 
43  std::vector<size_t> sorted_in = sort_indexes(all_dist); // index of all dist in descending order
44  size_t max_e = std::min((size_t)Npts,hitz.size());
45 
46  for(size_t i =0; i<max_e; i++){
47  t_wire.push_back(all_wire[sorted_in[hitz.size()-1-i]]);
48  t_tick.push_back(all_tick[sorted_in[hitz.size()-1-i]]);
49  }
50 
51  return new TGraph(t_wire.size(),&t_wire[0],&t_tick[0]);
52  }
53 
54  sss_score ScoreCluster(int p, int cl, std::vector<art::Ptr<recob::Hit>> &hits, double vertex_wire, double vertex_tick, const art::Ptr<recob::Shower> &shower){
55  sss_score score(p,cl);
56  score.n_hits = hits.size();
57 
58  std::vector<double> t_wires;
59  std::vector<double> t_ticks;
60 
61  //
62  int n_min_ticks = 4;
63  int n_min_wires = 3;
64  double n_max_pca = 0.9999;
65 
66  score.pass = true;
67 
68  // ************* Some simple metrics relative to study point (usually vertex) ***************
69  // this can be moved to inclass initializer
70  score.max_dist_tick = 0;
71  score.min_dist_tick = 1e10;
72  score.mean_dist_tick = 0;
73 
74  score.max_dist_wire = 0;
75  score.min_dist_wire = 1e10;
76  score.mean_dist_wire = 0;
77 
78  score.max_dist = 0;
79  score.min_dist = 1e10;
80  score.mean_dist = 0;
81 
82  score.mean_tick =0;
83  score.max_tick =0;
84  score.min_tick =1e10;
85 
86  score.mean_wire =0;
87  score.max_wire =0;
88  score.min_wire =1e10;
89 
90  score.n_wires = 0;
91  score.n_ticks = 0;
92 
93  score.impact_parameter = -99;
94 
95  score.close_tick = -99;
96  score.close_wire = -99;
97 
98  std::map<int,bool> wire_count;
99  std::map<int,bool> tick_count;
100 
101  for(auto &h: hits){
102  double h_tick = (double)h->PeakTime();
103  double h_wire = (double)h->WireID().Wire;
104 
105  score.mean_wire += h_wire;
106  score.mean_tick += h_tick;
107 
108  score.max_wire = std::max(score.max_wire, h_wire);
109  score.min_wire = std::min(score.min_wire, h_wire);
110 
111  score.max_tick = std::max(score.max_tick, h_tick);
112  score.min_tick = std::min(score.min_tick, h_tick);
113 
114  score.max_dist_tick = std::max(score.max_dist_tick, fabs(h_tick-vertex_tick));
115  score.min_dist_tick = std::min(score.min_dist_tick, fabs(h_tick-vertex_tick));
116 
117  score.max_dist_wire = std::max(score.max_dist_wire, fabs(h_wire-vertex_wire));
118  score.min_dist_wire = std::min(score.min_dist_wire, fabs(h_wire-vertex_wire));
119 
120  score.mean_dist_tick += fabs(h_tick-vertex_tick);
121  score.mean_dist_wire += fabs(h_wire-vertex_wire);
122 
123  //wierd dits
124  //requires that hit in hits has to be on the same plane as vertex_wire.
125  double dd =sqrt(pow(h_wire*0.3-vertex_wire*0.3,2)+pow(h_tick/25.0- vertex_tick/25.0,2));
126  score.mean_dist += dd;
127  if(dd< score.min_dist){
128  score.close_wire = h_wire;
129  score.close_tick = h_tick;
130  }
131 
132  score.max_dist = std::max(dd,score.max_dist);
133  score.min_dist = std::min(dd,score.min_dist);
134 
135 
136  t_wires.push_back(h_wire);
137  t_ticks.push_back(h_tick);
138 
139  if(wire_count.count((int)h_wire)<1){
140  wire_count[((int)h_wire)] = true;
141  score.n_wires++;
142  }
143  if(tick_count.count((int)h_tick)<1){
144  tick_count[((int)h_tick)] = true;
145  score.n_ticks++;
146  }
147 
148  }
149 
150  // TGraph * g_pts = new TGraph(t_wires.size(),&t_ticks[0],&t_wires[0]);
151 
152  score.mean_tick = score.mean_tick/(double)score.n_hits;
153  score.mean_wire = score.mean_wire/(double)score.n_hits;
154 
155  score.mean_dist = score.mean_dist/(double)score.n_hits;
156 
157  score.mean_dist_tick = score.mean_dist_tick/(double)score.n_hits;
158  score.mean_dist_wire = score.mean_dist_wire/(double)score.n_hits;
159 
160  // **************** Metrics of Pointing: Does this cluster "point" back to the vertex? *************************
161  // **************** First off, PCA
162 
163  TPrincipal* principal = new TPrincipal(2,"D");
164  double mod_wire = 1.0;
165  double mod_tick = 1.0;
166 
167  for(int i = 0; i < score.n_hits; i++){
168  std::vector<double> tmp_pts = {t_wires[i]*mod_wire, t_ticks[i]/mod_tick};
169  principal->AddRow(&tmp_pts[0]);
170  }
171  principal->MakePrincipals();
172  //principal->Print();
173 
174  TVectorD * eigenval = (TVectorD*) principal->GetEigenValues();
175  //TMatrixD * eigenvec = (TMatrixD*) principal->GetEigenVectors();
176  TMatrixD * covar = (TMatrixD*) principal->GetCovarianceMatrix();
177 
178  score.pca_0 = (*eigenval)(0);
179  score.pca_1 = (*eigenval)(1);
180 
181  //(*eigenvec).Print();
182  //(*covar).Print();
183  //std::cout<<"SSS\t||\tEigen: "<<score.pca_0<<" "<<score.pca_1<<std::endl;
184 
185  score.pca_theta = atan((*covar)[0][0]/(*covar)[0][1])*180.0/3.14159;
186 
187 
188  double slope = ((*covar)[0][0]/(*covar)[0][1]);
189  double c = score.mean_tick*mod_wire - slope*score.mean_wire/mod_tick;
190  score.impact_parameter = fabs(slope*vertex_wire*mod_wire +vertex_tick/mod_tick+c)/sqrt(slope*slope+1.0*1.0);
191 
192 
193  if(score.n_wires < n_min_wires || score.n_ticks < n_min_ticks || score.pca_0 >= n_max_pca){
194  score.pass = false;
195  }
196 
197 
198 
199 
200  delete principal;
201 
202  return score;
203  }
204 
205  int CompareToShowers(int p ,int cl, std::vector<art::Ptr<recob::Hit>>& hitz,double vertex_wire,double vertex_tick,
206  const std::vector<art::Ptr<recob::Shower>>& showers, std::map<art::Ptr<recob::Shower>, art::Ptr<recob::PFParticle>> & showerToPFParticleMap, const std::map<art::Ptr<recob::PFParticle>, std::vector<art::Ptr<recob::Hit>> > & pfParticleToHitsMap, double eps){
207 
208 
209  for(size_t s =0; s< showers.size(); s++){
210  art::Ptr<recob::Shower> shower = showers[s];
211  art::Ptr<recob::PFParticle> pfp = showerToPFParticleMap.at(shower);
212  std::vector<art::Ptr<recob::Hit>> showerhits = pfParticleToHitsMap.at(pfp);
213 
214  bool in_primary_shower = false;
215  for(size_t h = 0; h< hitz.size(); h++){
216  auto hit = hitz[h];
217  double h_wire = (double)hit->WireID().Wire;
218  double h_tick = (double)hit->PeakTime();
219 
220 
221  for(auto &sh: showerhits){
222 
223  if(sh->View() != hit->View()) continue;
224 
225  double sh_wire = (double)sh->WireID().Wire;
226  double sh_tick = (double)sh->PeakTime();
227 
228 
229  double dist = sqrt(pow(sh_wire*0.3-h_wire*0.3,2)+pow(sh_tick/25.0-h_tick/25.0,2));
230 
231  if(dist<=eps){
232  in_primary_shower = true;
233  return (int)s;
234  }
235 
236  }
237 
238  }
239 
240  if(in_primary_shower){
241  return (int)s;
242  }
243  }
244 
245 
246  return -1;
247  }
248 
249 
250 
251  std::vector<double>SecondShowerMatching(
252  std::vector<art::Ptr<recob::Hit>>& hitz,
253  art::FindManyP<simb::MCParticle,anab::BackTrackerHitMatchingData>& mcparticles_per_hit,
254  std::vector<art::Ptr<simb::MCParticle>>& mcParticleVector,
255  // std::map< size_t, art::Ptr<recob::PFParticle>> & pfParticleIdMap,
256  std::map< int ,art::Ptr<simb::MCParticle>> & MCParticleToTrackIdMap,
257  var_all& vars){
258 
259 
260  std::vector<double> ans; //matched,pdg,parentpdg,trkid
261 
262 
263  std::vector<double> vec_fraction_matched;
264  std::map<std::string,bool> map_is_shower_process = {{"compt",true},{"FastScintillation",true},{"eBrem",true},{"phot",true},{"eIoni",true},{"conv",true},{"annihil",true}};
265  bool reco_verbose = false;
266 
267  std::unordered_map<int,double> objide; //map between the MCParticle track ID and the backtracker energy
268 
269  //energy for an MCParticle that comprises the most energy when sum over associated hits in PFP
270  //total energy of the reco PFP taken from the sum of the hits associated to an MCParticle
271  double maxe=-1, tote=0;
272 
273  std::vector<double> total_energy_on_plane = {0.0,0.0,0.0};
274  art::Ptr<simb::MCParticle> best_matched_mcparticle; //pointer for the MCParticle match we will calculate
275  std::vector<art::Ptr<simb::MCParticle>> particle_vec; //vector of all MCParticles associated with a given hit in the cluster
276  std::vector<anab::BackTrackerHitMatchingData const *> match_vec; //vector of some backtracker thing
277 
278  int n_associated_mcparticle_hits = 0;
279  int n_not_associated_hits = 0;
280 
281  //this is the vector that will store the associated MC paritcles, as well as a MAP to the amount of energy associated
282  std::vector<art::Ptr<simb::MCParticle>> asso_mcparticles_vec;
283  std::map<art::Ptr<simb::MCParticle>, std::vector<double>> map_asso_mcparticles_energy;
284  bool found_a_match = false;
285 
286  //loop only over hits associated to this reco PFP
287  for(size_t i_h=0; i_h < hitz.size(); ++i_h){
288  int which_plane = (int)hitz[i_h]->View();
289  particle_vec.clear(); match_vec.clear(); //only store per hit
290  //for the hit, fill the backtracker info
291  mcparticles_per_hit.get(hitz[i_h].key(), particle_vec, match_vec);
292 
293  //if there is an MCParticle associated to this hit
294  if(particle_vec.size()>0) n_associated_mcparticle_hits++;
295  if(particle_vec.size()==0) n_not_associated_hits++;
296 
297  //for each MCParticle associated with this hit
298  for(size_t i_p=0; i_p<particle_vec.size(); ++i_p){
299  //add the energy of the back tracked hit for this MCParticle to the track id for the MCParticle in the map
300  objide[ particle_vec[i_p]->TrackId()] += match_vec[i_p]->energy; //store energy per track id
301 
302  //if the id isn't already in the map, store it in the vector of all associated MCParticles
303  if(std::find(asso_mcparticles_vec.begin(), asso_mcparticles_vec.end(), particle_vec[i_p]) == asso_mcparticles_vec.end()){
304  asso_mcparticles_vec.push_back(particle_vec[i_p]);
305  map_asso_mcparticles_energy[particle_vec[i_p]] = {0.0,0.0,0.0};
306  map_asso_mcparticles_energy[particle_vec[i_p]][which_plane] = match_vec[i_p]->energy;
307  }else{
308  map_asso_mcparticles_energy[particle_vec[i_p]][which_plane] += match_vec[i_p]->energy;
309  }
310  //add the energy of the back tracked hit to the total energy for the PFP
311  tote += match_vec[i_p]->energy; //calculate total energy deposited
312  total_energy_on_plane[which_plane]+=match_vec[i_p]->energy;
313 
314  //want the MCParticle with the max total energy summed from the back tracker hit energy from hits in PFP
315  //TODO: this part will change once the parts below are fully implemented
316  if( objide[ particle_vec[i_p]->TrackId()] > maxe ){ //keep track of maximum
317  maxe = objide[ particle_vec[i_p]->TrackId() ];
318  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
319  found_a_match = true;//will be false for showers from overlay
320  }
321  }//end loop over particles per hit
322 
323  } // end loop over hit
324  if(found_a_match){
325  std::cout<<"Found a match!"<<std::endl;
326  }
327  double fraction_num_hits_overlay = (double)n_not_associated_hits/(double)hitz.size();
328 
329  // if(reco_verbose)std::cout << "recoMC()\t||\t On Object "<<i<<". The number of MCParticles associated with this PFP is "<<objide.size()<<std::endl;
330  // if(reco_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;
331 
332 
333  if(n_associated_mcparticle_hits == 0){
334  //This will only occur if the whole recob::PFParticle is PURELY associated with an overlay object
335  found_a_match =false;
336  //Here we will fill every sivars.m_shower_XXX variable with -999 or something like that
337  return {0,0,0,0,0,0,0};
338  }//
339 
340  /*
341  *
342  * Loop over each MCParticle associated to the reco shower to find the source particle
343  *
344  */
345 
346  std::map<int, art::Ptr<simb::MCParticle>> mother_MCP_map; //map between MCP track id and the source MCP
347 
348  std::vector<art::Ptr<simb::MCParticle>> marks_mother_vector;
349  std::map<art::Ptr<simb::MCParticle>, std::vector<double>> marks_mother_energy_fraction_map;
350 
351  int this_mcp_id = -1; //the track id for the current MCP in parent tree
352  int last_mcp_id = -1; //the track id for the previous MCP in parent tree
353  int i_mcp = 0;
354 
355  int num_bt_mothers =0;
356 
357  //reco_verbose = false;
358  //for each MCP that's associated to the reco shower
359  for(auto mcp:asso_mcparticles_vec){
360 
361  if(reco_verbose) std::cout<<"-----------------------------Start L1 Loop --------------------------------------------------"<<std::endl;
362  // if(reco_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;
363  // if(reco_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;
364  // std::cout<<"L1: the mother of this MCP is track id "<<mcp->Mother()<<" and there are "<<mcp->NumberDaughters()<<" daughters"<<std::endl;
365 
366  //get the track ID for the current MCP
367  this_mcp_id = mcp->TrackId();
368  last_mcp_id = this_mcp_id;//initialize the previous one
369 
370  //while the track id is valid, move up the parent tree for the MCP that contributes to the reco shower
371  //currently it keeps going until it hits the top of the interaction chain, but this is likely too far
372  //to do a proper match you need to check for different cases and stop once one is fulfilled
373  while(this_mcp_id >= 0 ){
374  art::Ptr<simb::MCParticle> this_mcp = MCParticleToTrackIdMap[this_mcp_id];//get the MCP associated to the track ID
375  // std::cout<<"going up the tree got mother particle"<<std::endl;
376 
377  //check if it's a valid MCP
378  if (this_mcp.isNull()){
379  // if(reco_verbose) std::cout<<"L1: ("<<i<<" <-> "<<i_mcp<<") null pointer at id "<<this_mcp_id<<std::endl;
380  this_mcp_id = last_mcp_id; //if invalid, move back a level to the previous MCP in parent tree and break the loop
381  break;
382  }
383 
384  //If primary particle will have process "primary"
385  // if(reco_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;
386 
387  //if it is a valid particle, iterate forward to the mother
388  last_mcp_id = this_mcp_id;
389  this_mcp_id = this_mcp->Mother();
390 
391  //Check to see if this MCP was created in a "showery" process
392  if(map_is_shower_process.count(this_mcp->Process()) > 0){
393  //if it was, keep going,
394 
395  }else if(this_mcp->Process()=="primary"){
396  //if its primary, great! Note it.
397  if(reco_verbose) std::cout<<"L1: Backtracked to primary! breaking"<<std::endl;
398  this_mcp_id = last_mcp_id; //if invalid, move back a level to the previous MCP in parent tree and break the loop
399  break;
400  }else{
401  if(reco_verbose) std::cout<<"L1: Backtracked to a particle created in "<<this_mcp->EndProcess()<<"! breaking"<<std::endl;
402  this_mcp_id = last_mcp_id; //if invalid, move back a level to the previous MCP in parent tree and break the loop
403  break;
404  }
405  }
406 
407  //if the MCP at the top of the interaction chain has a valid track id store this in the mother map
408  if (this_mcp_id >= 0){
409 
410  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
411 
412  bool is_old = false;
413 
414  for(size_t k=0; k< marks_mother_vector.size(); k++){
415  //if its in it before, just run with it
416  if(marks_mother_vector[k]==MCParticleToTrackIdMap[this_mcp_id]){
417  marks_mother_energy_fraction_map[marks_mother_vector[k]][0] += map_asso_mcparticles_energy[mcp][0];
418  marks_mother_energy_fraction_map[marks_mother_vector[k]][1] += map_asso_mcparticles_energy[mcp][1];
419  marks_mother_energy_fraction_map[marks_mother_vector[k]][2] += map_asso_mcparticles_energy[mcp][2];
420  is_old = true;
421  break;
422  }
423  }
424  if(is_old==false){
425  marks_mother_vector.push_back(MCParticleToTrackIdMap[this_mcp_id]);
426  marks_mother_energy_fraction_map[marks_mother_vector.back()] = {0.0,0.0,0.0};
427  marks_mother_energy_fraction_map[marks_mother_vector.back()][0] = map_asso_mcparticles_energy[mcp][0];
428  marks_mother_energy_fraction_map[marks_mother_vector.back()][1] = map_asso_mcparticles_energy[mcp][1];
429  marks_mother_energy_fraction_map[marks_mother_vector.back()][2] = map_asso_mcparticles_energy[mcp][2];
430  }
431 
432 
433  num_bt_mothers++;
434  } else{
435  if(reco_verbose) std::cout<<"L1: error, the mother mother id was "<<this_mcp_id <<std::endl;
436 
437  }
438 
439  if(reco_verbose) std::cout<<"-----------------------------End L1 Loop --------------------------------------------------"<<std::endl;
440  i_mcp++;
441  }//for each MCParticle that's associated to a the recob::Shower
442 
443  //reco_verbose = true;
444  //there should be at least 1 mother MCP
445  if(reco_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;
446 
447  if(reco_verbose) std::cout<<"---------------------------- L2-------------------------------"<<std::endl;
448 
449  double best_mother_index = 0;
450  double best_mother_energy = -9999;
451  int best_mother_plane = -99;
452 
453  for(size_t p=0; p< marks_mother_vector.size(); p++){
454  art::Ptr<simb::MCParticle> mother = marks_mother_vector[p];
455  std::vector<double> mother_energy_recod = marks_mother_energy_fraction_map[mother];
456  if(reco_verbose) std::cout<<"L2: Mother candidate "<<p<<" TrackID "<<mother->TrackId()<<" Process: "<<mother->Process()<<" EndProcess: "<<mother->EndProcess()<<std::endl;
457  if(reco_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;
458 
459  if( mother_energy_recod[0] > best_mother_energy){
460  best_mother_index = p;
461  best_mother_energy = mother_energy_recod[0];
462  best_mother_plane = 0;
463  }
464 
465  if( mother_energy_recod[1] > best_mother_energy){
466  best_mother_index = p;
467  best_mother_energy = mother_energy_recod[1];
468  best_mother_plane = 1;
469  }
470 
471  if( mother_energy_recod[2] > best_mother_energy){
472  best_mother_index = p;
473  best_mother_energy = mother_energy_recod[2];
474  best_mother_plane = 2;
475  }
476 
477  }
478 
479  if(marks_mother_vector.size()!=0){
480  //if(reco_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;
481  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;
482  for(int l=0; l<3; l++){
483  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;
484  }
485  }
486 
487 
488  if(reco_verbose) std::cout<<"---------------------------- L2-------------------------------"<<std::endl;
489  const art::Ptr<simb::MCParticle> match = marks_mother_vector[best_mother_index];
490 
491  std::vector<double> corrected_vertex(3), corrected_start(3);
492  spacecharge_correction(match, corrected_vertex);
493 
494 
495  art::Ptr<simb::MCParticle> match_mother = MCParticleToTrackIdMap[match->Mother()];
496  int par_pdg = -1;
497  if (match_mother.isNull()){
498  par_pdg = -1;
499 
500  }else{
501  par_pdg = match_mother->PdgCode();
502  }
503 
504  ans = {1,(double)match->PdgCode(), (double)par_pdg, (double)match->TrackId(), match->E(), fraction_num_hits_overlay, best_mother_energy/total_energy_on_plane.at(best_mother_plane)};
505 
506  return ans;
507  }//end sss matching;
508 
509 
510 
511 
512 
513 
514  //************************************************ Shower Search Slice Second SSS3D ********** /
515 
516 
517 
518 
519 
520 
521 
523  std::vector<art::Ptr<recob::Shower>> & showers,
524  std::map<art::Ptr<recob::Shower>, art::Ptr<recob::PFParticle>> & NormalShowerToPFParticleMap,
525  std::vector<art::Ptr<recob::Track>> & tracks,
526  std::map<art::Ptr<recob::Track>,
527  art::Ptr<recob::PFParticle>> & NormalTrackToPFParticleMap,
528  art::Event const & evt,
529  var_all& vars,
530  para_all& paras
531  ){
532 
533  std::string sss3dlabel = "pandoraShower";//"pandoraAllOutcomesShower" WARNING, should check this!
534 
535  art::ValidHandle<std::vector<recob::Shower>> const & allShowerHandle = evt.getValidHandle<std::vector<recob::Shower>>(sss3dlabel);
536  std::vector<art::Ptr<recob::Shower>> allShowerVector;
537  art::fill_ptr_vector(allShowerVector,allShowerHandle);
538  std::cout<<"We have "<<showers.size()<<" showers in primary slice and "<<allShowerVector.size()<<" in full event."<<std::endl;
539 
540  art::FindManyP<recob::Hit> hits_per_shower(allShowerHandle, evt, sss3dlabel);
541  std::map<art::Ptr<recob::Shower>, std::vector<art::Ptr<recob::Hit>> > showerToHitsMap;
542  for(size_t i=0; i< allShowerVector.size(); ++i){
543  showerToHitsMap[allShowerVector[i]] = hits_per_shower.at(allShowerVector[i].key());
544  }
545 
546  art::FindOneP<recob::PFParticle> pfparticle_per_shower(allShowerHandle, evt, sss3dlabel);
547  std::map<art::Ptr<recob::Shower>, art::Ptr<recob::PFParticle> > showerToPFParticleMap;
548  for(size_t i=0; i< allShowerVector.size(); ++i){
549  showerToPFParticleMap[allShowerVector[i]] = pfparticle_per_shower.at(allShowerVector[i].key());
550  }
551 
552  art::ValidHandle<std::vector<recob::PFParticle>> const & pfParticleHandle = evt.getValidHandle<std::vector<recob::PFParticle>>("pandora");//""pandoraPatRec:allOutcomes");
553  std::vector<art::Ptr<recob::PFParticle>> allPFParticleVector;
554  art::fill_ptr_vector(allPFParticleVector,pfParticleHandle);
555 
556  //art::FindManyP< larpandoraobj::PFParticleMetadata > pfPartToMetadataAssoc(pfParticleHandle, evt, "pandora");//PatRec:allOutcomes");
557  //pfPartToMetadataAssoc.at(pfp.key());
558 
559  size_t n_all_shr = allShowerVector.size();
560  vars.m_sss3d_num_showers = (int)n_all_shr-showers.size();
561 
562  if(showers.size()==0) return;
563 
564  auto primary_shower = showers.front();
565 
566  std::cout<<"PandoraAllOutcomesShower has "<<n_all_shr<<" Showers in total. "<<std::endl;
567  for(auto &shr: allShowerVector){
568  //lets look at 3D distance to "vertex", and only go further with things that are within 80cm [default]
569  double dist = sqrt(pow(vars.m_vertex_pos_x - shr->ShowerStart().X(),2)+pow(vars.m_vertex_pos_y - shr->ShowerStart().Y(),2)+pow(vars.m_vertex_pos_z - shr->ShowerStart().Z(),2) );
570  if(dist>paras.s_max_conv_dist) continue;
571 
572  auto pfp = showerToPFParticleMap[shr];
573  //for(auto &prr: allPFParticleVector){
574  // std::cout<<pfp->Self()<<" "<<pfp.key()<<" "<<prr->Self()<<" "<<prr.key()<<std::endl;
575  //}
576 
577  //What are we intested in learning
578  std::vector<std::string> interested = {"IsClearCosmic","TrackScore","NuScore","IsNeutrino","SliceIndex"};
579 
580  /*
581  std::vector<art::Ptr<larpandoraobj::PFParticleMetadata>> metadatas = pfPartToMetadataAssoc.at(pfp.key());
582  for(auto &meta: metadatas){
583  std::map<std::string, float> propertiesmap = meta->GetPropertiesMap();
584 
585  for (auto it:propertiesmap ){
586  std::cout<<it.first<<" "<<it.second<<" ";
587  }
588  std::cout<<std::endl;
589 
590  //for each of the things in the list
591  for(auto &s: interested){
592  if(propertiesmap.count(s)==1){
593  std::cout<<" "<<s<<" : "<<propertiesmap[s]<<" ";
594  }else{
595  std::cout<<" NO "<<s<<" . ";
596  }
597  }
598  }
599  */
600 
601  //std::cout<<shr.key()<<" Length "<<shr->Length()<<" Dist "<<dist<<" Impact: "<<impact_paramater_shr(vars.m_vertex_pos_x, vars.m_vertex_pos_y, vars.m_vertex_pos_z, shr)<<" pfp key: "<<showerToPFParticleMap[shr].key()<<" Self "<<showerToPFParticleMap[shr]->Self()<<std::endl;
602 
603  //OK we need to "remove" the showers that are neutrino showers as well as those that are the "track"
604 
605  bool is_matched = false;
606 
607  for(auto &s: showers){
608  //const art::Ptr<recob::Slice> s_slice = slice_per_pfparticle.at(NormalShowerToPFParticleMap[s].key());
609  //std::cout<<s.key()<<"shr is in slice "<<s_slice->ID()<<std::endl;
610  if(s->ShowerStart().X() == shr->ShowerStart().X() || pfp->Self()== NormalShowerToPFParticleMap[s]->Self()){
611  //std::cout<<"Its a match!"<<std::endl;
612  is_matched = true;
613  }
614  }
615 
616  for(auto &s: tracks){
617  //const art::Ptr<recob::Slice> s_slice = slice_per_pfparticle.at(NormalTrackToPFParticleMap[s].key());
618  //std::cout<<s.key()<<"trk is in slice "<<s_slice->ID()<<std::endl;
619  if(pfp->Self()== NormalTrackToPFParticleMap[s]->Self()){
620  //std::cout<<"Its a match!"<<std::endl;
621  is_matched = true;
622  }
623  }
624 
625  if(is_matched)
626  {
627  // std::cout<<"matched and continuing"<<std::endl;
628  continue;
629  }
630 
631  double senergy = std::max( CalcEShowerPlane(showerToHitsMap[shr], 0, paras), std::max( CalcEShowerPlane(showerToHitsMap[shr], 1, paras), CalcEShowerPlane(showerToHitsMap[shr], 2, paras)) );
632  double invar = implied_invar_mass(vars.m_vertex_pos_x, vars.m_vertex_pos_y, vars.m_vertex_pos_z, primary_shower, vars.m_reco_shower_energy_max[0], shr, senergy);
633  double implied_invar = invar_mass(primary_shower, vars.m_reco_shower_energy_max[0], shr, senergy) ;
634  double shr_score = 0.0; //need pfp and metadata to get score, and might give slice! (This will be harder..) but on reflection, kinda important. PCA spread might be a good rplacement.
635  int is_clear_cosmic_slice = 0 ;
636  int is_nu_slice = 0;
637 
638 
639  vars.m_sss3d_shower_start_x.push_back(shr->ShowerStart().X());
640  vars.m_sss3d_shower_start_y.push_back(shr->ShowerStart().Y());
641  vars.m_sss3d_shower_start_z.push_back(shr->ShowerStart().Z());
642  vars.m_sss3d_shower_dir_x.push_back(shr->Direction().X());
643  vars.m_sss3d_shower_dir_y.push_back(shr->Direction().Y());
644  vars.m_sss3d_shower_dir_z.push_back(shr->Direction().Z());
645  vars.m_sss3d_shower_length.push_back(shr->Length());
646  vars.m_sss3d_shower_conversion_dist.push_back(dist);
647  vars.m_sss3d_shower_invariant_mass.push_back(invar);
648  vars.m_sss3d_shower_implied_invariant_mass.push_back(implied_invar);
649  double imp = impact_paramater_shr(vars.m_vertex_pos_x, vars.m_vertex_pos_y, vars.m_vertex_pos_z, shr);
650  vars.m_sss3d_shower_impact_parameter.push_back(imp);
651 
652  if(dist!=0) {
653  vars.m_sss3d_shower_ioc_ratio.push_back(imp/dist);
654  }else{
655  vars.m_sss3d_shower_ioc_ratio.push_back(0);
656 
657  }
658  vars.m_sss3d_shower_energy_max.push_back(senergy);
659  vars.m_sss3d_shower_score.push_back(shr_score);
660  vars.m_sss3d_slice_clear_cosmic.push_back(is_clear_cosmic_slice);
661  vars.m_sss3d_slice_nu.push_back(is_nu_slice);
662  }
663 
664  return;
665  }
666 
667 
668 
670 
671  std::string base = "sss3d_";
672  std::vector<std::string> mod = {"ioc_ranked","invar_ranked"};
673 
674  vars.m_sss3d_ioc_ranked_en = -9;
675  vars.m_sss3d_ioc_ranked_conv = -9;
676  vars.m_sss3d_ioc_ranked_invar = -9;
678  vars.m_sss3d_ioc_ranked_ioc = -9;
679  vars.m_sss3d_ioc_ranked_opang = -9;
681  vars.m_sss3d_ioc_ranked_id = -9;
682 
683  vars.m_sss3d_invar_ranked_en = -9;
684  vars.m_sss3d_invar_ranked_conv = -9;
685  vars.m_sss3d_invar_ranked_invar = -9;
687  vars.m_sss3d_invar_ranked_ioc = -9;
688  vars.m_sss3d_invar_ranked_opang = -9;
690  vars.m_sss3d_invar_ranked_id = -9;
691 
692 
693  std::string base2d = "sss_";
694  std::vector<std::string> mod2d = {"ioc_ranked","conv_ranked","invar_ranked"};
695 
696  vars.m_sss2d_ioc_ranked_en = -9;
697  vars.m_sss2d_ioc_ranked_conv = -9;
698  vars.m_sss2d_ioc_ranked_ioc = -9;
699  vars.m_sss2d_ioc_ranked_pca = -9;
700  vars.m_sss2d_ioc_ranked_invar = -9;
703 
704  vars.m_sss2d_conv_ranked_en = -9;
705  vars.m_sss2d_conv_ranked_conv = -9;
706  vars.m_sss2d_conv_ranked_ioc = -9;
707  vars.m_sss2d_conv_ranked_pca = -9;
708  vars.m_sss2d_conv_ranked_invar = -9;
711 
712  vars.m_sss2d_invar_ranked_en = -9;
713  vars.m_sss2d_invar_ranked_conv = -9;
714  vars.m_sss2d_invar_ranked_ioc = -9;
715  vars.m_sss2d_invar_ranked_pca = -9;
716  vars.m_sss2d_invar_ranked_invar = -9;
719 
720  //---------------------------------------
721  //First off, the 3D showers
722  //First some 3D shower information
723  if(vars.m_sss3d_shower_conversion_dist.size()>0 && vars.m_reco_shower_energy_max.size()>0){
724  //std::cout<<"Primary shower en "<<reco_shower_energy_max->at(0)<<std::endl;
725 
726  std::vector<double> inv = vars.m_sss3d_shower_implied_invariant_mass;
727  for(auto &v : inv) v = fabs(v-paras.s_mass_pi0_mev);
728 
729  std::vector<size_t> ranked_ioc = sort_indexes_rev<double>((vars.m_sss3d_shower_ioc_ratio));
730  std::vector<size_t> ranked_invar = sort_indexes_rev<double>((inv));
731  std::vector<size_t> ranked_conv = sort_indexes_rev<double>((vars.m_sss3d_shower_conversion_dist));
732  std::vector<size_t> ranked_en = sort_indexes_rev<double>((vars.m_sss3d_shower_energy_max));
733 
734  int to_consider = vars.m_sss3d_shower_conversion_dist.size();
735 
736  if(false){
737  std::cout<<"IOC"<<std::endl;
738  for(int j=0; j<to_consider; j++){
739  std::cout<<"--"<<ranked_ioc[j]<<" ioc: "<<vars.m_sss3d_shower_ioc_ratio.at( ranked_ioc[j] )<<" invar: "<<vars.m_sss3d_shower_implied_invariant_mass.at(ranked_ioc[j])<<" en: "<<vars.m_sss3d_shower_energy_max.at(ranked_ioc[j])<<" conv: "<<vars.m_sss3d_shower_conversion_dist.at(ranked_ioc[j])<<std::endl;
740  }
741 
742  std::cout<<"INVAR"<<std::endl;
743  for(int j=0; j<to_consider; j++){
744  std::cout<<"--"<<ranked_invar[j]<<" ioc: "<<vars.m_sss3d_shower_ioc_ratio.at( ranked_invar[j] )<<" invar: "<<vars.m_sss3d_shower_implied_invariant_mass.at(ranked_invar[j])<<" en: "<<vars.m_sss3d_shower_energy_max.at(ranked_invar[j])<<" conv: "<<vars.m_sss3d_shower_conversion_dist.at(ranked_invar[j]) <<std::endl;
745  }
746 
747  std::cout<<"EN"<<std::endl;
748  for(int j=0; j<to_consider; j++){
749  int rk = ranked_en[ranked_en.size()-1-j];
750  std::cout<<"--"<<rk<<" ioc: "<<vars.m_sss3d_shower_ioc_ratio.at( rk )<<" invar: "<<vars.m_sss3d_shower_implied_invariant_mass.at(rk)<<" en: "<<vars.m_sss3d_shower_energy_max.at(rk)<<" conv: "<<vars.m_sss3d_shower_conversion_dist.at(rk)<<std::endl;
751  }
752  std::cout<<"CONV"<<std::endl;
753  for(int j=0; j<to_consider; j++){
754  std::cout<<"--"<<ranked_conv[j]<<" ioc: "<<vars.m_sss3d_shower_ioc_ratio.at( ranked_conv[j] )<<" invar: "<<vars.m_sss3d_shower_implied_invariant_mass.at(ranked_conv[j])<<" en: "<<vars.m_sss3d_shower_energy_max.at(ranked_conv[j])<<" conv: "<<vars.m_sss3d_shower_conversion_dist.at(ranked_conv[j])<<std::endl;
755  }
756  }
757 
758 
759  //std::cout<<"Best IOC "<<"--"<<ranked_ioc[0]<<" ioc: "<<sss3d_shower_ioc_ratio->at( ranked_ioc[0] )<<" invar: "<<sss3d_shower_implied_invariant_mass->at(ranked_ioc[0])<<" en: "<<sss3d_shower_energy_max->at(ranked_ioc[0])<<" conv: "<<sss3d_shower_conversion_dist->at(ranked_ioc[0])<<std::endl;
760  vars.m_sss3d_ioc_ranked_en = vars.m_sss3d_shower_energy_max.at(ranked_ioc[0]);
761  vars.m_sss3d_ioc_ranked_conv = vars.m_sss3d_shower_conversion_dist.at(ranked_ioc[0]);
762  vars.m_sss3d_ioc_ranked_invar = vars.m_sss3d_shower_invariant_mass.at(ranked_ioc[0]);
764  vars.m_sss3d_ioc_ranked_ioc = vars.m_sss3d_shower_ioc_ratio.at(ranked_ioc[0]);
765  vars.m_sss3d_ioc_ranked_opang = 1.0 - pow(vars.m_sss3d_shower_invariant_mass.at(ranked_ioc[0]),2)/(2.0*vars.m_sss3d_shower_energy_max.at(ranked_ioc[0])*vars.m_reco_shower_energy_max.at(0));
766  vars.m_sss3d_ioc_ranked_implied_opang = 1.0 - pow(vars.m_sss3d_shower_implied_invariant_mass.at(ranked_ioc[0]),2)/(2.0*vars.m_sss3d_shower_energy_max.at(ranked_ioc[0])*vars.m_reco_shower_energy_max.at(0));
767  vars.m_sss3d_ioc_ranked_id = ranked_ioc[0];
768 
769 
770  // std::cout<<"Best invar "<<"--"<<ranked_invar[0]<<" ioc: "<<sss3d_shower_ioc_ratio.at( ranked_invar[0] )<<" invar: "<<sss3d_shower_implied_invariant_mass.at(ranked_invar[0])<<" en: "<<sss3d_shower_energy_max.at(ranked_invar[0])<<" conv: "<<sss3d_shower_conversion_dist.at(ranked_invar[0])<<std::endl;
771 
772  // minimum discrepancy between implied invariant mass and pi0 mass
773  vars.m_sss3d_invar_ranked_en = vars.m_sss3d_shower_energy_max.at(ranked_invar[0]);
774  vars.m_sss3d_invar_ranked_conv = vars.m_sss3d_shower_conversion_dist.at(ranked_invar[0]);
775  vars.m_sss3d_invar_ranked_invar = vars.m_sss3d_shower_invariant_mass.at(ranked_invar[0]);
777  vars.m_sss3d_invar_ranked_ioc = vars.m_sss3d_shower_ioc_ratio.at(ranked_invar[0]);
778  vars.m_sss3d_invar_ranked_opang = 1.0 - pow(vars.m_sss3d_shower_invariant_mass.at(ranked_invar[0]),2)/(2.0*vars.m_sss3d_shower_energy_max.at(ranked_invar[0])*vars.m_reco_shower_energy_max.at(0));
779  vars.m_sss3d_invar_ranked_implied_opang = 1.0 - pow(vars.m_sss3d_shower_implied_invariant_mass.at(ranked_invar[0]),2)/(2.0*vars.m_sss3d_shower_energy_max.at(ranked_invar[0])*vars.m_reco_shower_energy_max.at(0));
780  vars.m_sss3d_invar_ranked_id = ranked_invar[0];
781 
782  }//end of 3D shower searching
783 
784 
785  //Now some 2D shower information
786  //
787  if(vars.m_sss_num_candidates>0){
788  //std::cout<<"2D clusters: "<<sss_num_candidates<<std::endl;
789  std::vector<int> nplans(3,0);
790  std::vector<std::vector<int>> indexmap(3);
791 
792 
793  for(int i=0; i< vars.m_sss_num_candidates; i++){
794  //std::cout<<i<<" p: "<<vars.m_sss_candidate_plane->at(i)<<" pdg: "<<vars.m_sss_candidate_parent_pdg->at(i)<<" ovf "<<vars.m_sss_candidate_overlay_fraction->at(i)<<" conv: "<<vars.m_sss_candidate_min_dist->at(i)<<std::endl;
795  }
796 
797  std::vector<std::vector<int>> uniq_candidates;
798 
799  for(int i=0; i< vars.m_sss_num_candidates; i++){
800  int ip = vars.m_sss_candidate_plane.at(i);
801  //int nhits = sss_candidate_num_hits.at(i);
802  nplans[ip]++;
803  indexmap[ip].push_back(i);
804 
805  //Two passes to build up all "Candidates" for 2 and 3 plane matches
806  for(int j=i;j<vars.m_sss_num_candidates;j++){
807  int jp = vars.m_sss_candidate_plane.at(j);
808  if(jp==ip) continue;
809 
810  bool contain_ij = false;
811  bool contain_ji = false;
812  if(vars.m_sss_candidate_mean_tick.at(j)<=vars.m_sss_candidate_max_tick.at(i) && vars.m_sss_candidate_mean_tick.at(j) >= vars.m_sss_candidate_min_tick.at(i))contain_ij = true;
813  if(vars.m_sss_candidate_mean_tick.at(i)<=vars.m_sss_candidate_max_tick.at(j) && vars.m_sss_candidate_mean_tick.at(i) >= vars.m_sss_candidate_min_tick.at(j))contain_ji = true;
814  // std::cout<<i<<" "<<j<<" "<<contain_ij<<" "<<contain_ji<<std::endl;
815  if(contain_ij && contain_ji){
816  uniq_candidates.push_back({i,j});
817  }
818  }
819  }
820 
821  //Now loop over to check if any indlude a third plane
822  for(int i = 0; i< (int)uniq_candidates.size(); i++){
823  for(int k=0; k<vars.m_sss_num_candidates; k++){
824  //first check if this possible 3rd match is on a seperate plane
825  bool new_plane = true;
826  for(auto &pp:uniq_candidates[i]){
827  if(vars.m_sss_candidate_plane.at(k)==vars.m_sss_candidate_plane.at(pp) ) new_plane = false;
828  }
829  if(new_plane){
830 
831  bool contain_ik = false;
832  bool contain_ki = false;
833  bool contain_jk = false;
834  bool contain_kj = false;
835  if(vars.m_sss_candidate_mean_tick.at(k)<=vars.m_sss_candidate_max_tick.at(uniq_candidates[i][0]) && vars.m_sss_candidate_mean_tick.at(k) >= vars.m_sss_candidate_min_tick.at(uniq_candidates[i][0]))contain_ik = true;
836  if(vars.m_sss_candidate_mean_tick.at(uniq_candidates[i][0])<=vars.m_sss_candidate_max_tick.at(k) && vars.m_sss_candidate_mean_tick.at(uniq_candidates[i][0]) >= vars.m_sss_candidate_min_tick.at(k))contain_ki = true;
837  if(vars.m_sss_candidate_mean_tick.at(k)<=vars.m_sss_candidate_max_tick.at(uniq_candidates[i][1]) && vars.m_sss_candidate_mean_tick.at(k) >= vars.m_sss_candidate_min_tick.at(uniq_candidates[i][1]))contain_ik = true;
838  if(vars.m_sss_candidate_mean_tick.at(uniq_candidates[i][1])<=vars.m_sss_candidate_max_tick.at(k) && vars.m_sss_candidate_mean_tick.at(uniq_candidates[i][1]) >= vars.m_sss_candidate_min_tick.at(k))contain_ki = true;
839 
840  //If this matches well with Either last candidate, include as a possibility
841  if((contain_ik&&contain_ki) || (contain_jk&&contain_kj)){
842  uniq_candidates[i].push_back(k);
843  }
844 
845  }
846  }
847  }
848  //Check which candidates have been used where
849  std::vector<int> used_candidates(vars.m_sss_num_candidates);
850  for(int i = 0; i< (int)uniq_candidates.size(); i++){
851  for(auto &j: uniq_candidates[i]){
852  used_candidates[j]++;
853  }
854  }
855 
856  //If a candidate has been included in NO 2 or 3 plane cluster, treat it on its own
857  for(int i = 0; i< (int)used_candidates.size(); i++){
858  if(used_candidates[i]==0) uniq_candidates.push_back({i});
859  }
860 
861  //Now lets delete any permutations
862  std::vector<std::vector<int>> uniq_candidates2;
863  uniq_candidates2.push_back(uniq_candidates.front());
864 
865  for(int i = 1; i< (int)uniq_candidates.size(); i++){
866 
867  bool perm = false;
868  for(int j = 0; j< (int)uniq_candidates2.size(); j++){
869  perm = marks_compare_vec_nonsense<int>(uniq_candidates[i], uniq_candidates2[j]);
870  if(perm) break;
871  }
872  if(!perm) uniq_candidates2.push_back(uniq_candidates[i]);
873  }
874 
875  //Printing candidates (After perm check)
876  std::cout<<"After: used_candidates "<<vars.m_sss_num_candidates<<std::endl;
877  for(int i = 0; i< (int)uniq_candidates2.size(); i++){
878  std::cout<<i<<" | ";
879  for(auto &j: uniq_candidates2[i])std::cout<<" "<<j;
880  std::cout<<std::endl;
881  }
882 
883  //Right lets CULL and rank the candidates
884  std::vector<bool> candidate_pass(uniq_candidates2.size(),false);
885  std::vector<double> candidates_en(uniq_candidates2.size(),0);
886  std::vector<double> candidates_ioc(uniq_candidates2.size(),0);
887  std::vector<double> candidates_conv(uniq_candidates2.size(),0);
888  std::vector<double> candidates_pca(uniq_candidates2.size(),0);
889  std::vector<double> candidates_angle_to_shower(uniq_candidates2.size(),0);
890  std::vector<int> candidates_num_planes(uniq_candidates2.size(),0);
891  std::vector<double> candidates_eff_invar(uniq_candidates2.size(),0);
892  std::vector<double> candidates_eff_invar_diff(uniq_candidates2.size(),0);
893 
894  //rank by min_impat/max_min_dist and select
895  //rank by Energy energy
896 
897  for(int j=0; j<(int)uniq_candidates2.size();j++){
898  int nt=uniq_candidates2[j].size();
899  //std::cout<<"Candidate #: "<<j<<" has "<<nt<<" 2D clusters"<<std::endl;
900 
901  double mean_min_dist = 0.0;
902  double max_min_dist = 0.0;
903 
904  double mean_energy = 0.0;
905 
906  double mean_impact = 0.0;
907  double mean_conv = 0.0;
908  double min_conv = 999;
909 
910  double min_impact = 999;
911  double mean_invar = 0.0;
912  double mean_invar_diff = 0.0;
913 
914  double max_pca = 0;
915  double min_angle = 999;
916 
917 
918  //int is_min_slice = 999;
919  //std::vector<int> is_in_slice;
920 
921  for(int c=0; c< nt;++c){
922  int ic = uniq_candidates2[j][c];
923 
924  //std::cout<<"----- plane: "<<vars.m_sss_candidate_plane.at(ic)<<" nhits: "<<vars.m_sss_candidate_num_hits.at(ic)<<" imp: "<<vars.m_sss_candidate_impact_parameter.at(ic)<<" en: "<<vars.m_sss_candidate_energy.at(ic)<<" a2s: "<<vars.m_sss_candidate_angle_to_shower.at(ic)<<" conv: "<<vars.m_sss_candidate_min_dist.at(ic)<<" pdg: "<<vars.m_sss_candidate_parent_pdg.at(ic)<<std::endl;
925 
926  double eff_invar = sqrt(2.0*vars.m_sss_candidate_energy.at(ic)*vars.m_reco_shower_energy_max.at(0)*(1.0-cos(vars.m_sss_candidate_angle_to_shower.at(ic))));
927  double eff_invar_diff = fabs(eff_invar-139.5);
928 
929  //is_min_slice = std::min(is_in_slice, vars.m_sss_candidate_in_nu_slice[ic] );
930  //is_in_slice.push_back(vars.m_sss_candidate_in_nu_slice[ic]);
931 
932  mean_min_dist +=vars.m_sss_candidate_min_dist.at(ic)/(double)nt;
933  mean_energy +=vars.m_sss_candidate_energy.at(ic)/(double)nt;
934  mean_impact +=vars.m_sss_candidate_impact_parameter.at(ic)/(double)nt;
935  mean_conv +=vars.m_sss_candidate_min_dist.at(ic)/(double)nt;
936  mean_invar +=eff_invar/(double)nt;
937  mean_invar_diff +=eff_invar_diff/(double)nt;
938 
939  min_conv = std::min(min_conv, vars.m_sss_candidate_min_dist.at(ic));
940  max_min_dist = std::max(max_min_dist, vars.m_sss_candidate_min_dist.at(ic));
941  max_pca = std::max(max_pca, vars.m_sss_candidate_PCA.at(ic));
942  min_impact = std::min(min_impact, vars.m_sss_candidate_impact_parameter.at(ic));
943  min_angle = std::min(min_angle, vars.m_sss_candidate_angle_to_shower.at(ic));
944 
945  }
946  std::cout<<"======== Mean En "<<mean_energy<<" mean dist "<<mean_min_dist<<" meanimpact "<<mean_impact<<" minimpact/maxdist : "<<min_impact/max_min_dist<<" invar "<<mean_invar<<std::endl;
947  candidates_ioc[j]=min_impact/max_min_dist;
948  candidates_en[j]=mean_energy;
949  candidates_conv[j] = min_conv;
950  candidates_pca[j] = max_pca;
951  candidates_angle_to_shower[j] = min_angle;
952  candidates_num_planes[j] =nt;
953  candidates_eff_invar_diff[j] = mean_invar_diff;
954  candidates_eff_invar[j] = mean_invar;
955  //candidates_min_slice[j] = is_min_slice;
956  //candidates_in_slice[j] = is_in_slice;
957  }
958 
959  std::vector<size_t> ranked_ioc = sort_indexes_rev<double>(candidates_ioc);
960  std::vector<size_t> ranked_invar = sort_indexes_rev<double>(candidates_eff_invar_diff);
961  std::vector<size_t> ranked_conv = sort_indexes_rev<double>(candidates_conv);
962 
963  std::cout<<"========== Ranking ======== "<<std::endl;
964  std::cout<<"IOC "; for (auto &ii: ranked_ioc) std::cout<<" "<<ii; std::cout<<std::endl;
965  std::cout<<"CONV "; for (auto &ii: ranked_conv) std::cout<<" "<<ii; std::cout<<std::endl;
966  std::cout<<"INVAR ";for (auto &ii: ranked_invar) std::cout<<" "<<ii; std::cout<<std::endl;
967 
968  vars.m_sss2d_ioc_ranked_en = candidates_en[ranked_ioc[0]];
969  vars.m_sss2d_ioc_ranked_conv = candidates_conv[ranked_ioc[0]];
970  vars.m_sss2d_ioc_ranked_ioc = candidates_ioc[ranked_ioc[0]];
971  vars.m_sss2d_ioc_ranked_invar = candidates_eff_invar[ranked_ioc[0]];
972  vars.m_sss2d_ioc_ranked_pca = candidates_pca[ranked_ioc[0]];
973  vars.m_sss2d_ioc_ranked_angle_to_shower = candidates_angle_to_shower[ranked_ioc[0]];
974  vars.m_sss2d_ioc_ranked_num_planes = candidates_num_planes[ranked_ioc[0]];
975 
976  vars.m_sss2d_conv_ranked_en = candidates_en[ranked_conv[0]];
977  vars.m_sss2d_conv_ranked_conv = candidates_conv[ranked_conv[0]];
978  vars.m_sss2d_conv_ranked_ioc = candidates_ioc[ranked_conv[0]];
979  vars.m_sss2d_conv_ranked_invar = candidates_eff_invar[ranked_conv[0]];
980  vars.m_sss2d_conv_ranked_pca = candidates_pca[ranked_conv[0]];
981  vars.m_sss2d_conv_ranked_angle_to_shower = candidates_angle_to_shower[ranked_conv[0]];
982  vars.m_sss2d_conv_ranked_num_planes = candidates_num_planes[ranked_conv[0]];
983 
984  vars.m_sss2d_invar_ranked_en = candidates_en[ranked_invar[0]];
985  vars.m_sss2d_invar_ranked_conv = candidates_conv[ranked_invar[0]];
986  vars.m_sss2d_invar_ranked_ioc = candidates_ioc[ranked_invar[0]];
987  vars.m_sss2d_invar_ranked_invar = candidates_eff_invar[ranked_invar[0]];
988  vars.m_sss2d_invar_ranked_pca = candidates_pca[ranked_invar[0]];
989  vars.m_sss2d_invar_ranked_angle_to_shower = candidates_angle_to_shower[ranked_invar[0]];
990  vars.m_sss2d_invar_ranked_num_planes = candidates_num_planes[ranked_invar[0]];
991  }
992 
993  return ;
994  }
995 
996 
997 
998  std::pair<bool, std::vector<double>> clusterCandidateOverlap(const std::vector<int> & candidate_indices, const std::vector<int>& cluster_planes, const std::vector<double>& cluster_max_ticks, const std::vector<double>& cluster_min_ticks){
999 
1000  size_t size = candidate_indices.size();
1001  if(size == 0){
1002  throw std::runtime_error("clusterCandidateOverlap: No cluster candidates to analyze time overlap for..");
1003  }
1004 
1005  // at most 3 cluster indices (for 3 planes)
1006  std::vector<int> planes;
1007  std::vector<double> max_ticks;
1008  std::vector<double> min_ticks;
1009  std::vector<double> tick_length;
1010 
1011  for(auto i : candidate_indices){
1012  planes.push_back(cluster_planes[i]);
1013 
1014  max_ticks.push_back(cluster_max_ticks[i]);
1015  min_ticks.push_back(cluster_min_ticks[i]);
1016  tick_length.push_back(cluster_max_ticks[i] - cluster_min_ticks[i]);
1017  }
1018 
1019 
1020  //if candidates are not on different planes
1021  if( size == 2 && planes[0] == planes[1])
1022  return {false, std::vector<double>(2, -1.0)};
1023  if( size == 3 && (planes[0] == planes[1] || planes[1] == planes[2] || planes[0] == planes[2]))
1024  return {false, std::vector<double>(3, -1.0)};
1025 
1026  //calculate the overlapping tick-span
1027  double tick_overlap = DBL_MAX;
1028 
1029  //can be simplied as picking the minimum max_tick and maximum min_tick and do the subtraction
1030  for(auto max_e : max_ticks)
1031  for(auto min_e : min_ticks)
1032  if(max_e - min_e < tick_overlap)
1033  tick_overlap = max_e - min_e;
1034 
1035  // if tick overlap is negative, meaning these clusters are not overlapping
1036  if(tick_overlap < 0)
1037  return {false, std::vector<double>(size, -1.0)};
1038  else{
1039  std::vector<double> overlap_fraction;
1040  for(auto l: tick_length){
1041  overlap_fraction.push_back( l==0? 1.0 : tick_overlap/l);
1042  }
1043  return {true, overlap_fraction};
1044  }
1045  }
1046 
1047 
1048  std::pair<int, std::pair<std::vector<std::vector<double>>, std::vector<double>>> GroupClusterCandidate(int num_clusters, const std::vector<int>& cluster_planes, const std::vector<double>& cluster_max_ticks, const std::vector<double>& cluster_min_ticks){
1049  std::cout << "group_cluster_candidate\t|| Total of " << num_clusters << " to be grouped" << std::endl;
1050 
1051  int num_cluster_groups=0; // number of matched cluster groups in total
1052  std::vector<std::vector<double>> grouped_cluster_indices;
1053  std::vector<double> cluster_group_timeoverlap_fraction;
1054  if(num_clusters <= 1)
1055  return {num_cluster_groups, {grouped_cluster_indices, cluster_group_timeoverlap_fraction}};
1056 
1057  for(int i = 0; i != num_clusters -1; ++i){
1058  for(int j = i+1; j != num_clusters; ++j){
1059 
1060  //first, look at candidate pairs
1061  auto pair_result = clusterCandidateOverlap({i,j}, cluster_planes, cluster_max_ticks, cluster_min_ticks);
1062  if( pair_result.first){
1063 
1064  ++num_cluster_groups;
1065  grouped_cluster_indices.push_back({(double)i,(double)j});
1066  double min_frac = *std::min_element(pair_result.second.cbegin(), pair_result.second.cend());
1067  cluster_group_timeoverlap_fraction.push_back(min_frac);
1068  std::cout << "Grouped cluster candidate: (" << i << ", " << j << ") | Minimum time tick overlap fraction: " << min_frac << std::endl;
1069 
1070  // if the pair is succefully grouped, look at possible trios
1071  for(int k = j+1; k!= num_clusters; ++k){
1072  auto tri_result = clusterCandidateOverlap({i,j,k}, cluster_planes, cluster_max_ticks, cluster_min_ticks);
1073  if(tri_result.first){
1074  ++num_cluster_groups;
1075  grouped_cluster_indices.push_back({(double)i,(double)j,(double)k});
1076  min_frac = *std::min_element(tri_result.second.cbegin(), tri_result.second.cend());
1077  cluster_group_timeoverlap_fraction.push_back(min_frac);
1078  std::cout << "Grouped cluster candidate: (" << i << ", " << j << ", " << k << ") | Minimum time tick overlap fraction: " << min_frac << std::endl;
1079  }
1080  } //k loop
1081  }
1082  }//j loop
1083  }//i loop
1084 
1085  std::cout << "GroupClusterCandidate\t|| Formed " << num_cluster_groups << " cluster groups" << std::endl;
1086 
1087  return {num_cluster_groups, {grouped_cluster_indices, cluster_group_timeoverlap_fraction}};
1088  }
1089 
1090  //isolation.h
1091  /* Arguments to Function IsolationStudy (all are const):
1092  * 1. vector named tracks of art ptr to recob track
1093  * 2. map named trackToPFPParticleMap of .i. art ptr to recob track .ii. art ptr to recob pfparticle
1094  * 3. vector named showers of art ptr to recob showers
1095  * 4. map named showerToPFParticleMap of .i. art ptr to recob showe .ii. art ptr to recob pfparticle
1096  * 5. map named pfParticleToHistMap of .i. art ptr to recob prparticle .ii. vector of art ptr to recob hit
1097  * 6. map named pfParticleToSliceIDMap of .i. art ptr to recob pfparticle .ii. int
1098  * 7. map named sliceIDToHitsMap of .i. int and .ii. art ptr to recob hit
1099  */
1101  std::vector<PandoraPFParticle> all_PPFPs,
1102  const std::vector<art::Ptr<recob::Track>>& tracks,
1103  const std::vector<art::Ptr<recob::Shower>>& showers,
1104  detinfo::DetectorPropertiesData const & theDetector,
1105  var_all& vars,
1106  para_all& paras){
1107 
1108  int total_track_hits =0;
1109  int total_shower_hits =0;
1110  int nu_slice_id = -999;
1111 
1112  std::vector< art::Ptr<recob::Hit> > associated_hits;
1113  std::vector< art::Ptr<recob::Hit> > unassociated_hits;
1114  std::vector< art::Ptr<recob::Hit> > unassociated_hits_plane0;
1115  std::vector< art::Ptr<recob::Hit> > unassociated_hits_plane1;
1116  std::vector< art::Ptr<recob::Hit> > unassociated_hits_plane2;
1117 
1118  std::vector< std::map<size_t, std::vector< art::Ptr<recob::Hit> >> > v_newClusterToHitsMap(3);
1119 
1120  std::vector<art::Ptr<recob::Hit>> slicehits;
1121 
1122  // BEGIN FOR LOOP TO COUNT TRACK HITS AND PUSH INTO ASSOCIATED HITS
1123  for(size_t t =0; t< tracks.size(); t++){
1124  art::Ptr<recob::Track> track = tracks[t];
1125  PandoraPFParticle* ppfp = PPFP_GetPPFPFromTrack(all_PPFPs, track);
1126  // art::Ptr<recob::PFParticle> pfp = ppfp->pPFParticle;//trackToPFParticleMap[track];
1127 
1128  int sliceid = ppfp->get_SliceID();//pfParticleToSliceIDMap.at(pfp);
1129  //WARNING the temp. solution only work with best nuscore slice Keng
1130  if(!ppfp->get_IsNuSlice()) continue;
1131 
1132  std::vector<art::Ptr<recob::Hit>> tmp_slicehits = ppfp->pSliceHits;//sliceIDToHitsMap.at(sliceid);
1133  std::vector<art::Ptr<recob::Hit>> trackhits = ppfp->pPFPHits;//pfParticleToHitsMap.at(pfp);
1134 
1135  if(ppfp->get_IsNeutrino()) slicehits.insert(slicehits.end(), tmp_slicehits.begin(), tmp_slicehits.end());//add up all nu slice hits
1136 
1137  std::cout << "*SSS: track "<< t <<" is in slice "<< sliceid <<" which has "<< tmp_slicehits.size() <<" hits. This track has "<< trackhits.size() <<" of them. " << std::endl;
1138  total_track_hits += trackhits.size();
1139 
1140  //WARNING nu_slice_id is updated? Oh, tracks[0] and tracks[1] have different slide IDs (both nu slice but different nu score), need to fix this;
1141  // temporary solution is to skip tracks[1];
1142  // if(nu_slice_id != sliceid && nu_slice_id != -999){
1143  // std::cout<<"*ERROR!! In Second Shower Search (Isolation Study), the neutrino slice ID changed? this: "<<sliceid<<", last: "<<nu_slice_id<<std::endl;
1144  // exit(EXIT_FAILURE);
1145  // }
1146  // nu_slice_id = sliceid;
1147 
1148  for(auto &h: trackhits){
1149  associated_hits.push_back(h);
1150  }
1151  }
1152  // END FOR LOOPING TRACKS
1153 
1154 
1155 
1156  // BEGIN FOR LOOPING SHOWERS TO COUNT SHOWER HITS AND PUSH INTO ASSOC HITS
1157  for(size_t s =0; s< showers.size(); s++){
1158  art::Ptr<recob::Shower> shower = showers[s];
1159  PandoraPFParticle* ppfp = PPFP_GetPPFPFromShower(all_PPFPs, shower);
1160  // art::Ptr<recob::PFParticle> pfp = ppfp->pPFParticle;//showerToPFParticleMap.at(shower);
1161 
1162  int sliceid = ppfp->get_SliceID();//pfParticleToSliceIDMap.at(pfp);
1163 
1164  // if(sliceid != slice_w_bestnuID) continue;//WARNING only deal with nu slice with best nu score for now Keng
1165  if(!ppfp->get_IsNuSlice()) continue;
1166  if(sliceid<0) continue; //negative sliceid is bad
1167 
1168  auto tmp_slicehits = ppfp->pSliceHits;//sliceIDToHitsMap.at(sliceid);
1169  auto showerhits = ppfp->pPFPHits;//pfParticleToHitsMap.at(pfp);
1170 
1171  std::cout<<"*SSS: shower "<< s <<" is in slice "<< sliceid <<" which has "<< tmp_slicehits.size() <<" hits. This shower has "<< showerhits.size() <<" of them. "<< std::endl;
1172  total_shower_hits+=showerhits.size();
1173 
1174  for(auto &h: showerhits){
1175  associated_hits.push_back(h);
1176  }
1177  }
1178  // END FOR LOOP COUNTING SHOWER HITS
1179 
1180  vars.m_sss_num_associated_hits = total_shower_hits + total_track_hits;
1181 
1182  // PRINT SUMMARY OF HIT TYPES
1183  std::cout<<"*SSS: So in total we have "<<total_shower_hits<<" shower hits and "<<total_track_hits<<" track hits"<<" associatedHits total: "<<associated_hits.size()<<std::endl;
1184 
1185 
1186  // IF VALID SLICE
1187  if(nu_slice_id >= 0){
1188  vars.m_sss_num_unassociated_hits = slicehits.size()-total_shower_hits-total_track_hits;
1189 
1190  std::cout<<"*SSS: So that leaves "<<slicehits.size()-total_shower_hits-total_track_hits<<" hits not included in tracks and showers"<<std::endl;
1191 
1192  if(vars.m_sss_num_unassociated_hits < 0){
1193  std::cout<<"ERROR!! Number of unassociated hits is negative, i.e: num_associated: "<<vars.m_sss_num_associated_hits<<" and total slice hits: "<<slicehits.size()<<std::endl;
1194  exit(EXIT_FAILURE);
1195  }
1196 
1197 
1198 
1199  // DETERMINE UNASSOCIATED HITS BY COMPARING ALL SLICE HITS WITH LIST OF ASSOCIATED HITS
1200  for(auto &h: slicehits){
1201 
1202  bool is_associated = false;
1203  for(auto &a: associated_hits){
1204  if(h==a){
1205  is_associated = true;
1206  break;
1207  }
1208  }
1209 
1210  if(!is_associated){
1211  unassociated_hits.push_back(h);
1212  auto plane_view = h->View();
1213  switch((int)plane_view){
1214  case (0) :
1215  unassociated_hits_plane0.push_back(h);
1216  break;
1217  case (1) :
1218  unassociated_hits_plane1.push_back(h);
1219  break;
1220  case (2) :
1221  unassociated_hits_plane2.push_back(h);
1222  break;
1223  }
1224 
1225  }
1226 
1227  }
1228 
1229  std::vector<std::vector<art::Ptr<recob::Hit>>> unassociated_hits_all = {unassociated_hits_plane0,unassociated_hits_plane1,unassociated_hits_plane2};
1230 
1231  std::cout<<" *associated_hits.size() "<<associated_hits.size()<<" unassociated_hits.size() "<<unassociated_hits.size()<<" p0: "<<unassociated_hits_plane0.size()<<" p1: "<<unassociated_hits_plane1.size()<<" p2: "<<unassociated_hits_plane2.size()<<std::endl;
1232 
1233 
1234  // IF HAVE 1+G 1P AND WANT TO PLOT
1235  if(paras.s_make_sss_plots && showers.size()==1 && tracks.size()==1){
1236 
1237  std::string print_name = "isolation_"+std::to_string(vars.m_run_number)+"_"+std::to_string(vars.m_subrun_number)+"_"+std::to_string(vars.m_event_number);
1238  TCanvas *can = new TCanvas(print_name.c_str(), print_name.c_str(),3000,800);
1239  can->Divide(4, 1, 0.0, 0.1);
1240 
1241  double tick_max = 0;
1242  double tick_min = 1e10;
1243  std::vector<double> chan_max(3,0);
1244  std::vector<double> chan_min(3,1e10);
1245 
1246  // Creation of canvas and histograms to hold hit distance data
1247  TCanvas *histcan = new TCanvas(("hists_"+print_name).c_str(), "Distances from the track", 600, 400);
1248  histcan->Divide(3, 2, 0.005, 0.1);
1249 
1250  TH1D *s_hist0 = new TH1D("shower hits hist plane0", "Showers Plane 0", 30, 0.0, 30.0);
1251  TH1D *s_hist1 = new TH1D("shower hist plane1", "Showers Plane 1", 30, 0.0, 30.0);
1252  TH1D *s_hist2 = new TH1D("shower hist plane2", "Showers Plane 2", 30, 0.0, 30.0);
1253  std::vector<TH1D *> s_hists = {s_hist0, s_hist1, s_hist2};
1254 
1255  TH1D *u_hist0 = new TH1D("unassociated hits hist plane0", "Unassoc Plane 0", 30, 0.0, 30.0);
1256  TH1D *u_hist1 = new TH1D("unassociated hits hist plane1", "Unassoc Plane 1", 30, 0.0, 30.0);
1257  TH1D *u_hist2 = new TH1D("unassociated hits hist plane2", "Unassoc Plane 2", 30, 0.0, 30.0);
1258  std::vector<TH1D *> u_hists = {u_hist0, u_hist1, u_hist2};
1259 
1260 
1261  std::cout << "Isolation: Acquiring track hit coordinates" << std::endl;
1262  // saving wire and time coordinates
1263  std::vector<std::vector<TGraph *>> pts_trk( tracks.size(), std::vector<TGraph *>(3) );
1264 
1265  PandoraPFParticle* ppfpt = PPFP_GetPPFPFromTrack(all_PPFPs, tracks[0]);
1266  // art::Ptr<recob::PFParticle> pfpt = trackToPFParticleMap.at(tracks[0]);
1267  auto trackhits = ppfpt->pPFPHits;//pfParticleToHitsMap.at(pfpt);
1268 
1269  std::vector<TGraph*> t_pts(3);
1270  std::vector<std::vector<double>> t_vec_t(3); // peak time of track hits on 3 planes.
1271  std::vector<std::vector<double>> t_vec_c(3); // wire number of track hits on 3 planes.
1272 
1273  for(auto &th: trackhits){
1274  double wire = (double)th->WireID().Wire;
1275  t_vec_c[(int)th->View()].push_back(wire);
1276 
1277  double time = (double)th->PeakTime();
1278  t_vec_t[(int)th->View()].push_back(time);
1279 
1280  tick_max = std::max(tick_max, time);
1281  tick_min = std::min(tick_min, time);
1282  chan_max[(int)th->View()] = std::max( chan_max[(int)th->View()], wire);
1283  chan_min[(int)th->View()] = std::min( chan_min[(int)th->View()], wire);
1284 
1285  }
1286 
1287  t_pts[0] = new TGraph(t_vec_c[0].size(), &(t_vec_c[0])[0], &(t_vec_t[0])[0]);
1288  t_pts[1] = new TGraph(t_vec_c[1].size(), &(t_vec_c[1])[0], &(t_vec_t[1])[0]);
1289  t_pts[2] = new TGraph(t_vec_c[2].size(), &(t_vec_c[2])[0], &(t_vec_t[2])[0]);
1290  pts_trk[0] = t_pts;
1291 
1292  std::cout << "Isolation: plane0 track hits = " << t_vec_t[0].size() << std::endl;
1293  std::cout << "Isolation: plane1 track hits = " << t_vec_t[1].size() << std::endl;
1294  std::cout << "Isolation: plane2 track hits = " << t_vec_t[2].size() << std::endl;
1295 
1296 
1297  std::cout << "Isolation: Acquiring shower hit coordinates and comparing with track hits " << std::endl;
1298 
1299  //First grab all shower clusters
1300  std::vector<std::vector<TGraph *>> pts_shr( showers.size(), std::vector<TGraph *>(3) );
1301 
1302  // map shower hits to distance to the closest track hit (hold up to 10 hits with minimum distance)
1303  std::vector<std::map< art::Ptr< recob::Hit>, double >> sh_dist(3);
1304  // vector to save hit with largest minimum distance (in sh_dist) on each plane
1305  std::vector< std::pair<art::Ptr< recob::Hit >, double > > max_min_hit(3);
1306 
1307  PandoraPFParticle* ppfps = PPFP_GetPPFPFromShower(all_PPFPs, showers[0]);
1308  auto showerhits = ppfps->pPFPHits;//pfParticleToHitsMap.at(pfp_s);
1309  // art::Ptr<recob::PFParticle> pfp_s = showerToPFParticleMap.at(showers[0]);
1310 
1311  std::vector<TGraph*> t_pts_s(3);
1312  std::vector<std::vector<double>> vec_t(3);
1313  std::vector<std::vector<double>> vec_c(3);
1314  std::vector<int> num_shr_hits(3);
1315 
1316  for(auto &sh: showerhits){
1317  int plane = (int)sh->View();
1318  num_shr_hits[plane] += 1;
1319 
1320  double minDist = 999.9; //minimum distance between this shower hit and all track hits
1321  double dist;
1322  // only do if there are track hits on this plane with which to compare
1323  if (t_vec_c[(int)sh->View()].size() != 0){
1324  double wire = (double)sh->WireID().Wire;
1325  vec_c[(int)sh->View()].push_back(wire);
1326  double time = (double)sh->PeakTime();
1327  vec_t[(int)sh->View()].push_back(time);
1328 
1329  for (unsigned int th = 0; th < t_vec_c[(int)sh->View()].size(); th++){
1330  dist = sqrt( pow (time/25 - (t_vec_t[(int)sh->View()])[th]/25, 2) + pow( wire*0.3 - (t_vec_c[(int)sh->View()])[th]*0.3, 2) );
1331  if (dist < minDist) {
1332  minDist = dist;
1333  }
1334 
1335  } // end of track hits for
1336  s_hists[(int)sh->View()]->Fill(minDist);
1337 
1338  // keep track of 10 smallest distances and their corresponding hits
1339  if (sh_dist[plane].size() < 10){
1340  (sh_dist[plane])[sh] = minDist; // insert shower hit with accompanying minimum distance
1341  max_min_hit[plane] = (*std::max_element(sh_dist[plane].begin(), sh_dist[plane].end(), map_max_fn)); // find new min dist hit
1342  }
1343  else{ if (minDist < max_min_hit[plane].second){
1344  sh_dist[plane].erase(max_min_hit[plane].first); // erase old max of min distances from map
1345  (sh_dist[plane])[sh] = minDist; // insert shower hit with accompanying minimum distance
1346  max_min_hit[plane] = (*std::max_element(sh_dist[plane].begin(), sh_dist[plane].end(), map_max_fn)); // find new min dist hit
1347  } }
1348 
1349  // finds the necessary plot boundaries to fit the shower
1350  tick_max = std::max(tick_max, (double)sh->PeakTime());
1351  tick_min = std::min(tick_min, (double)sh->PeakTime());
1352  chan_max[(int)sh->View()] = std::max( chan_max[(int)sh->View()], wire);
1353  chan_min[(int)sh->View()] = std::min( chan_min[(int)sh->View()], wire);
1354  } // end if stmnt t_vec_c
1355  } // end looping shower hits
1356 
1357  // create graphs from newly compiled shower coordinates
1358  t_pts_s[0] = new TGraph(vec_c[0].size(), &(vec_c[0])[0], &(vec_t[0])[0]);
1359  t_pts_s[1] = new TGraph(vec_c[1].size(), &(vec_c[1])[0], &(vec_t[1])[0]);
1360  t_pts_s[2] = new TGraph(vec_c[2].size(), &(vec_c[2])[0], &(vec_t[2])[0]);
1361  // save new graphs for this shower into vector containing all showers
1362  pts_shr[0] = t_pts_s;
1363 
1364  // place data into approriate vertex_tree variables
1365  for(int plane = 0; plane < 3; plane++){
1366  if (num_shr_hits[plane] == 0){ // if there are no shower hits on this plane, is extremely isolated
1367  vars.m_isolation_min_dist_trk_shr.push_back(999);
1368  vars.m_isolation_nearest_shr_hit_to_trk_wire.push_back(999);
1369  vars.m_isolation_nearest_shr_hit_to_trk_time.push_back(999);
1370  }
1371  else if (t_vec_t[plane].size() > 0) { // have to have both shower and track hits on this plane to have valid comparisons for distance
1372  auto abs_min = (*std::min_element(sh_dist[plane].begin(), sh_dist[plane].end(), map_min_fn));
1373  vars.m_isolation_min_dist_trk_shr.push_back(abs_min.second);
1374  vars.m_isolation_nearest_shr_hit_to_trk_wire.push_back((double)abs_min.first->WireID().Wire);
1375  vars.m_isolation_nearest_shr_hit_to_trk_time.push_back((double)abs_min.first->PeakTime());
1376  }
1377  else{ // if there are no shower hits or there are no track hits on this plane, getting min distance fails
1378  vars.m_isolation_min_dist_trk_shr.push_back(-999);
1379  vars.m_isolation_nearest_shr_hit_to_trk_wire.push_back(-999);
1380  vars.m_isolation_nearest_shr_hit_to_trk_time.push_back(-999);
1381  }
1382  vars.m_isolation_num_shr_hits_win_1cm_trk.push_back(s_hists[plane]->Integral(1,1));
1383  vars.m_isolation_num_shr_hits_win_2cm_trk.push_back(s_hists[plane]->Integral(1,2));
1384  vars.m_isolation_num_shr_hits_win_5cm_trk.push_back(s_hists[plane]->Integral(1,5));
1385  vars.m_isolation_num_shr_hits_win_10cm_trk.push_back(s_hists[plane]->Integral(1,10));
1386  }
1387 
1388  /* DRAW SHOWER HISTOGRAM */
1389  histcan->cd(1);
1390  s_hists[0]->Draw();
1391  s_hists[0]->GetXaxis()->SetTitle("distance from shower hit to closest track hit [cm]");
1392 
1393  histcan->cd(2);
1394  s_hists[1]->Draw();
1395  s_hists[1]->GetXaxis()->SetTitle("distance from shower hit to closest track hit [cm]");
1396 
1397  histcan->cd(3);
1398  s_hists[2]->Draw();
1399  s_hists[2]->GetXaxis()->SetTitle("distance from shower hit to closest track hit [cm]");
1400 
1401 
1402 
1403  //NOW THE UNASSOCIATED HITS - that is ones not part of an identified track or shower
1404  std::cout << "Isolation: Acquiring unassociated hits coordinates and comparing with track hits" << std::endl;
1405 
1406  // create vector of three layers for unassoc hits
1407  std::vector<TGraph *> g_unass(3);
1408 
1409  std::vector<std::vector<std::vector<double>>> pts_to_recluster(3); //plane, point, {wire,tic}
1410  //make a map tp actual hits here I guess.
1411  std::vector<std::map<int, art::Ptr<recob::Hit>>> mapPointIndexToHit(3);
1412 
1413  std::vector<double> minDist_tot(3);
1414  std::vector<double> minWire(3);
1415  std::vector<double> minTime(3);
1416 
1417  for(int plane = 0; plane < 3; plane++){
1418  minDist_tot[plane] = 999;
1419  std::vector<double> vec_t;
1420  std::vector<double> vec_c;
1421 
1422  for(auto &uh: unassociated_hits_all[plane]){
1423 
1424  if (t_vec_c[plane].size() == 0) break; // if track doesn't have hits on that plane
1425 
1426  double wire = (double)uh->WireID().Wire;
1427  vec_c.push_back(wire);
1428  double time = (double)uh->PeakTime();
1429  vec_t.push_back(time);
1430 
1431  double minDist = 999.9;
1432  double dist;
1433  for (unsigned int th = 0; th < t_vec_c[(int)uh->View()].size(); th++){
1434  dist = sqrt( pow (time/25 - (t_vec_t[(int)uh->View()])[th]/25, 2) + pow( wire*0.3 - (t_vec_c[(int)uh->View()])[th]*0.3, 2) );
1435  if (dist < minDist) { minDist = dist; }
1436  }
1437  u_hists[(int)uh->View()]->Fill(minDist);
1438 
1439  if (minDist < minDist_tot[plane]) { // of all unassociated hits, the one that has min distance to closest track hits
1440  minDist_tot[plane] = minDist;
1441  minWire[plane] = wire;
1442  minTime[plane] = time;
1443  }
1444 
1445  // for reclustering
1446  std::vector<double> pt = {wire, vec_t.back()};
1447  pts_to_recluster[(int)uh->View()].push_back(pt);
1448  mapPointIndexToHit[(int)uh->View()][pts_to_recluster[(int)uh->View()].size()-1] = uh;
1449 
1450  } // end looping unassociated_hits_all
1451 
1452  g_unass[plane] = new TGraph(vec_c.size(), &vec_c[0], &vec_t[0]);
1453  } // end looping planes
1454 
1455  // place data into appropriate vertex_tree variables
1456  for(int plane = 0; plane < 3; plane++){
1457  if (t_vec_t[plane].size() > 0 && unassociated_hits_all[plane].size() > 0){
1458  vars.m_isolation_min_dist_trk_unassoc.push_back(minDist_tot[plane]);
1459  vars.m_isolation_nearest_unassoc_hit_to_trk_wire.push_back(minWire[plane]);
1460  vars.m_isolation_nearest_unassoc_hit_to_trk_time.push_back(minTime[plane]);
1461  }
1462  else {
1463  vars.m_isolation_min_dist_trk_unassoc.push_back(-999);
1464  vars.m_isolation_nearest_unassoc_hit_to_trk_wire.push_back(-999);
1465  vars.m_isolation_nearest_unassoc_hit_to_trk_time.push_back(-999);
1466  }
1467  vars.m_isolation_num_unassoc_hits_win_1cm_trk.push_back(u_hists[plane]->Integral(1,1));
1468  vars.m_isolation_num_unassoc_hits_win_2cm_trk.push_back(u_hists[plane]->Integral(1,2));
1469  vars.m_isolation_num_unassoc_hits_win_5cm_trk.push_back(u_hists[plane]->Integral(1,5));
1470  vars.m_isolation_num_unassoc_hits_win_10cm_trk.push_back(u_hists[plane]->Integral(1,10));
1471  }
1472 
1473  /* DRAW UNASSOCIATED HITS DISTANCE HISTOGRAMS */
1474  histcan->cd(4);
1475  u_hists[0]->Draw();
1476  u_hists[0]->GetXaxis()->SetTitle("distance from unassoc hit to closest track hit [cm]");
1477 
1478  histcan->cd(5);
1479  u_hists[1]->Draw();
1480  u_hists[1]->GetXaxis()->SetTitle("distance from unassoc hit to closest track hit [cm]");
1481 
1482  histcan->cd(6);
1483  u_hists[2]->Draw();
1484  u_hists[2]->GetXaxis()->SetTitle("distance from unassoc hit to closest track hit [cm]");
1485 
1486 
1487  /* SAVE THE CANVAS -which holds all 6 distance histograms for shower and unassociated hits*/
1488  /* histcan->Update();
1489  histcan->SaveAs((print_name + "_hist.pdf").c_str(), "pdf");
1490  */
1491 
1492  delete histcan;
1493 
1494 
1495  //PLOTTING NOW
1496  //SET-UP
1497  double plot_point_size = 0.6;
1498 
1499  std::vector<int> tcols = {kRed-7, kBlue-7, kGreen-3, kOrange-3, kCyan-3, kMagenta-3, kGreen+1 , kRed+1};
1500  int used_col=0;
1501  if(showers.size()+tracks.size() > tcols.size()){
1502  for(int i =0; i< (int)(showers.size()+tracks.size() - tcols.size() +2); i++){
1503  tcols.push_back(tcols[(int)paras.rangen->Uniform(0,7)]+(int)paras.rangen->Uniform(-5,5));
1504  }
1505  }
1506 
1507  std::cout<<"*Tick Min: "<<tick_min<<" Max: "<<tick_max<<std::endl;
1508  auto const TPC = (*paras.s_geom).begin_TPC();
1509  auto ID = TPC.ID();
1510  int fCryostat = ID.Cryostat;
1511  int fTPC = ID.TPC;
1512  std::cout<<TPC.ID()<<"*= the beginning TPC ID" <<std::endl;
1513  std::cout<<"*the cryostat id = "<<fCryostat<<std::endl;
1514  std::cout<<"*the tpc id = "<<fTPC<<std::endl;
1515 
1516 
1517  //PLOTTING THE VERTEX POSITION ON THE PLOT
1518 
1519  std::vector<double> vertex_time(3);
1520  std::vector<double> vertex_wire(3);
1521 
1522 
1523  std::vector<TGraph*> g_vertex(3);
1524  for(int i=0; i<3; i++){
1525  TPad * pader = (TPad*)can->cd(i+1);
1526 
1527  if(i==0 ) pader->SetLeftMargin(0.1);
1528 
1529  std::vector<double> wire = {(double)calcWire(vars.m_vertex_pos_y, vars.m_vertex_pos_z, i, fTPC, fCryostat, *paras.s_geom)};
1530  std::vector<double> time = {theDetector.ConvertXToTicks(vars.m_vertex_pos_x, i, fTPC,fCryostat)};
1531 
1532  vertex_time[i] = time[0];
1533  vertex_wire[i] = wire[0];
1534 
1535  if(i==0) vars.m_vertex_pos_wire_p0 = wire[0];
1536  if(i==1) vars.m_vertex_pos_wire_p1 = wire[0];
1537  if(i==2) vars.m_vertex_pos_wire_p2 = wire[0];
1538  vars.m_vertex_pos_tick = time[0];
1539 
1540  chan_max[i] = std::max( chan_max[i],wire[0]);
1541  chan_min[i] = std::min( chan_min[i],wire[0]);
1542 
1543  g_vertex[i] = new TGraph(1,&wire[0],&time[0]);
1544  g_vertex[i]->SetMarkerStyle(29);
1545  g_vertex[i]->SetMarkerSize(4);
1546  g_vertex[i]->SetMarkerColor(kMagenta-3);
1547  g_vertex[i]->GetYaxis()->SetRangeUser(tick_min*0.9,tick_max*1.1);
1548  g_vertex[i]->GetXaxis()->SetLimits(chan_min[i]*0.9,chan_max[i]*1.1);
1549  g_vertex[i]->SetTitle(("Plane " +std::to_string(i)).c_str());
1550  g_vertex[i]->GetYaxis()->SetTitle("Peak Hit Time Tick");
1551  g_vertex[i]->GetXaxis()->SetTitle( ("Wire Number Plane " +std::to_string(i)).c_str());
1552  g_vertex[i]->Draw("ap");
1553 
1554  if(i>0){
1555  g_vertex[i]->GetYaxis()->SetLabelOffset(999);
1556  g_vertex[i]->GetYaxis()->SetLabelSize(0);
1557  }
1558 
1559 
1560  }
1561 
1562  // ******************************** DeadWireRegions ********************************************
1563  //plot dead wire
1564  // for(size_t i=0; i< bad_channel_list_fixed_mcc9.size(); i++){
1565  // int badchan = bad_channel_list_fixed_mcc9[i].first;
1566  // int ok = bad_channel_list_fixed_mcc9[i].second;
1567  //
1568  // if(ok>1)continue;
1569  // auto hs = geom->ChannelToWire(badchan);
1570  //
1571  // int thisp = (int)hs[0].Plane;
1572  // double bc = hs[0].Wire;
1573  // // std::cout<<"WIRE "<<thisp<<" "<<bc<<" "<<hs.size()<<std::endl;
1574  // if(chan_min[thisp]*0.9 < bc && bc < chan_max[thisp]*1.1 ){
1575  // can->cd(thisp+1);
1576  // TLine *l = new TLine(bc,tick_min*0.9,bc,tick_max*1.1);
1577  // l->SetLineColor(kGray+1);
1578  // l->Draw("same");
1579  // }
1580  // }
1581 
1582  // plot track
1583  for(size_t t=0; t< pts_trk.size(); t++){
1584  int tcol = tcols[used_col];
1585  used_col++;
1586 
1587  for(int i=0; i<3; i++){
1588  can->cd(i+1);
1589  if(pts_trk[t][i]->GetN()>0){//need a check in case this track has no hits on this plane.
1590  pts_trk[t][i]->Draw("p same");
1591  pts_trk[t][i]->SetMarkerColor(tcol);
1592  pts_trk[t][i]->SetFillColor(tcol);
1593  pts_trk[t][i]->SetMarkerStyle(20);
1594  pts_trk[t][i]->SetMarkerSize(plot_point_size);
1595  }
1596  }
1597  }
1598 
1599  // plot shower hits
1600  for(size_t t=0; t< pts_shr.size(); t++){
1601  int tcol = tcols[used_col];
1602  used_col++;
1603 
1604  for(int i=0; i<3; i++){
1605  can->cd(i+1);
1606  if(pts_shr[t][i]->GetN()>0){
1607  pts_shr[t][i]->Draw("p same"); //used in the vertex
1608  pts_shr[t][i]->SetMarkerColor(tcol);
1609  pts_shr[t][i]->SetFillColor(tcol);
1610  pts_shr[t][i]->SetMarkerStyle(20);
1611  pts_shr[t][i]->SetMarkerSize(plot_point_size);
1612  }
1613  }
1614  }
1615 
1616 
1617  // plot unassociated hits
1618  for(int i=0; i<3; i++){
1619  can->cd(i+1);
1620  if (g_unass[i]->GetN() > 0){
1621  g_unass[i]->SetMarkerColor(kBlack);
1622  g_unass[i]->SetMarkerStyle(20);
1623  g_unass[i]->SetMarkerSize(plot_point_size);
1624  }
1625  g_vertex[i]->Draw("p same");
1626  }
1627 
1628 
1629 
1630 
1631  //******************* INFO Plotting *******************************
1632 
1633  TPad *p_top_info = (TPad*)can->cd(4);
1634  p_top_info->cd();
1635 
1636  TLatex pottex;
1637  pottex.SetTextSize(0.045);
1638  pottex.SetTextAlign(13); //align at top
1639  pottex.SetNDC();
1640  std::string pot_draw = "Run: "+std::to_string(vars.m_run_number)+" SubRun: "+std::to_string(vars.m_subrun_number)+" Event: "+std::to_string(vars.m_event_number);
1641  pottex.DrawLatex(.1,.94, pot_draw.c_str());
1642 
1643  TLegend * l_top = new TLegend(0.5,0.5,0.85,0.85);
1644 
1645  // PLOTTING SHOWER?
1646  for(size_t t=0; t< pts_shr.size(); t++){
1647  std::string sname = "Shower "+std::to_string(t);
1648  if(pts_shr[t][0]->GetN()>0){
1649  l_top->AddEntry(pts_shr[t][0],sname.c_str(),"f");
1650  }else if(pts_shr[t][1]->GetN()>0){
1651  l_top->AddEntry(pts_shr[t][1],sname.c_str(),"f");
1652  }else if(pts_shr[t][2]->GetN()>0){
1653  l_top->AddEntry(pts_shr[t][2],sname.c_str(),"f");
1654  }
1655  }
1656 
1657  // PLOTTING
1658  for(size_t t=0; t< pts_trk.size(); t++){
1659  std::string sname = "Track "+std::to_string(t);
1660  if(pts_trk[t][0]->GetN()>0){
1661  l_top->AddEntry(pts_trk[t][0],sname.c_str(),"f");
1662  }else if(pts_trk[t][1]->GetN()>0){
1663  l_top->AddEntry(pts_trk[t][1],sname.c_str(),"f");
1664  }else if(pts_trk[t][2]->GetN()>0){
1665  l_top->AddEntry(pts_trk[t][2],sname.c_str(),"f");
1666  }
1667  }
1668  l_top->SetLineWidth(0);
1669  l_top->SetLineColor(kWhite);
1670  l_top->Draw("same");
1671 
1672  can->Update();
1673  // can->SaveAs((print_name+".pdf").c_str(),"pdf");
1674  std::cout<<"*PRINTING"<<std::endl;
1675 
1676  delete can;
1677  }
1678  }
1679  return;
1680  }
1681 }
std::vector< double > m_sss_candidate_PCA
Definition: variables.h:207
std::vector< double > m_sss3d_shower_start_z
Definition: variables.h:240
std::vector< double > m_sss3d_shower_invariant_mass
Definition: variables.h:247
std::vector< double > SecondShowerMatching(std::vector< art::Ptr< recob::Hit >> &hitz, 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_isolation_num_shr_hits_win_10cm_trk
Definition: variables.h:735
std::vector< double > m_isolation_min_dist_trk_shr
Definition: variables.h:722
std::vector< double > m_isolation_nearest_shr_hit_to_trk_wire
Definition: variables.h:727
std::vector< double > m_sss3d_shower_dir_x
Definition: variables.h:241
ClusterModuleLabel join with tracks
double m_sss2d_conv_ranked_angle_to_shower
Definition: variables.h:301
std::vector< int > m_sss_candidate_plane
Definition: variables.h:206
std::vector< double > m_sss3d_shower_implied_invariant_mass
Definition: variables.h:250
std::vector< double > m_sss_candidate_impact_parameter
Definition: variables.h:210
double m_sss3d_ioc_ranked_invar
Definition: variables.h:263
std::vector< double > m_sss3d_shower_start_x
Definition: variables.h:238
double m_sss3d_invar_ranked_en
Definition: variables.h:271
std::vector< double > m_sss3d_shower_energy_max
Definition: variables.h:256
std::vector< double > m_sss_candidate_angle_to_shower
Definition: variables.h:223
pdgs p
Definition: selectors.fcl:22
std::vector< double > m_isolation_num_unassoc_hits_win_10cm_trk
Definition: variables.h:748
double m_sss2d_conv_ranked_conv
Definition: variables.h:297
BEGIN_PROLOG or score(default)}sbnd_crttrackmatchingalg_crID
double m_sss2d_ioc_ranked_invar
Definition: variables.h:292
double m_sss2d_invar_ranked_en
Definition: variables.h:304
std::vector< double > m_isolation_nearest_unassoc_hit_to_trk_time
Definition: variables.h:743
std::vector< double > m_isolation_num_unassoc_hits_win_1cm_trk
Definition: variables.h:744
std::pair< int, std::pair< std::vector< std::vector< double > >, std::vector< double > > > GroupClusterCandidate(int num_clusters, const std::vector< int > &cluster_planes, const std::vector< double > &cluster_max_ticks, const std::vector< double > &cluster_min_ticks)
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
std::vector< size_t > sort_indexes(const std::vector< T > &v)
Definition: helper_math.h:20
std::vector< double > m_isolation_nearest_unassoc_hit_to_trk_wire
Definition: variables.h:742
process_name use argoneut_mc_hitfinder track
process_name hit
Definition: cheaterreco.fcl:51
double m_sss3d_invar_ranked_implied_opang
Definition: variables.h:277
double calcWire(double Y, double Z, int plane, int fTPC, int fCryostat, geo::GeometryCore const &geo)
Definition: helper_math.h:54
process_name shower
Definition: cheaterreco.fcl:51
BEGIN_PROLOG TPC
std::vector< double > m_isolation_num_unassoc_hits_win_2cm_trk
Definition: variables.h:746
std::vector< double > m_isolation_num_unassoc_hits_win_5cm_trk
Definition: variables.h:747
std::vector< double > m_sss3d_shower_score
Definition: variables.h:257
double invar_mass(art::Ptr< recob::Shower > &s1, double E1, art::Ptr< recob::Shower > &s2, double E2)
Definition: helper_math.cxx:74
process_name gaushit a
double m_sss3d_ioc_ranked_en
Definition: variables.h:261
std::vector< art::Ptr< recob::Hit > > pPFPHits
while getopts h
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::vector< double > m_isolation_min_dist_trk_unassoc
Definition: variables.h:738
bool map_min_fn(const std::pair< art::Ptr< recob::Hit >, double > p1, const std::pair< art::Ptr< recob::Hit >, double > p2)
double implied_invar_mass(double vx, double vy, double vz, art::Ptr< recob::Shower > &s1, double E1, art::Ptr< recob::Shower > &s2, double E2)
Definition: helper_math.cxx:50
double m_sss3d_ioc_ranked_opang
Definition: variables.h:266
TGraph * GetNearestNpts(int p, int cl, std::vector< art::Ptr< recob::Hit >> &hitz, double vertex_wire, double vertex_tick, int Npts)
std::vector< double > m_sss3d_shower_conversion_dist
Definition: variables.h:245
std::vector< double > m_sss3d_shower_length
Definition: variables.h:244
bool map_max_fn(const std::pair< art::Ptr< recob::Hit >, double > p1, const std::pair< art::Ptr< recob::Hit >, double > p2)
double m_sss3d_ioc_ranked_ioc
Definition: variables.h:265
std::vector< double > m_reco_shower_energy_max
Definition: variables.h:988
void IsolationStudy(std::vector< PandoraPFParticle > all_PPFPs, const std::vector< art::Ptr< recob::Track >> &tracks, const std::vector< art::Ptr< recob::Shower >> &showers, detinfo::DetectorPropertiesData const &theDetector, var_all &vars, para_all &paras)
double m_sss2d_ioc_ranked_ioc
Definition: variables.h:290
std::vector< double > m_isolation_nearest_shr_hit_to_trk_time
Definition: variables.h:728
std::vector< double > m_sss3d_shower_ioc_ratio
Definition: variables.h:254
std::vector< art::Ptr< recob::Hit > > pSliceHits
double m_sss3d_ioc_ranked_implied_invar
Definition: variables.h:264
std::vector< double > m_sss_candidate_energy
Definition: variables.h:222
std::vector< double > m_sss3d_shower_dir_y
Definition: variables.h:242
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
geo::GeometryCore const * s_geom
Definition: variables.h:143
double ConvertXToTicks(double X, int p, int t, int c) const
double m_sss3d_ioc_ranked_conv
Definition: variables.h:262
double m_sss2d_invar_ranked_invar
Definition: variables.h:308
std::vector< double > m_sss_candidate_mean_tick
Definition: variables.h:214
string sname
std::vector< double > m_sss_candidate_min_dist
Definition: variables.h:220
double m_sss2d_invar_ranked_conv
Definition: variables.h:305
int m_sss2d_conv_ranked_num_planes
Definition: variables.h:302
double m_sss2d_invar_ranked_ioc
Definition: variables.h:306
double m_sss3d_invar_ranked_ioc
Definition: variables.h:275
std::vector< int > m_sss3d_slice_nu
Definition: variables.h:258
PandoraPFParticle * PPFP_GetPPFPFromTrack(std::vector< PandoraPFParticle > &PPFPs, art::Ptr< recob::Track > pTrack)
double m_sss3d_invar_ranked_opang
Definition: variables.h:276
int spacecharge_correction(const art::Ptr< simb::MCParticle > &mcparticle, std::vector< double > &corrected, std::vector< double > &input)
Definition: Processors.cxx:25
double m_sss2d_conv_ranked_invar
Definition: variables.h:300
double m_sss2d_ioc_ranked_en
Definition: variables.h:288
sss_score ScoreCluster(int p, int cl, std::vector< art::Ptr< recob::Hit >> &hits, double vertex_wire, double vertex_tick, const art::Ptr< recob::Shower > &shower)
std::vector< double > m_sss3d_shower_impact_parameter
Definition: variables.h:253
auto begin(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:573
double m_sss2d_conv_ranked_en
Definition: variables.h:296
BEGIN_PROLOG Z planes
double CalcEShowerPlane(const std::vector< art::Ptr< recob::Hit >> &hits, int this_plane, para_all &paras)
Definition: Processors.cxx:293
std::vector< double > m_sss3d_shower_start_y
Definition: variables.h:239
double m_sss3d_invar_ranked_implied_invar
Definition: variables.h:274
double m_sss2d_ioc_ranked_angle_to_shower
Definition: variables.h:293
double m_sss3d_invar_ranked_invar
Definition: variables.h:273
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
std::string to_string(WindowPattern const &pattern)
then echo File list $list not found else cat $list while read file do echo $file sed s
Definition: file_to_url.sh:60
double m_sss3d_ioc_ranked_implied_opang
Definition: variables.h:267
PandoraPFParticle * PPFP_GetPPFPFromShower(std::vector< PandoraPFParticle > &PPFPs, art::Ptr< recob::Shower > pShower)
double m_sss2d_ioc_ranked_pca
Definition: variables.h:291
double m_sss2d_conv_ranked_ioc
Definition: variables.h:298
double impact_paramater_shr(double x, double y, double z, art::Ptr< recob::Shower > &shr)
Definition: helper_math.cxx:39
double m_sss2d_ioc_ranked_conv
Definition: variables.h:289
std::vector< double > m_isolation_num_shr_hits_win_2cm_trk
Definition: variables.h:733
then echo ***************************************echo Variable FHICL_FILE_PATH not found echo You porbably haven t set up larsoft echo Try setup uboonecode vXX_XX_XX q e10
Definition: find_fhicl.sh:6
void SimpleSecondShowerCluster(var_all &vars, para_all &paras)
int CompareToShowers(int p, int cl, std::vector< art::Ptr< recob::Hit >> &hitz, double vertex_wire, double vertex_tick, const std::vector< art::Ptr< recob::Shower >> &showers, std::map< art::Ptr< recob::Shower >, art::Ptr< recob::PFParticle >> &showerToPFParticleMap, const std::map< art::Ptr< recob::PFParticle >, std::vector< art::Ptr< recob::Hit >> > &pfParticleToHitsMap, double eps)
double m_sss3d_invar_ranked_conv
Definition: variables.h:272
TCEvent evt
Definition: DataStructs.cxx:8
pdgs k
Definition: selectors.fcl:22
std::pair< bool, std::vector< double > > clusterCandidateOverlap(const std::vector< int > &candidate_indices, const std::vector< int > &cluster_planes, const std::vector< double > &cluster_max_ticks, const std::vector< double > &cluster_min_ticks)
std::vector< double > m_sss3d_shower_dir_z
Definition: variables.h:243
std::vector< double > m_isolation_num_shr_hits_win_1cm_trk
Definition: variables.h:731
double m_sss2d_invar_ranked_angle_to_shower
Definition: variables.h:309
std::vector< double > m_isolation_num_shr_hits_win_5cm_trk
Definition: variables.h:734
int m_sss2d_invar_ranked_num_planes
Definition: variables.h:310
double m_sss2d_conv_ranked_pca
Definition: variables.h:299
void SecondShowerSearch3D(std::vector< art::Ptr< recob::Shower >> &showers, std::map< art::Ptr< recob::Shower >, art::Ptr< recob::PFParticle >> &NormalShowerToPFParticleMap, std::vector< art::Ptr< recob::Track >> &tracks, std::map< art::Ptr< recob::Track >, art::Ptr< recob::PFParticle >> &NormalTrackToPFParticleMap, art::Event const &evt, var_all &vars, para_all &paras)
std::vector< double > m_sss_candidate_max_tick
Definition: variables.h:215
double m_sss2d_invar_ranked_pca
Definition: variables.h:307
BEGIN_PROLOG could also be cout
std::vector< int > m_sss3d_slice_clear_cosmic
Definition: variables.h:259
std::vector< double > m_sss_candidate_min_tick
Definition: variables.h:216