TrajCluster_module.cc
Go to the documentation of this file.
1 /**
2  * @file TrajCluster_module.cc
3  * @brief Cluster finder using trajectories
4  * @author Bruce Baller (baller@fnal.gov)
5  *
6 *
7  */
8 
9 // C/C++ standard libraries
10 #include <string>
11 
12 // Framework libraries
16 #include "art_root_io/TFileService.h"
17 #include "canvas/Persistency/Common/FindManyP.h"
19 #include "fhiclcpp/ParameterSet.h"
20 
21 // LArSoft includes
36 
37 //root includes
38 #include "TTree.h"
39 
40 // ... more includes in the implementation section
41 
42 namespace cluster {
43  /**
44  * @brief Produces clusters by the TrajCluster algorithm
45  *
46  * Configuration parameters
47  * -------------------------
48  *
49  * - *HitFinderModuleLabel* (InputTag, mandatory): label of the hits to be
50  * used as input (usually the label of the producing module is enough)
51  * - *TrajClusterAlg* (parameter set, mandatory): full configuration for
52  * TrajClusterAlg algorithm
53  *
54  */
55  class TrajCluster : public art::EDProducer {
56  public:
57  explicit TrajCluster(fhicl::ParameterSet const& pset);
58 
59  private:
60  void produce(art::Event& evt) override;
61  void beginJob() override;
62  void endJob() override;
63 
64  tca::TrajClusterAlg fTCAlg; // define TrajClusterAlg object
65  TTree* showertree;
66  void GetHits(const std::vector<recob::Hit>& inputHits,
67  const geo::TPCID& tpcid,
68  std::vector<std::vector<unsigned int>>& tpcHits);
69  void GetHits(const std::vector<recob::Hit>& inputHits,
70  const geo::TPCID& tpcid,
71  const std::vector<recob::Slice>& inputSlices,
72  art::FindManyP<recob::Hit>& hitFromSlc,
73  std::vector<std::vector<unsigned int>>& tpcHits,
74  std::vector<int>& slcIDs);
75 
80 
81  unsigned int fMaxSliceHits;
85  }; // class TrajCluster
86 
87 } // namespace cluster
88 
89 //******************************************************************************
90 //*** implementation
91 //***
92 
93 // C/C++ standard libraries
94 #include <memory> // std::move()
95 
96 // Framework libraries
99 #include "canvas/Persistency/Common/FindManyP.h"
101 
102 //LArSoft includes
104 #include "lardata/ArtDataHelper/HitCreator.h" // recob::HitCollectionAssociator
108 #include "lardataobj/RecoBase/Hit.h"
112 
113 namespace cluster {
114 
115  struct HitLoc {
116  unsigned int index; // index of this entry in a sort vector
117  unsigned int ctp; // encoded Cryostat, TPC and Plane
118  unsigned int wire;
119  int tick; // hit StartTick using typedef int TDCtick_t in RawTypes.h
120  short localIndex; // defined in Hit.h
121  };
122 
123  //----------------------------------------------------------------------------
124  bool
125  SortHits(HitLoc const& h1, HitLoc const& h2)
126  {
127  // sort by hit location (Cryostat, TPC, Plane, Wire, StartTick, hit LocalIndex)
128  if (h1.ctp != h2.ctp) return h1.ctp < h2.ctp;
129  if (h1.wire != h2.wire) return h1.wire < h2.wire;
130  if (h1.tick != h2.tick) return h1.tick < h2.tick;
131  return h1.localIndex < h2.localIndex;
132  } // SortHits
133 
134  //----------------------------------------------------------------------------
136  : EDProducer{pset}, fTCAlg{pset.get<fhicl::ParameterSet>("TrajClusterAlg")}
137  {
138  fHitModuleLabel = "NA";
139  if (pset.has_key("HitModuleLabel")) fHitModuleLabel = pset.get<art::InputTag>("HitModuleLabel");
140  fSliceModuleLabel = "NA";
141  if (pset.has_key("SliceModuleLabel"))
142  fSliceModuleLabel = pset.get<art::InputTag>("SliceModuleLabel");
143  fMaxSliceHits = UINT_MAX;
144  if (pset.has_key("MaxSliceHits")) fMaxSliceHits = pset.get<unsigned int>("MaxSliceHits");
145  fSpacePointModuleLabel = "NA";
146  if (pset.has_key("SpacePointModuleLabel"))
147  fSpacePointModuleLabel = pset.get<art::InputTag>("SpacePointModuleLabel");
149  if (pset.has_key("SpacePointHitAssnLabel"))
150  fSpacePointHitAssnLabel = pset.get<art::InputTag>("SpacePointHitAssnLabel");
151  fDoWireAssns = pset.get<bool>("DoWireAssns", true);
152  fDoRawDigitAssns = pset.get<bool>("DoRawDigitAssns", true);
153  fSaveAll2DVertices = false;
154  if (pset.has_key("SaveAll2DVertices")) fSaveAll2DVertices = pset.get<bool>("SaveAll2DVertices");
155 
156  // let HitCollectionAssociator declare that we are going to produce
157  // hits and associations with wires and raw digits
158  // (with no particular product label)
160  producesCollector(), "", fDoWireAssns, fDoRawDigitAssns);
161 
162  produces<std::vector<recob::Cluster>>();
163  produces<std::vector<recob::Vertex>>();
164  produces<std::vector<recob::EndPoint2D>>();
165  produces<std::vector<recob::Seed>>();
166  produces<std::vector<recob::Shower>>();
167  produces<art::Assns<recob::Cluster, recob::Hit>>();
168  produces<art::Assns<recob::Cluster, recob::EndPoint2D, unsigned short>>();
169  produces<art::Assns<recob::Cluster, recob::Vertex, unsigned short>>();
170  produces<art::Assns<recob::Shower, recob::Hit>>();
171 
172  produces<std::vector<recob::PFParticle>>();
173  produces<art::Assns<recob::PFParticle, recob::Cluster>>();
174  produces<art::Assns<recob::PFParticle, recob::Shower>>();
175  produces<art::Assns<recob::PFParticle, recob::Vertex>>();
176  produces<art::Assns<recob::PFParticle, recob::Seed>>();
177 
178  produces<art::Assns<recob::Slice, recob::Cluster>>();
179  produces<art::Assns<recob::Slice, recob::PFParticle>>();
180  produces<art::Assns<recob::Slice, recob::Hit>>();
181 
182  produces<std::vector<anab::CosmicTag>>();
183  produces<art::Assns<recob::PFParticle, anab::CosmicTag>>();
184 
185  // www: declear/create SpacePoint and association between SpacePoint and Hits from TrajCluster (Hit->SpacePoint)
186  produces<art::Assns<recob::SpacePoint, recob::Hit>>();
187  } // TrajCluster::TrajCluster()
188 
189  //----------------------------------------------------------------------------
190  void
192  {
194 
195  showertree = tfs->make<TTree>("showervarstree", "showerVarsTree");
197  }
198 
199  //----------------------------------------------------------------------------
200  void
202  {
203  std::vector<unsigned int> const& fAlgModCount = fTCAlg.GetAlgModCount();
204  std::vector<std::string> const& fAlgBitNames = fTCAlg.GetAlgBitNames();
205  if (fAlgBitNames.size() != fAlgModCount.size()) return;
206  mf::LogVerbatim myprt("TC");
207  myprt << "TrajCluster algorithm counts\n";
208  unsigned short icol = 0;
209  for (unsigned short ib = 0; ib < fAlgModCount.size(); ++ib) {
210  if (ib == tca::kKilled) continue;
211  myprt << std::left << std::setw(18) << fAlgBitNames[ib] << std::right << std::setw(10)
212  << fAlgModCount[ib] << " ";
213  ++icol;
214  if (icol == 4) {
215  myprt << "\n";
216  icol = 0;
217  }
218  } // ib
219  } // endJob
220 
221  //----------------------------------------------------------------------------
222  void
224  {
225  // Get a single hit collection from a HitsModuleLabel or multiple sets of "sliced" hits
226  // (aka clusters of hits that are close to each other in 3D) from a SliceModuleLabel.
227  // A pointer to the full hit collection is passed to TrajClusterAlg. The hits that are
228  // in each slice are reconstructed to find 2D trajectories (that become clusters),
229  // 2D vertices (EndPoint2D), 3D vertices, PFParticles and Showers. These data products
230  // are then collected and written to the event. Each slice is considered as an independent
231  // collection of hits with the additional requirement that all hits in a slice reside in
232  // one TPC
233 
234  // pointers to the slices in the event
235  std::vector<art::Ptr<recob::Slice>> slices;
236  std::vector<int> slcIDs;
237  unsigned int nInputHits = 0;
238 
239  // get a reference to the Hit collection
240  auto inputHits = art::Handle<std::vector<recob::Hit>>();
241  if (!evt.getByLabel(fHitModuleLabel, inputHits))
242  throw cet::exception("TrajClusterModule")
243  << "Failed to get a handle to hit collection '" << fHitModuleLabel.label() << "'\n";
244  nInputHits = (*inputHits).size();
245  if (!fTCAlg.SetInputHits(*inputHits, evt.run(), evt.event()))
246  throw cet::exception("TrajClusterModule")
247  << "Failed to process hits from '" << fHitModuleLabel.label() << "'\n";
248  // Try to determine the source of the hit collection using the assumption that it was
249  // derived from gaushit. If this is successful, pass the handle to TrajClusterAlg to
250  // recover hits that were incorrectly removed by disambiguation (DUNE)
251  if (fHitModuleLabel != "gaushit") {
252  auto sourceHits = art::Handle<std::vector<recob::Hit>>();
253  art::InputTag sourceModuleLabel("gaushit");
254  if (evt.getByLabel(sourceModuleLabel, sourceHits)) fTCAlg.SetSourceHits(*sourceHits);
255  } // look for gaushit collection
256 
257  // get an optional reference to the Slice collection
258  auto inputSlices = art::Handle<std::vector<recob::Slice>>();
259  if (fSliceModuleLabel != "NA") {
261  if (!evt.getByLabel(fSliceModuleLabel, inputSlices))
262  throw cet::exception("TrajClusterModule") << "Failed to get a inputSlices";
263  } // fSliceModuleLabel specified
264 
265  // get an optional reference to the SpacePoint collection
266  auto InputSpts = art::Handle<std::vector<recob::SpacePoint>>();
267  if (fSpacePointModuleLabel != "NA") {
268  if (!evt.getByLabel(fSpacePointModuleLabel, InputSpts))
269  throw cet::exception("TrajClusterModule") << "Failed to get a handle to SpacePoints\n";
270  tca::evt.sptHits.resize((*InputSpts).size(), {{UINT_MAX, UINT_MAX, UINT_MAX}});
271  art::FindManyP<recob::Hit> hitsFromSpt(InputSpts, evt, fSpacePointHitAssnLabel);
272  // TrajClusterAlg doesn't use the SpacePoint positions (only the assns to hits) but pass it
273  // anyway in case it is useful
274  fTCAlg.SetInputSpts(*InputSpts);
275  if (!hitsFromSpt.isValid())
276  throw cet::exception("TrajClusterModule")
277  << "Failed to get a handle to SpacePoint -> Hit assns\n";
278  // ensure that the assn is to the inputHit collection
279  auto& firstHit = hitsFromSpt.at(0)[0];
280  if (firstHit.id() != inputHits.id())
281  throw cet::exception("TrajClusterModule")
282  << "The SpacePoint -> Hit assn doesn't reference the input hit collection\n";
283  tca::evt.sptHits.resize((*InputSpts).size(), {{UINT_MAX, UINT_MAX, UINT_MAX}});
284  for (unsigned int isp = 0; isp < (*InputSpts).size(); ++isp) {
285  auto& hits = hitsFromSpt.at(isp);
286  for (unsigned short iht = 0; iht < hits.size(); ++iht) {
287  unsigned short plane = hits[iht]->WireID().Plane;
288  tca::evt.sptHits[isp][plane] = hits[iht].key();
289  } // iht
290  } // isp
291  } // fSpacePointModuleLabel specified
292 
293  if (nInputHits > 0) {
294  auto const clockData =
296  auto const detProp =
298  auto const* geom = lar::providerFrom<geo::Geometry>();
299  for (const auto& tpcid : geom->IterateTPCIDs()) {
300  // ignore protoDUNE dummy TPCs
301  if (geom->TPC(tpcid).DriftDistance() < 25.0) continue;
302  // a vector for the subset of hits in each slice in a TPC
303  // slice hits in this tpc
304  std::vector<std::vector<unsigned int>> sltpcHits;
305  if (inputSlices.isValid()) {
306  // get hits in this TPC and slice
307  art::FindManyP<recob::Hit> hitFromSlc(inputSlices, evt, fSliceModuleLabel);
308  GetHits(*inputHits, tpcid, *inputSlices, hitFromSlc, sltpcHits, slcIDs);
309  }
310  else {
311  // get hits in this TPC
312  // All hits are in one "fake" slice
313  GetHits(*inputHits, tpcid, sltpcHits);
314  slcIDs.resize(1);
315  slcIDs[0] = 1;
316  }
317  if (sltpcHits.empty()) continue;
318  for (unsigned short isl = 0; isl < sltpcHits.size(); ++isl) {
319  auto& tpcHits = sltpcHits[isl];
320  if (tpcHits.empty()) continue;
321  // only reconstruct slices with MC-matched hits?
322  // sort the slice hits by Cryostat, TPC, Wire, Plane, Start Tick and LocalIndex.
323  // This assumes that hits with larger LocalIndex are at larger Tick.
324  std::vector<HitLoc> sortVec(tpcHits.size());
325  for (unsigned int indx = 0; indx < tpcHits.size(); ++indx) {
326  auto& hit = (*inputHits)[tpcHits[indx]];
327  sortVec[indx].index = indx;
328  sortVec[indx].ctp = tca::EncodeCTP(hit.WireID());
329  sortVec[indx].wire = hit.WireID().Wire;
330  sortVec[indx].tick = hit.StartTick();
331  sortVec[indx].localIndex = hit.LocalIndex();
332  } // iht
333  std::sort(sortVec.begin(), sortVec.end(), SortHits);
334  std::vector tmp = tpcHits;
335  for (unsigned int ii = 0; ii < tpcHits.size(); ++ii)
336  tpcHits[ii] = tmp[sortVec[ii].index];
337  // clear the temp vector
338  tmp.resize(0);
339  sortVec.resize(0);
340  // look for a debug hit
341  if (tca::tcc.dbgStp) {
342  tca::debug.Hit = UINT_MAX;
343  for (unsigned short indx = 0; indx < tpcHits.size(); ++indx) {
344  auto& hit = (*inputHits)[tpcHits[indx]];
345  if ((int)hit.WireID().TPC == tca::debug.TPC &&
346  (int)hit.WireID().Plane == tca::debug.Plane &&
347  (int)hit.WireID().Wire == tca::debug.Wire &&
348  hit.PeakTime() > tca::debug.Tick - 10 && hit.PeakTime() < tca::debug.Tick + 10) {
349  std::cout << "Debug hit " << tpcHits[indx] << " found in slice ID " << slcIDs[isl];
350  std::cout << " RMS " << hit.RMS();
351  std::cout << " Multiplicity " << hit.Multiplicity();
352  std::cout << " GoodnessOfFit " << hit.GoodnessOfFit();
353  std::cout << "\n";
354  tca::debug.Hit = tpcHits[indx];
355  break;
356  } // Look for debug hit
357  } // iht
358  } // tca::tcc.dbgStp
359  fTCAlg.RunTrajClusterAlg(clockData, detProp, tpcHits, slcIDs[isl]);
360  } // isl
361  } // TPC
362  // stitch PFParticles between TPCs, create PFP start vertices, etc
364  if (tca::tcc.dbgSummary) tca::PrintAll(detProp, "TCM");
365  } // nInputHits > 0
366 
367  // Vectors to hold all data products that will go into the event
368  std::vector<recob::Hit> hitCol; // output hit collection
369  std::vector<recob::Cluster> clsCol;
370  std::vector<recob::PFParticle> pfpCol;
371  std::vector<recob::Vertex> vx3Col;
372  std::vector<recob::EndPoint2D> vx2Col;
373  std::vector<recob::Seed> sedCol;
374  std::vector<recob::Shower> shwCol;
375  std::vector<anab::CosmicTag> ctCol;
376  // a vector to correlate inputHits with output hits
377  std::vector<unsigned int> newIndex(nInputHits, UINT_MAX);
378 
379  // assns for those data products
380  // Cluster -> ...
381  std::unique_ptr<art::Assns<recob::Cluster, recob::Hit>> cls_hit_assn(
383  // unsigned short is the end to which a vertex is attached
384  std::unique_ptr<art::Assns<recob::Cluster, recob::EndPoint2D, unsigned short>> cls_vx2_assn(
386  std::unique_ptr<art::Assns<recob::Cluster, recob::Vertex, unsigned short>> cls_vx3_assn(
388  // Shower -> ...
389  std::unique_ptr<art::Assns<recob::Shower, recob::Hit>> shwr_hit_assn(
391  // PFParticle -> ...
392  std::unique_ptr<art::Assns<recob::PFParticle, recob::Cluster>> pfp_cls_assn(
394  std::unique_ptr<art::Assns<recob::PFParticle, recob::Shower>> pfp_shwr_assn(
396  std::unique_ptr<art::Assns<recob::PFParticle, recob::Vertex>> pfp_vx3_assn(
398  std::unique_ptr<art::Assns<recob::PFParticle, anab::CosmicTag>> pfp_cos_assn(
400  std::unique_ptr<art::Assns<recob::PFParticle, recob::Seed>> pfp_sed_assn(
402  // Slice -> ...
403  std::unique_ptr<art::Assns<recob::Slice, recob::Cluster>> slc_cls_assn(
405  std::unique_ptr<art::Assns<recob::Slice, recob::PFParticle>> slc_pfp_assn(
407  std::unique_ptr<art::Assns<recob::Slice, recob::Hit>> slc_hit_assn(
409  // www: Hit -> SpacePoint
410  std::unique_ptr<art::Assns<recob::SpacePoint, recob::Hit>> sp_hit_assn(
412 
413  // temp struct to get the index of a 2D (or 3D vertex) into vx2Col (or vx3Col)
414  // given a slice index and a vertex ID (not UID)
415  struct slcVxStruct {
416  unsigned short slIndx;
417  int ID;
418  unsigned short vxColIndx;
419  };
420  std::vector<slcVxStruct> vx2StrList;
421  // vector to map 3V UID -> ID in each sub-slice
422  std::vector<slcVxStruct> vx3StrList;
423 
424  if (nInputHits > 0) {
425  unsigned short nSlices = fTCAlg.GetSlicesSize();
426  // define a hit collection begin index to pass to CreateAssn for each cluster
427  unsigned int hitColBeginIndex = 0;
428  for (unsigned short isl = 0; isl < nSlices; ++isl) {
429  unsigned short slcIndex = 0;
430  if (!slices.empty()) {
431  for (slcIndex = 0; slcIndex < slices.size(); ++slcIndex)
432  if (slices[slcIndex]->ID() == slcIDs[isl]) break;
433  if (slcIndex == slices.size()) continue;
434  }
435  auto& slc = fTCAlg.GetSlice(isl);
436  // See if there was a serious reconstruction failure that made the sub-slice invalid
437  if (!slc.isValid) continue;
438  // make EndPoint2Ds
439  for (auto& vx2 : slc.vtxs) {
440  if (vx2.ID <= 0) continue;
441  // skip complete 2D vertices?
442  if (!fSaveAll2DVertices && vx2.Vx3ID != 0) continue;
443  unsigned int vtxID = vx2.UID;
444  unsigned int wire = std::nearbyint(vx2.Pos[0]);
445  geo::PlaneID plID = tca::DecodeCTP(vx2.CTP);
446  geo::WireID wID = geo::WireID(plID.Cryostat, plID.TPC, plID.Plane, wire);
447  geo::View_t view = tca::tcc.geom->View(wID);
448  vx2Col.emplace_back((double)vx2.Pos[1] / tca::tcc.unitsPerTick, // Time
449  wID, // WireID
450  vx2.Score, // strength = score
451  vtxID, // ID
452  view, // View
453  0); // total charge - not relevant
454 
455  // fill the mapping struct
456  slcVxStruct tmp;
457  tmp.slIndx = isl;
458  tmp.ID = vx2.ID;
459  tmp.vxColIndx = vx2Col.size() - 1;
460  vx2StrList.push_back(tmp);
461 
462  } // vx2
463  // make Vertices
464  for (auto& vx3 : slc.vtx3s) {
465  if (vx3.ID <= 0) continue;
466  // ignore incomplete vertices
467  if (vx3.Wire >= 0) continue;
468  unsigned int vtxID = vx3.UID;
469  double xyz[3];
470  xyz[0] = vx3.X;
471  xyz[1] = vx3.Y;
472  xyz[2] = vx3.Z;
473  vx3Col.emplace_back(xyz, vtxID);
474  // fill the mapping struct
475  slcVxStruct tmp;
476  tmp.slIndx = isl;
477  tmp.ID = vx3.ID;
478  tmp.vxColIndx = vx3Col.size() - 1;
479  vx3StrList.push_back(tmp);
480  } // vx3
481  // Convert the tjs to clusters
482  for (auto& tj : slc.tjs) {
483  if (tj.AlgMod[tca::kKilled]) continue;
484  hitColBeginIndex = hitCol.size();
485  for (unsigned short ipt = tj.EndPt[0]; ipt <= tj.EndPt[1]; ++ipt) {
486  auto& tp = tj.Pts[ipt];
487  if (tp.Chg <= 0) continue;
488  // index of inputHits indices of hits used in one TP
489  std::vector<unsigned int> tpHits;
490  for (unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
491  if (!tp.UseHit[ii]) continue;
492  if (tp.Hits[ii] > slc.slHits.size() - 1) { break; } // bad slHits index
493  unsigned int allHitsIndex = slc.slHits[tp.Hits[ii]].allHitsIndex;
494  if (allHitsIndex > nInputHits - 1) { break; } // bad allHitsIndex
495  tpHits.push_back(allHitsIndex);
496  if (newIndex[allHitsIndex] != UINT_MAX) {
497  std::cout << "Bad Slice " << isl << " tp.Hits " << tp.Hits[ii] << " allHitsIndex "
498  << allHitsIndex;
499  std::cout << " old newIndex " << newIndex[allHitsIndex];
500  auto& oldhit = (*inputHits)[allHitsIndex];
501  std::cout << " old " << oldhit.WireID().Plane << ":" << oldhit.WireID().Wire << ":"
502  << (int)oldhit.PeakTime();
503  auto& newhit = hitCol[newIndex[allHitsIndex]];
504  std::cout << " new " << newhit.WireID().Plane << ":" << newhit.WireID().Wire << ":"
505  << (int)newhit.PeakTime();
506  std::cout << " hitCol size " << hitCol.size();
507  std::cout << "\n";
508  break;
509  }
510  } // ii
511  // Let the alg define the hit either by merging multiple hits or by a simple copy
512  // of a single hit from inputHits
513  // Merge hits in the TP that are on the same wire or create hits on multiple wires
514  // and update the old hits -> new hits assn (newIndex)
515  if (tj.AlgMod[tca::kHaloTj]) {
516  // dressed muon - don't merge hits
517  for (auto iht : tpHits) {
518  hitCol.push_back((*inputHits)[iht]);
519  newIndex[iht] = hitCol.size() - 1;
520  } // iht
521  }
522  else {
523  fTCAlg.MergeTPHits(tpHits, hitCol, newIndex);
524  }
525  } // tp
526  if (hitCol.empty()) continue;
527  // Sum the charge and make the associations
528  float sumChg = 0;
529  float sumADC = 0;
530  for (unsigned int indx = hitColBeginIndex; indx < hitCol.size(); ++indx) {
531  auto& hit = hitCol[indx];
532  sumChg += hit.Integral();
533  sumADC += hit.SummedADC();
534  if (!slices.empty() &&
535  !util::CreateAssn(*this, evt, hitCol, slices[slcIndex], *slc_hit_assn, indx)) {
537  << "Failed to associate hits with Slice";
538  }
539  } // indx
540  geo::View_t view = hitCol[hitColBeginIndex].View();
541  auto& firstTP = tj.Pts[tj.EndPt[0]];
542  auto& lastTP = tj.Pts[tj.EndPt[1]];
543  int clsID = tj.UID;
544  if (tj.AlgMod[tca::kShowerLike]) clsID = -clsID;
545  // dressed muon - give the halo cluster the same ID as the parent
546  if (tj.AlgMod[tca::kHaloTj]) clsID = -tj.ParentID;
547  unsigned int nclhits = hitCol.size() - hitColBeginIndex + 1;
548  clsCol.emplace_back(firstTP.Pos[0], // Start wire
549  0, // sigma start wire
550  firstTP.Pos[1] / tca::tcc.unitsPerTick, // start tick
551  0, // sigma start tick
552  firstTP.AveChg, // start charge
553  firstTP.Ang, // start angle
554  0, // start opening angle (0 for line-like clusters)
555  lastTP.Pos[0], // end wire
556  0, // sigma end wire
557  lastTP.Pos[1] / tca::tcc.unitsPerTick, // end tick
558  0, // sigma end tick
559  lastTP.AveChg, // end charge
560  lastTP.Ang, // end angle
561  0, // end opening angle (0 for line-like clusters)
562  sumChg, // integral
563  0, // sigma integral
564  sumADC, // summed ADC
565  0, // sigma summed ADC
566  nclhits, // n hits
567  0, // wires over hits
568  0, // width (0 for line-like clusters)
569  clsID, // ID from TrajClusterAlg
570  view, // view
571  tca::DecodeCTP(tj.CTP), // planeID
572  recob::Cluster::Sentry // sentry
573  );
574  if (!util::CreateAssn(
575  *this, evt, clsCol, hitCol, *cls_hit_assn, hitColBeginIndex, hitCol.size())) {
577  << "Failed to associate hits with cluster ID " << tj.UID;
578  } // exception
579  // make Slice -> cluster assn
580  if (!slices.empty()) {
581  if (!util::CreateAssn(*this, evt, clsCol, slices[slcIndex], *slc_cls_assn)) {
583  << "Failed to associate slice with PFParticle";
584  } // exception
585  } // slices exist
586  // Make cluster -> 2V and cluster -> 3V assns
587  for (unsigned short end = 0; end < 2; ++end) {
588  if (tj.VtxID[end] <= 0) continue;
589  for (auto& vx2str : vx2StrList) {
590  if (vx2str.slIndx != isl) continue;
591  if (vx2str.ID != tj.VtxID[end]) continue;
592  if (!util::CreateAssnD(
593  *this, evt, *cls_vx2_assn, clsCol.size() - 1, vx2str.vxColIndx, end)) {
595  << "Failed to associate cluster " << tj.UID << " with EndPoint2D";
596  } // exception
597  auto& vx2 = slc.vtxs[tj.VtxID[end] - 1];
598  if (vx2.Vx3ID > 0) {
599  for (auto vx3str : vx3StrList) {
600  if (vx3str.slIndx != isl) continue;
601  if (vx3str.ID != vx2.Vx3ID) continue;
602  if (!util::CreateAssnD(
603  *this, evt, *cls_vx3_assn, clsCol.size() - 1, vx3str.vxColIndx, end)) {
605  << "Failed to associate cluster " << tj.UID << " with Vertex";
606  } // exception
607  break;
608  } // vx3str
609  } // vx2.Vx3ID > 0
610  break;
611  } // vx2str
612  } // end
613  } // tj (aka cluster)
614 
615  // make Showers
616  for (auto& ss3 : slc.showers) {
617  if (ss3.ID <= 0) continue;
619  shower.set_id(ss3.UID);
620  shower.set_total_energy(ss3.Energy);
621  shower.set_total_energy_err(ss3.EnergyErr);
622  shower.set_total_MIPenergy(ss3.MIPEnergy);
623  shower.set_total_MIPenergy_err(ss3.MIPEnergyErr);
624  shower.set_total_best_plane(ss3.BestPlane);
625  TVector3 dir = {ss3.Dir[0], ss3.Dir[1], ss3.Dir[2]};
626  shower.set_direction(dir);
627  TVector3 dirErr = {ss3.DirErr[0], ss3.DirErr[1], ss3.DirErr[2]};
628  shower.set_direction_err(dirErr);
629  TVector3 pos = {ss3.Start[0], ss3.Start[1], ss3.Start[2]};
630  shower.set_start_point(pos);
631  TVector3 posErr = {ss3.StartErr[0], ss3.StartErr[1], ss3.StartErr[2]};
632  shower.set_start_point_err(posErr);
633  shower.set_dedx(ss3.dEdx);
634  shower.set_dedx_err(ss3.dEdxErr);
635  shower.set_length(ss3.Len);
636  shower.set_open_angle(ss3.OpenAngle);
637  shwCol.push_back(shower);
638  // make the shower - hit association
639  std::vector<unsigned int> shwHits(ss3.Hits.size());
640  for (unsigned int iht = 0; iht < ss3.Hits.size(); ++iht)
641  shwHits[iht] = newIndex[ss3.Hits[iht]];
643  *this, evt, *shwr_hit_assn, shwCol.size() - 1, shwHits.begin(), shwHits.end())) {
645  << "Failed to associate hits with Shower";
646  } // exception
647  } // ss3
648  } // slice isl
649 
650  // Add PFParticles now that clsCol is filled
651  for (unsigned short isl = 0; isl < nSlices; ++isl) {
652  unsigned short slcIndex = 0;
653  if (!slices.empty()) {
654  for (slcIndex = 0; slcIndex < slices.size(); ++slcIndex)
655  if (slices[slcIndex]->ID() == slcIDs[isl]) break;
656  if (slcIndex == slices.size()) continue;
657  }
658  auto& slc = fTCAlg.GetSlice(isl);
659  // See if there was a serious reconstruction failure that made the slice invalid
660  if (!slc.isValid) continue;
661  // make PFParticles
662  for (size_t ipfp = 0; ipfp < slc.pfps.size(); ++ipfp) {
663  auto& pfp = slc.pfps[ipfp];
664  if (pfp.ID <= 0) continue;
665  // parents and daughters are indexed within a slice so find the index offset in pfpCol
666  size_t self = pfpCol.size();
667  size_t offset = self - ipfp;
668  size_t parentIndex = UINT_MAX;
669  if (pfp.ParentUID > 0) parentIndex = pfp.ParentUID + offset - 1;
670  std::vector<size_t> dtrIndices(pfp.DtrUIDs.size());
671  for (unsigned short idtr = 0; idtr < pfp.DtrUIDs.size(); ++idtr)
672  dtrIndices[idtr] = pfp.DtrUIDs[idtr] + offset - 1;
673  pfpCol.emplace_back(pfp.PDGCode, self, parentIndex, dtrIndices);
674  auto pos = PosAtEnd(pfp, 0);
675  auto dir = DirAtEnd(pfp, 0);
676  double sp[] = {pos[0], pos[1], pos[2]};
677  double sd[] = {dir[0], dir[1], dir[2]};
678  double spe[] = {0., 0., 0.};
679  double sde[] = {0., 0., 0.};
680  sedCol.emplace_back(sp, sd, spe, sde);
681  // PFParticle -> clusters
682  std::vector<unsigned int> clsIndices;
683  for (auto tuid : pfp.TjUIDs) {
684  unsigned int clsIndex = 0;
685  for (clsIndex = 0; clsIndex < clsCol.size(); ++clsIndex)
686  if (abs(clsCol[clsIndex].ID()) == tuid) break;
687  if (clsIndex == clsCol.size()) continue;
688  clsIndices.push_back(clsIndex);
689  } // tjid
690  if (!util::CreateAssn(*this,
691  evt,
692  *pfp_cls_assn,
693  pfpCol.size() - 1,
694  clsIndices.begin(),
695  clsIndices.end())) {
697  << "Failed to associate clusters with PFParticle";
698  } // exception
699  // PFParticle -> Vertex
700  if (pfp.Vx3ID[0] > 0) {
701  for (auto vx3str : vx3StrList) {
702  if (vx3str.slIndx != isl) continue;
703  if (vx3str.ID != pfp.Vx3ID[0]) continue;
704  std::vector<unsigned short> indx(1, vx3str.vxColIndx);
705  if (!util::CreateAssn(
706  *this, evt, *pfp_vx3_assn, pfpCol.size() - 1, indx.begin(), indx.end())) {
708  << "Failed to associate PFParticle " << pfp.UID << " with Vertex";
709  } // exception
710  break;
711  } // vx3Index
712  } // start vertex exists
713  // PFParticle -> Seed
714  if (!sedCol.empty()) {
715  if (!util::CreateAssn(*this,
716  evt,
717  pfpCol,
718  sedCol,
719  *pfp_sed_assn,
720  sedCol.size() - 1,
721  sedCol.size(),
722  pfpCol.size() - 1)) {
724  << "Failed to associate seed with PFParticle";
725  } // exception
726  } // seeds exist
727  // PFParticle -> Slice
728  if (!slices.empty()) {
729  if (!util::CreateAssn(*this, evt, pfpCol, slices[slcIndex], *slc_pfp_assn)) {
731  << "Failed to associate slice with PFParticle";
732  } // exception
733  } // slices exist
734  // PFParticle -> Shower
735  if (pfp.PDGCode == 1111) {
736  std::vector<unsigned short> shwIndex(1, 0);
737  for (auto& ss3 : slc.showers) {
738  if (ss3.ID <= 0) continue;
739  if (ss3.PFPIndex == ipfp) break;
740  ++shwIndex[0];
741  } // ss3
742  if (shwIndex[0] < shwCol.size()) {
743  if (!util::CreateAssn(*this,
744  evt,
745  *pfp_shwr_assn,
746  pfpCol.size() - 1,
747  shwIndex.begin(),
748  shwIndex.end())) {
750  << "Failed to associate shower with PFParticle";
751  } // exception
752  } // valid shwIndex
753  } // pfp -> Shower
754  // PFParticle cosmic tag
755  if (tca::tcc.modes[tca::kTagCosmics]) {
756  std::vector<float> tempPt1, tempPt2;
757  tempPt1.push_back(-999);
758  tempPt1.push_back(-999);
759  tempPt1.push_back(-999);
760  tempPt2.push_back(-999);
761  tempPt2.push_back(-999);
762  tempPt2.push_back(-999);
763  ctCol.emplace_back(tempPt1, tempPt2, pfp.CosmicScore, anab::CosmicTagID_t::kNotTagged);
764  if (!util::CreateAssn(
765  *this, evt, pfpCol, ctCol, *pfp_cos_assn, ctCol.size() - 1, ctCol.size())) {
767  << "Failed to associate CosmicTag with PFParticle";
768  }
769  } // cosmic tag
770  } // ipfp
771  } // isl
772 
773  // add the hits that weren't used in any slice to hitCol unless this is a
774  // special debugging mode and would be a waste of time
775  if (!slices.empty() && tca::tcc.recoSlice == 0) {
776  auto inputSlices = evt.getValidHandle<std::vector<recob::Slice>>(fSliceModuleLabel);
777  art::FindManyP<recob::Hit> hitFromSlc(inputSlices, evt, fSliceModuleLabel);
778  for (unsigned int allHitsIndex = 0; allHitsIndex < nInputHits; ++allHitsIndex) {
779  if (newIndex[allHitsIndex] != UINT_MAX) continue;
780  std::vector<unsigned int> oneHit(1, allHitsIndex);
781  fTCAlg.MergeTPHits(oneHit, hitCol, newIndex);
782  // find out which slice it is in
783  bool gotit = false;
784  for (size_t isl = 0; isl < slices.size(); ++isl) {
785  auto& hit_in_slc = hitFromSlc.at(isl);
786  for (auto& hit : hit_in_slc) {
787  if (hit.key() != allHitsIndex) continue;
788  gotit = true;
789  // Slice -> Hit assn
790  if (!util::CreateAssn(*this, evt, hitCol, slices[isl], *slc_hit_assn)) {
792  << "Failed to associate old Hit with Slice";
793  } // exception
794  break;
795  } // hit
796  if (gotit) break;
797  } // isl
798  } // allHitsIndex
799  } // slices exist
800  else {
801  // no recob::Slices. Just copy the unused hits
802  for (unsigned int allHitsIndex = 0; allHitsIndex < nInputHits; ++allHitsIndex) {
803  if (newIndex[allHitsIndex] != UINT_MAX) continue;
804  std::vector<unsigned int> oneHit(1, allHitsIndex);
805  fTCAlg.MergeTPHits(oneHit, hitCol, newIndex);
806  } // allHitsIndex
807  } // recob::Slices
808  } // input hits exist
809 
810  // www: find spacepoint from hits (inputHits) through SpacePoint->Hit assns, then create association between spacepoint and trajcluster hits (here, hits in hitCol)
811  if (nInputHits > 0) {
812  // www: expecting to find spacepoint from hits (inputHits): SpacePoint->Hit assns
813  if (fSpacePointModuleLabel != "NA") {
814  art::FindManyP<recob::SpacePoint> spFromHit(inputHits, evt, fSpacePointModuleLabel);
815  // www: using sp from hit
816  for (unsigned int allHitsIndex = 0; allHitsIndex < nInputHits; ++allHitsIndex) {
817  if (newIndex[allHitsIndex] == UINT_MAX)
818  continue; // skip hits not used in slice (not TrajCluster hits)
819  auto& sp_from_hit = spFromHit.at(allHitsIndex);
820  for (auto& sp : sp_from_hit) {
821  // SpacePoint -> Hit assn
822  if (!util::CreateAssn(*this, evt, hitCol, sp, *sp_hit_assn, newIndex[allHitsIndex])) {
824  << "Failed to associate new Hit with SpacePoint";
825  } // exception
826  } // sp
827  } // allHitsIndex
828  } // fSpacePointModuleLabel != "NA"
829  } // nInputHits > 0
830 
831  // clear the alg data structures
833 
834  // convert vectors to unique_ptrs
835  std::unique_ptr<std::vector<recob::Hit>> hcol(new std::vector<recob::Hit>(std::move(hitCol)));
836  std::unique_ptr<std::vector<recob::Cluster>> ccol(
837  new std::vector<recob::Cluster>(std::move(clsCol)));
838  std::unique_ptr<std::vector<recob::EndPoint2D>> v2col(
839  new std::vector<recob::EndPoint2D>(std::move(vx2Col)));
840  std::unique_ptr<std::vector<recob::Vertex>> v3col(
841  new std::vector<recob::Vertex>(std::move(vx3Col)));
842  std::unique_ptr<std::vector<recob::PFParticle>> pcol(
843  new std::vector<recob::PFParticle>(std::move(pfpCol)));
844  std::unique_ptr<std::vector<recob::Seed>> sdcol(
845  new std::vector<recob::Seed>(std::move(sedCol)));
846  std::unique_ptr<std::vector<recob::Shower>> scol(
847  new std::vector<recob::Shower>(std::move(shwCol)));
848  std::unique_ptr<std::vector<anab::CosmicTag>> ctgcol(
849  new std::vector<anab::CosmicTag>(std::move(ctCol)));
850 
851  // move the cluster collection and the associations into the event:
852  if (fHitModuleLabel != "NA") {
854  shcol.use_hits(std::move(hcol));
855  shcol.put_into(evt);
856  }
857  else {
859  shcol.use_hits(std::move(hcol));
860  shcol.put_into(evt);
861  }
862  evt.put(std::move(ccol));
863  evt.put(std::move(cls_hit_assn));
864  evt.put(std::move(v2col));
865  evt.put(std::move(v3col));
866  evt.put(std::move(scol));
867  evt.put(std::move(sdcol));
868  evt.put(std::move(shwr_hit_assn));
869  evt.put(std::move(cls_vx2_assn));
870  evt.put(std::move(cls_vx3_assn));
871  evt.put(std::move(pcol));
872  evt.put(std::move(pfp_cls_assn));
873  evt.put(std::move(pfp_shwr_assn));
874  evt.put(std::move(pfp_vx3_assn));
875  evt.put(std::move(pfp_sed_assn));
876  evt.put(std::move(slc_cls_assn));
877  evt.put(std::move(slc_pfp_assn));
878  evt.put(std::move(slc_hit_assn));
879  evt.put(std::move(ctgcol));
880  evt.put(std::move(pfp_cos_assn));
881  evt.put(std::move(sp_hit_assn)); // www: association between sp and hit (trjaclust)
882  } // TrajCluster::produce()
883 
884  ////////////////////////////////////////////////
885  void
886  TrajCluster::GetHits(const std::vector<recob::Hit>& inputHits,
887  const geo::TPCID& tpcid,
888  std::vector<std::vector<unsigned int>>& tpcHits)
889  {
890  // Put hits in this TPC into a single "slice", unless a special debugging mode is specified to
891  // only reconstruct hits that are MC-matched
892  unsigned int tpc = tpcid.TPC;
893  tpcHits.resize(1);
894  for (size_t iht = 0; iht < inputHits.size(); ++iht) {
895  auto& hit = inputHits[iht];
896  if (hit.WireID().TPC == tpc) tpcHits[0].push_back(iht);
897  }
898  } // GetHits
899 
900  ////////////////////////////////////////////////
901  void
902  TrajCluster::GetHits(const std::vector<recob::Hit>& inputHits,
903  const geo::TPCID& tpcid,
904  const std::vector<recob::Slice>& inputSlices,
905  art::FindManyP<recob::Hit>& hitFromSlc,
906  std::vector<std::vector<unsigned int>>& tpcHits,
907  std::vector<int>& slcIDs)
908  {
909  // Put the hits in all slices into tpcHits in this TPC
910  tpcHits.clear();
911  slcIDs.clear();
912  if (!hitFromSlc.isValid()) return;
913 
914  unsigned int tpc = tpcid.TPC;
915 
916  for (size_t isl = 0; isl < inputSlices.size(); ++isl) {
917  auto& hit_in_slc = hitFromSlc.at(isl);
918  if (hit_in_slc.size() < 3) continue;
919  int slcID = inputSlices[isl].ID();
920  for (auto& hit : hit_in_slc) {
921  if (hit->WireID().TPC != tpc) continue;
922  unsigned short indx = 0;
923  for (indx = 0; indx < slcIDs.size(); ++indx)
924  if (slcID == slcIDs[indx]) break;
925  if (indx == slcIDs.size()) {
926  slcIDs.push_back(slcID);
927  tpcHits.resize(tpcHits.size() + 1);
928  }
929  tpcHits[indx].push_back(hit.key());
930  } // hit
931  } // isl
932 
933  } // GetHits
934 
935  //----------------------------------------------------------------------------
937 
938 } // namespace cluster
void PrintAll(detinfo::DetectorPropertiesData const &detProp, std::string someText)
Definition: Utils.cxx:5519
void ClearResults()
Deletes all the results.
end
while True: pbar.update(maxval-len(onlies[E][S])) #print iS, "/", len(onlies[E][S]) found = False for...
void set_start_point_err(const TVector3 &xyz_e)
Definition: Shower.h:138
void set_dedx_err(const std::vector< double > &q)
Definition: Shower.h:140
void set_direction_err(const TVector3 &dir_e)
Definition: Shower.h:136
EventNumber_t event() const
Definition: DataViewImpl.cc:85
tca::TrajClusterAlg fTCAlg
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
unsigned int ID
TCConfig tcc
Definition: DataStructs.cxx:8
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
void set_total_energy(const std::vector< double > &q)
Definition: Shower.h:129
void RunTrajClusterAlg(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< unsigned int > &hitsInSlice, int sliceID)
struct vector vector
art::InputTag fSliceModuleLabel
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
void set_total_MIPenergy_err(const std::vector< double > &q)
Definition: Shower.h:132
Point3_t PosAtEnd(const PFPStruct &pfp, unsigned short end)
Definition: PFPUtils.cxx:3292
string dir
Cluster finding and building.
std::vector< std::string > const & GetAlgBitNames() const
bool SortHits(HitLoc const &h1, HitLoc const &h2)
std::vector< std::array< unsigned int, 3 > > sptHits
SpacePoint -> Hits assns by plane.
Definition: DataStructs.h:635
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
void set_total_energy_err(const std::vector< double > &q)
Definition: Shower.h:130
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
void set_id(const int id)
Definition: Shower.h:128
bool SetInputHits(std::vector< recob::Hit > const &inputHits, unsigned int run, unsigned int event)
void DefineShTree(TTree *t)
std::string const & label() const noexcept
Definition: InputTag.cc:79
unsigned int Hit
set to the hit index in evt.allHits if a Plane:Wire:Tick match is found
Definition: DebugStruct.h:26
T abs(T value)
Helper functions to create a hit.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
art::InputTag fHitModuleLabel
fInnerVessel push_back(Point(-578.400000, 0.000000, 0.000000))
void set_direction(const TVector3 &dir)
Definition: Shower.h:135
void use_hits(std::unique_ptr< std::vector< recob::Hit >> &&srchits)
Uses the specified collection as data product.
Definition: HitCreator.cxx:528
int Wire
Select hit Wire for debugging.
Definition: DebugStruct.h:24
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
float unitsPerTick
scale factor from Tick to WSE equivalent units
Definition: DataStructs.h:573
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
DebugStuff debug
Definition: DebugStruct.cxx:4
void put_into(art::Event &)
Moves the data into the event.
Definition: HitCreator.h:908
bool CreateAssnD(PRODUCER const &prod, art::Event &evt, art::Assns< T, U, D > &assn, size_t first_index, size_t second_index, typename art::Assns< T, U, D >::data_t &&data)
Creates a single one-to-one association with associated data.
def move(depos, offset)
Definition: depos.py:107
unsigned short GetSlicesSize() const
void set_length(const double &l)
Definition: Shower.h:141
int Plane
Select plane.
Definition: DebugStruct.h:22
void set_open_angle(const double &a)
Definition: Shower.h:142
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
A class handling a collection of hits and its associations.
Definition: HitCreator.h:842
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
string tmp
Definition: languages.py:63
const geo::GeometryCore * geom
Definition: DataStructs.h:578
RunNumber_t run() const
Definition: DataViewImpl.cc:71
The data type to uniquely identify a TPC.
Definition: geo_types.h:386
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
void set_total_best_plane(const int q)
Definition: Shower.h:133
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
Definition of data types for geometry description.
void set_total_MIPenergy(const std::vector< double > &q)
Definition: Shower.h:131
std::vector< TCSlice > slices
Definition: DataStructs.cxx:12
Detector simulation of raw signals on wires.
TCSlice const & GetSlice(unsigned short sliceIndex) const
art::InputTag fSpacePointModuleLabel
Q_EXPORT QTSManip setw(int w)
Definition: qtextstream.h:331
ProducesCollector & producesCollector() noexcept
void GetHits(const std::vector< recob::Hit > &inputHits, const geo::TPCID &tpcid, std::vector< std::vector< unsigned int >> &tpcHits)
cet::coded_exception< errors::ErrorCodes, ExceptionDetail::translate > Exception
Definition: Exception.h:66
int Tick
Select hit PeakTime for debugging (< 0 for vertex finding)
Definition: DebugStruct.h:25
int TPC
Select TPC.
Definition: DebugStruct.h:21
Declaration of signal hit object.
geo::PlaneID DecodeCTP(CTP_t CTP)
Produces clusters by the TrajCluster algorithm.
void produce(art::Event &evt) override
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
Definition: DataStructs.h:54
void MergeTPHits(std::vector< unsigned int > &tpHits, std::vector< recob::Hit > &newHitCol, std::vector< unsigned int > &newHitAssns) const
void SetSourceHits(std::vector< recob::Hit > const &srcHits)
std::vector< PFPStruct > pfps
Definition: DataStructs.h:680
TCEvent evt
Definition: DataStructs.cxx:7
void set_start_point(const TVector3 &xyz)
Definition: Shower.h:137
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
void SetInputSpts(std::vector< recob::SpacePoint > const &sptHandle)
Vector3_t DirAtEnd(const PFPStruct &pfp, unsigned short end)
Definition: PFPUtils.cxx:3283
if(!yymsg) yymsg
short recoSlice
only reconstruct the slice with ID (0 = all)
Definition: DataStructs.h:590
tag cosmic rays
Definition: DataStructs.h:541
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
art::InputTag fSpacePointHitAssnLabel
void set_dedx(const std::vector< double > &q)
Definition: Shower.h:139
std::vector< unsigned int > const & GetAlgModCount() const
TrajCluster(fhicl::ParameterSet const &pset)