DisambigFromSpacePoints_module.cc
Go to the documentation of this file.
1 #ifndef DISAMBIGFROMSP__CC
2 #define DISAMBIGFROMSP__CC
3 
4 ////////////////////////////////////////////////////////////////////////
5 //
6 // DisambigFromSpacePoints module
7 //
8 // R.Sulej
9 //
10 // Just look at SpacePoints created with SpacePointSolver and put hits
11 // in the right wires. Resolve hits undisambiguated by SpacePoints using
12 // assignments of neighboring hits.
13 //
14 ////////////////////////////////////////////////////////////////////////
15 
16 #include <string>
17 #include <vector>
18 #include <utility>
19 #include <memory>
20 #include <iostream>
21 
22 // Framework includes
27 #include "art_root_io/TFileService.h"
28 #include "fhiclcpp/types/Atom.h"
31 
32 // LArSoft Includes
40 
41 // ROOT includes
42 #include "TTree.h"
43 
44 namespace dune {
45  // these types to be replaced with use of feature proposed in redmine #12602
46  typedef std::map< unsigned int, std::vector< size_t > > plane_keymap;
47  typedef std::map< unsigned int, plane_keymap > tpc_plane_keymap;
48  typedef std::map< unsigned int, tpc_plane_keymap > cryo_tpc_plane_keymap;
49 
51  public:
52  struct Config {
53  using Name = fhicl::Name;
55 
56  fhicl::Atom<art::InputTag> HitModuleLabel { Name("HitModuleLabel"), Comment("HitPointSolver label.") };
57  fhicl::Atom<art::InputTag> SpModuleLabel { Name("SpModuleLabel"), Comment("SpacePointSolver label.") };
58  fhicl::Sequence<size_t> ExcludeTPCs { Name("ExcludeTPCs"), Comment("TPC inndexes where hits are not allowed.") };
59  fhicl::Atom<bool> UseNeighbors { Name("UseNeighbors"), Comment("Use neighboring hits to complete hits unresolved with spacepoints.") };
60  fhicl::Atom<size_t> NumNeighbors { Name("NumNeighbors"), Comment("Number of neighboring hits to complete hits unresolved with spacepoints.") };
61  fhicl::Atom<float> MaxDistance { Name("MaxDistance"), Comment("Distance [cm] used to complete hits unresolved with spacepoints.") };
62  fhicl::Atom<std::string> MoveLeftovers { Name("MoveLeftovers"), Comment("Mode of dealing with undisambiguated hits.") };
63  fhicl::Atom<bool> MonitoringPlots { Name("MonitoringPlots"), Comment("Create histograms of no. of unresolved hits at eacch stage, per plane.") };
64  };
66 
67  explicit DisambigFromSpacePoints(Parameters const& config);
68 
69  void produce(art::Event& evt);
70 
71  private:
72  int runOnSpacePoints(
73  const std::vector< art::Ptr<recob::Hit> > & eventHits,
74  const art::FindManyP< recob::SpacePoint > & spFromHit,
75  const std::unordered_map< size_t, size_t > & spToTPC,
76  std::unordered_map< size_t, geo::WireID > & assignments,
77  cryo_tpc_plane_keymap & indHits,
78  std::vector<size_t> & unassigned
79  );
80 
82  detinfo::DetectorPropertiesData const& detProp,
83  std::unordered_map< size_t, geo::WireID > & assignments,
84  const std::vector< art::Ptr<recob::Hit> > & eventHits,
85  cryo_tpc_plane_keymap & indHits,
86  std::vector<size_t> & unassigned,
87  size_t nNeighbors
88  );
89 
91  std::unordered_map< size_t, geo::WireID > & assignments,
92  const std::vector< art::Ptr<recob::Hit> > & eventHits,
93  const std::vector<size_t> & unassigned
94  ) const;
95 
97  std::unordered_map< size_t, std::vector<geo::WireID> > & assignments,
98  const std::vector< art::Ptr<recob::Hit> > & eventHits,
99  const std::vector<size_t> & unassigned
100  ) const;
101 
102 
104 
105  int fRun, fEvent;
106  int fNHits[3]; // n all hits in each plane
107  int fNMissedBySpacePoints[2]; // n hits unresolved by SpacePoints in induction planes
108  int fNMissedByNeighbors[2]; // n hits unresolved by using neighboring hits
109  TTree *fTree;
110 
111  const bool fMonitoringPlots;
112  const bool fUseNeighbors;
113  const size_t fNumNeighbors;
114  const float fMaxDistance;
116  const std::vector< size_t > fExcludeTPCs;
119  };
120 
122  EDProducer(config),
123  fTree(0),
124  fMonitoringPlots(config().MonitoringPlots()),
125  fUseNeighbors(config().UseNeighbors()),
126  fNumNeighbors(config().NumNeighbors()),
127  fMaxDistance(config().MaxDistance()),
128  fMoveLeftovers(config().MoveLeftovers()),
129  fExcludeTPCs(config().ExcludeTPCs()),
130  fHitModuleLabel(config().HitModuleLabel()),
131  fSpModuleLabel(config().SpModuleLabel())
132  {
133  if (fNumNeighbors < 1)
134  {
135  throw cet::exception("DisambigFromSpacePoints") << "NumNeighbors should be at least 1." << std::endl;
136  }
137 
138  // let HitCollectionCreator declare that we are going to produce
139  // hits and associations with wires and raw digits
140  // (with no particular product label)
142 
143  // will also copy associations of SpacePoints to original hits
144  produces<art::Assns<recob::Hit, recob::SpacePoint>>();
145 
147 
148  if (fMonitoringPlots)
149  {
151  fTree = tfs->make<TTree>("hitstats", "Unresolved hits statistics");
152  fTree->Branch("fRun", &fRun, "fRun/I");
153  fTree->Branch("fEvent", &fEvent, "fEvent/I");
154  fTree->Branch("fNHits", fNHits, "fNHits[3]/I");
155  fTree->Branch("fNMissedBySpacePoints", fNMissedBySpacePoints, "fNMissedBySpacePoints[2]/I");
156  fTree->Branch("fNMissedByNeighbors", fNMissedByNeighbors, "fNMissedByNeighbors[2]/I");
157  }
158  }
159 
161  {
162  fRun = evt.run();
163  fEvent = evt.id().event();
164 
165  auto hitsHandle = evt.getValidHandle< std::vector<recob::Hit> >(fHitModuleLabel);
166  auto spHandle = evt.getValidHandle< std::vector<recob::SpacePoint> >(fSpModuleLabel);
167 
168  // also get the associated wires and raw digits;
169  // we assume they have been created by the same module as the hits
170  //art::FindOneP<raw::RawDigit> channelHitRawDigits(hitsHandle, evt, fHitModuleLabel);
171  art::FindOneP<recob::Wire> channelHitWires (hitsHandle, evt, fHitModuleLabel);
172 
173  // this object contains the hit collection
174  // and its associations to wires and raw digits:
176  channelHitWires.isValid(), // doWireAssns
177  //channelHitRawDigits.isValid() // doRawDigitAssns
178  false // do not save raw digits
179  );
180 
181  // here is the copy of associations to hits, based on original hit assns
182  auto assns = std::make_unique<art::Assns<recob::Hit, recob::SpacePoint>>();
183 
184  // all hits in the collection
185  std::vector< art::Ptr<recob::Hit> > eventHits;
186  art::fill_ptr_vector(eventHits, hitsHandle);
187 
188  art::FindManyP< recob::SpacePoint > spFromHit(hitsHandle, evt, fSpModuleLabel);
189  art::FindManyP< recob::Hit > hitsFromSp(spHandle, evt, fSpModuleLabel);
190 
191  auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt);
192  // map induction spacepoints to TPC by collection hits
193  std::unordered_map< size_t, size_t > spToTPC;
194  for (size_t i = 0; i < spHandle->size(); ++i)
195  {
196  auto hits = hitsFromSp.at(i);
197  size_t tpc = geo::WireID::InvalidID;
198  for (const auto & h : hits) // find Collection hit, assume one is enough
199  {
200  if (h->SignalType() == geo::kCollection) { tpc = h->WireID().TPC; break; }
201  }
202  if (tpc == geo::WireID::InvalidID)
203  {
204  //mf::LogWarning("DisambigFromSpacePoints") << "No collection hit for this spacepoint.";
205  continue;
206  }
207  for (const auto & h : hits) // set mapping for Induction hits
208  {
209  if (h->SignalType() == geo::kInduction) { spToTPC[i] = tpc; }
210  }
211  }
212 
213  cryo_tpc_plane_keymap indHits; // induction hits resolved with spacepoints
214  std::vector<size_t> unassignedHits; // hits to resolve by neighoring assignments
215  std::unordered_map< size_t, geo::WireID > hitToWire; // final hit-wire assignments
216  std::unordered_map< size_t, std::vector<geo::WireID> > hitToNWires; // final hit-many-wires assignments
217 
218  hitToWire.reserve(eventHits.size());
219 
220  int n = runOnSpacePoints(eventHits, spFromHit, spToTPC, hitToWire, indHits, unassignedHits);
221  mf::LogInfo("DisambigFromSpacePoints") << n << " hits undisambiguated by space points.";
222 
223  if (fUseNeighbors)
224  {
225  n = resolveUnassigned(detProp, hitToWire, eventHits, indHits, unassignedHits, fNumNeighbors);
226  mf::LogInfo("DisambigFromSpacePoints") << n << " hits undisambiguated by neighborhood.";
227  }
228 
229  if (fMoveLeftovers == "repeat") { assignEveryAllowedWire(hitToNWires, eventHits, unassignedHits); }
230  else if (fMoveLeftovers == "first") { assignFirstAllowedWire(hitToWire, eventHits, unassignedHits); }
231  else { mf::LogInfo("DisambigFromSpacePoints") << "Remaining undisambiguated hits dropped."; }
232 
233  auto const hitPtrMaker = art::PtrMaker<recob::Hit>(evt);
234 
235  for (auto const & hw : hitToWire)
236  {
237  size_t key = hw.first;
238  geo::WireID wid = hw.second;
239 
240  recob::HitCreator new_hit(*(eventHits[key]), wid);
241 
242  hcol.emplace_back(new_hit.move(), channelHitWires.at(key));//, channelHitRawDigits.at(key));
243 
244  auto hitPtr = hitPtrMaker(hcol.size() - 1);
245  auto sps = spFromHit.at(eventHits[key].key());
246  for (auto const & spPtr : sps)
247  {
248  assns->addSingle(hitPtr, spPtr);
249  }
250  }
251 
252  for (auto const & hws : hitToNWires)
253  {
254  size_t key = hws.first;
255  for (auto const & wid : hws.second)
256  {
257  recob::HitCreator new_hit(*(eventHits[key]), wid);
258 
259  hcol.emplace_back(new_hit.move(), channelHitWires.at(key));//, channelHitRawDigits.at(key));
260 
261  auto hitPtr = hitPtrMaker(hcol.size() - 1);
262  auto sps = spFromHit.at(eventHits[key].key());
263  for (auto const & spPtr : sps)
264  {
265  assns->addSingle(hitPtr, spPtr);
266  }
267  }
268  }
269 
270  if (fMonitoringPlots && fTree) { fTree->Fill(); } // save statistics if MonitoringPlots was set to true
271 
272  // put the hit collection and associations into the event
273  hcol.put_into(evt);
274  evt.put(std::move(assns));
275  }
276 
278  const std::vector< art::Ptr<recob::Hit> > & eventHits,
279  const art::FindManyP< recob::SpacePoint > & spFromHit,
280  const std::unordered_map< size_t, size_t > & spToTPC,
281  std::unordered_map< size_t, geo::WireID > & assignments,
282  cryo_tpc_plane_keymap & indHits,
283  std::vector<size_t> & unassigned
284  )
285  {
286  fNHits[0] = 0; fNHits[1] = 0; fNHits[2] = 0;
287  fNMissedBySpacePoints[0] = 0;
288  fNMissedBySpacePoints[1] = 0;
289 
290  for (size_t i = 0; i < eventHits.size(); ++i)
291  {
292  const art::Ptr<recob::Hit> & hit = eventHits[i];
293  std::vector<geo::WireID> cwids = fGeom->ChannelToWire(hit->Channel());
294  if (cwids.empty()) { mf::LogWarning("DisambigFromSpacePoints") << "No wires for this channel???"; continue; }
295  if (hit->SignalType() == geo::kCollection)
296  {
297  assignments[hit.key()] = cwids.front();
298  fNHits[2]++; // count collection hit
299  }
300  else
301  {
302  geo::WireID id = hit->WireID();
303  size_t cryo = id.Cryostat, plane = id.Plane;
304  fNHits[plane]++; // count induction hit
305 
306  if (spFromHit.at(hit.key()).size() == 0)
307  {
308  unassigned.push_back(hit.key());
309  fNMissedBySpacePoints[plane]++; //count unresolved hit
310  }
311  else
312  {
313  std::unordered_map< size_t, geo::WireID > tpcBestWire;
314  std::unordered_map< size_t, size_t > tpcScore;
315 
316  for (const auto & sp : spFromHit.at(hit.key()))
317  {
318  auto search = spToTPC.find(sp.key());
319  if (search == spToTPC.end()) { continue; }
320  size_t spTpc = search->second;
321 
322  const float max_dw = 1.; // max dist to wire [wire pitch]
323  for (size_t w = 0; w < cwids.size(); ++w)
324  {
325  if (cwids[w].TPC != spTpc) { continue; } // not that side of APA
326 
327  float sp_wire = fGeom->WireCoordinate(sp->XYZ()[1], sp->XYZ()[2], plane, spTpc, cryo);
328  float dw = std::fabs(sp_wire - cwids[w].Wire);
329  if (dw < max_dw)
330  {
331  tpcBestWire[spTpc] = cwids[w];
332  tpcScore[spTpc]++;
333  }
334  }
335  }
336  if (!tpcScore.empty())
337  {
338  geo::WireID bestId;
339  size_t maxScore = 0;
340  for (const auto & score : tpcScore)
341  {
342  if (score.second > maxScore)
343  {
344  maxScore = score.second;
345  bestId = tpcBestWire[score.first];
346  }
347  }
348  indHits[cryo][bestId.TPC][plane].push_back(hit.key());
349  assignments[hit.key()] = bestId;
350  }
351  else
352  {
353  //mf::LogWarning("DisambigFromSpacePoints") << "Did not find matching wire (plane:" << plane << ").";
354  unassigned.push_back(hit.key());
355  fNMissedBySpacePoints[plane]++; //count unresolved hit
356  }
357  }
358  }
359  }
360 
362  }
363 
365  detinfo::DetectorPropertiesData const& detProp,
366  std::unordered_map< size_t, geo::WireID > & assignments,
367  const std::vector< art::Ptr<recob::Hit> > & eventHits,
368  cryo_tpc_plane_keymap & allIndHits,
369  std::vector<size_t> & unassigned,
370  size_t nNeighbors
371  )
372  {
373  fNMissedByNeighbors[0] = 0;
374  fNMissedByNeighbors[1] = 0;
375 
376  std::unordered_map< size_t, geo::WireID > result;
377 
378  for (const size_t key : unassigned)
379  {
380  const auto & hit = eventHits[key];
381  geo::WireID id = hit->WireID();
382  size_t cryo = id.Cryostat, plane = id.Plane;
383  float hitDrift = hit->PeakTime();
384 
385  std::vector<geo::WireID> cwids = fGeom->ChannelToWire(hit->Channel());
386  if (cwids.empty()) { mf::LogWarning("DisambigFromSpacePoints") << "No wires for this channel???"; continue; }
387 
388  const float dwMax = fMaxDistance / fGeom->TPC(0, 0).Plane(plane).WirePitch(); // max distance in wires to look for neighbors
389  const float ddMax = dwMax * fGeom->TPC(0, 0).Plane(plane).WirePitch() / std::fabs(detProp.GetXTicksCoefficient(0, 0));
390 
391  float bestScore = 0;
392  geo::WireID bestId;
393  for (size_t w = 0; w < cwids.size(); ++w)
394  {
395  const size_t tpc = cwids[w].TPC;
396  const size_t hitWire = cwids[w].Wire;
397 
398  bool allowed = true;
399  for (auto t : fExcludeTPCs) { if (t == tpc) { allowed = false; break; } }
400  if (!allowed) { continue; }
401 
402  const float wirePitch = fGeom->TPC(tpc, cryo).Plane(plane).WirePitch();
403  const float driftPitch = std::fabs(detProp.GetXTicksCoefficient(tpc, cryo));
404 
405  float maxDValue = fMaxDistance*fMaxDistance;
406  std::vector<float> distBuff(nNeighbors, maxDValue); // distance to n closest hits
407  const auto & keys = allIndHits[cryo][tpc][plane];
408  for (const size_t keyInd : keys)
409  {
410  const auto & hitInd = eventHits[keyInd];
411 
412  auto search = assignments.find(keyInd); // find resolved wire id
413  if (search == assignments.end())
414  {
415  mf::LogWarning("DisambigFromSpacePoints") << "Did not find resolved wire id.";
416  continue;
417  }
418 
419  //float dWire = std::abs(hitWire - search->second.Wire);
420  float dWire = std::abs(float(hitWire) - float(search->second.Wire));
421  float dDrift = std::fabs(hitDrift - hitInd->PeakTime());
422 
423  if ((dWire > dwMax) || (dDrift > ddMax)) { continue; }
424 
425  dWire *= wirePitch;
426  dDrift *= driftPitch;
427  float dist2 = dWire * dWire + dDrift * dDrift;
428 
429  float maxd2 = 0;
430  size_t maxIdx = 0;
431  for (size_t i = 0; i < distBuff.size(); ++i )
432  {
433  if (distBuff[i] > maxd2) { maxd2 = distBuff[i]; maxIdx = i; }
434  }
435  if (dist2 < maxd2) { distBuff[maxIdx] = dist2; }
436  }
437  float score = 0;
438  size_t nhits = 0;
439  for (size_t i = 0; i < distBuff.size(); ++i )
440  {
441  if (distBuff[i] < maxDValue) { score += 1./(1. + distBuff[i]); ++nhits; }
442  }
443  if (nhits > 0)
444  {
445  if (score > bestScore)
446  {
447  bestScore = score;
448  bestId = cwids[w];
449  }
450  }
451  }
452  if (bestId.isValid) { result[key] = bestId; }
453  else { fNMissedByNeighbors[plane]++; }
454  }
455 
456  // remove from list of unassigned hits
457  for (const auto & entry : result)
458  {
459  unassigned.erase(std::remove(unassigned.begin(), unassigned.end(), entry.first), unassigned.end());
460  }
461 
462  //assignments.merge(result); // use this with C++ 17
463  assignments.insert(result.begin(), result.end());
465  }
466 
468  std::unordered_map< size_t, geo::WireID > & assignments,
469  const std::vector< art::Ptr<recob::Hit> > & eventHits,
470  const std::vector<size_t> & unassigned
471  ) const
472  {
473  for (const size_t key : unassigned)
474  {
475  const auto & hit = eventHits[key];
476  std::vector<geo::WireID> cwids = fGeom->ChannelToWire(hit->Channel());
477  if (cwids.empty()) { mf::LogWarning("DisambigFromSpacePoints") << "No wires for this channel???"; continue; }
478 
479  geo::WireID bestId;
480  for (size_t w = 0; w < cwids.size(); ++w)
481  {
482  const size_t tpc = cwids[w].TPC;
483 
484  bool allowed = true;
485  for (auto t : fExcludeTPCs) { if (t == tpc) { allowed = false; break; } }
486  if (allowed) { bestId = cwids[w]; break; }
487  }
488  if (bestId.isValid) { assignments[key] = bestId; }
489  else { mf::LogWarning("DisambigFromSpacePoints") << "None of wires is allowed for this hit???"; }
490  }
491  }
492 
494  std::unordered_map< size_t, std::vector<geo::WireID> > & assignments,
495  const std::vector< art::Ptr<recob::Hit> > & eventHits,
496  const std::vector<size_t> & unassigned
497  ) const
498  {
499  for (const size_t key : unassigned)
500  {
501  const auto & hit = eventHits[key];
502  std::vector<geo::WireID> cwids = fGeom->ChannelToWire(hit->Channel());
503  if (cwids.empty()) { continue; } // add warning here
504 
505  for (size_t w = 0; w < cwids.size(); ++w)
506  {
507  const size_t tpc = cwids[w].TPC;
508 
509  bool allowed = true;
510  for (auto t : fExcludeTPCs) { if (t == tpc) { allowed = false; break; } }
511  if (allowed) { assignments[key].push_back(cwids[w]); }
512  }
513  }
514  }
515 
517 
518 } // end of dune namespace
519 #endif
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
geo::SigType_t SignalType() const
Signal type for the plane of the hit.
Definition: Hit.h:231
QList< Entry > entry
static QCString result
void assignFirstAllowedWire(std::unordered_map< size_t, geo::WireID > &assignments, const std::vector< art::Ptr< recob::Hit > > &eventHits, const std::vector< size_t > &unassigned) const
double GetXTicksCoefficient(int t, int c) const
std::string string
Definition: nybbler.cc:12
MaybeLogger_< ELseverityLevel::ELsev_info, false > LogInfo
geo::WireID WireID() const
Definition: Hit.h:233
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
bool isValid
Whether this ID points to a valid element.
Definition: geo_types.h:211
struct vector vector
ChannelGroupService::Name Name
int runOnSpacePoints(const std::vector< art::Ptr< recob::Hit > > &eventHits, const art::FindManyP< recob::SpacePoint > &spFromHit, const std::unordered_map< size_t, size_t > &spToTPC, std::unordered_map< size_t, geo::WireID > &assignments, cryo_tpc_plane_keymap &indHits, std::vector< size_t > &unassigned)
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
static constexpr WireID_t InvalidID
Special code for an invalid ID.
Definition: geo_types.h:577
std::map< unsigned int, plane_keymap > tpc_plane_keymap
static void declare_products(art::ProducesCollector &collector, std::string instance_name="", bool doWireAssns=true, bool doRawDigitAssns=true)
Declares the hit products we are going to fill.
Definition: HitCreator.cxx:248
art framework interface to geometry description
std::map< unsigned int, tpc_plane_keymap > cryo_tpc_plane_keymap
QCollection::Item first()
Definition: qglist.cpp:807
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
Definition: StdUtils.h:92
Class managing the creation of a new recob::Hit object.
Definition: HitCreator.h:83
T abs(T value)
Helper functions to create a hit.
A class handling a collection of hits and its associations.
Definition: HitCreator.h:508
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
Signal from induction planes.
Definition: geo_types.h:145
def key(type, name=None)
Definition: graph.py:13
static Config * config
Definition: config.cpp:1054
std::void_t< T > n
def move(depos, offset)
Definition: depos.py:107
key_type key() const noexcept
Definition: Ptr.h:216
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
Definition: search.py:1
RunNumber_t run() const
Definition: DataViewImpl.cc:71
Description of geometry of one entire detector.
std::map< unsigned int, std::vector< size_t > > plane_keymap
Detector simulation of raw signals on wires.
ProducesCollector & producesCollector() noexcept
Declaration of signal hit object.
#define Comment
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
int resolveUnassigned(detinfo::DetectorPropertiesData const &detProp, std::unordered_map< size_t, geo::WireID > &assignments, const std::vector< art::Ptr< recob::Hit > > &eventHits, cryo_tpc_plane_keymap &indHits, std::vector< size_t > &unassigned, size_t nNeighbors)
DisambigFromSpacePoints(Parameters const &config)
EventNumber_t event() const
Definition: EventID.h:116
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
PlaneGeo const & Plane(geo::View_t view) const
Return the plane in the tpc with View_t view.
Definition: TPCGeo.cxx:263
TCEvent evt
Definition: DataStructs.cxx:7
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
recob::Hit && move()
Prepares the constructed hit to be moved away.
Definition: HitCreator.h:343
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
void assignEveryAllowedWire(std::unordered_map< size_t, std::vector< geo::WireID > > &assignments, const std::vector< art::Ptr< recob::Hit > > &eventHits, const std::vector< size_t > &unassigned) const
EventID id() const
Definition: Event.cc:34
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
double WirePitch() const
Return the wire pitch (in centimeters). It is assumed constant.
Definition: PlaneGeo.h:411
QTextStream & endl(QTextStream &s)
Signal from collection planes.
Definition: geo_types.h:146