LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
MCMatchAlg.cxx
Go to the documentation of this file.
1 #ifndef RECOTOOL_MCMATCHALG_CXX
2 #define RECOTOOL_MCMATCHALG_CXX
3 
4 #include "MCMatchAlg.h"
5 
6 namespace btutil {
7 
9  _view_to_plane.clear();
10  }
11 
12  bool MCMatchAlg::BuildMap(const std::vector< unsigned int> &g4_trackid_v,
13  const std::vector<sim::SimChannel> &simch_v,
14  const std::vector<std::vector<art::Ptr<recob::Hit> > > &cluster_v)
15  {
16  fBTAlgo.Reset(g4_trackid_v,simch_v);
17 
18  return BuildMap(cluster_v);
19  }
20 
21  bool MCMatchAlg::BuildMap(const std::vector<std::vector< unsigned int> > &g4_trackid_v,
22  const std::vector<sim::SimChannel> &simch_v,
23  const std::vector<std::vector<art::Ptr<recob::Hit> > > &cluster_v)
24  {
25 
26  fBTAlgo.Reset(g4_trackid_v,simch_v);
27 
28  return BuildMap(cluster_v);
29  }
30 
32  {
33  size_t num_mcobj = fBTAlgo.NumParts();
34  size_t num_cluster = cluster_v.size();
35  //auto geo = ::larutil::Geometry::GetME();
37 
38  //
39  // Perform back-tracking
40  //
41  // (1) Load cluster/hit data product
42  // (2) Loop over all clusters and find charge fraction to each MC object
43  // (3) For each MC object, find a cluster per plane with the highest charge
44 
45  // Loop over clusters & get charge fraction per MC object
46  _summed_mcq.clear();
47  _cluster_mcq_v.clear();
48  _cluster_plane_id.clear();
49 
50  _summed_mcq.resize(num_mcobj+1,std::vector<double>(geo->Nplanes(),0));
51  _cluster_mcq_v.reserve(num_cluster);
52  _cluster_plane_id.reserve(num_cluster);
53 
54  for(auto const& hit_v : cluster_v) {
55 
56  size_t plane = geo->Nplanes();
57 
58  // Create hit list
59  std::vector<WireRange_t> wr_v;
60  wr_v.reserve(hit_v.size());
61 
62  for(auto const& h : hit_v) {
63 
64  WireRange_t wr;
65  wr.ch = h->Channel();
66  wr.start = h->StartTick();
67  wr.end = h->EndTick();
68  wr_v.push_back(wr);
69  if(plane==geo->Nplanes()) plane = h->WireID().Plane;
70  //if(plane==geo->Nplanes()) plane = h->View();
71  }
72 
73  _cluster_plane_id.push_back(plane);
74 
75  auto mcq_v = fBTAlgo.MCQ(wr_v);
76 
77 
78  for(size_t i=0; i<mcq_v.size(); ++i)
79 
80  _summed_mcq[i][plane] += mcq_v[i];
81 
82  _cluster_mcq_v.push_back(mcq_v);
83 
84  }
85 
86  //
87  // Find the best matched pair (and its charge) per MC object
88  //
89  _bmatch_id.clear();
90  _bmatch_id.resize(num_mcobj,std::vector<int>(geo->Nplanes(),-1));
91 
92  std::vector<std::vector<double> > bmatch_mcq (num_mcobj,std::vector<double>(geo->Nplanes(),0));
93 
94  for(size_t mc_index=0; mc_index < num_mcobj; ++mc_index) {
95 
96  for(size_t cluster_index=0; cluster_index < num_cluster; ++cluster_index) {
97 
98  //if((_cluster_mcq_v[cluster_index].back()) < 0) continue;
99 
100  auto plane = _cluster_plane_id.at(cluster_index);
101 
102  double q = _cluster_mcq_v[cluster_index][mc_index];
103 
104  if( bmatch_mcq[mc_index][plane] < q ) {
105 
106  bmatch_mcq[mc_index][plane] = q;
107  _bmatch_id[mc_index][plane] = cluster_index;
108 
109  }
110  }
111  }
112 
113  return true;
114  }
115 
116  double MCMatchAlg::ClusterCorrectness(const size_t cluster_index,
117  const size_t mc_index) const
118  {
119 
120  if(!_bmatch_id.size())
121  throw MCBTException("Preparation not done yet!");
122 
123  if( cluster_index >= _cluster_mcq_v.size())
124  throw MCBTException(Form("Input cluster index (%zu) out of range (%zu)!",
125  cluster_index,
126  _cluster_mcq_v.size())
127  );
128 
129  if( mc_index >= _bmatch_id.size() )
130  throw MCBTException(Form("Input MC object index (%zu) out of range (%zu)!",
131  mc_index,
132  _bmatch_id.size())
133  );
134 
135  auto plane = _cluster_plane_id.at(cluster_index);
136 
137  auto best_cluster_index = _bmatch_id.at(mc_index).at(plane);
138 
139  if(best_cluster_index < 0) return -1;
140 
141  return _cluster_mcq_v.at(cluster_index).at(mc_index) / _cluster_mcq_v.at(best_cluster_index).at(mc_index);
142 
143  }
144 
145  std::pair<size_t,double> MCMatchAlg::ShowerCorrectness(const std::vector<unsigned int> cluster_indices) const
146  {
147 
148  if(!_bmatch_id.size())
149  throw MCBTException("Preparation not done yet!");
150 
151  if( cluster_indices.size() > _cluster_mcq_v.size())
152  throw MCBTException(Form("Input cluster indices length (%zu) > # of registered clusters (%zu)!",
153  cluster_indices.size(),
154  _cluster_mcq_v.size())
155  );
156 
157  if(!cluster_indices.size()) throw MCBTException("Input cluster indices empty!");
158 
159  // Compute efficiency per MC
160  std::vector<double> match_eff(_bmatch_id.size(),1);
161 
162  for(auto const& cluster_index : cluster_indices) {
163 
164  for(size_t mc_index=0; mc_index < _bmatch_id.size(); ++mc_index) {
165 
166  double correctness = ClusterCorrectness(cluster_index, mc_index);
167 
168  if(correctness>=0)
169  match_eff.at(mc_index) *= correctness;
170 
171  }
172  }
173 
174  std::pair<size_t,double> result(0,-1);
175 
176  // Find the best qratio
177  for(size_t mc_index=0; mc_index < match_eff.size(); ++mc_index) {
178 
179  if(match_eff.at(mc_index) < result.second) continue;
180 
181  result.second = match_eff.at(mc_index);
182 
183  result.first = mc_index;
184 
185  }
186  return result;
187  }
188 
189  std::pair<double,double> MCMatchAlg::ClusterEP(const size_t cluster_index,
190  const size_t mc_index) const
191  {
192  if(!_bmatch_id.size())
193  throw MCBTException("Preparation not done yet!");
194 
195  if( cluster_index >= _cluster_mcq_v.size())
196  throw MCBTException(Form("Input cluster index (%zu) out of range (%zu)!",
197  cluster_index,
198  _cluster_mcq_v.size())
199  );
200 
201  if( mc_index >= _bmatch_id.size() )
202  throw MCBTException(Form("Input MC object index (%zu) out of range (%zu)!",
203  mc_index,
204  _bmatch_id.size())
205  );
206 
207  // efficiency = this cluster's mcq for specified mc obj / total mcq by this mcshower in all clusters
208  // purity = this cluster's mcq for this mcshower / total mcq from all mc obj in this cluster
209 
210  std::pair<double,double> result;
211 
212  auto plane = _cluster_plane_id[cluster_index];
213 
214  result.first = _cluster_mcq_v[cluster_index][mc_index] / _summed_mcq[mc_index][plane];
215 
216  double cluster_mcq_total = 0;
217  for(auto const& q : _cluster_mcq_v[cluster_index]) cluster_mcq_total += q;
218 
219  result.second = _cluster_mcq_v[cluster_index][mc_index] / cluster_mcq_total;
220 
221  return result;
222  }
223 
224  const std::vector<int>& MCMatchAlg::BestClusters(const size_t mc_index) const
225  {
226  if(!_bmatch_id.size())
227  throw MCBTException("Preparation not done yet!");
228 
229  if( mc_index >= _bmatch_id.size() )
230  throw MCBTException(Form("Input MC object index (%zu) out of range (%zu)!",
231  mc_index,
232  _bmatch_id.size())
233  );
234 
235  return _bmatch_id[mc_index];
236 
237  }
238 
239  std::pair<double,double> MCMatchAlg::BestClusterEP(const size_t mc_index,
240  const size_t plane_id) const
241  {
242 
243  auto c_index_v = BestClusters(mc_index);
244 
245  if(c_index_v.size() <= plane_id)
246  throw MCBTException(Form("Plane ID %zu exceeds # of planes recorded in data (%zu)...",
247  plane_id,
248  c_index_v.size())
249  );
250 
251  std::pair<double,double> result(0,0);
252 
253  if(c_index_v[plane_id]<0) return result;
254 
255  return ClusterEP(c_index_v[plane_id],mc_index);
256 
257  }
258 
259 }
260 #endif
unsigned int ch
Definition: MCBTAlg.h:37
Class def header for a class MCMatchAlg.
std::pair< double, double > BestClusterEP(const size_t mcshower_index, const size_t plane_id) const
Definition: MCMatchAlg.cxx:239
void Reset(const std::vector< unsigned int > &g4_trackid_v, const std::vector< sim::SimChannel > &simch_v)
Definition: MCBTAlg.cxx:14
std::vector< std::vector< double > > _summed_mcq
Definition: MCMatchAlg.h:100
std::vector< unsigned char > _cluster_plane_id
Definition: MCMatchAlg.h:103
std::vector< std::vector< double > > _cluster_mcq_v
Definition: MCMatchAlg.h:101
bool BuildMap(const std::vector< unsigned int > &g4_trackid_v, const std::vector< sim::SimChannel > &simch_v, const std::vector< std::vector< art::Ptr< recob::Hit > > > &cluster_v)
Constructs needed information for Reco=>MC matching.
Definition: MCMatchAlg.cxx:12
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
double ClusterCorrectness(const size_t cluster_index, const size_t mcshower_index) const
Definition: MCMatchAlg.cxx:116
MCBTAlg fBTAlgo
MCBTAlg instance.
Definition: MCMatchAlg.h:96
std::pair< double, double > ClusterEP(const size_t cluster_index, const size_t mcshower_index) const
For a specified cluster, compute cluster efficiency and purity in terms of specified MC object...
Definition: MCMatchAlg.cxx:189
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
size_t NumParts() const
Definition: MCBTAlg.h:109
const std::vector< int > & BestClusters(const size_t mcshower_index) const
Definition: MCMatchAlg.cxx:224
std::vector< size_t > _view_to_plane
Definition: MCMatchAlg.h:98
std::vector< double > MCQ(const WireRange_t &hit) const
Definition: MCBTAlg.cxx:95
MCMatchAlg()
Default constructor.
Definition: MCMatchAlg.cxx:8
std::pair< size_t, double > ShowerCorrectness(const std::vector< unsigned int > cluster_indices) const
Definition: MCMatchAlg.cxx:145
std::vector< std::vector< int > > _bmatch_id
Definition: MCMatchAlg.h:104
Namespace collecting geometry-related classes utilities.