PointIdAlg.cxx
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////////////////////////////////
2 // Class: PointIdAlg
3 // Authors: D.Stefan (Dorota.Stefan@ncbj.gov.pl), from DUNE, CERN/NCBJ, since May 2016
4 // R.Sulej (Robert.Sulej@cern.ch), from DUNE, FNAL/NCBJ, since May 2016
5 // P.Plonski, from DUNE, WUT, since May 2016
6 // D.Smith, from LArIAT, BU, 2017: real data dump
7 ////////////////////////////////////////////////////////////////////////////////////////////////////
8 
11 
16 
17 #include "larcore/CoreUtils/ServiceUtil.h" // lar::providerFrom<>()
19 #include "larcorealg/Geometry/Exceptions.h" // geo::InvalidWireIDError
24 
25 #include "CLHEP/Random/RandGauss.h"
26 
27 #include <sys/stat.h>
28 
29 // ------------------------------------------------------
30 // -------------------ModelInterface---------------------
31 // ------------------------------------------------------
32 
33 std::vector<std::vector<float>>
34 nnet::ModelInterface::Run(std::vector<std::vector<std::vector<float>>> const& inps, int samples)
35 {
36  if ((samples == 0) || inps.empty() || inps.front().empty() || inps.front().front().empty())
37  return std::vector<std::vector<float>>();
38 
39  if ((samples == -1) || (samples > (int)inps.size())) { samples = inps.size(); }
40 
41  std::vector<std::vector<float>> results;
42  for (int i = 0; i < samples; ++i) {
43  results.push_back(Run(inps[i]));
44  }
45  return results;
46 }
47 
50 {
51  std::string fname_out;
52  cet::search_path sp("FW_SEARCH_PATH");
53  if (!sp.find_file(fileName, fname_out)) {
54  struct stat buffer;
55  if (stat(fileName, &buffer) == 0) { fname_out = fileName; }
56  else {
57  throw art::Exception(art::errors::NotFound) << "Could not find the model file " << fileName;
58  }
59  }
60  return fname_out;
61 }
62 
63 // ------------------------------------------------------
64 // ----------------KerasModelInterface-------------------
65 // ------------------------------------------------------
66 
68  : m(nnet::ModelInterface::findFile(modelFileName).c_str())
69 {
70  mf::LogInfo("KerasModelInterface") << "Keras model loaded.";
71 }
72 // ------------------------------------------------------
73 
74 std::vector<float>
75 nnet::KerasModelInterface::Run(std::vector<std::vector<float>> const& inp2d)
76 {
77  std::vector<std::vector<std::vector<float>>> inp3d;
78  inp3d.push_back(inp2d); // lots of copy, should add 2D to keras...
79 
80  keras::DataChunk* sample = new keras::DataChunk2D();
81  sample->set_data(inp3d); // and more copy...
82  std::vector<float> out = m.compute_output(sample);
83  delete sample;
84  return out;
85 }
86 
87 // ------------------------------------------------------
88 // -----------------TfModelInterface---------------------
89 // ------------------------------------------------------
90 
91 nnet::TfModelInterface::TfModelInterface(const char* modelFileName)
92 {
93  g = tf::Graph::create(nnet::ModelInterface::findFile(modelFileName).c_str(),
94  {"cnn_output", "_netout"});
95  if (!g) { throw art::Exception(art::errors::Unknown) << "TF model failed."; }
96 
97  mf::LogInfo("TfModelInterface") << "TF model loaded.";
98 }
99 // ------------------------------------------------------
100 
101 std::vector<std::vector<float>>
102 nnet::TfModelInterface::Run(std::vector<std::vector<std::vector<float>>> const& inps, int samples)
103 {
104  if ((samples == 0) || inps.empty() || inps.front().empty() || inps.front().front().empty())
105  return std::vector<std::vector<float>>();
106 
107  if ((samples == -1) || (samples > (long long int)inps.size())) { samples = inps.size(); }
108 
109  long long int rows = inps.front().size(), cols = inps.front().front().size();
110 
111  tensorflow::Tensor _x(tensorflow::DT_FLOAT, tensorflow::TensorShape({samples, rows, cols, 1}));
112  auto input_map = _x.tensor<float, 4>();
113  for (long long int s = 0; s < samples; ++s) {
114  const auto& sample = inps[s];
115  for (long long int r = 0; r < rows; ++r) {
116  const auto& row = sample[r];
117  for (long long int c = 0; c < cols; ++c) {
118  input_map(s, r, c, 0) = row[c];
119  }
120  }
121  }
122 
123  return g->run(_x);
124 }
125 // ------------------------------------------------------
126 
127 std::vector<float>
128 nnet::TfModelInterface::Run(std::vector<std::vector<float>> const& inp2d)
129 {
130  long long int rows = inp2d.size(), cols = inp2d.front().size();
131 
132  tensorflow::Tensor _x(tensorflow::DT_FLOAT, tensorflow::TensorShape({1, rows, cols, 1}));
133  auto input_map = _x.tensor<float, 4>();
134  for (long long int r = 0; r < rows; ++r) {
135  const auto& row = inp2d[r];
136  for (long long int c = 0; c < cols; ++c) {
137  input_map(0, r, c, 0) = row[c];
138  }
139  }
140 
141  auto out = g->run(_x);
142  if (!out.empty())
143  return out.front();
144  else
145  return std::vector<float>();
146 }
147 
148 // ------------------------------------------------------
149 // --------------------PointIdAlg------------------------
150 // ------------------------------------------------------
151 
153  : img::DataProviderAlg(config)
154  , fNNet(0)
155  , fPatchSizeW(config.PatchSizeW())
156  , fPatchSizeD(config.PatchSizeD())
157  , fCurrentWireIdx(99999)
158  , fCurrentScaledDrift(99999)
159 {
161  fNNetOutputs = config.NNetOutputs();
162 
163  deleteNNet();
164 
165  if ((fNNetModelFilePath.length() > 5) &&
166  (fNNetModelFilePath.compare(fNNetModelFilePath.length() - 5, 5, ".nnet") == 0)) {
168  }
169  else if ((fNNetModelFilePath.length() > 3) &&
170  (fNNetModelFilePath.compare(fNNetModelFilePath.length() - 3, 3, ".pb") == 0)) {
172  }
173  else {
174  mf::LogError("PointIdAlg") << "File name extension not supported.";
175  }
176 
177  if (!fNNet) { throw cet::exception("nnet::PointIdAlg") << "Loading model from file failed."; }
178 
179  resizePatch();
180 }
181 // ------------------------------------------------------
182 
184 {
185  deleteNNet();
186 }
187 // ------------------------------------------------------
188 
189 void
191 {
193  for (auto& r : fWireDriftPatch)
194  r.resize(fPatchSizeD);
195 }
196 // ------------------------------------------------------
197 
198 float
199 nnet::PointIdAlg::predictIdValue(unsigned int wire, float drift, size_t outIdx) const
200 {
201  float result = 0.;
202 
203  if (!bufferPatch(wire, drift)) {
204  mf::LogError("PointIdAlg") << "Patch buffering failed.";
205  return result;
206  }
207 
208  if (fNNet) {
209  auto out = fNNet->Run(fWireDriftPatch);
210  if (!out.empty()) { result = out[outIdx]; }
211  else {
212  mf::LogError("PointIdAlg") << "Problem with applying model to input.";
213  }
214  }
215 
216  return result;
217 }
218 // ------------------------------------------------------
219 
220 std::vector<float>
221 nnet::PointIdAlg::predictIdVector(unsigned int wire, float drift) const
222 {
223  std::vector<float> result;
224 
225  if (!bufferPatch(wire, drift)) {
226  mf::LogError("PointIdAlg") << "Patch buffering failed.";
227  return result;
228  }
229 
230  if (fNNet) {
231  result = fNNet->Run(fWireDriftPatch);
232  if (result.empty()) { mf::LogError("PointIdAlg") << "Problem with applying model to input."; }
233  }
234 
235  return result;
236 }
237 // ------------------------------------------------------
238 
239 std::vector<std::vector<float>>
240 nnet::PointIdAlg::predictIdVectors(std::vector<std::pair<unsigned int, float>> points) const
241 {
242  if (points.empty() || !fNNet) { return std::vector<std::vector<float>>(); }
243 
244  std::vector<std::vector<std::vector<float>>> inps(
245  points.size(), std::vector<std::vector<float>>(fPatchSizeW, std::vector<float>(fPatchSizeD)));
246  for (size_t i = 0; i < points.size(); ++i) {
247  unsigned int wire = points[i].first;
248  float drift = points[i].second;
249  if (!bufferPatch(wire, drift, inps[i])) {
250  throw cet::exception("PointIdAlg") << "Patch buffering failed" << std::endl;
251  }
252  }
253 
254  return fNNet->Run(inps);
255 }
256 // ------------------------------------------------------
257 
258 bool
259 nnet::PointIdAlg::isSamePatch(unsigned int wire1,
260  float drift1,
261  unsigned int wire2,
262  float drift2) const
263 {
264  if (fDownscaleFullView) {
265  size_t sd1 = (size_t)(drift1 / fDriftWindow);
266  size_t sd2 = (size_t)(drift2 / fDriftWindow);
267  if ((wire1 == wire2) && (sd1 == sd2)) return true; // the same position
268  }
269  else {
270  if ((wire1 == wire2) && ((size_t)drift1 == (size_t)drift2)) return true; // the same position
271  }
272 
273  return false; // not the same position
274 }
275 
276 bool
277 nnet::PointIdAlg::isCurrentPatch(unsigned int wire, float drift) const
278 {
279  if (fDownscaleFullView) {
280  size_t sd = (size_t)(drift / fDriftWindow);
281  if ((fCurrentWireIdx == wire) && (fCurrentScaledDrift == sd))
282  return true; // still within the current position
283  }
284  else {
285  if ((fCurrentWireIdx == wire) && (fCurrentScaledDrift == drift))
286  return true; // still within the current position
287  }
288 
289  return false; // not a current position
290 }
291 // ------------------------------------------------------
292 
293 std::vector<float>
295 {
296  std::vector<float> flat;
297  if (patch.empty() || patch.front().empty()) {
298  mf::LogError("DataProviderAlg") << "Patch is empty.";
299  return flat;
300  }
301 
302  flat.resize(patch.size() * patch.front().size());
303 
304  for (size_t w = 0, i = 0; w < patch.size(); ++w) {
305  auto const& wire = patch[w];
306  for (size_t d = 0; d < wire.size(); ++d, ++i) {
307  flat[i] = wire[d];
308  }
309  }
310 
311  return flat;
312 }
313 // ------------------------------------------------------
314 
315 bool
316 nnet::PointIdAlg::isInsideFiducialRegion(unsigned int wire, float drift) const
317 {
318  size_t marginW = fPatchSizeW / 8; // fPatchSizeX/2 will make patch always completely filled
319  size_t marginD = fPatchSizeD / 8;
320 
321  size_t scaledDrift = (size_t)(drift / fDriftWindow);
322  if ((wire >= marginW) && (wire < fAlgView.fNWires - marginW) && (scaledDrift >= marginD) &&
323  (scaledDrift < fAlgView.fNScaledDrifts - marginD))
324  return true;
325  else
326  return false;
327 }
328 // ------------------------------------------------------
329 
330 // ------------------------------------------------------
331 // ------------------TrainingDataAlg---------------------
332 // ------------------------------------------------------
333 
335  : img::DataProviderAlg(config)
336  , fEdepTot(0)
337  , fWireProducerLabel(config.WireLabel())
338  , fHitProducerLabel(config.HitLabel())
339  , fTrackModuleLabel(config.TrackLabel())
340  , fSimulationProducerLabel(config.SimulationLabel())
341  , fSimChannelProducerLabel(config.SimChannelLabel())
342  , fSaveVtxFlags(config.SaveVtxFlags())
343  , fAdcDelay(config.AdcDelayTicks())
344  , fEventsPerBin(100, 0)
345 {
346  // If no sim channel producer is set then make it the same as the simulation label
347  if(fSimChannelProducerLabel.label().empty())
349 
351 }
352 // ------------------------------------------------------
353 
355 // ------------------------------------------------------
356 
359  detinfo::DetectorPropertiesData const& det_prop,
360  size_t wires,
361  size_t drifts)
362 {
363  auto view = img::DataProviderAlg::resizeView(clock_data, det_prop, wires, drifts);
364 
365  fWireDriftEdep.resize(wires);
366  for (auto& w : fWireDriftEdep) {
367  w.resize(view.fNCachedDrifts);
368  std::fill(w.begin(), w.end(), 0.0F);
369  }
370 
371  fWireDriftPdg.resize(wires);
372  for (auto& w : fWireDriftPdg) {
373  w.resize(view.fNCachedDrifts);
374  std::fill(w.begin(), w.end(), 0);
375  }
376  return view;
377 }
378 // ------------------------------------------------------
379 
380 bool
381 nnet::TrainingDataAlg::setWireEdepsAndLabels(std::vector<float> const& edeps,
382  std::vector<int> const& pdgs,
383  size_t wireIdx)
384 {
385  if ((wireIdx >= fWireDriftEdep.size()) || (edeps.size() != pdgs.size())) { return false; }
386 
387  size_t dstep = 1;
388  if (fDownscaleFullView) { dstep = fDriftWindow; }
389 
390  if (edeps.size() / dstep > fAlgView.fNCachedDrifts) { return false; }
391 
392  auto& wEdep = fWireDriftEdep[wireIdx];
393  auto& wPdg = fWireDriftPdg[wireIdx];
394 
395  for (size_t i = 0; i < fAlgView.fNCachedDrifts; ++i) {
396  size_t i0 = i * dstep;
397  size_t i1 = (i + 1) * dstep;
398 
399  int best_pdg = pdgs[i0] & nnet::TrainingDataAlg::kPdgMask;
400  int vtx_flags = pdgs[i0] & nnet::TrainingDataAlg::kVtxMask;
401  int type_flags = pdgs[i0] & nnet::TrainingDataAlg::kTypeMask;
402  float max_edep = edeps[i0];
403  for (size_t k = i0 + 1; k < i1; ++k) {
404  float ek = edeps[k];
405  if (ek > max_edep) {
406  max_edep = ek;
407  best_pdg = pdgs[k] & nnet::TrainingDataAlg::kPdgMask; // remember best matching pdg
408  }
409  type_flags |= pdgs[k] & nnet::TrainingDataAlg::kTypeMask; // accumulate track type flags
410  vtx_flags |= pdgs[k] & nnet::TrainingDataAlg::kVtxMask; // accumulate all vtx flags
411  }
412 
413  wEdep[i] = max_edep;
414 
415  best_pdg |= type_flags;
416  if (fSaveVtxFlags) best_pdg |= vtx_flags;
417  wPdg[i] = best_pdg;
418  }
419 
420  return true;
421 }
422 // ------------------------------------------------------
423 
426  detinfo::DetectorPropertiesData const& detProp,
427  const TLorentzVector& tvec,
428  unsigned int plane) const
429 {
431  wd.Wire = 0;
432  wd.Drift = 0;
433  wd.TPC = -1;
434  wd.Cryo = -1;
435 
436  try {
437  double vtx[3] = {tvec.X(), tvec.Y(), tvec.Z()};
438  if (fGeometry->FindTPCAtPosition(vtx).isValid) {
439  geo::TPCID tpcid = fGeometry->FindTPCAtPosition(vtx);
440  unsigned int tpc = tpcid.TPC, cryo = tpcid.Cryostat;
441 
442  // correct for the time offset
443  float dx = tvec.T() * 1.e-3 * detProp.DriftVelocity();
444  int driftDir = fGeometry->TPC(tpcid).DetectDriftDirection();
445  if (driftDir == 1) { dx *= -1; }
446  else if (driftDir != -1) {
447  throw cet::exception("nnet::TrainingDataAlg") << "drift direction is not X." << std::endl;
448  }
449  vtx[0] = tvec.X() + dx;
450 
451  wd.Wire = fGeometry->NearestWire(vtx, plane, tpc, cryo);
452  wd.Drift = detProp.ConvertXToTicks(vtx[0], plane, tpc, cryo);
453  wd.TPC = tpc;
454  wd.Cryo = cryo;
455  }
456  }
457  catch (const geo::InvalidWireIDError& e) {
458  mf::LogWarning("TrainingDataAlg")
459  << "Vertex projection out of wire planes, just skipping this vertex.";
460  }
461  catch (...) {
462  mf::LogWarning("TrainingDataAlg") << "Vertex projection out of wire planes, skip MC vertex.";
463  }
464  return wd;
465 }
466 // ------------------------------------------------------
467 
468 bool
470  const simb::MCParticle& particle,
471  const std::unordered_map<int, const simb::MCParticle*>& particleMap) const
472 {
473  const float minElectronLength2 = 2.5 * 2.5;
474  const float maxDeltaLength2 = 0.15 * 0.15;
475 
476  int pdg = abs(particle.PdgCode());
477  if (pdg != 11) return false; // should be applied only to electrons
478 
479  size_t nSec = particle.NumberDaughters();
480  for (size_t d = 0; d < nSec; ++d) {
481  auto d_search = particleMap.find(particle.Daughter(d));
482  if (d_search != particleMap.end()) {
483  auto const& daughter = *((*d_search).second);
484  int d_pdg = abs(daughter.PdgCode());
485  if (d_pdg != 22) { return false; } // not the end of the shower
486  }
487  }
488 
489  float trkLength2 = 0;
490  auto const* p = &particle;
491  bool branching = false;
492  while (!branching) {
493  trkLength2 += particleRange2(*p);
494  auto m_search = particleMap.find(p->Mother());
495  if (m_search != particleMap.end()) {
496  p = (*m_search).second;
497  int m_pdg = abs(p->PdgCode());
498  if (m_pdg == 11) {
499  nSec = p->NumberDaughters();
500  size_t ne = 0;
501  for (size_t d = 0; d < nSec; ++d) {
502  auto d_search = particleMap.find(p->Daughter(d));
503  if (d_search != particleMap.end()) {
504  auto const& daughter = *((*d_search).second);
505  int d_pdg = abs(daughter.PdgCode());
506  if (d_pdg == 11) {
507  if (particleRange2(daughter) > maxDeltaLength2) { ne++; }
508  }
509  }
510  }
511  if (ne > 1) { branching = true; }
512  }
513  else
514  break;
515  }
516  else
517  break;
518  }
519 
520  return (trkLength2 > minElectronLength2);
521 }
522 
523 bool
525  const simb::MCParticle& particle,
526  const std::unordered_map<int, const simb::MCParticle*>& particleMap) const
527 {
528  bool hasElectron = false, hasNuMu = false, hasNuE = false;
529 
530  int pdg = abs(particle.PdgCode());
531  //if ((pdg == 13) && (particle.EndProcess() == "FastScintillation" || particle.EndProcess() == "Decay" || particle.EndProcess() == "muMinusCaptureAtRest")) // potential muon decay at rest
532  if ((pdg == 13) && (particle.EndProcess() == "FastScintillation" || particle.EndProcess() == "Decay")) // potential muon decay at rest
533  {
534  unsigned int nSec = particle.NumberDaughters();
535  for (size_t d = 0; d < nSec; ++d) {
536  auto d_search = particleMap.find(particle.Daughter(d));
537  if (d_search != particleMap.end()) {
538  auto const& daughter = *((*d_search).second);
539  int d_pdg = abs(daughter.PdgCode());
540  if (d_pdg == 11)
541  hasElectron = true;
542  else if (d_pdg == 14)
543  hasNuMu = true;
544  else if (d_pdg == 12)
545  hasNuE = true;
546  }
547  }
548  }
549 
550  return (hasElectron && hasNuMu && hasNuE);
551 }
552 
553 void
555  std::unordered_map<size_t, std::unordered_map<int, int>>& wireToDriftToVtxFlags,
556  detinfo::DetectorClocksData const& clockData,
557  detinfo::DetectorPropertiesData const& detProp,
558  const std::unordered_map<int, const simb::MCParticle*>& particleMap,
559  unsigned int plane) const
560 {
561  for (auto const& p : particleMap) {
562  auto const& particle = *p.second;
563 
564  double ekStart = 1000. * (particle.E() - particle.Mass());
565  double ekEnd = 1000. * (particle.EndE() - particle.Mass());
566  int pdg = abs(particle.PdgCode());
567  int flagsStart = nnet::TrainingDataAlg::kNone;
568  int flagsEnd = nnet::TrainingDataAlg::kNone;
569 
570  switch (pdg) {
571  case 22: // gamma
572  if ((particle.EndProcess() == "conv") && (ekStart > 40.0)) // conversion, gamma > 40MeV
573  {
574  flagsEnd = nnet::TrainingDataAlg::kConv;
575  }
576  break;
577 
578  case 11: // e+/-
579  if (isElectronEnd(particle, particleMap)) { flagsEnd = nnet::TrainingDataAlg::kElectronEnd; }
580  break;
581 
582  case 13: // mu+/-
583  if (isMuonDecaying(particle, particleMap)) { flagsEnd = nnet::TrainingDataAlg::kDecay; }
584  break;
585 
586  case 111: // pi0
587  flagsStart = nnet::TrainingDataAlg::kPi0;
588  break;
589 
590  case 321: // K+/-
591  case 211: // pi+/-
592  case 2212: // proton
593  if (ekStart > 50.0) {
594  if (particle.Mother() != 0) {
595  auto search = particleMap.find(particle.Mother());
596  if (search != particleMap.end()) {
597  auto const& mother = *((*search).second);
598  int m_pdg = abs(mother.PdgCode());
599  unsigned int nSec = mother.NumberDaughters();
600  unsigned int nVisible = 0;
601  if (nSec > 1) {
602  for (size_t d = 0; d < nSec; ++d) {
603  auto d_search = particleMap.find(mother.Daughter(d));
604  if (d_search != particleMap.end()) {
605  auto const& daughter = *((*d_search).second);
606  int d_pdg = abs(daughter.PdgCode());
607  if (((d_pdg == 2212) || (d_pdg == 211) || (d_pdg == 321)) &&
608  (1000. * (daughter.E() - daughter.Mass()) > 50.0)) {
609  ++nVisible;
610  }
611  }
612  }
613  }
614  // hadron with Ek > 50MeV (so well visible) and
615  // produced by another hadron (but not neutron, so not single track from nothing) or
616  // at least secondary hadrons with Ek > 50MeV (so this is a good kink or V-like)
617  if (((m_pdg != pdg) && (m_pdg != 2112)) || ((m_pdg != 2112) && (nVisible > 0)) ||
618  ((m_pdg == 2112) && (nVisible > 1))) {
619  flagsStart = nnet::TrainingDataAlg::kHadr;
620  }
621  }
622  }
623 
624  if (particle.EndProcess() == "FastScintillation") // potential decay at rest
625  {
626  unsigned int nSec = particle.NumberDaughters();
627  for (size_t d = 0; d < nSec; ++d) {
628  auto d_search = particleMap.find(particle.Daughter(d));
629  if (d_search != particleMap.end()) {
630  auto const& daughter = *((*d_search).second);
631  int d_pdg = abs(daughter.PdgCode());
632  if ((pdg == 321) && (d_pdg == 13)) {
634  break;
635  }
636  if ((pdg == 211) && (d_pdg == 13)) {
638  break;
639  }
640  }
641  }
642  }
643 
644  if ((particle.EndProcess() == "Decay") && (ekEnd > 200.0)) // decay in flight
645  {
646  unsigned int nSec = particle.NumberDaughters();
647  for (size_t d = 0; d < nSec; ++d) {
648  auto d_search = particleMap.find(particle.Daughter(d));
649  if (d_search != particleMap.end()) {
650  auto const& daughter = *((*d_search).second);
651  int d_pdg = abs(daughter.PdgCode());
652  if ((pdg == 321) && (d_pdg == 13)) {
653  flagsEnd = nnet::TrainingDataAlg::kHadr;
654  break;
655  }
656  if ((pdg == 211) && (d_pdg == 13)) {
657  flagsEnd = nnet::TrainingDataAlg::kHadr;
658  break;
659  }
660  }
661  }
662  }
663  }
664  break;
665 
666  default: continue;
667  }
668 
669  if (particle.Process() == "primary") { flagsStart |= nnet::TrainingDataAlg::kNuPri; }
670 
671  if (flagsStart != nnet::TrainingDataAlg::kNone) {
672  auto wd = getProjection(clockData, detProp, particle.Position(), plane);
673 
674  if ((wd.TPC == TPC()) && (wd.Cryo == Cryo())) {
675  wireToDriftToVtxFlags[wd.Wire][wd.Drift] |= flagsStart;
676  }
677  }
678  if (flagsEnd != nnet::TrainingDataAlg::kNone) {
679  auto wd = getProjection(clockData, detProp, particle.EndPosition(), plane);
680  if ((wd.TPC == TPC()) && (wd.Cryo == Cryo())) {
681  wireToDriftToVtxFlags[wd.Wire][wd.Drift] |= flagsEnd;
682  }
683  }
684 
685  //TY: check elastic/inelastic scattering
686  if (pdg == 321 || pdg == 211 || pdg == 2212) {
687  simb::MCTrajectory truetraj = particle.Trajectory();
688  auto thisTrajectoryProcessMap1 = truetraj.TrajectoryProcesses();
689  if (thisTrajectoryProcessMap1.size()) {
690  for (auto const& couple1 : thisTrajectoryProcessMap1) {
691  if ((truetraj.KeyToProcess(couple1.second)).find("Elastic") != std::string::npos) {
692  auto wd = getProjection(clockData, detProp, truetraj.at(couple1.first).first, plane);
693  if ((wd.TPC == TPC()) && (wd.Cryo == Cryo())) {
694  wireToDriftToVtxFlags[wd.Wire][wd.Drift] |= nnet::TrainingDataAlg::kElastic;
695  }
696  }
697  if ((truetraj.KeyToProcess(couple1.second)).find("Inelastic") != std::string::npos) {
698  auto wd = getProjection(clockData, detProp, truetraj.at(couple1.first).first, plane);
699  if ((wd.TPC == TPC()) && (wd.Cryo == Cryo())) {
700  wireToDriftToVtxFlags[wd.Wire][wd.Drift] |= nnet::TrainingDataAlg::kInelastic;
701  }
702  }
703  }
704  }
705  }
706  }
707 }
708 // ------------------------------------------------------
709 
710 bool
712  detinfo::DetectorClocksData const& clockData,
713  detinfo::DetectorPropertiesData const& detProp,
714  unsigned int plane,
715  unsigned int tpc,
716  unsigned int cryo)
717 {
718 
720  std::vector<art::Ptr<recob::Wire>> Wirelist;
721 
722  if (event.getByLabel(fWireProducerLabel, wireHandle)) art::fill_ptr_vector(Wirelist, wireHandle);
723 
724  if (!setWireDriftData(clockData, detProp, *wireHandle, plane, tpc, cryo)) {
725  mf::LogError("TrainingDataAlg") << "Wire data not set.";
726  return false;
727  }
728 
729  // Hit info
731  std::vector<art::Ptr<recob::Hit>> Hitlist;
732 
733  if (event.getByLabel(fHitProducerLabel, HitHandle)) art::fill_ptr_vector(Hitlist, HitHandle);
734 
735  // Track info
737  std::vector<art::Ptr<recob::Track>> Tracklist;
738 
739  if (event.getByLabel(fTrackModuleLabel, TrackHandle))
740  art::fill_ptr_vector(Tracklist, TrackHandle);
741 
742  art::FindManyP<recob::Track> ass_trk_hits(HitHandle, event, fTrackModuleLabel);
743 
744  // Loop over wires (sorry about hard coded value) to fill in 1) pdg and 2) charge depo
745  for (size_t widx = 0; widx < 240; ++widx) {
746 
747  std::vector<float> labels_deposit(fAlgView.fNDrifts, 0); // full-drift-length buffers
748  std::vector<int> labels_pdg(fAlgView.fNDrifts, 0);
749 
750  // First, the charge depo
751  for (size_t subwidx = 0; subwidx < Wirelist.size(); ++subwidx) {
752  if (widx + 240 == Wirelist[subwidx]->Channel()) {
753  labels_deposit = Wirelist[subwidx]->Signal();
754  break;
755  }
756  }
757 
758  // Second, the pdg code
759  // This code finds the angle of the track and records
760  // events based on its angle to try to get an isometric sample
761  // instead of just a bunch of straight tracks
762 
763  // Meta code:
764  // For each hit:
765  // find farthest hit from point
766  // then find farthest hit from THAT one
767  // should be start and end of track, then just use trig
768 
769  for (size_t iHit = 0; iHit < Hitlist.size(); ++iHit) {
770 
771  if (Hitlist[iHit]->Channel() != widx + 240) { continue; }
772  if (Hitlist[iHit]->View() != 1) { continue; }
773 
774  // Make sure there is a track association
775  if (ass_trk_hits.at(iHit).size() == 0) { continue; }
776 
777  // Not sure about this
778  // Cutting on length to not just get a bunch of shower stubs
779  // Might add a lot of bias though
780  if (ass_trk_hits.at(iHit)[0]->Length() < 5) { continue; }
781 
782  // Search for farest hit from this one
783  int far_index = 0;
784  double far_dist = 0;
785 
786  for (size_t jHit = 0; jHit < Hitlist.size(); ++jHit) {
787  if (jHit == iHit) { continue; }
788  if (Hitlist[jHit]->View() != 1) { continue; }
789 
790  if (ass_trk_hits.at(jHit).size() == 0) { continue; }
791  if (ass_trk_hits.at(jHit)[0]->ID() != ass_trk_hits.at(iHit)[0]->ID()) { continue; }
792 
793  double dist = sqrt((Hitlist[iHit]->Channel() - Hitlist[jHit]->Channel()) *
794  (Hitlist[iHit]->Channel() - Hitlist[jHit]->Channel()) +
795  (Hitlist[iHit]->PeakTime() - Hitlist[jHit]->PeakTime()) *
796  (Hitlist[iHit]->PeakTime() - Hitlist[jHit]->PeakTime()));
797 
798  if (far_dist < dist) {
799  far_dist = dist;
800  far_index = jHit;
801  }
802  }
803 
804  // Search for the other end of the track
805  int other_end = 0;
806  int other_dist = 0;
807 
808  for (size_t jHit = 0; jHit < Hitlist.size(); ++jHit) {
809  if (jHit == iHit or int(jHit) == far_index) { continue; }
810  if (Hitlist[jHit]->View() != 1) { continue; }
811 
812  if (ass_trk_hits.at(jHit).size() == 0) { continue; }
813  if (ass_trk_hits.at(jHit)[0]->ID() != ass_trk_hits.at(iHit)[0]->ID()) { continue; }
814 
815  double dist = sqrt((Hitlist[far_index]->Channel() - Hitlist[jHit]->Channel()) *
816  (Hitlist[far_index]->Channel() - Hitlist[jHit]->Channel()) +
817  (Hitlist[far_index]->PeakTime() - Hitlist[jHit]->PeakTime()) *
818  (Hitlist[far_index]->PeakTime() - Hitlist[jHit]->PeakTime()));
819 
820  if (other_dist < dist) {
821  other_dist = dist;
822  other_end = jHit;
823  }
824  }
825 
826  // We have the end points now
827  double del_wire = double(Hitlist[other_end]->Channel() - Hitlist[far_index]->Channel());
828  double del_time = double(Hitlist[other_end]->PeakTime() - Hitlist[far_index]->PeakTime());
829  double hypo = sqrt(del_wire * del_wire + del_time * del_time);
830 
831  if (hypo == 0) { continue; } // Should never happen, but doing it anyway
832 
833  double cosser = TMath::Abs(del_wire / hypo);
834  double norm_ang = TMath::ACos(cosser) * 2 / TMath::Pi();
835 
836  // Using fEventsPerBin to keep track of number of hits per angle (normalized to 0 to 1)
837 
838  int binner = int(norm_ang * fEventsPerBin.size());
839  if (binner >= (int)fEventsPerBin.size()) {
840  binner = fEventsPerBin.size() - 1;
841  } // Dealing with rounding errors
842 
843  // So we should get a total of 5000 * 100 = 50,000 if we use the whole set
844  if (fEventsPerBin[binner] > 5000) { continue; }
845  fEventsPerBin[binner]++;
846 
847  // If survives everything, saves the pdg
848  labels_pdg[Hitlist[iHit]->PeakTime()] = 211; // Same as pion for now
849  }
850 
851  setWireEdepsAndLabels(labels_deposit, labels_pdg, widx);
852 
853  } // for each Wire
854 
855  return true;
856 }
857 
858 bool
860  detinfo::DetectorClocksData const& clockData,
861  detinfo::DetectorPropertiesData const& detProp,
862  unsigned int plane,
863  unsigned int tpc,
864  unsigned int cryo)
865 {
867  event.getValidHandle<std::vector<recob::Wire>>(fWireProducerLabel);
868 
869  if (!setWireDriftData(clockData, detProp, *wireHandle, plane, tpc, cryo)) {
870  mf::LogError("TrainingDataAlg") << "Wire data not set.";
871  return false;
872  }
873 
874  if (!fSaveSimInfo || event.isRealData()) {
875  mf::LogInfo("TrainingDataAlg") << "Skip MC simulation info.";
876  return true;
877  }
878 
880  double electronsToGeV = 1. / larParameters->GeVToElectrons();
881 
882  auto particleHandle =
883  event.getValidHandle<std::vector<simb::MCParticle>>(fSimulationProducerLabel);
884 
885  auto simChannelHandle =
886  event.getValidHandle<std::vector<sim::SimChannel>>(fSimChannelProducerLabel);
887 
888  std::unordered_map<int, const simb::MCParticle*> particleMap;
889  for (auto const& particle : *particleHandle) {
890  particleMap[particle.TrackId()] = &particle;
891  }
892 
893  std::unordered_map<size_t, std::unordered_map<int, int>> wireToDriftToVtxFlags;
894  if (fSaveVtxFlags) collectVtxFlags(wireToDriftToVtxFlags, clockData, detProp, particleMap, plane);
895 
896  fEdepTot = 0;
897 
898  std::map<int, int> trackToPDG;
899  for (size_t widx = 0; widx < fAlgView.fNWires; ++widx) {
900  auto wireChannelNumber = fAlgView.fWireChannels[widx];
901  if (wireChannelNumber == raw::InvalidChannelID) continue;
902 
903  std::vector<float> labels_deposit(fAlgView.fNDrifts, 0); // full-drift-length buffers,
904  std::vector<int> labels_pdg(labels_deposit.size(), 0); // both of the same size,
905  int labels_size = labels_deposit.size(); // cached as int for comparisons below
906 
907  std::map<int, std::map<int, double>> timeToTrackToCharge;
908  for (auto const& channel : *simChannelHandle) {
909  if (channel.Channel() != wireChannelNumber) continue;
910 
911  auto const& timeSlices = channel.TDCIDEMap();
912  for (auto const& timeSlice : timeSlices) {
913  int time = timeSlice.first;
914 
915  auto const& energyDeposits = timeSlice.second;
916  for (auto const& energyDeposit : energyDeposits) {
917  int pdg = 0;
918  int tid = energyDeposit.trackID;
919  if (tid < 0) // negative tid means it is EM activity, and -tid is the mother
920  {
921  pdg = 11;
922  tid = -tid;
923 
924  auto search = particleMap.find(tid);
925  if (search == particleMap.end()) {
926  mf::LogWarning("TrainingDataAlg") << "PARTICLE NOT FOUND";
927  continue;
928  }
929  auto const& mother = *((*search).second); // mother particle of this EM
930  int mPdg = abs(mother.PdgCode());
931  if ((mPdg == 13) || (mPdg == 211) || (mPdg == 2212)) {
932  if (energyDeposit.numElectrons > 10)
933  pdg |= nnet::TrainingDataAlg::kDelta; // tag delta ray
934  }
935  }
936  else {
937  auto search = particleMap.find(tid);
938  if (search == particleMap.end()) {
939  mf::LogWarning("TrainingDataAlg") << "PARTICLE NOT FOUND";
940  continue;
941  }
942  auto const& particle = *((*search).second);
943  pdg = abs(particle.PdgCode());
944 
945  if (particle.Process() == "primary") {
946  if (pdg == 11) {
947  pdg |= nnet::TrainingDataAlg::kPriEl; // tag primary
948  }
949  else if (pdg == 13) {
950  pdg |= nnet::TrainingDataAlg::kPriMu; // tag primary
951  }
952  }
953 
954  /*
955  auto msearch = particleMap.find(particle.Mother());
956  if (msearch != particleMap.end()) {
957  auto const& mother = *((*msearch).second);
958  if (pdg == 11) // electron, check if it is Michel
959  {
960  if (nnet::TrainingDataAlg::isMuonDecaying(mother, particleMap)) {
961  std::cout<<particle.Process()<<std::endl;
962  pdg |= nnet::TrainingDataAlg::kMichel; // tag Michel
963  }
964  }
965  }
966  */
967  if (pdg == 11){ // electron, check if it is Michel or delta ray
968  if (particle.Process() == "Decay"){
969  pdg |= nnet::TrainingDataAlg::kMichel; // tag Michel
970  }
971  else if (particle.Process() == "muIoni"){
972  pdg |= nnet::TrainingDataAlg::kDelta; // tag delta ray
973  }
974  }
975  }
976 
977  trackToPDG[energyDeposit.trackID] = pdg;
978 
979  double energy = energyDeposit.numElectrons * electronsToGeV;
980  timeToTrackToCharge[time][energyDeposit.trackID] += energy;
981  fEdepTot += energy;
982 
983  } // loop over energy deposits
984  } // loop over time slices
985  } // for each SimChannel
986 
988  for (auto const& ttc : timeToTrackToCharge) {
989  float max_deposit = 0.0;
990  int max_pdg = 0;
991  for (auto const& tc : ttc.second) {
992 
993  if (tc.second > max_deposit) {
994  max_deposit = tc.second;
995  max_pdg = trackToPDG[tc.first];
996  }
997  }
998 
999  if (ttc.first < labels_size) {
1000  int tick_idx = ttc.first + fAdcDelay;
1001  if (tick_idx < labels_size) {
1002  labels_deposit[tick_idx] = max_deposit;
1003  labels_pdg[tick_idx] = max_pdg & type_pdg_mask;
1004  }
1005  }
1006  }
1007 
1008  for (auto const& drift_flags : wireToDriftToVtxFlags[widx]) {
1009  int drift = drift_flags.first, flags = drift_flags.second;
1010  if ((drift >= 0) && (drift < labels_size)) { labels_pdg[drift] |= flags; }
1011  }
1012  setWireEdepsAndLabels(labels_deposit, labels_pdg, widx);
1013  } // for each Wire
1014 
1015  return true;
1016 }
1017 // ------------------------------------------------------
1018 
1019 bool
1021  unsigned int& w0,
1022  unsigned int& w1,
1023  unsigned int& d0,
1024  unsigned int& d1) const
1025 {
1026  if (fWireDriftEdep.empty() || fWireDriftEdep.front().empty()) return false;
1027 
1028  float max_cut = 0.25 * max_e_cut;
1029 
1030  w0 = 0;
1031  float cut = 0;
1032  while (w0 < fWireDriftEdep.size()) {
1033  for (auto const d : fWireDriftEdep[w0])
1034  cut += d;
1035  if (cut < max_cut)
1036  w0++;
1037  else
1038  break;
1039  }
1040  w1 = fWireDriftEdep.size() - 1;
1041  cut = 0;
1042  while (w1 > w0) {
1043  for (auto const d : fWireDriftEdep[w1])
1044  cut += d;
1045  if (cut < max_cut)
1046  w1--;
1047  else
1048  break;
1049  }
1050  w1++;
1051 
1052  d0 = 0;
1053  cut = 0;
1054  while (d0 < fWireDriftEdep.front().size()) {
1055  for (size_t i = w0; i < w1; ++i)
1056  cut += fWireDriftEdep[i][d0];
1057  if (cut < max_cut)
1058  d0++;
1059  else
1060  break;
1061  }
1062  d1 = fWireDriftEdep.front().size() - 1;
1063  cut = 0;
1064  while (d1 > d0) {
1065  for (size_t i = w0; i < w1; ++i)
1066  cut += fWireDriftEdep[i][d1];
1067  if (cut < max_cut)
1068  d1--;
1069  else
1070  break;
1071  }
1072  d1++;
1073 
1074  unsigned int margin = 20;
1075  if ((w1 - w0 > 8) && (d1 - d0 > 8)) {
1076  if (w0 < margin)
1077  w0 = 0;
1078  else
1079  w0 -= margin;
1080 
1081  if (w1 > fWireDriftEdep.size() - margin)
1082  w1 = fWireDriftEdep.size();
1083  else
1084  w1 += margin;
1085 
1086  if (d0 < margin)
1087  d0 = 0;
1088  else
1089  d0 -= margin;
1090 
1091  if (d1 > fWireDriftEdep.front().size() - margin)
1092  d1 = fWireDriftEdep.front().size();
1093  else
1094  d1 += margin;
1095 
1096  return true;
1097  }
1098  else
1099  return false;
1100 }
1101 // ------------------------------------------------------
bool isInsideFiducialRegion(unsigned int wire, float drift) const
Definition: PointIdAlg.cxx:316
void collectVtxFlags(std::unordered_map< size_t, std::unordered_map< int, int >> &wireToDriftToVtxFlags, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const std::unordered_map< int, const simb::MCParticle * > &particleMap, unsigned int plane) const
Definition: PointIdAlg.cxx:554
Store parameters for running LArG4.
geo::GeometryCore const * fGeometry
int PdgCode() const
Definition: MCParticle.h:212
bool setWireEdepsAndLabels(std::vector< float > const &edeps, std::vector< int > const &pdgs, size_t wireIdx)
Definition: PointIdAlg.cxx:381
bool isMuonDecaying(const simb::MCParticle &particle, const std::unordered_map< int, const simb::MCParticle * > &particleMap) const
Definition: PointIdAlg.cxx:524
static constexpr double g
Definition: Units.h:144
static QCString result
std::vector< std::vector< float > > Run(std::vector< std::vector< std::vector< float >>> const &inps, int samples=-1) override
Definition: PointIdAlg.cxx:102
std::vector< std::vector< float > > fWireDriftPatch
Definition: PointIdAlg.h:153
bool setDataEventData(const art::Event &event, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: PointIdAlg.cxx:711
unsigned int fAdcDelay
Definition: PointIdAlg.h:365
AdcChannelData::View View
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
art::InputTag fTrackModuleLabel
Definition: PointIdAlg.h:359
virtual DataProviderAlgView resizeView(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, size_t wires, size_t drifts)
const value_type & at(const size_type i) const
Definition: MCTrajectory.h:175
bool setEventData(const art::Event &event, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, unsigned int plane, unsigned int tpc, unsigned int cryo)
Definition: PointIdAlg.cxx:859
bool bufferPatch(size_t wire, float drift, std::vector< std::vector< float >> &patch) const
Definition: PointIdAlg.h:158
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
std::string KeyToProcess(unsigned char const &key) const
struct vector vector
virtual void set_data(std::vector< std::vector< std::vector< float > > > const &)
Definition: keras_model.h:47
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
DataProviderAlg(const fhicl::ParameterSet &pset)
uint8_t channel
Definition: CRTFragment.hh:201
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
WireDrift getProjection(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TLorentzVector &tvec, unsigned int plane) const
Definition: PointIdAlg.cxx:425
std::vector< float > compute_output(keras::DataChunk *dc)
Definition: keras_model.cc:400
std::vector< std::string > fNNetOutputs
Definition: PointIdAlg.h:150
~PointIdAlg() override
Definition: PointIdAlg.cxx:183
bool isCurrentPatch(unsigned int wire, float drift) const
Definition: PointIdAlg.cxx:277
int NumberDaughters() const
Definition: MCParticle.h:217
int Daughter(const int i) const
Definition: MCParticle.cxx:112
art::InputTag fWireProducerLabel
Definition: PointIdAlg.h:357
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
bool isElectronEnd(const simb::MCParticle &particle, const std::unordered_map< int, const simb::MCParticle * > &particleMap) const
Definition: PointIdAlg.cxx:469
std::string const & label() const noexcept
Definition: InputTag.cc:79
bool isRealData() const
std::vector< float > predictIdVector(unsigned int wire, float drift) const
calculate multi-class probabilities for [wire, drift] point
Definition: PointIdAlg.cxx:221
T abs(T value)
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
constexpr ChannelID_t InvalidChannelID
ID of an invalid channel.
Definition: RawTypes.h:32
const double e
fileName
Definition: dumpTree.py:9
std::string EndProcess() const
Definition: MCParticle.h:216
fhicl::Sequence< std::string > NNetOutputs
Definition: PointIdAlg.h:96
Collection of exceptions for Geometry system.
static Config * config
Definition: config.cpp:1054
geo::WireID::WireID_t NearestWire(geo::Point_t const &point, geo::PlaneID const &planeid) const
Returns the index of wire closest to position in the specified TPC.
size_t size
Definition: lodepng.cpp:55
std::vector< raw::ChannelID_t > fWireChannels
virtual std::vector< float > Run(std::vector< std::vector< float >> const &inp2d)=0
std::vector< size_t > fEventsPerBin
Definition: PointIdAlg.h:367
p
Definition: test.py:223
double ConvertXToTicks(double X, int p, int t, int c) const
KerasModelInterface(const char *modelFileName)
Definition: PointIdAlg.cxx:67
art::InputTag fSimChannelProducerLabel
Definition: PointIdAlg.h:361
Definition: search.py:1
bool findCrop(float max_e_cut, unsigned int &w0, unsigned int &w1, unsigned int &d0, unsigned int &d1) const
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
size_t fPatchSizeD
Definition: PointIdAlg.h:154
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
std::vector< float > Run(std::vector< std::vector< float >> const &inp2d) override
Definition: PointIdAlg.cxx:75
ProcessMap const & TrajectoryProcesses() const
Definition: MCTrajectory.h:188
keras::KerasModel m
Definition: PointIdAlg.h:71
DataProviderAlgView fAlgView
static std::unique_ptr< Graph > create(const char *graph_file_name, const std::vector< std::string > &outputs={}, int ninputs=1, int noutputs=1)
Definition: tf_graph.h:32
std::vector< std::vector< int > > fWireDriftPdg
Definition: PointIdAlg.h:355
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
bool setWireDriftData(const detinfo::DetectorClocksData &clock_data, const detinfo::DetectorPropertiesData &det_prop, const std::vector< recob::Wire > &wires, unsigned int plane, unsigned int tpc, unsigned int cryo)
def fill(s)
Definition: translator.py:93
fhicl::Atom< std::string > NNetModelFile
Definition: PointIdAlg.h:94
~TrainingDataAlg() override
TfModelInterface(const char *modelFileName)
Definition: PointIdAlg.cxx:91
std::vector< std::vector< float > > fWireDriftEdep
Definition: PointIdAlg.h:354
Contains all timing reference information for the detector.
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
std::string findFile(const char *fileName) const
Definition: PointIdAlg.cxx:49
short int DetectDriftDirection() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.cxx:157
unsigned int Cryo() const
Pool sum of pixels in a patch around the wire/drift pixel.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
static float particleRange2(const simb::MCParticle &particle)
Definition: PointIdAlg.h:340
img::DataProviderAlgView resizeView(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, size_t wires, size_t drifts) override
Definition: PointIdAlg.cxx:358
size_t fCurrentScaledDrift
Definition: PointIdAlg.h:156
std::string find_file(std::string const &filename) const
Definition: search_path.cc:96
Interface for experiment-specific channel quality info provider.
nnet::ModelInterface * fNNet
Definition: PointIdAlg.h:151
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
size_t fPatchSizeW
Definition: PointIdAlg.h:154
Exception thrown on invalid wire number (e.g. NearestWireID())
Definition: Exceptions.h:158
art::InputTag fSimulationProducerLabel
Definition: PointIdAlg.h:360
std::string fNNetModelFilePath
Definition: PointIdAlg.h:149
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
Interface for experiment-specific service for channel quality info.
bool isSamePatch(unsigned int wire1, float drift1, unsigned int wire2, float drift2) const
test if two wire/drift coordinates point to the same patch
Definition: PointIdAlg.cxx:259
Interface to algorithm class for a specific detector channel mapping.
std::vector< std::vector< float > > predictIdVectors(std::vector< std::pair< unsigned int, float >> points) const
Definition: PointIdAlg.cxx:240
art::InputTag fHitProducerLabel
Definition: PointIdAlg.h:358
static QCString * s
Definition: config.cpp:1042
double GeVToElectrons() const
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
Event finding and building.
TrainingDataAlg(const fhicl::ParameterSet &pset)
Definition: PointIdAlg.h:254
size_t fCurrentWireIdx
Definition: PointIdAlg.h:156
unsigned int TPC() const
float predictIdValue(unsigned int wire, float drift, size_t outIdx=0) const
calculate single-value prediction (2-class probability) for [wire, drift] point
Definition: PointIdAlg.cxx:199
PointIdAlg(const fhicl::ParameterSet &pset)
Definition: PointIdAlg.h:104
static std::vector< float > flattenData2D(std::vector< std::vector< float >> const &patch)
Definition: PointIdAlg.cxx:294