LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
ClusterMatchAlg.cxx
Go to the documentation of this file.
1 //
3 // ClusterMatchAlg source
4 //
6 
7 #ifndef CLUSTERMATCHALG_CC
8 #define CLUSTERMATCHALG_CC
9 
10 #include "ClusterMatchAlg.h"
11 
12 namespace cluster{
13 
14  //##################################################################
16  _ModName_MCTruth("")
17  //##################################################################
18  {
19 
20  _debug_mode = pset.get<bool> ("DebugMode");
21  _store_sps = pset.get<bool> ("StoreSpacePoint");
22  _num_sps_cut = pset.get<size_t> ("CutParam_NumSpacePoint");
23  _overlay_tratio_cut = pset.get<double> ("CutParam_OverlayTimeFraction");
24  _qratio_cut = pset.get<double> ("CutParam_SumChargeRatio");
25  std::vector<size_t> algo_list = pset.get<std::vector<size_t> > ("MatchAlgoList");
26 
27  _sps_algo = new trkf::SpacePointAlg(pset.get<fhicl::ParameterSet>("SpacePointAlg"));
28  _match_tree = 0;
29  _cluster_tree = 0;
30  _save_cluster_info = true;
31  _det_params_prepared = false;
32 
33  for(size_t i=0; i<(size_t)(kMATCH_METHOD_MAX); ++i)
34 
35  _match_methods[i]=false;
36 
37  for(auto const v : algo_list) {
38 
39  if(v >= (size_t)(kMATCH_METHOD_MAX))
40 
41  mf::LogError("ClusterMatchAlg")<<Form("Invalid algorithm enum: %zu",v);
42 
43  else _match_methods[v]=true;
44  }
45 
46  ReportConfig();
47 
49  }
50 
51  //########################################
53  //########################################
54  {
55  std::ostringstream msg;
56  msg
57  << std::endl
58  << " ClusterMatchAlg Configuration: " << std::endl
59  << "---------------------------------------------" << std::endl;
60  msg << " Debug Mode ... " << (_debug_mode ? "enabled!" : "disabled!") << std::endl;
61  msg << " RoughZ ....... " << (_match_methods[kRoughZ] ? "enabled!" : "disabled!") << std::endl;
62  msg << " RoughT ....... " << (_match_methods[kRoughT] ? "enabled!" : "disabled!") << std::endl;
63  msg << " SpacePoint ... " << (_match_methods[kSpacePoint] ? "enabled!" : "disabled!") << std::endl;
64  msg << " SumCharge .... " << (_match_methods[kSumCharge] ? "enabled!" : "disabled!") << std::endl;
65  msg << std::endl;
66  msg
67  << " Overlay-Time Fraction Cut : " << _overlay_tratio_cut << std::endl
68  << " Charge-Ratio Diff. Cut : " << _qratio_cut << std::endl
69  << " Minimum # of SpacePoint : " << _num_sps_cut << std::endl
70  << std::endl;
71  msg
72  << "---------------------------------------------" << std::endl;
73 
74  mf::LogWarning("ClusterMatchAlg")<<msg.str();
75 
76  }
77 
79  {
80  _ucluster_v.clear();
81  _vcluster_v.clear();
82  _wcluster_v.clear();
83 
84  _uhits_v.clear();
85  _vhits_v.clear();
86  _whits_v.clear();
87  }
88 
90  {
91  _matched_uclusters_v.clear();
92  _matched_vclusters_v.clear();
93  _matched_wclusters_v.clear();
94  _matched_sps_v.clear();
95  }
96 
98  {
99 
100  _mc_E = 0;
101  _mc_Px = 0;
102  _mc_Py = 0;
103  _mc_Pz = 0;
104  _mc_Vx = 0;
105  _mc_Vy = 0;
106  _mc_Vz = 0;
107  _pdgid = 0;
108  _tot_u = 0;
109  _tot_v = 0;
110  _tot_w = 0;
111  _tot_pass_z = 0;
112  _tot_pass_t = 0;
113  _tot_pass_sps = 0;
114  _tot_pass_qsum = 0;
115  _qratio_v.clear();
116  _uv_tratio_v.clear();
117  _vw_tratio_v.clear();
118  _wu_tratio_v.clear();
119  _u_nhits_v.clear();
120  _v_nhits_v.clear();
121  _w_nhits_v.clear();
122  _nsps.clear();
123 
124  _view_v.clear();
125  _charge_v.clear();
126  _nhits_v.clear();
127  _tstart_min_v.clear();
128  _tstart_max_v.clear();
129  _tpeak_min_v.clear();
130  _tpeak_max_v.clear();
131  _tend_min_v.clear();
132  _tend_max_v.clear();
133 
134  }
135 
136  //##################################################################
138  //##################################################################
139  {
140  // Clear input event data holders
142 
143  // Clear result data holders
145 
147  ClearTTreeInfo();
148 
149  }
150 
151  //##################################################################
153  //##################################################################
154  {
155  if(!_match_tree){
157  _match_tree = fileService->make<TTree>("match_tree","");
158  _match_tree->Branch("mc_E",&_mc_E,"mc_E/D");
159  _match_tree->Branch("mc_Px",&_mc_Px,"mc_Px/D");
160  _match_tree->Branch("mc_Py",&_mc_Py,"mc_Py/D");
161  _match_tree->Branch("mc_Pz",&_mc_Pz,"mc_Pz/D");
162  _match_tree->Branch("mc_Vx",&_mc_Vx,"mc_Vx/D");
163  _match_tree->Branch("mc_Vy",&_mc_Vy,"mc_Vy/D");
164  _match_tree->Branch("mc_Vz",&_mc_Vz,"mc_Vz/D");
165 
166  _match_tree->Branch("pdgid",&_pdgid,"pdgid/I");
167  _match_tree->Branch("tot_u",&_tot_u,"tot_u/s");
168  _match_tree->Branch("tot_v",&_tot_v,"tot_v/s");
169  _match_tree->Branch("tot_w",&_tot_w,"tot_w/s");
170  _match_tree->Branch("tot_pass_t",&_tot_pass_t,"tot_pass_t/s");
171  _match_tree->Branch("tot_pass_z",&_tot_pass_z,"tot_pass_z/s");
172  _match_tree->Branch("tot_pass_sps",&_tot_pass_sps,"tot_pass_sps/s");
173  _match_tree->Branch("tot_pass_qsum",&_tot_pass_qsum,"tot_pass_qsum/s");
174 
175  _match_tree->Branch("uv_tratio_v","std::vector<double>",&_uv_tratio_v);
176  _match_tree->Branch("vw_tratio_v","std::vector<double>",&_vw_tratio_v);
177  _match_tree->Branch("wu_tratio_v","std::vector<double>",&_wu_tratio_v);
178 
179  _match_tree->Branch("qratio_v", "std::vector<double>",&_qratio_v);
180  _match_tree->Branch("u_nhits_v", "std::vector<UShort_t>",&_u_nhits_v);
181  _match_tree->Branch("v_nhits_v", "std::vector<UShort_t>",&_v_nhits_v);
182  _match_tree->Branch("w_nhits_v", "std::vector<UShort_t>",&_w_nhits_v);
183  _match_tree->Branch("nsps", "std::vector<UShort_t>",&_nsps);
184  }
187  _cluster_tree = fileService->make<TTree>("cluster_tree","");
188  _cluster_tree->Branch("view_v","std::vector<uint16_t>", &_view_v);
189  _cluster_tree->Branch("charge_v","std::vector<double>", &_charge_v);
190  _cluster_tree->Branch("nhits_v","std::vector<uint16_t>",&_nhits_v);
191  _cluster_tree->Branch("tstart_min_v","std::vector<double>",&_tstart_min_v);
192  _cluster_tree->Branch("tstart_max_v","std::vector<double>",&_tstart_max_v);
193  _cluster_tree->Branch("tpeak_min_v","std::vector<double>",&_tpeak_min_v);
194  _cluster_tree->Branch("tpeak_max_v","std::vector<double>",&_tpeak_max_v);
195  _cluster_tree->Branch("tend_min_v","std::vector<double>",&_tend_min_v);
196  _cluster_tree->Branch("tend_max_v","std::vector<double>",&_tend_max_v);
197  }
198  }
199 
200  //##########################################################################################
202  //##########################################################################################
203  {
204  if(!_ModName_MCTruth.size()) return;
205 
206  std::vector<const simb::MCTruth*> mciArray;
207 
208  try {
209 
210  evt.getView(_ModName_MCTruth,mciArray);
211 
212  }catch (art::Exception const& e) {
213 
214  if (e.categoryCode() != art::errors::ProductNotFound ) throw;
215 
216  }
217 
218  for(size_t i=0; i < mciArray.size(); ++i){
219 
220  if(i==1) {
221  mf::LogWarning("ClusterMatchAlg")<<" Ignoring > 2nd MCTruth in MC generator...";
222  break;
223  }
224  const simb::MCTruth* mci_ptr(mciArray.at(i));
225 
226  for(size_t j=0; j < (size_t)(mci_ptr->NParticles()); ++j){
227 
228  if(j==1) {
229  mf::LogWarning("ClusterMatchAlg")<<" Ignoring > 2nd MCParticle in MC generator...";
230  break;
231  }
232 
233  const simb::MCParticle part(mci_ptr->GetParticle(j));
234 
235  _pdgid = part.PdgCode();
236  _mc_E = part.E();
237  _mc_Px = part.Px();
238  _mc_Py = part.Py();
239  _mc_Pz = part.Pz();
240  _mc_Vx = part.Vx();
241  _mc_Vy = part.Vy();
242  _mc_Vz = part.Vz();
243  }
244  }
245  }
246 
248  {
250  // Total number of planes
252  _tot_planes = geo->Nplanes();
253 
254  // Ask DetectorPrperties about time-offset among different wire planes ... used to correct timing
255  // difference among different wire planes in the following loop.
256  const detinfo::DetectorProperties* det_h = lar::providerFrom<detinfo::DetectorPropertiesService>();
260  if (_tot_planes >2 )
262  _det_params_prepared = true;
263  }
264  }
265 
267  const std::vector<art::Ptr<recob::Hit> > &in_hit_v) {
268 
270  cluster_match_info ci(in_cluster.ID());
271  ci.view = in_cluster.View();
272 
274  FillHitInfo(ci, hit_ptrv, in_hit_v);
275 
276  // Save created art::PtrVector & cluster_match_info struct object
277  switch(ci.view){
278  case geo::kU:
279  _uhits_v.push_back(hit_ptrv);
280  _ucluster_v.push_back(ci);
282  break;
283  case geo::kV:
284  _vhits_v.push_back(hit_ptrv);
285  _vcluster_v.push_back(ci);
287  break;
288  case geo::kW:
289  _whits_v.push_back(hit_ptrv);
290  _wcluster_v.push_back(ci);
292  break;
293  default:
294  mf::LogError("ClusterMatchAlg")<<Form("Found an invalid plane ID: %d",in_cluster.View());
295  }
296 
297  }
298 
300  const std::vector<art::Ptr<recob::Hit> > &in_hit_v) {
301 
303  cluster_match_info ci(in_cluster->ID());
304  ci.view = in_cluster->View();
305 
307  FillHitInfo(ci, hit_ptrv, in_hit_v);
308 
309  // Save created art::PtrVector & cluster_match_info struct object
310  switch(ci.view){
311  case geo::kU:
312  _uhits_v.push_back(hit_ptrv);
313  _ucluster_v.push_back(ci);
315  break;
316  case geo::kV:
317  _vhits_v.push_back(hit_ptrv);
318  _vcluster_v.push_back(ci);
320  break;
321  case geo::kW:
322  _whits_v.push_back(hit_ptrv);
323  _wcluster_v.push_back(ci);
325  break;
326  default:
327  mf::LogError("ClusterMatchAlg")<<Form("Found an invalid plane ID: %d",in_cluster->View());
328  }
329 
330  }
331 
332 
333 
335  art::PtrVector<recob::Hit> &out_hit_v,
336  const std::vector<art::Ptr<recob::Hit> > &in_hit_v)
337  {
338 
339  out_hit_v.reserve(in_hit_v.size());
340 
341  double time_offset = 0;
342  if(ci.view == geo::kU) time_offset = _time_offset_uplane;
343  else if(ci.view == geo::kV) time_offset = _time_offset_vplane;
344  else if(ci.view == geo::kW) time_offset = _time_offset_wplane;
345 
346  // Loop over hits in this cluster
347  for(auto const hit : in_hit_v){
348 
349  unsigned int wire = hit->WireID().Wire;
350  double tstart = hit->PeakTimePlusRMS(-1.) - time_offset;
351  double tpeak = hit->PeakTime() - time_offset;
352  double tend = hit->PeakTimePlusRMS(+1.) - time_offset;
353 
354  ci.sum_charge += hit->Integral();
355 
356  ci.wire_max = (ci.wire_max < wire) ? wire : ci.wire_max;
357  ci.wire_min = (ci.wire_min > wire) ? wire : ci.wire_min;
358 
359  ci.start_time_max = ( ci.start_time_max < tstart ) ? tstart : ci.start_time_max;
360  ci.peak_time_max = ( ci.peak_time_max < tpeak ) ? tpeak : ci.peak_time_max;
361  ci.end_time_max = ( ci.end_time_max < tend ) ? tend : ci.end_time_max;
362 
363  ci.start_time_min = ( ci.start_time_min > tstart) ? tstart : ci.start_time_min;
364  ci.peak_time_min = ( ci.peak_time_min > tpeak) ? tpeak : ci.peak_time_min;
365  ci.end_time_min = ( ci.end_time_min > tend) ? tend : ci.end_time_min;
366 
367  out_hit_v.push_back(hit);
368  }
369 
370  ci.nhits = in_hit_v.size();
371  }
372 
374  {
375 
376  if(_cluster_tree){
377  _view_v.push_back(ci.view);
378  _charge_v.push_back(ci.sum_charge);
379  _nhits_v.push_back(ci.nhits);
380  _tstart_min_v.push_back(ci.start_time_min);
381  _tstart_max_v.push_back(ci.start_time_max);
382  _tpeak_min_v.push_back(ci.peak_time_min);
383  _tpeak_max_v.push_back(ci.peak_time_max);
384  _tend_min_v.push_back(ci.end_time_min);
385  _tend_max_v.push_back(ci.end_time_max);
386  }
387 
388  }
389 
390  //########################################################################################
392  const geo::View_t v1, const geo::View_t v2 ) const
393  //########################################################################################
394  {
396  double y, z_min, z_max;
397  y = z_min = z_max = -1;
398  geo_h->IntersectionPoint(ci1.wire_min, ci2.wire_min, v1, v2, 0, 0, y, z_min);
399  geo_h->IntersectionPoint(ci1.wire_max, ci2.wire_max, v1, v2, 0, 0, y, z_max);
400  return (z_max > z_min);
401  }
402 
403  //###########################################################################################
405  //###########################################################################################
406  {
407  //return (!(ci1.end_time_max < ci2.start_time_min || ci2.end_time_max < ci1.start_time_min));
408  double time_overlay = std::min(ci1.end_time_max,ci2.end_time_max) - std::max(ci1.start_time_min,ci2.start_time_min);
409 
410  //if(time_overlay <= 0 && !_debug_mode) return false;
411 
412  double overlay_tratio = time_overlay / (ci1.end_time_max - ci1.start_time_min + ci2.end_time_max - ci2.start_time_min) * 2.;
413 
414  if( (ci1.view==geo::kU && ci2.view==geo::kV) || (ci1.view==geo::kV && ci2.view==geo::kU) )
415  _uv_tratio_v.push_back(overlay_tratio);
416  else if( (ci1.view==geo::kV && ci2.view==geo::kW) || (ci1.view==geo::kW && ci2.view==geo::kV) )
417  _vw_tratio_v.push_back(overlay_tratio);
418  else if( (ci1.view==geo::kW && ci2.view==geo::kU) || (ci1.view==geo::kU && ci2.view==geo::kW) )
419  _wu_tratio_v.push_back(overlay_tratio);
420 
421  return (overlay_tratio > _overlay_tratio_cut);
422  }
423 
424  //##############################################################################################
426  //##############################################################################################
427  {
428  double qratio = (uc.sum_charge)/(vc.sum_charge);
429 
430  // For quality check log
431  _qratio_v.push_back(qratio);
432 
433  return ( (1 - _qratio_cut) < qratio && (qratio) < (1 + _qratio_cut) );
434  }
435 
436  //#####################################################################################################
437  bool ClusterMatchAlg::Match_SpacePoint(const size_t uindex,
438  const size_t vindex,
439  const size_t windex,
440  std::vector<recob::SpacePoint> &sps_v)
441  //#####################################################################################################
442  {
443  bool use_wplane = _tot_planes > 2;
444 
445  if( uindex >= _ucluster_v.size() ||
446  vindex >= _vcluster_v.size() ||
447  (use_wplane && (windex >= _wcluster_v.size())) ) {
448 
449  mf::LogError("ClusterMatchAlg")
450  << std::endl
451  << Form("Requested to cluster-index (U,V,W) = (%zu,%zu,%zu) where max-length is (%zu,%zu,%zu)",
452  uindex, vindex, windex, _ucluster_v.size(), _vcluster_v.size(), _wcluster_v.size())
453  << std::endl;
454  return false;
455  }
456 
457  // Define a time range in which hits are used for spacepoint finding ... here "peak time" is the relevant one
458  double trange_min = std::min(_ucluster_v.at(uindex).peak_time_min,_vcluster_v.at(vindex).peak_time_min);
459  if(use_wplane) trange_min = std::min(trange_min, _wcluster_v.at(windex).peak_time_min);
460 
461  double trange_max = std::max(_ucluster_v.at(uindex).peak_time_max,_vcluster_v.at(vindex).peak_time_max);
462  if(use_wplane) trange_max = std::max(trange_max,_wcluster_v.at(windex).peak_time_max);
463 
464  // Space-point algorithm applies additional dT
465  trange_min -= _sps_algo->maxDT();
466  trange_max += _sps_algo->maxDT();
467 
468  // Make PtrVector<recob::Hit> for relevant Hits
469  art::PtrVector<recob::Hit> hit_group;
470  size_t max_size = _uhits_v.at(uindex).size() + _vhits_v.at(vindex).size();
471  if(use_wplane) max_size += _whits_v.at(windex).size();
472  hit_group.reserve(max_size);
473  // Loop over hits in U-plane
474  for(auto const hit : _uhits_v.at(uindex)) {
475  if(hit->PeakTime() < trange_min) continue;
476  if(hit->PeakTime() > trange_max) continue;
477  hit_group.push_back(hit);
478  }
479  // Check if any hit found in this plane
480  size_t u_nhits = hit_group.size();
481  if( !u_nhits && !_debug_mode) return false;
482  // Loop over hits in V-plane
483  for(auto const hit: _vhits_v.at(vindex)) {
484  if(hit->PeakTime() < trange_min) continue;
485  if(hit->PeakTime() > trange_max) continue;
486  hit_group.push_back(hit);
487  }
488  // Check if any hit found in this plane
489  size_t v_nhits = hit_group.size() - u_nhits;
490  if( !(v_nhits) && !_debug_mode) return false;
491 
492  // Loop over hits in W-plane
493  if(use_wplane) {
494  for(auto const hit: _whits_v.at(windex)) {
495  if(hit->PeakTime() < trange_min) continue;
496  if(hit->PeakTime() > trange_max) continue;
497  hit_group.push_back(hit);
498  }
499  }
500  // Check if any hit found in this plane
501  size_t w_nhits = hit_group.size() - u_nhits - v_nhits;
502  if( !(w_nhits) && use_wplane && !_debug_mode) return false;
503 
504  // Run SpacePoint finder algo
505  if(u_nhits && v_nhits &&
506  (!use_wplane || (w_nhits && use_wplane))) {
508  _sps_algo->makeSpacePoints(hit_group,sps_v);
509  }
510 
511  size_t nsps = sps_v.size();
512  _u_nhits_v.push_back(u_nhits);
513  _v_nhits_v.push_back(v_nhits);
514  if(use_wplane)
515  _w_nhits_v.push_back(w_nhits);
516  _nsps.push_back(nsps);
517 
518  if( nsps < _num_sps_cut ) return false;
519  return true;
520  }
521 
522  //#################################################################################
523  std::vector<std::vector<unsigned int> > ClusterMatchAlg::GetMatchedClusters() const
524  //#################################################################################
525  {
526  std::vector<std::vector<unsigned int> > result;
527  result.push_back(_matched_uclusters_v);
528  result.push_back(_matched_vclusters_v);
529  result.push_back(_matched_wclusters_v);
530  return result;
531  }
532 
533  //#######################################################################
535  //#######################################################################
536  {
537  std::ostringstream msg;
538  msg << Form("Received (U,V,W) = (%zu,%zu,%zu) clusters...",
539  _uhits_v.size(),
540  _vhits_v.size(),
541  _whits_v.size())
542  << std::endl;
543  _tot_u = _ucluster_v.size();
544  _tot_v = _vcluster_v.size();
545  _tot_w = _wcluster_v.size();
546 
547  if(!(_tot_u + _tot_v + _tot_w)) {
548 
549  mf::LogError(__PRETTY_FUNCTION__)<<"No input cluster info found! Aborting the function call...";
550 
551  return;
552  }
553 
554  // Initialization
555  PrepareTTree();
557 
558  bool overlay_2d = false;
559  for(size_t uci_index=0; uci_index<_ucluster_v.size(); ++uci_index) {
560 
561  for(size_t vci_index=0; vci_index<_vcluster_v.size(); ++vci_index) {
562 
563  overlay_2d = true;
564 
565  // Apply cuts
566  // Rough z-position overlay cut
567  if(_match_methods[kRoughZ]) {
568 
569  if(Match_RoughZ(_ucluster_v.at(uci_index), _vcluster_v.at(vci_index), geo::kU, geo::kV))
570  _tot_pass_z++;
571  else if(!_debug_mode) continue;
572  else overlay_2d = false;
573  }
574 
575 
576  // Sum charge cut
578 
579  if(Match_SumCharge(_ucluster_v.at(uci_index),_vcluster_v.at(vci_index)))
580  _tot_pass_qsum++;
581  else if(!_debug_mode) continue;
582  else overlay_2d = false;
583  }
584 
585  // Rough time overlap cut
586  if(_match_methods[kRoughT]) {
587 
588  if(Match_RoughTime(_ucluster_v.at(uci_index), _vcluster_v.at(vci_index)))
589  _tot_pass_t++;
590  else if(!_debug_mode) continue;
591  else overlay_2d = false;
592  }
593 
594  // SpacePoint cut
595  std::vector<recob::SpacePoint> sps_v;
597 
598  if(Match_SpacePoint(uci_index, vci_index, 0, sps_v))
599  _tot_pass_sps++;
600  else if(!_debug_mode) continue;
601  else overlay_2d = false;
602  }
603 
604  if(overlay_2d) {
605  _matched_uclusters_v.push_back((unsigned int)(_ucluster_v[uci_index].cluster_index));
606  _matched_vclusters_v.push_back((unsigned int)(_vcluster_v[vci_index].cluster_index));
607  if(_store_sps)
608  _matched_sps_v.push_back(sps_v);
609  }
610  } // end of ... _vcluster_v loop
611  } // end of ... _ucluster_v loop
612 
613  // Report
614  msg << std::endl
615  << Form("Found %zu matched cluster pairs...",_matched_uclusters_v.size())
616  << std::endl;
617  for(size_t i=0; i<_matched_uclusters_v.size(); ++i){
618 
619  if(i==0) msg << "Listing matched clusters (U,V)..." << std::endl;
620 
621  msg << Form("Pair %-2zu: (%-3d, %-3d)",i,_matched_uclusters_v[i],_matched_vclusters_v[i]) << std::endl;
622 
623  }
624  msg << std::endl;
625  mf::LogWarning("ClusterMatchAlg")<<msg.str();
626 
627  if(_match_tree) _match_tree->Fill();
628  if(_cluster_tree) _cluster_tree->Fill();
629 
630  // Clear input event data holders
633  ClearTTreeInfo();
634  }
635 
636  //#######################################################################
638  //#######################################################################
639  {
640  std::ostringstream msg;
641  msg << Form("Received (U,V,W) = (%zu,%zu,%zu) clusters...",
642  _uhits_v.size(),
643  _vhits_v.size(),
644  _whits_v.size())
645  << std::endl;
646  _tot_u = _ucluster_v.size();
647  _tot_v = _vcluster_v.size();
648  _tot_w = _wcluster_v.size();
649 
650  if(!(_tot_u + _tot_v + _tot_w)) {
651 
652  mf::LogError(__PRETTY_FUNCTION__)<<"No input cluster info found! Aborting the function call...";
653 
654  return;
655  }
656 
657  // Clear match information
658  PrepareTTree();
660 
661  bool overlay_2d=true;
662  bool overlay_3d=true;
663  // Loop over all possible u-v-w cluster combination
664  for(size_t uci_index=0; uci_index<_ucluster_v.size(); ++uci_index) {
665 
666  for(size_t vci_index=0; vci_index<_vcluster_v.size(); ++vci_index) {
667 
668  // Apply cuts that can be done with U&V planes here
669  overlay_2d = true;
670 
671  // Rough z-position overlay cut
672  if(_match_methods[kRoughZ]) {
673 
674  if(Match_RoughZ(_ucluster_v.at(uci_index), _vcluster_v.at(vci_index), geo::kU, geo::kV))
675  _tot_pass_z++;
676  else if(!_debug_mode) continue;
677  else overlay_2d = false;
678  }
679 
680  // Sum charge cut
682 
683  if(Match_SumCharge(_ucluster_v.at(uci_index),_vcluster_v.at(vci_index)))
684  _tot_pass_qsum++;
685  else if(!_debug_mode) continue;
686  else overlay_2d = false;
687  }
688 
689  for(size_t wci_index=0; wci_index<_wcluster_v.size(); ++wci_index) {
690 
691  overlay_3d = overlay_2d;
692  // Apply cuts that requires 3 planes here
693 
694  // Rough time overlap cut
695  if(_match_methods[kRoughT]) {
696 
697  bool rough_time_match = Match_RoughTime(_ucluster_v.at(uci_index), _vcluster_v.at(vci_index));
698  if(!_debug_mode && !rough_time_match) continue;
699 
700  rough_time_match = (Match_RoughTime(_vcluster_v.at(vci_index), _wcluster_v.at(wci_index)) && rough_time_match);
701  if(!_debug_mode && !rough_time_match) continue;
702 
703  rough_time_match = (Match_RoughTime(_wcluster_v.at(wci_index), _ucluster_v.at(uci_index)) && rough_time_match);
704 
705  overlay_3d = overlay_3d && rough_time_match;
706  if(rough_time_match) _tot_pass_t++;
707  else if(!_debug_mode) continue;
708  }
709 
710  // SpacePoint cut
711  std::vector<recob::SpacePoint> sps_v;
713 
714  if(Match_SpacePoint(uci_index, vci_index, wci_index, sps_v))
715  _tot_pass_sps++;
716  else if(!_debug_mode) continue;
717  else overlay_3d = false;
718  }
719 
720  if(overlay_3d) {
721  _matched_uclusters_v.push_back((unsigned int)(_ucluster_v[uci_index].cluster_index));
722  _matched_vclusters_v.push_back((unsigned int)(_vcluster_v[vci_index].cluster_index));
723  _matched_wclusters_v.push_back((unsigned int)(_wcluster_v[wci_index].cluster_index));
724  if(_store_sps)
725  _matched_sps_v.push_back(sps_v);
726  }
727  } // end of ... _wcluster_v loop
728  } // end of ... _vcluster_v loop
729  } // end of ... _ucluster_v loop
730 
731  // Report
732  msg << std::endl
733  << Form("Found %zu matched cluster pairs...",_matched_uclusters_v.size())
734  << std::endl;
735  for(size_t i=0; i<_matched_uclusters_v.size(); ++i){
736 
737  if(i==0) msg << "Listing matched clusters (U,V,W)..." << std::endl;
738 
739  msg << Form("Pair %-2zu: (%-3d, %-3d, %-3d)",
740  i,
743  _matched_wclusters_v[i]) << std::endl;
744 
745  }
746  msg << std::endl;
747  mf::LogWarning("ClusterMatchAlg")<<msg.str();
748 
749  if(_match_tree) _match_tree->Fill();
750  if(_cluster_tree) _cluster_tree->Fill();
751  // Clear input event data holders
754  ClearTTreeInfo();
755 
756  }
757 
758 } // namespace match
759 
760 #endif
std::vector< uint16_t > _w_nhits_v
Use summed charge comparison ... see Match_SumCharge() description.
void ClearMatchInputInfo()
Method to clear input cluster information.
void reserve(size_type n)
Definition: PtrVector.h:343
std::vector< std::vector< unsigned int > > GetMatchedClusters() const
Method to retrieve matched cluster combinations. The format is [wire_plane][cluster_index].
trkf::SpacePointAlg * _sps_algo
SpacePointFinder algorithm pointer.
double peak_time_max
Maximum "peak time" among all hits in this cluster.
std::vector< art::PtrVector< recob::Hit > > _vhits_v
Local Hit pointer vector container ... V-plane.
void FillMCInfo(const art::Event &evt)
Internal method to fill MCTruth information when available.
bool Match_RoughTime(const cluster_match_info &ci1, const cluster_match_info &ci2)
Checks min/max hit timing among two clusters and make sure there is an overlap.
double end_time_min
Minimum "end time" among all hits in this cluster.
std::vector< double > _vw_tratio_v
unsigned short wire_min
Minimum wire number in this cluster.
std::vector< art::PtrVector< recob::Hit > > _whits_v
Local Hit pointer vector container ... W-plane.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Planes which measure V.
Definition: geo_types.h:77
double end_time_max
Maximum "end time" among all hits in this cluster.
Float_t y
Definition: compare.C:6
std::vector< double > _wu_tratio_v
std::vector< double > _qratio_v
void ClearEventInfo()
Method to clear event-wise information.
void FillHitInfo(cluster_match_info &ci, art::PtrVector< recob::Hit > &out_hit_v, const std::vector< art::Ptr< recob::Hit > > &in_hit_v)
double _qratio_cut
Maximum difference among clusters&#39; charge sum used in Match_SumCharge method.
void ClearMatchOutputInfo()
Method to clear output matched cluster information.
bool _store_sps
Boolean to enable storage of SpacePoint vector.
bool Match_RoughZ(const cluster_match_info &ci1, const cluster_match_info &ci2, const geo::View_t v1, const geo::View_t v2) const
Set of hits with a 2D structure.
Definition: Cluster.h:71
Use SpacePoint finder algorithm ... see Match_SpacePoint() description.
void MatchTwoPlanes()
Two plane version of cluster matching method.
void AppendClusterInfo(const recob::Cluster &in_cluster, const std::vector< art::Ptr< recob::Hit > > &in_hit_v)
Method to fill cluster information to be used for matching.
std::vector< cluster_match_info > _wcluster_v
Local cluster data container... W-plane.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
unsigned short _tot_pass_sps
std::vector< double > _tpeak_max_v
double _overlay_tratio_cut
Minimum overlayed time fraction among two clusters used in Match_RoughTime method.
std::vector< double > _charge_v
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
std::size_t getView(std::string const &moduleLabel, std::string const &productInstanceName, std::vector< ELEMENT const * > &result) const
Definition: DataViewImpl.h:474
std::vector< uint16_t > _nhits_v
Planes which measure U.
Definition: geo_types.h:76
void PrepareTTree()
Internal method to create output TTree for quality checking of the algorithm.
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
Int_t max
Definition: plot.C:27
std::vector< double > _tend_max_v
std::vector< double > _tend_min_v
std::vector< uint16_t > _nsps
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:441
double peak_time_min
Minimum "peak time" among all hits in this cluster.
T get(std::string const &key) const
Definition: ParameterSet.h:231
TString part[npart]
Definition: Style.C:32
double sum_charge
Summed charge among all hits in this cluster.
Rough-Time comparison method ... see Match_RoughTime() description.
std::string _ModName_MCTruth
MCTruth producer&#39;s module name.
bool Match_SpacePoint(const size_t uindex, const size_t vindex, const size_t windex, std::vector< recob::SpacePoint > &sps_v)
double maxDT() const
Definition: SpacePointAlg.h:90
std::vector< art::PtrVector< recob::Hit > > _uhits_v
Local Hit pointer vector container ... U-plane.
std::vector< uint16_t > _u_nhits_v
void AppendClusterTreeVariables(const cluster_match_info &ci)
Internal method to fill cluster-info tree.
bool IntersectionPoint(geo::WireID const &wid1, geo::WireID const &wid2, double &y, double &z) const
Returns the intersection point of two wires.
std::vector< double > _tstart_max_v
std::vector< cluster_match_info > _vcluster_v
Local cluster data container... V-plane.
std::vector< double > _tstart_min_v
std::vector< double > _uv_tratio_v
bool _debug_mode
Boolean to enable debug mode (call all enabled matching methods)
ClusterMatchAlg(fhicl::ParameterSet const &pset)
Default constructor with fhicl parameters.
size_type size() const
Definition: PtrVector.h:308
Detector simulation of raw signals on wires.
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
void ClearTTreeInfo()
Method to clear TTree variables.
void makeSpacePoints(const art::PtrVector< recob::Hit > &hits, std::vector< recob::SpacePoint > &spts) const
geo::View_t View() const
Returns the view for this cluster.
Definition: Cluster.h:741
void clearHitMap() const
bool Match_SumCharge(const cluster_match_info &uc, const cluster_match_info &vc)
T * make(ARGS...args) const
size_t _num_sps_cut
Number of SpacePoint used to cut in Match_SpacePoint method.
std::vector< uint16_t > _view_v
unsigned short _tot_pass_qsum
Int_t min
Definition: plot.C:26
ID_t ID() const
Identifier of this cluster.
Definition: Cluster.h:738
unsigned short wire_max
Maximum wire number in this cluster.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
std::vector< uint16_t > _v_nhits_v
std::vector< std::vector< recob::SpacePoint > > _matched_sps_v
Local SpacePoint vector container.
std::vector< unsigned int > _matched_uclusters_v
U plane matched clusters&#39; index.
double start_time_max
Maximum "start time" among all hits in this cluster.
Planes which measure W (third view for Bo, MicroBooNE, etc).
Definition: geo_types.h:78
bool _match_methods[kMATCH_METHOD_MAX]
Boolean list for enabled algorithms.
Event generator information.
Definition: MCTruth.h:30
void PrepareDetParams()
Internal method, called only once, to fill detector-wise information.
void ReportConfig() const
Method to report the current configuration.
Float_t e
Definition: plot.C:34
Namespace collecting geometry-related classes utilities.
std::vector< unsigned int > _matched_wclusters_v
W plane matched clusters&#39; index.
std::vector< unsigned int > _matched_vclusters_v
V plane matched clusters&#39; index.
Rough-Z comparison method ... see Match_RoughZ() description.
std::vector< double > _tpeak_min_v
std::vector< cluster_match_info > _ucluster_v
Local cluster data container... U-plane.
virtual double GetXTicksOffset(int p, int t, int c) const =0
double start_time_min
Minimum "start time" among all hits in this cluster.