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