BeamFlashTrackMatchTaggerAlg.cxx
Go to the documentation of this file.
1 /*!
2  * Title: Beam Flash<-->Track Match Algorithim Class
3  * Author: Wes Ketchum (wketchum@lanl.gov), based on code from Ben Jones
4  *
5  * Description: Algorithm that compares all tracks to the flash during the
6  * beam gate, and determines if that track is consistent with
7  * having produced that flash.
8  * Input: recob::OpFlash, recob::Track
9  * Output: anab::CosmicTag (and Assn<anab::CosmicTag,recob::Track>)
10 */
11 
14 
15 #include <limits>
16 
17 #include "TH1F.h"
18 #include "TTree.h"
19 
21  : COSMIC_TYPE_FLASHMATCH(anab::CosmicTagID_t::kFlash_BeamIncompatible),
22  COSMIC_TYPE_OUTSIDEDRIFT(anab::CosmicTagID_t::kOutsideDrift_Partial),
23  DEBUG_FLAG(p.get<bool>("RunDebugMode",false)),
24  fMinTrackLength(p.get<float>("MinTrackLength")),
25  fMinOpHitPE(p.get<float>("MinOpHitPE",0.1)),
26  fMIPdQdx(p.get<float>("MIPdQdx",2.1)),
27  fOpDetSaturation(p.get<float>("OpDetSaturation",200.)),
28  fSingleChannelCut(p.get<float>("SingleChannelCut")),
29  fCumulativeChannelThreshold(p.get<float>("CumulativeChannelThreshold")),
30  fCumulativeChannelCut(p.get<unsigned int>("CumulativeChannelCut")),
31  fIntegralCut(p.get<float>("IntegralCut")),
32  fMakeOutsideDriftTags(p.get<bool>("MakeOutsideDriftTags",false)),
33  fNormalizeHypothesisToFlash(p.get<bool>("NormalizeHypothesisToFlash"))
34 {}
35 
37  TH1F* hist_flash, TH1F* hist_hyp){
38  cTree = tree;
39 
40  cOpDetHist_flash = hist_flash;
41  cOpDetHist_flash->SetNameTitle("opdet_hist_flash","Optical Detector Occupancy, Flash");
42 
43  cOpDetHist_hyp = hist_hyp;
44  cOpDetHist_hyp->SetNameTitle("opdet_hist_hyp","Optical Detector Occupancy, Hypothesis");
45 
47  cTree->Branch("opdet_hyp",&cOpDetVector_hyp);
48  cTree->Branch("opdet_flash",&cOpDetVector_flash);
49  cTree->Branch("opdet_hist_flash","TH1F",cOpDetHist_flash);
50  cTree->Branch("opdet_hist_hyp","TH1F",cOpDetHist_hyp);
51 }
52 
53 void cosmic::BeamFlashTrackMatchTaggerAlg::RunCompatibilityCheck(std::vector<recob::OpFlash> const& flashVector,
54  std::vector<recob::Track> const& trackVector,
55  std::vector<anab::CosmicTag>& cosmicTagVector,
56  std::vector<size_t>& assnTrackTagVector,
57  Providers_t providers,
59  opdet::OpDigiProperties const& opdigip){
60 
61  auto const& geom = *(providers.get<geo::GeometryCore>());
62 
63  std::vector< const recob::OpFlash* > flashesOnBeamTime;
64  for(auto const& flash : flashVector){
65  if(!flash.OnBeamTime()) continue;
66  flashesOnBeamTime.push_back(&flash);
67  }
68 
69  //make sure this association vector is initialized properly
70  assnTrackTagVector.resize(trackVector.size(),std::numeric_limits<size_t>::max());
71  cosmicTagVector.reserve(trackVector.size());
72 
73  for(size_t track_i=0; track_i<trackVector.size(); track_i++){
74 
75  recob::Track const& track(trackVector[track_i]);
76 
77  if(track.Length() < fMinTrackLength) continue;
78 
79  //get the begin and end points of this track
80  TVector3 const& pt_begin = track.LocationAtPoint<TVector3>(0);
81  TVector3 const& pt_end = track.LocationAtPoint<TVector3>(track.NumberTrajectoryPoints()-1);
82  std::vector<float> xyz_begin = { (float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
83  std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
84 
85  //check if this track is outside the drift window, and if it is continue
86  if(!InDriftWindow(pt_begin.x(),pt_end.x(),geom)) {
88  cosmicTagVector.emplace_back(xyz_begin,xyz_end,1.,COSMIC_TYPE_OUTSIDEDRIFT);
89  assnTrackTagVector[track_i] = cosmicTagVector.size()-1;
90  }
91  continue;
92  }
93 
94  //get light hypothesis for track
95  std::vector<float> lightHypothesis = GetMIPHypotheses(track,providers,pvs,opdigip);
96 
97  //check compatibility with beam flash
98  bool compatible=false;
99  for(const recob::OpFlash* flashPointer : flashesOnBeamTime){
100  CompatibilityResultType result = CheckCompatibility(lightHypothesis,flashPointer, geom);
101  if(result==CompatibilityResultType::kCompatible) compatible=true;
102  if(DEBUG_FLAG){
103  PrintTrackProperties(track);
104  PrintFlashProperties(*flashPointer);
105  PrintHypothesisFlashComparison(lightHypothesis,flashPointer,geom,result);
106  }
107  }
108 
109  //make tag
110  float cosmicScore=1.;
111  if(compatible) cosmicScore=0.;
112  cosmicTagVector.emplace_back(xyz_begin,xyz_end,cosmicScore,COSMIC_TYPE_FLASHMATCH);
113  assnTrackTagVector[track_i]=cosmicTagVector.size()-1;
114  }
115 
116 }
117 
118 //this compares the hypothesis to the flash itself.
120  unsigned int const event,
121  std::vector<recob::OpFlash> const& flashVector,
122  std::vector<recob::Track> const& trackVector,
123  Providers_t providers,
125  opdet::OpDigiProperties const& opdigip){
126 
127  auto const& geom = *(providers.get<geo::GeometryCore>());
128 
131 
132  std::vector< std::pair<unsigned int, const recob::OpFlash*> > flashesOnBeamTime;
133  for(unsigned int i=0; i<flashVector.size(); i++){
134  recob::OpFlash const& flash = flashVector[i];
135  if(!flash.OnBeamTime()) continue;
136  flashesOnBeamTime.push_back(std::make_pair(i,&flash));
137  }
138 
139  for(size_t track_i=0; track_i<trackVector.size(); track_i++){
140 
141  recob::Track const& track(trackVector[track_i]);
142 
143  if(track.Length() < fMinTrackLength) continue;
144 
145  //get the begin and end points of this track
146  TVector3 const& pt_begin = track.LocationAtPoint<TVector3>(0);
147  TVector3 const& pt_end = track.LocationAtPoint<TVector3>(track.NumberTrajectoryPoints()-1);
148  std::vector<float> xyz_begin = { (float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
149  std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
150 
151  //check if this track is outside the drift window, and if it is continue
152  if(!InDriftWindow(pt_begin.x(),pt_end.x(),geom)) continue;
153 
154  cFlashComparison_p.trk_startx = pt_begin.x();
155  cFlashComparison_p.trk_starty = pt_begin.y();
156  cFlashComparison_p.trk_startz = pt_begin.z();
157  cFlashComparison_p.trk_endx = pt_end.x();
158  cFlashComparison_p.trk_endy = pt_end.y();
159  cFlashComparison_p.trk_endz = pt_end.z();
160 
161  //get light hypothesis for track
162  cOpDetVector_hyp = GetMIPHypotheses(track,providers,pvs,opdigip);
163 
164  cFlashComparison_p.hyp_index = track_i;
169  geom);
170 
171  for(auto flash : flashesOnBeamTime){
172  cOpDetVector_flash = std::vector<float>(geom.NOpDets(),0);
174  for(size_t c=0; c<=geom.MaxOpChannel(); c++){
175  if ( geom.IsValidOpChannel( c ) ) {
176  unsigned int OpDet = geom.OpDetFromOpChannel(c);
177  cOpDetVector_flash[OpDet] += flash.second->PE(c);
178  }
179  }
180  for(size_t o=0; o<cOpDetVector_flash.size(); o++)
182 
183  cFlashComparison_p.flash_index = flash.first;
184  cFlashComparison_p.flash_totalPE = flash.second->TotalPE();
185  cFlashComparison_p.flash_y = flash.second->YCenter();
186  cFlashComparison_p.flash_sigmay = flash.second->YWidth();
187  cFlashComparison_p.flash_z = flash.second->ZCenter();
188  cFlashComparison_p.flash_sigmaz = flash.second->ZWidth();
189 
191 
192  cTree->Fill();
193  }//end loop over flashes
194 
195  }//end loop over tracks
196 
197 
198 }
199 
200 //this compares the hypothesis to the flash itself.
202  unsigned int const event,
203  std::vector<recob::OpFlash> const& flashVector,
204  std::vector<simb::MCParticle> const& mcParticleVector,
205  Providers_t providers,
207  opdet::OpDigiProperties const& opdigip){
208 
209  auto const& geom = *(providers.get<geo::GeometryCore>());
210 
213 
214  std::vector< std::pair<unsigned int, const recob::OpFlash*> > flashesOnBeamTime;
215  for(unsigned int i=0; i<flashVector.size(); i++){
216  recob::OpFlash const& flash = flashVector[i];
217  if(!flash.OnBeamTime()) continue;
218  flashesOnBeamTime.push_back(std::make_pair(i,&flash));
219  }
220 
221  for(size_t particle_i=0; particle_i<mcParticleVector.size(); particle_i++){
222 
223  simb::MCParticle const& particle(mcParticleVector[particle_i]);
224  if(particle.Process().compare("primary")!=0) continue;
225  if(particle.Trajectory().TotalLength() < fMinTrackLength) continue;
226 
227  //get the begin and end points of this track
228  size_t start_i=0, end_i=particle.NumberTrajectoryPoints()-1;
229  bool prev_inside=false;
230  for(size_t pt_i=0; pt_i < particle.NumberTrajectoryPoints(); pt_i++){
231  bool inside = InDetector(particle.Position(pt_i).Vect(),geom);
232  if(inside && !prev_inside) start_i = pt_i;
233  if(!inside && prev_inside) { end_i = pt_i-1; break; }
234  prev_inside = inside;
235  }
236  TVector3 const& pt_begin = particle.Position(start_i).Vect();
237  TVector3 const& pt_end = particle.Position(end_i).Vect();
238  std::vector<float> xyz_begin = { (float)pt_begin.x(), (float)pt_begin.y(), (float)pt_begin.z()};
239  std::vector<float> xyz_end = {(float)pt_end.x(), (float)pt_end.y(), (float)pt_end.z()};
240 
241  //check if this track is outside the drift window, and if it is continue
242  if(!InDriftWindow(pt_begin.x(),pt_end.x(),geom)) continue;
243 
244  cFlashComparison_p.trk_startx = pt_begin.x();
245  cFlashComparison_p.trk_starty = pt_begin.y();
246  cFlashComparison_p.trk_startz = pt_begin.z();
247  cFlashComparison_p.trk_endx = pt_end.x();
248  cFlashComparison_p.trk_endy = pt_end.y();
249  cFlashComparison_p.trk_endz = pt_end.z();
250 
251  //get light hypothesis for track
252  cOpDetVector_hyp = GetMIPHypotheses(particle,start_i,end_i,providers,pvs,opdigip);
253 
254  cFlashComparison_p.hyp_index = particle_i;
259  geom);
260 
261  for(auto flash : flashesOnBeamTime){
262  cOpDetVector_flash = std::vector<float>(geom.NOpDets(),0);
264  //for(size_t c=0; c<geom.NOpChannels(); c++){
265  for(size_t c=0; c<=geom.MaxOpChannel(); c++){
266  if ( geom.IsValidOpChannel(c) ) {
267  unsigned int OpDet = geom.OpDetFromOpChannel(c);
268  cOpDetVector_flash[OpDet] += flash.second->PE(c);
269  }
270  }
271  for(size_t o=0; o<cOpDetVector_flash.size(); o++)
273  cFlashComparison_p.flash_index = flash.first;
274  cFlashComparison_p.flash_totalPE = flash.second->TotalPE();
275  cFlashComparison_p.flash_y = flash.second->YCenter();
276  cFlashComparison_p.flash_sigmay = flash.second->YWidth();
277  cFlashComparison_p.flash_z = flash.second->ZCenter();
278  cFlashComparison_p.flash_sigmaz = flash.second->ZWidth();
279 
281 
282  //cOpDetHist_flash->SetBins(cOpDetVector_flash.size(),0,cOpDetVector_flash.size());
283  for(size_t i=0; i<cOpDetVector_flash.size(); i++)
284  cOpDetHist_flash->SetBinContent(i+1,cOpDetVector_flash[i]);
285 
286  //cOpDetHist_hyp->SetBins(cOpDetVector_hyp.size(),0,cOpDetVector_hyp.size());
287  for(size_t i=0; i<cOpDetVector_hyp.size(); i++)
288  cOpDetHist_hyp->SetBinContent(i+1,cOpDetVector_hyp[i]);
289 
290  for(size_t i=0; i<cOpDetVector_flash.size(); i++){
291  std::cout << "Flash/Hyp " << i << " : "
292  << cOpDetHist_flash->GetBinContent(i+1) << " "
293  << cOpDetHist_hyp->GetBinContent(i+1) << std::endl;
294  }
295 
296  cTree->Fill();
297  }//end loop over flashes
298 
299  }//end loop over tracks
300 
301 
302 }
303 
304 void cosmic::BeamFlashTrackMatchTaggerAlg::FillFlashProperties(std::vector<float> const& opdetVector,
305  float& sum,
306  float& y, float& sigmay,
307  float& z, float& sigmaz,
308  geo::GeometryCore const& geom){
309  y=0; sigmay=0; z=0; sigmaz=0; sum=0;
310  double xyz[3];
311  for(unsigned int opdet=0; opdet<opdetVector.size(); opdet++){
312  sum+=opdetVector[opdet];
313  geom.Cryostat(0).OpDet(opdet).GetCenter(xyz);
314  y += opdetVector[opdet]*xyz[1];
315  z += opdetVector[opdet]*xyz[2];
316  }
317 
318  y /= sum; z /= sum;
319 
320  for(unsigned int opdet=0; opdet<opdetVector.size(); opdet++){
321  geom.Cryostat(0).OpDet(opdet).GetCenter(xyz);
322  sigmay += (opdetVector[opdet]*xyz[1]-y)*(opdetVector[opdet]*xyz[1]-y);
323  sigmaz += (opdetVector[opdet]*xyz[2]-y)*(opdetVector[opdet]*xyz[2]-y);
324  }
325 
326  sigmay = std::sqrt(sigmay)/sum;
327  sigmaz = std::sqrt(sigmaz)/sum;
328 
329 }
330 
332  if(pt.x() < 0 || pt.x() > 2*geom.DetHalfWidth()) return false;
333  if(std::abs(pt.y()) > geom.DetHalfHeight()) return false;
334  if(pt.z() < 0 || pt.z() > geom.DetLength()) return false;
335  return true;
336 }
337 
338 bool cosmic::BeamFlashTrackMatchTaggerAlg::InDriftWindow(double start_x, double end_x, geo::GeometryCore const& geom){
339  if(start_x < 0. || end_x < 0.) return false;
340  if(start_x > 2*geom.DetHalfWidth() || end_x > 2*geom.DetHalfWidth()) return false;
341  return true;
342 }
343 
345  TVector3 const& pt2,
346  std::vector<float> & lightHypothesis,
347  float & totalHypothesisPE,
348  geo::GeometryCore const& geom,
350  float const& PromptMIPScintYield,
351  float XOffset){
352 
353  double xyz_segment[3];
354  xyz_segment[0] = 0.5*(pt2.x()+pt1.x()) + XOffset;
355  xyz_segment[1] = 0.5*(pt2.y()+pt1.y());
356  xyz_segment[2] = 0.5*(pt2.z()+pt1.z());
357 
358  //get the visibility vector
359  auto const& PointVisibility = pvs.GetAllVisibilities(xyz_segment);
360 
361  //check pointer, as it may be null if given a y/z outside some range
362  if(!PointVisibility) return;
363 
364  //get the amount of light
365  float LightAmount = PromptMIPScintYield*(pt2-pt1).Mag();
366 
367  for(size_t opdet_i=0; opdet_i<pvs.NOpChannels(); opdet_i++){
368  lightHypothesis[opdet_i] += PointVisibility[opdet_i]*LightAmount;
369  totalHypothesisPE += PointVisibility[opdet_i]*LightAmount;
370 
371  //apply saturation limit
372  if(lightHypothesis[opdet_i]>fOpDetSaturation){
373  totalHypothesisPE -= (lightHypothesis[opdet_i]-fOpDetSaturation);
374  lightHypothesis[opdet_i] = fOpDetSaturation;
375  }
376  }
377 
378 }//end AddLightFromSegment
379 
380 void cosmic::BeamFlashTrackMatchTaggerAlg::NormalizeLightHypothesis(std::vector<float> & lightHypothesis,
381  float const& totalHypothesisPE,
382  geo::GeometryCore const& geom){
383  for(size_t opdet_i=0; opdet_i<geom.NOpDets(); opdet_i++)
384  lightHypothesis[opdet_i] /= totalHypothesisPE;
385 }
386 
387 
388 // Get a hypothesis for the light collected for a track
390  Providers_t providers,
392  opdet::OpDigiProperties const& opdigip,
393  float XOffset)
394 {
395  auto const& geom = *(providers.get<geo::GeometryCore>());
396  auto const& larp = *(providers.get<detinfo::LArProperties>());
397  std::vector<float> lightHypothesis(geom.NOpDets(),0);
398  float totalHypothesisPE=0;
399  const float PromptMIPScintYield = larp.ScintYield()*larp.ScintYieldRatio()*opdigip.QE()*fMIPdQdx;
400 
401  //get QE from ubChannelConfig, which gives per tube, so goes in AddLightFromSegment
402  //VisibleEnergySeparation(step);
403 
404  for(size_t pt=1; pt<track.NumberTrajectoryPoints(); pt++)
405  AddLightFromSegment(track.LocationAtPoint<TVector3>(pt-1),track.LocationAtPoint<TVector3>(pt),
406  lightHypothesis,totalHypothesisPE,
407  geom,pvs,PromptMIPScintYield,
408  XOffset);
409 
410  if(fNormalizeHypothesisToFlash && totalHypothesisPE > std::numeric_limits<float>::epsilon())
411  NormalizeLightHypothesis(lightHypothesis,totalHypothesisPE,geom);
412 
413  return lightHypothesis;
414 
415 }//end GetMIPHypotheses
416 
417 
418 // Get a hypothesis for the light collected for a particle trajectory
420  size_t start_i, size_t end_i,
421  Providers_t providers,
423  opdet::OpDigiProperties const& opdigip,
424  float XOffset)
425 {
426  auto const& geom = *(providers.get<geo::GeometryCore>());
427  auto const& larp = *(providers.get<detinfo::LArProperties>());
428  std::vector<float> lightHypothesis(geom.NOpDets(),0);
429  float totalHypothesisPE=0;
430  const float PromptMIPScintYield = larp.ScintYield()*larp.ScintYieldRatio()*opdigip.QE()*fMIPdQdx;
431 
432  for(size_t pt=start_i+1; pt<=end_i; pt++)
433  AddLightFromSegment(particle.Position(pt-1).Vect(),particle.Position(pt).Vect(),
434  lightHypothesis,totalHypothesisPE,
435  geom,pvs,PromptMIPScintYield,
436  XOffset);
437 
438  if(fNormalizeHypothesisToFlash && totalHypothesisPE > std::numeric_limits<float>::epsilon())
439  NormalizeLightHypothesis(lightHypothesis,totalHypothesisPE,geom);
440 
441  return lightHypothesis;
442 
443 }//end GetMIPHypotheses
444 
445 
446 //---------------------------------------
447 // Check whether a hypothesis can be accomodated in a flash
448 // Flashes fail if 1 bin is far in excess of the observed signal
449 // or if the whole flash intensity is much too large for the hypothesis.
450 // MIP dEdx is assumed for now. Accounting for real dQdx will
451 // improve performance of this algorithm.
452 //---------------------------------------
454 cosmic::BeamFlashTrackMatchTaggerAlg::CheckCompatibility(std::vector<float> const& lightHypothesis,
455  const recob::OpFlash* flashPointer,
456  geo::GeometryCore const& geom)
457 {
458  float hypothesis_integral=0;
459  float flash_integral=0;
460  unsigned int cumulativeChannels=0;
461 
462  std::vector<double> PEbyOpDet(geom.NOpDets(),0);
463  //for (unsigned int c = 0; c < geom.NOpChannels(); c++){
464  for (unsigned int c = 0; c <= geom.MaxOpChannel(); c++){
465  if ( geom.IsValidOpChannel(c) ) {
466  unsigned int o = geom.OpDetFromOpChannel(c);
467  PEbyOpDet[o] += flashPointer->PE(c);
468  }
469  }
470 
471  float hypothesis_scale=1.;
472  if(fNormalizeHypothesisToFlash) hypothesis_scale = flashPointer->TotalPE();
473 
474  for(size_t pmt_i=0; pmt_i<lightHypothesis.size(); pmt_i++){
475 
476  flash_integral += PEbyOpDet[pmt_i];
477 
478  if(lightHypothesis[pmt_i] < std::numeric_limits<float>::epsilon() ) continue;
479  hypothesis_integral += lightHypothesis[pmt_i]*hypothesis_scale;
480 
481  if(PEbyOpDet[pmt_i] < fMinOpHitPE) continue;
482 
483  float diff_scaled = (lightHypothesis[pmt_i]*hypothesis_scale - PEbyOpDet[pmt_i])/std::sqrt(lightHypothesis[pmt_i]*hypothesis_scale);
484 
485  if( diff_scaled > fSingleChannelCut ) return CompatibilityResultType::kSingleChannelCut;
486 
487  if( diff_scaled > fCumulativeChannelThreshold ) cumulativeChannels++;
488  if(cumulativeChannels >= fCumulativeChannelCut) return CompatibilityResultType::kCumulativeChannelCut;
489 
490  }
491 
492  if( (hypothesis_integral - flash_integral)/std::sqrt(hypothesis_integral)
493  > fIntegralCut) return CompatibilityResultType::kIntegralCut;
494 
495  return CompatibilityResultType::kCompatible;
496 }
497 
498 
499 float cosmic::BeamFlashTrackMatchTaggerAlg::CalculateChi2(std::vector<float> const& light_flash,
500  std::vector<float> const& light_track){
501 
502  float chi2=0;
503  for(size_t pmt_i=0; pmt_i<light_flash.size(); pmt_i++){
504 
505  if(light_flash[pmt_i] < fMinOpHitPE) continue;
506 
507  float err2 = 1;
508  if(light_track[pmt_i] > 1) err2 = light_track[pmt_i];
509 
510  chi2 += (light_flash[pmt_i]-light_track[pmt_i])*(light_flash[pmt_i]-light_track[pmt_i]) / err2;
511  }
512 
513  return chi2;
514 }
515 
516 
518 {
519  *output << "----------------------------------------------" << std::endl;
520  *output << "Track properties: ";
521  *output << "\n\tLength=" << track.Length();
522 
523  auto const& pt_begin = track.LocationAtPoint(0);
524  *output << "\n\tBegin Location (x,y,z)=(" << pt_begin.x() << "," << pt_begin.y() << "," << pt_begin.z() << ")";
525 
526  auto const& pt_end = track.LocationAtPoint(track.NumberTrajectoryPoints()-1);
527  *output << "\n\tEnd Location (x,y,z)=(" << pt_end.x() << "," << pt_end.y() << "," << pt_end.z() << ")";
528 
529  *output << "\n\tTrajectoryPoints=" << track.NumberTrajectoryPoints();
530  *output << std::endl;
531  *output << "----------------------------------------------" << std::endl;
532 }
533 
535 {
536  *output << "----------------------------------------------" << std::endl;
537  *output << "Flash properties: ";
538 
539  *output << "\n\tTime=" << flash.Time();
540  *output << "\n\tOnBeamTime=" << flash.OnBeamTime();
541  *output << "\n\ty position (center,width)=(" << flash.YCenter() << "," << flash.YWidth() << ")";
542  *output << "\n\tz position (center,width)=(" << flash.ZCenter() << "," << flash.ZWidth() << ")";
543  *output << "\n\tTotal PE=" << flash.TotalPE();
544 
545  *output << std::endl;
546  *output << "----------------------------------------------" << std::endl;
547 
548 }
549 
550 void cosmic::BeamFlashTrackMatchTaggerAlg::PrintHypothesisFlashComparison(std::vector<float> const& lightHypothesis,
551  const recob::OpFlash* flashPointer,
552  geo::GeometryCore const& geom,
554  std::ostream* output)
555 {
556 
557  *output << "----------------------------------------------" << std::endl;
558  *output << "Hypothesis-flash comparison: ";
559 
560  float hypothesis_integral=0;
561  float flash_integral=0;
562 
563  float hypothesis_scale=1.;
564  if(fNormalizeHypothesisToFlash) hypothesis_scale = flashPointer->TotalPE();
565 
566 
567  std::vector<double> PEbyOpDet(geom.NOpDets(),0);
568  //for (unsigned int c = 0; c < geom.NOpChannels(); c++){
569  for ( unsigned int c = 0; c <= geom.MaxOpChannel(); c++){
570  if ( geom.IsValidOpChannel(c) ) {
571  unsigned int o = geom.OpDetFromOpChannel(c);
572  PEbyOpDet[o] += flashPointer->PE(c);
573  }
574  }
575 
576  for(size_t pmt_i=0; pmt_i<lightHypothesis.size(); pmt_i++){
577 
578  flash_integral += PEbyOpDet[pmt_i];
579 
580  *output << "\n\t pmt_i=" << pmt_i << ", (hypothesis,flash)=("
581  << lightHypothesis[pmt_i]*hypothesis_scale << "," << PEbyOpDet[pmt_i] << ")";
582 
583  if(lightHypothesis[pmt_i] < std::numeric_limits<float>::epsilon() ) continue;
584 
585  *output << " difference="
586  << (lightHypothesis[pmt_i]*hypothesis_scale - PEbyOpDet[pmt_i])/std::sqrt(lightHypothesis[pmt_i]*hypothesis_scale);
587 
588  hypothesis_integral += lightHypothesis[pmt_i]*hypothesis_scale;
589  }
590 
591  *output << "\n\t TOTAL (hypothesis,flash)=("
592  << hypothesis_integral << "," << flash_integral << ")"
593  << " difference=" << (hypothesis_integral - flash_integral)/std::sqrt(hypothesis_integral);
594 
595  *output << std::endl;
596  *output << "End result=" << result << std::endl;
597  *output << "----------------------------------------------" << std::endl;
598 
599 }
unsigned int NumberTrajectoryPoints() const
Definition: MCParticle.h:218
const TLorentzVector & Position(const int i=0) const
Definition: MCParticle.h:219
CompatibilityResultType CheckCompatibility(std::vector< float > const &lightHypothesis, const recob::OpFlash *flashPointer, geo::GeometryCore const &geom)
geo::Length_t DetHalfWidth(geo::TPCID const &tpcid) const
Returns the half width of the active volume of the specified TPC.
BeamFlashTrackMatchTaggerAlg(fhicl::ParameterSet const &p)
static QCString result
const simb::MCTrajectory & Trajectory() const
Definition: MCParticle.h:253
enum anab::cosmic_tag_id CosmicTagID_t
Point_t const & LocationAtPoint(size_t i) const
Definition: Track.h:126
void RunHypothesisComparison(unsigned int const, unsigned int const, std::vector< recob::OpFlash > const &, std::vector< recob::Track > const &, Providers_t, phot::PhotonVisibilityService const &, opdet::OpDigiProperties const &)
float CalculateChi2(std::vector< float > const &, std::vector< float > const &)
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
Provider const * get() const
Returns the provider with the specified type.
Definition: ProviderPack.h:193
void GetCenter(double *xyz, double localz=0.0) const
Definition: OpDetGeo.cxx:40
double PE(unsigned int i) const
Definition: OpFlash.h:110
std::string Process() const
Definition: MCParticle.h:215
void RunCompatibilityCheck(std::vector< recob::OpFlash > const &, std::vector< recob::Track > const &, std::vector< anab::CosmicTag > &, std::vector< size_t > &, Providers_t, phot::PhotonVisibilityService const &, opdet::OpDigiProperties const &)
unsigned int OpDetFromOpChannel(int opChannel) const
Convert unique channel to detector number.
double ZCenter() const
Definition: OpFlash.h:117
std::vector< float > GetMIPHypotheses(recob::Track const &track, Providers_t providers, phot::PhotonVisibilityService const &pvs, opdet::OpDigiProperties const &, float XOffset=0)
T abs(T value)
double Time() const
Definition: OpFlash.h:106
double QE() const noexcept
Returns quantum efficiency.
geo::Length_t DetHalfHeight(geo::TPCID const &tpcid) const
Returns the half height of the active volume of the specified TPC.
double Length(size_t p=0) const
Access to various track properties.
Definition: Track.h:167
void NormalizeLightHypothesis(std::vector< float > &lightHypothesis, float const &totalHypothesisPE, geo::GeometryCore const &geom)
const OpDetGeo & OpDet(unsigned int iopdet) const
Return the iopdet&#39;th optical detector in the cryostat.
int OnBeamTime() const
Definition: OpFlash.h:123
void AddLightFromSegment(TVector3 const &pt1, TVector3 const &pt2, std::vector< float > &lightHypothesis, float &totalHypothesisPE, geo::GeometryCore const &geom, phot::PhotonVisibilityService const &pvs, float const &PromptMIPScintYield, float XOffset)
void PrintTrackProperties(recob::Track const &, std::ostream *output=&std::cout)
p
Definition: test.py:223
geo::Length_t DetLength(geo::TPCID const &tpcid) const
Returns the length of the active volume of the specified TPC.
CryostatGeo const & Cryostat(geo::CryostatID const &cryoid) const
Returns the specified cryostat.
unsigned int MaxOpChannel() const
Largest optical channel number.
static int max(int a, int b)
Description of geometry of one entire detector.
MappedCounts_t GetAllVisibilities(Point const &p, bool wantReflected=false) const
void SetHypothesisComparisonTree(TTree *, TH1F *, TH1F *)
unsigned int NOpDets() const
Number of OpDets in the whole detector.
Encapsulate the geometry of an optical detector.
double YWidth() const
Definition: OpFlash.h:116
double TotalLength() const
void PrintHypothesisFlashComparison(std::vector< float > const &, const recob::OpFlash *, geo::GeometryCore const &geom, CompatibilityResultType, std::ostream *output=&std::cout)
Container for a list of pointers to providers.
Definition: ProviderPack.h:114
bool InDriftWindow(double, double, geo::GeometryCore const &)
void FillFlashProperties(std::vector< float > const &opdetVector, float &, float &, float &, float &, float &, geo::GeometryCore const &geom)
double TotalPE() const
Definition: OpFlash.cxx:68
bool InDetector(TVector3 const &, geo::GeometryCore const &)
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
double YCenter() const
Definition: OpFlash.h:115
int bool
Definition: qglobal.h:345
bool IsValidOpChannel(int opChannel) const
Is this a valid OpChannel number?
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
QTextStream & endl(QTextStream &s)
double ZWidth() const
Definition: OpFlash.h:118
Event finding and building.
void PrintFlashProperties(recob::OpFlash const &, std::ostream *output=&std::cout)