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