All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
MCMatchAlg.cxx
Go to the documentation of this file.
1 #include "MCMatchAlg.h"
2 
3 #include "TString.h"
4 #include "art/Framework/Services/Registry/ServiceHandle.h"
5 #include "canvas/Persistency/Common/Ptr.h"
11 
12 #include <string>
13 
14 namespace btutil {
15 
17 
18  bool
20  const std::vector<unsigned int>& g4_trackid_v,
21  const std::vector<sim::SimChannel>& simch_v,
22  const std::vector<std::vector<art::Ptr<recob::Hit>>>& cluster_v)
23  {
24  fBTAlgo.Reset(g4_trackid_v, simch_v);
25 
26  return BuildMap(clockData, cluster_v);
27  }
28 
29  bool
31  const std::vector<std::vector<unsigned int>>& g4_trackid_v,
32  const std::vector<sim::SimChannel>& simch_v,
33  const std::vector<std::vector<art::Ptr<recob::Hit>>>& cluster_v)
34  {
35 
36  fBTAlgo.Reset(g4_trackid_v, simch_v);
37 
38  return BuildMap(clockData, cluster_v);
39  }
40 
41  bool
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  //auto geo = ::larutil::Geometry::GetME();
48  art::ServiceHandle<geo::Geometry const> geo;
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>(geo->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 = geo->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 == geo->Nplanes()) plane = h->WireID().Plane;
82  //if(plane==geo->Nplanes()) plane = h->View();
83  }
84 
85  _cluster_plane_id.push_back(plane);
86 
87  auto mcq_v = fBTAlgo.MCQ(clockData, wr_v);
88 
89  for (size_t i = 0; i < mcq_v.size(); ++i)
90 
91  _summed_mcq[i][plane] += mcq_v[i];
92 
93  _cluster_mcq_v.push_back(mcq_v);
94  }
95 
96  //
97  // Find the best matched pair (and its charge) per MC object
98  //
99  _bmatch_id.clear();
100  _bmatch_id.resize(num_mcobj, std::vector<int>(geo->Nplanes(), -1));
101 
102  std::vector<std::vector<double>> bmatch_mcq(num_mcobj, std::vector<double>(geo->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  //if((_cluster_mcq_v[cluster_index].back()) < 0) continue;
109 
110  auto plane = _cluster_plane_id.at(cluster_index);
111 
112  double q = _cluster_mcq_v[cluster_index][mc_index];
113 
114  if (bmatch_mcq[mc_index][plane] < q) {
115 
116  bmatch_mcq[mc_index][plane] = q;
117  _bmatch_id[mc_index][plane] = cluster_index;
118  }
119  }
120  }
121 
122  return true;
123  }
124 
125  double
126  MCMatchAlg::ClusterCorrectness(const size_t cluster_index, const size_t mc_index) const
127  {
128 
129  if (!_bmatch_id.size()) throw MCBTException("Preparation not done yet!");
130 
131  if (cluster_index >= _cluster_mcq_v.size())
132  throw MCBTException(Form(
133  "Input cluster index (%zu) out of range (%zu)!", cluster_index, _cluster_mcq_v.size()));
134 
135  if (mc_index >= _bmatch_id.size())
136  throw MCBTException(
137  Form("Input MC object index (%zu) out of range (%zu)!", mc_index, _bmatch_id.size()));
138 
139  auto plane = _cluster_plane_id.at(cluster_index);
140 
141  auto best_cluster_index = _bmatch_id.at(mc_index).at(plane);
142 
143  if (best_cluster_index < 0) return -1;
144 
145  return _cluster_mcq_v.at(cluster_index).at(mc_index) /
146  _cluster_mcq_v.at(best_cluster_index).at(mc_index);
147  }
148 
149  std::pair<size_t, double>
150  MCMatchAlg::ShowerCorrectness(const std::vector<unsigned int> cluster_indices) const
151  {
152 
153  if (!_bmatch_id.size()) throw MCBTException("Preparation not done yet!");
154 
155  if (cluster_indices.size() > _cluster_mcq_v.size())
156  throw MCBTException(
157  Form("Input cluster indices length (%zu) > # of registered clusters (%zu)!",
158  cluster_indices.size(),
159  _cluster_mcq_v.size()));
160 
161  if (!cluster_indices.size()) throw MCBTException("Input cluster indices empty!");
162 
163  // Compute efficiency per MC
164  std::vector<double> match_eff(_bmatch_id.size(), 1);
165 
166  for (auto const& cluster_index : cluster_indices) {
167 
168  for (size_t mc_index = 0; mc_index < _bmatch_id.size(); ++mc_index) {
169 
170  double correctness = ClusterCorrectness(cluster_index, mc_index);
171 
172  if (correctness >= 0) match_eff.at(mc_index) *= correctness;
173  }
174  }
175 
176  std::pair<size_t, double> result(0, -1);
177 
178  // Find the best qratio
179  for (size_t mc_index = 0; mc_index < match_eff.size(); ++mc_index) {
180 
181  if (match_eff.at(mc_index) < result.second) continue;
182 
183  result.second = match_eff.at(mc_index);
184 
185  result.first = mc_index;
186  }
187  return result;
188  }
189 
190  std::pair<double, double>
191  MCMatchAlg::ClusterEP(const size_t cluster_index, const size_t mc_index) const
192  {
193  if (!_bmatch_id.size()) throw MCBTException("Preparation not done yet!");
194 
195  if (cluster_index >= _cluster_mcq_v.size())
196  throw MCBTException(Form(
197  "Input cluster index (%zu) out of range (%zu)!", cluster_index, _cluster_mcq_v.size()));
198 
199  if (mc_index >= _bmatch_id.size())
200  throw MCBTException(
201  Form("Input MC object index (%zu) out of range (%zu)!", mc_index, _bmatch_id.size()));
202 
203  // efficiency = this cluster's mcq for specified mc obj / total mcq by this mcshower in all clusters
204  // purity = this cluster's mcq for this mcshower / total mcq from all mc obj in this cluster
205 
206  std::pair<double, double> result;
207 
208  auto plane = _cluster_plane_id[cluster_index];
209 
210  result.first = _cluster_mcq_v[cluster_index][mc_index] / _summed_mcq[mc_index][plane];
211 
212  double cluster_mcq_total = 0;
213  for (auto const& q : _cluster_mcq_v[cluster_index])
214  cluster_mcq_total += q;
215 
216  result.second = _cluster_mcq_v[cluster_index][mc_index] / cluster_mcq_total;
217 
218  return result;
219  }
220 
221  const std::vector<int>&
222  MCMatchAlg::BestClusters(const size_t mc_index) const
223  {
224  if (!_bmatch_id.size()) throw MCBTException("Preparation not done yet!");
225 
226  if (mc_index >= _bmatch_id.size())
227  throw MCBTException(
228  Form("Input MC object index (%zu) out of range (%zu)!", mc_index, _bmatch_id.size()));
229 
230  return _bmatch_id[mc_index];
231  }
232 
233  std::pair<double, double>
234  MCMatchAlg::BestClusterEP(const size_t mc_index, const size_t plane_id) const
235  {
236 
237  auto c_index_v = BestClusters(mc_index);
238 
239  if (c_index_v.size() <= plane_id)
240  throw MCBTException(Form(
241  "Plane ID %zu exceeds # of planes recorded in data (%zu)...", plane_id, c_index_v.size()));
242 
243  std::pair<double, double> result(0, 0);
244 
245  if (c_index_v[plane_id] < 0) return result;
246 
247  return ClusterEP(c_index_v[plane_id], mc_index);
248  }
249 
250 }
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:234
void Reset(const std::vector< unsigned int > &g4_trackid_v, const std::vector< sim::SimChannel > &simch_v)
Definition: MCBTAlg.cxx:24
Declaration of signal hit object.
Class def header for a class MCBTAlg.
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=&gt;MC matching.
Definition: MCMatchAlg.cxx:19
std::vector< std::vector< double > > _summed_mcq
Definition: MCMatchAlg.h:107
std::vector< unsigned char > _cluster_plane_id
Definition: MCMatchAlg.h:110
std::vector< std::vector< double > > _cluster_mcq_v
Definition: MCMatchAlg.h:108
while getopts h
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:126
MCBTAlg fBTAlgo
MCBTAlg instance.
Definition: MCMatchAlg.h:103
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:191
std::vector< double > MCQ(detinfo::DetectorClocksData const &clockData, const WireRange_t &hit) const
Definition: MCBTAlg.cxx:106
size_t NumParts() const
Definition: MCBTAlg.h:116
Definition of data types for geometry description.
const std::vector< int > & BestClusters(const size_t mcshower_index) const
Definition: MCMatchAlg.cxx:222
std::vector< size_t > _view_to_plane
Definition: MCMatchAlg.h:105
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:150
std::vector< std::vector< int > > _bmatch_id
Definition: MCMatchAlg.h:111
art framework interface to geometry description
Class def header for exception classes in MCComp package.