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