All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
TrajClusterAlg.cxx
Go to the documentation of this file.
1 //////////////////////////////////////////////////////////////////////
2 ///
3 /// TrajClusterAlg
4 ///
5 /// Bruce Baller, baller@fnal.gov
6 /// Citation: Liquid argon TPC signal formation, signal processing and reconstruction techniques
7 /// B. Baller 2017 JINST 12 P07010
8 ///
9 ///
10 ////////////////////////////////////////////////////////////////////////
11 
23 
24 #include "messagefacility/MessageLogger/MessageLogger.h"
25 #include "fhiclcpp/ParameterSet.h"
26 
27 #include <iostream>
28 #include <string>
29 #include <vector>
30 
31 namespace tca {
32 
33  //------------------------------------------------------------------------------
34 
35  TrajClusterAlg::TrajClusterAlg(fhicl::ParameterSet const& pset)
36  : fCaloAlg(pset.get<fhicl::ParameterSet>("CaloAlg")), fMVAReader("Silent")
37  {
39 
40  bool badinput = false;
41  // set all configurable modes false
42  tcc.modes.reset();
43 
44  // default mode is stepping US -> DS
45  tcc.modes[kStepDir] = true;
46  short userMode = 1;
47  if (pset.has_key("Mode")) userMode = pset.get<short>("Mode");
48  if (userMode < 0) tcc.modes[kStepDir] = false;
49  if (pset.has_key("DoForecast")) tcc.doForecast = pset.get<bool>("DoForecast");
50  if (pset.has_key("UseChannelStatus")) tcc.useChannelStatus = pset.get<bool>("UseChannelStatus");
51  if (pset.has_key("StudyMode")) {
52  std::cout << "StudyMode is not valid anymore. Try Study: 1 or Study: 2, etc/n";
53  } // old StudyMode
54  if (pset.has_key("Study")) {
55  userMode = pset.get<short>("Study");
56  if (userMode == 1) tcc.modes[kStudy1] = true;
57  if (userMode == 2) tcc.modes[kStudy2] = true;
58  if (userMode == 3) tcc.modes[kStudy3] = true;
59  if (userMode == 4) tcc.modes[kStudy4] = true;
60  } // new Study mode
61  if (pset.has_key("SaveShowerTree"))
62  tcc.modes[kSaveShowerTree] = pset.get<bool>("SaveShowerTree");
63  if (pset.has_key("SaveCRTree")) tcc.modes[kSaveCRTree] = pset.get<bool>("SaveCRTree");
64  if (pset.has_key("TagCosmics")) tcc.modes[kTagCosmics] = pset.get<bool>("TagCosmics");
65  std::vector<std::string> skipAlgsVec;
66  if (pset.has_key("SkipAlgs")) skipAlgsVec = pset.get<std::vector<std::string>>("SkipAlgs");
67  std::vector<std::string> debugConfigVec;
68  if (pset.has_key("DebugConfig"))
69  debugConfigVec = pset.get<std::vector<std::string>>("DebugConfig");
70 
71  tcc.hitErrFac = pset.get<float>("HitErrFac", 0.4);
72  // Allow the user to specify the typical hit rms for small-angle tracks
73  std::vector<float> aveHitRMS;
74  if (pset.has_key("AveHitRMS")) aveHitRMS = pset.get<std::vector<float>>("AveHitRMS");
75  // Turn off the call to AnalyzeHits
76  if (!aveHitRMS.empty()) {
77  evt.aveHitRMSValid = true;
78  evt.aveHitRMS = aveHitRMS;
79  }
80  tcc.angleRanges = pset.get<std::vector<float>>("AngleRanges");
81  tcc.nPtsAve = pset.get<short>("NPtsAve", 20);
82  tcc.minPtsFit = pset.get<std::vector<unsigned short>>("MinPtsFit");
83  tcc.minPts = pset.get<std::vector<unsigned short>>("MinPts");
84  tcc.maxAngleCode = pset.get<std::vector<unsigned short>>("MaxAngleCode");
85  tcc.minMCSMom = pset.get<std::vector<short>>("MinMCSMom");
86  tcc.maxChi = pset.get<float>("MaxChi", 10);
87  tcc.chargeCuts = pset.get<std::vector<float>>("ChargeCuts", {3, 0.15, 0.25});
88  tcc.multHitSep = pset.get<float>("MultHitSep", 2.5);
89  tcc.kinkCuts = pset.get<std::vector<float>>("KinkCuts");
90  tcc.qualityCuts = pset.get<std::vector<float>>("QualityCuts", {0.8, 3});
91  tcc.maxWireSkipNoSignal = pset.get<float>("MaxWireSkipNoSignal", 1);
92  tcc.maxWireSkipWithSignal = pset.get<float>("MaxWireSkipWithSignal", 100);
93  tcc.projectionErrFactor = pset.get<float>("ProjectionErrFactor", 2);
94  tcc.VLAStepSize = pset.get<float>("VLAStepSize", 1.5);
95  tcc.JTMaxHitSep2 = pset.get<float>("JTMaxHitSep", 2);
96  tcc.deltaRayTag = pset.get<std::vector<short>>("DeltaRayTag", {-1, -1, -1});
97  tcc.muonTag = pset.get<std::vector<short>>("MuonTag", {-1, -1, -1, -1});
98  if (pset.has_key("ElectronTag")) tcc.electronTag = pset.get<std::vector<float>>("ElectronTag");
99  tcc.showerTag = pset.get<std::vector<float>>("ShowerTag", {-1, -1, -1, -1, -1, -1});
100  std::string fMVAShowerParentWeights = "NA";
101  pset.get_if_present<std::string>("MVAShowerParentWeights", fMVAShowerParentWeights);
102  tcc.chkStopCuts = pset.get<std::vector<float>>("ChkStopCuts", {-1, -1, -1});
103  if (pset.has_key("MatchTruth")) {
104  std::cout << "MatchTruth is not used. Use ClusterAnaV2 or DebugConfig to configure\n";
105  }
106  tcc.vtx2DCuts = pset.get<std::vector<float>>("Vertex2DCuts", {-1, -1, -1, -1, -1, -1, -1});
107  tcc.vtx3DCuts = pset.get<std::vector<float>>("Vertex3DCuts", {-1, -1});
108  tcc.vtxScoreWeights = pset.get<std::vector<float>>("VertexScoreWeights");
109  tcc.match3DCuts = pset.get<std::vector<float>>("Match3DCuts", {-1, -1, -1, -1, -1});
110  tcc.pfpStitchCuts = pset.get<std::vector<float>>("PFPStitchCuts", {-1});
111  // don't search for a neutrino vertex in test beam mode
112  tcc.modes[kTestBeam] = pset.get<bool>("TestBeam", false);
113  pset.get_if_present<std::vector<float>>("NeutralVxCuts", tcc.neutralVxCuts);
115 
116  // in the following section we ensure that the fcl vectors are appropriately sized so that later references are valid
117  if (tcc.minPtsFit.size() != tcc.minPts.size()) badinput = true;
118  if (tcc.maxAngleCode.size() != tcc.minPts.size()) badinput = true;
119  if (tcc.minMCSMom.size() != tcc.minPts.size()) badinput = true;
120  if (badinput)
121  throw art::Exception(art::errors::Configuration)
122  << "Bad input from fcl file. Vector lengths for MinPtsFit, MaxAngleRange and MinMCSMom "
123  "should be defined for each reconstruction pass";
124 
125  if (tcc.vtx2DCuts.size() < 10)
126  throw art::Exception(art::errors::Configuration)
127  << "Vertex2DCuts must be size 11\n 0 = Max length definition for short TJs\n 1 = Max "
128  "vtx-TJ sep short TJs\n 2 = Max vtx-TJ sep long TJs\n 3 = Max position pull for >2 "
129  "TJs\n 4 = Max vtx position error\n 5 = Min MCSMom for one of two TJs\n 6 = Min "
130  "fraction of wires hit btw vtx and Tjs\n 7 = Min Score\n 8 = min ChgFrac at a vtx or "
131  "merge point\n 9 = max MCSMom asymmetry, 10 = require chg on wires btw vtx and tjs in "
132  "induction planes?";
133  if (tcc.vtx2DCuts.size() == 10) {
134  // User didn't specify a requirement for the presence of charge between a vertex and the start of the
135  // vertex Tjs in induction planes. Assume that it is required
136  tcc.vtx2DCuts.resize(11, 1.);
137  }
138  if (tcc.vtx3DCuts.size() < 3)
139  throw art::Exception(art::errors::Configuration)
140  << "Vertex3DCuts must be size > 2\n 0 = 2D Vtx max dX (cm)\n 1 = 2D Vtx max pull\n 2 = max "
141  "3D separation (cm) btw PFP and vertex";
142  if (tcc.vtx3DCuts.size() == 2) {
143  std::cout << "WARNING: Vertex3DCuts is size 2 but should be size 3, where Vertex3DCuts[2] = "
144  "max 3D separation (cm) btw a PFP and a 3D vertex. Setting it to 3 cm\n";
145  tcc.vtx3DCuts.resize(3, 3.);
146  }
147  if (tcc.kinkCuts.size() < 4) {
148  throw art::Exception(art::errors::Configuration)
149  << "KinkCuts must be size 3\n 0 = Number of points to fit at the end of the trajectory\n 1 "
150  "= Minimum kink significance\n 2 = Use charge in significance calculation? (yes if > "
151  "0)\n 3 = 3D kink fit length (cm). \nYou are using an out-of-date specification?\n";
152  }
153  // throw an exception if the user appears to be using an old version of KinkCuts where
154  // KinkCuts[0] was a kink angle cut
155  if (tcc.kinkCuts[0] > 0 && tcc.kinkCuts[0] < 1.) {
156  throw art::Exception(art::errors::Configuration)
157  << "Are you using an out-of-date specification for KinkCuts? KinkCuts[0] is the number of "
158  "points to fit.\n";
159  }
160 
161  if (tcc.chargeCuts.size() != 3)
162  throw art::Exception(art::errors::Configuration)
163  << "ChargeCuts must be size 3\n 0 = Charge pull cut\n 1 = Min allowed fractional chg RMS\n "
164  "2 = Max allowed fractional chg RMS";
165  // dressed muons - change next line
166  if (tcc.muonTag.size() < 4)
167  throw art::Exception(art::errors::Configuration)
168  << "MuonTag must be size 4\n 0 = minPtsFit\n 1 = minMCSMom\n 2= maxWireSkipNoSignal\n 3 = "
169  "min delta ray length for tagging\n 4 = dress muon window size (optional)";
170  if (tcc.deltaRayTag.size() != 3)
171  throw art::Exception(art::errors::Configuration)
172  << "DeltaRayTag must be size 3\n 0 = Max endpoint sep\n 1 = min MCSMom\n 2 = max MCSMom";
173  if (tcc.chkStopCuts.size() < 3)
174  throw art::Exception(art::errors::Configuration)
175  << "ChkStopCuts must be size 3\n 0 = Min Charge ratio\n 1 = Charge slope pull cut\n 2 = "
176  "Charge fit chisq cut\n 3 = BraggSplit FOM (optional)";
177  if (tcc.showerTag.size() < 13) {
178  std::cout
179  << "ShowerTag must be size 13\n 0 = Mode\n 1 = max MCSMom\n 2 = max separation (WSE "
180  "units)\n 3 = Max angle diff\n 4 = Factor * rms width\n 5 = Min half width\n 6 = min "
181  "total Tps\n 7 = Min Tjs\n 8 = max parent FOM\n 9 = max direction FOM 10 = max "
182  "AspectRatio\n 11 = min Score to preserve a vertex\n 12 = Debug showers in CTP\n";
183  std::cout << " Fixing this problem...";
184  tcc.showerTag.resize(13);
185  // set the min score to 0
186  tcc.showerTag[11] = 0;
187  // turn off printing
188  tcc.showerTag[12] = -1;
189  }
190  if (tcc.match3DCuts.size() < 6)
191  throw art::Exception(art::errors::Configuration)
192  << "Match3DCuts must be size 5\n 0 = dx (cm) matching cut\n 1 = max number of 3D "
193  "combinations\n 2 = min length for 2-view match\n 3 = number of TP3Ds in each plane to "
194  "fit in each PFP section\n 4 = max pull for accepting TP3Ds in sections\n 5 = max "
195  "ChiDOF for a SectionFit";
196 
197  // check the angle ranges and convert from degrees to radians
198  if (tcc.angleRanges.back() < 90) {
199  mf::LogVerbatim("TC") << "Last element of AngleRange != 90 degrees. Fixing it\n";
200  tcc.angleRanges.back() = 90;
201  }
202 
203  // convert PFP stitch cuts
204  if (tcc.pfpStitchCuts.size() > 1 && tcc.pfpStitchCuts[0] > 0) {
205  // square the separation cut
207  // convert angle to cos
208  tcc.pfpStitchCuts[1] = cos(tcc.pfpStitchCuts[1]);
209  }
210 
211  // configure algorithm debugging. Configuration for debugging standard stepping
212  // is done in Utils/AnalyzeHits when the input hit collection is passed to SetInputHits
213  tcc.modes[kDebug] = false;
214  tcc.dbgAlg.reset();
215  for (auto strng : debugConfigVec) {
216  // try to interpret this as a C:T:P:W:Tick specification or something similar
217  if (!DecodeDebugString(strng)) {
218  // try to set a dbgAlg bit
219  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib) {
220  if (strng == AlgBitNames[ib]) {
221  tcc.dbgAlg[ib] = true;
222  tcc.modes[kDebug] = true;
223  break;
224  }
225  } // ib
226  // print some instructions and quit if there was a failure
227  if (!tcc.modes[kDebug]) {
228  std::cout << "DecodeDebugString failed: " << strng << "\n";
229  DecodeDebugString("instruct");
230  exit(1);
231  }
232  } // DecodeDebugString failed
233  } // strng
234 
235  for (auto& range : tcc.angleRanges) {
236  if (range < 0 || range > 90)
237  throw art::Exception(art::errors::Configuration)
238  << "Invalid angle range " << range << " Must be 0 - 90 degrees";
239  range *= M_PI / 180;
240  } // range
241 
242  // Ensure that the size of the AlgBitNames vector is consistent with the AlgBit typedef enum
243  if (kAlgBitSize != AlgBitNames.size())
244  throw art::Exception(art::errors::Configuration)
245  << "kAlgBitSize " << kAlgBitSize << " != AlgBitNames size " << AlgBitNames.size();
246  if (kAlgBitSize > 128)
247  throw art::Exception(art::errors::Configuration)
248  << "Increase the size of UseAlgs to at least " << kAlgBitSize;
249  fAlgModCount.resize(kAlgBitSize);
250 
251  if (kFlagBitSize != EndFlagNames.size())
252  throw art::Exception(art::errors::Configuration)
253  << "kFlagBitSize " << kFlagBitSize << " != EndFlagNames size " << EndFlagNames.size();
254 
255  if (kFlagBitSize > 8)
256  throw art::Exception(art::errors::Configuration)
257  << "Increase the size of EndFlag to at least " << kFlagBitSize;
258 
259  bool printHelp = false;
260  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib)
261  tcc.useAlg[ib] = true;
262 
263  // turn off the special algs
264  // Do an exhaustive (and slow) check of the hit -> trajectory associations
265  tcc.useAlg[kChkInTraj] = false;
266 
267  for (auto strng : skipAlgsVec) {
268  bool gotit = false;
269  if (strng == "All") {
270  // turn everything off
271  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib)
272  tcc.useAlg[ib] = false;
273  gotit = true;
274  break;
275  } // All off
276  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib) {
277  if (strng == AlgBitNames[ib]) {
278  tcc.useAlg[ib] = false;
279  gotit = true;
280  break;
281  }
282  } // ib
283  if (!gotit) {
284  std::cout << "******* Unknown SkipAlgs input string '" << strng << "'\n";
285  printHelp = true;
286  }
287  } // strng
288  if (printHelp) {
289  std::cout << "Valid AlgNames:";
290  for (auto strng : AlgBitNames)
291  std::cout << " " << strng;
292  std::cout << "\n";
293  std::cout << "Or specify All to turn all algs off\n";
294  }
295  // Configure the TMVA reader for the shower parent BDT
296  if (fMVAShowerParentWeights != "NA" && tcc.showerTag[0] > 0)
297  ConfigureMVA(tcc, fMVAShowerParentWeights);
298 
299  evt.eventsProcessed = 0;
300 
301  tcc.caloAlg = &fCaloAlg;
302  }
303 
304  ////////////////////////////////////////////////
305  bool
306  TrajClusterAlg::SetInputHits(std::vector<recob::Hit> const& inputHits,
307  unsigned int run,
308  unsigned int event)
309  {
310  // defines the pointer to the input hit collection, analyzes them,
311  // initializes global counters and refreshes service references
312  ClearResults();
313  evt.allHits = &inputHits;
314  evt.run = run;
315  evt.event = event;
316  // refresh service references
317  tcc.geom = lar::providerFrom<geo::Geometry>();
318  evt.WorkID = 0;
319  evt.globalT_UID = 0;
320  evt.global2V_UID = 0;
321  evt.global3V_UID = 0;
322  evt.globalP_UID = 0;
323  evt.global2S_UID = 0;
324  evt.global3S_UID = 0;
325  // find the average hit RMS using the full hit collection and define the
326  // configuration for the current TPC
327 
329 
330  return AnalyzeHits();
331  } // SetInputHits
332 
333  ////////////////////////////////////////////////
334  void
335  TrajClusterAlg::SetSourceHits(std::vector<recob::Hit> const& srcHits)
336  {
337  evt.srcHits = &srcHits;
338  evt.tpcSrcHitRange.resize(tcc.geom->NTPC());
339  for (auto& thr : evt.tpcSrcHitRange)
340  thr = {UINT_MAX, UINT_MAX};
341  for (unsigned int iht = 0; iht < (*evt.srcHits).size(); ++iht) {
342  auto& hit = (*evt.srcHits)[iht];
343  unsigned int tpc = hit.WireID().TPC;
344  if (tpc >= evt.tpcSrcHitRange.size()) return;
345  if (evt.tpcSrcHitRange[tpc].first == UINT_MAX) evt.tpcSrcHitRange[tpc].first = iht;
346  evt.tpcSrcHitRange[tpc].second = iht;
347  } // iht
348  } // SetSourceHits
349 
350  ////////////////////////////////////////////////
351  void
354  std::vector<unsigned int>& hitsInSlice,
355  int sliceID)
356  {
357  // Reconstruct everything using the hits in a slice
358 
359  if (slices.empty()) ++evt.eventsProcessed;
360  if (hitsInSlice.size() < 2) return;
361  if (tcc.recoSlice > 0 && sliceID != tcc.recoSlice) return;
362 
363  if (!CreateSlice(clockData, detProp, hitsInSlice, sliceID)) return;
364 
365  seeds.resize(0);
366  // get a reference to the stored slice
367  auto& slc = slices[slices.size() - 1];
368  // special debug mode reconstruction
369  if (tcc.recoTPC > 0 && (short)slc.TPCID.TPC != tcc.recoTPC) {
370  slices.pop_back();
371  return;
372  }
373 
374  if (evt.aveHitRMS.size() != slc.nPlanes)
375  throw art::Exception(art::errors::Configuration)
376  << " AveHitRMS vector size != the number of planes ";
377  if (tcc.recoSlice)
378  std::cout << "Reconstruct " << hitsInSlice.size() << " hits in Slice " << sliceID
379  << " in TPC " << slc.TPCID.TPC << "\n";
380  for (unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
381  CTP_t inCTP = EncodeCTP(slc.TPCID.Cryostat, slc.TPCID.TPC, plane);
382  ReconstructAllTraj(detProp, slc, inCTP);
383  if (!slc.isValid) return;
384  } // plane
385  // Compare 2D vertices in each plane and try to reconcile T -> 2V attachments using
386  // 2D and 3D(?) information
387  Reconcile2Vs(slc);
388  Find3DVertices(detProp, slc);
389  ScoreVertices(slc);
390  // Define the ParentID of trajectories using the vertex score
391  DefineTjParents(slc, false);
392  for (unsigned short plane = 0; plane < slc.nPlanes; ++plane) {
393  CTP_t inCTP = EncodeCTP(slc.TPCID.Cryostat, slc.TPCID.TPC, plane);
394  if (!ChkVtxAssociations(slc, inCTP)) {
395  std::cout << "RTC: ChkVtxAssociations found an error\n";
396  }
397  } // plane
398  if (tcc.match3DCuts[0] > 0) {
399  FindPFParticles(clockData, detProp, slc);
400  DefinePFPParents(slc, false);
401  } // 3D matching requested
402  KillPoorVertices(slc);
403  // Use 3D matching information to find showers in 2D. FindShowers3D returns
404  // true if the algorithm was successful indicating that the matching needs to be redone
405  if (tcc.showerTag[0] == 2 || tcc.showerTag[0] == 4) {
406  FindShowers3D(detProp, slc);
407  if (tcc.modes[kSaveShowerTree]) {
408  std::cout << "SHOWER TREE STAGE NUM SIZE: " << stv.StageNum.size() << std::endl;
409  showertree->Fill();
410  }
411  } // 3D shower code
412 
413  if (!slc.isValid) {
414  mf::LogVerbatim("TC") << "RunTrajCluster failed in MakeAllTrajClusters";
415  return;
416  }
417 
418  // dump a trajectory?
419  if (tcc.modes[kDebug] && tcc.dbgDump) DumpTj();
420 
421  Finish3DShowers(slc);
422 
423  // count algorithm usage
424  for (auto& tj : slc.tjs) {
425  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib)
426  if (tj.AlgMod[ib]) ++fAlgModCount[ib];
427  } // tj
428 
429  // clear vectors that are not needed later
430  slc.mallTraj.resize(0);
431 
432  } // RunTrajClusterAlg
433 
434  ////////////////////////////////////////////////
435  void
437  TCSlice& slc,
438  CTP_t inCTP)
439  {
440  // Reconstruct trajectories in inCTP and put them in allTraj
441 
442  unsigned short plane = DecodeCTP(inCTP).Plane;
443  if (slc.firstWire[plane] > slc.nWires[plane]) return;
444  unsigned int nwires = slc.lastWire[plane] - slc.firstWire[plane] - 1;
445  if (nwires > slc.nWires[plane]) return;
446 
447  // Make several passes through the hits with user-specified cuts for each
448  // pass. In general these are to not reconstruct large angle trajectories on
449  // the first pass
450  float maxHitsRMS = 4 * evt.aveHitRMS[plane];
451  for (unsigned short pass = 0; pass < tcc.minPtsFit.size(); ++pass) {
452  for (unsigned int ii = 0; ii < nwires; ++ii) {
453  // decide which way to step given the sign of StepDir
454  unsigned int iwire = 0;
455  unsigned int jwire = 0;
456  if (tcc.modes[kStepDir]) {
457  // step DS
458  iwire = slc.firstWire[plane] + ii;
459  jwire = iwire + 1;
460  }
461  else {
462  // step US
463  iwire = slc.lastWire[plane] - ii - 1;
464  jwire = iwire - 1;
465  }
466  if (iwire > slc.wireHitRange[plane].size() - 1) continue;
467  if (jwire > slc.wireHitRange[plane].size() - 1) continue;
468  // skip bad wires or no hits on the wire
469  if (slc.wireHitRange[plane][iwire].first == UINT_MAX) continue;
470  if (slc.wireHitRange[plane][jwire].first == UINT_MAX) continue;
471  unsigned int ifirsthit = slc.wireHitRange[plane][iwire].first;
472  unsigned int ilasthit = slc.wireHitRange[plane][iwire].second;
473  unsigned int jfirsthit = slc.wireHitRange[plane][jwire].first;
474  unsigned int jlasthit = slc.wireHitRange[plane][jwire].second;
475  if (ifirsthit > slc.slHits.size() || ilasthit > slc.slHits.size()) {
476  std::cout << "RAT: bad hit range " << ifirsthit << " " << ilasthit << " size "
477  << slc.slHits.size() << " inCTP " << inCTP << "\n";
478  return;
479  }
480  for (unsigned int iht = ifirsthit; iht <= ilasthit; ++iht) {
481  tcc.dbgStp = (tcc.modes[kDebug] && (slc.slHits[iht].allHitsIndex == debug.Hit));
482  if (tcc.dbgStp) {
483  mf::LogVerbatim("TC") << "+++++++ Pass " << pass << " Found debug hit "
484  << slices.size() - 1 << ":" << PrintHit(slc.slHits[iht])
485  << " iht " << iht;
486  }
487  // Only consider hits that are available
488  if (slc.slHits[iht].InTraj != 0) continue;
489  // We hope to make a trajectory point at the hit position of iht in WSE units
490  // with a direction pointing to jht
491  if (slc.slHits[iht].allHitsIndex > (*evt.allHits).size() - 1) {
492  std::cout << "RAT: Bad allHitsIndex\n";
493  continue;
494  }
495  auto& iHit = (*evt.allHits)[slc.slHits[iht].allHitsIndex];
496  if (LongPulseHit(iHit)) continue;
497  unsigned int fromWire = iHit.WireID().Wire;
498  float fromTick = iHit.PeakTime();
499  float iqtot = iHit.Integral();
500  float hitsRMSTick = iHit.RMS();
501  std::vector<unsigned int> iHitsInMultiplet;
502  if (pass == 0) {
503  // only use the hit on the first pass
504  iHitsInMultiplet.resize(1);
505  iHitsInMultiplet[0] = iht;
506  }
507  else {
508  GetHitMultiplet(slc, iht, iHitsInMultiplet, false);
509  if (iHitsInMultiplet.empty()) continue;
510  // ignore very high multiplicities
511  if (iHitsInMultiplet.size() > 4) continue;
512  }
513  if (iHitsInMultiplet.size() > 1) {
514  fromTick = HitsPosTick(slc, iHitsInMultiplet, iqtot, kUnusedHits);
515  hitsRMSTick = HitsRMSTick(slc, iHitsInMultiplet, kUnusedHits);
516  }
517  if (hitsRMSTick == 0) continue;
518  bool fatIHit = (hitsRMSTick > maxHitsRMS);
519  if (tcc.dbgStp)
520  mf::LogVerbatim("TC") << " hit RMS " << iHit.RMS() << " BB Multiplicity "
521  << iHitsInMultiplet.size() << " AveHitRMS[" << plane << "] "
522  << evt.aveHitRMS[plane] << " HitsRMSTick " << hitsRMSTick
523  << " fatIHit " << fatIHit;
524  for (unsigned int jht = jfirsthit; jht <= jlasthit; ++jht) {
525  // Only consider hits that are available
526  if (slc.slHits[iht].InTraj != 0) break;
527  if (slc.slHits[jht].InTraj != 0) continue;
528  // clear out any leftover work inTraj's that weren't cleaned up properly
529  for (auto& slHit : slc.slHits) {
530  if (slHit.InTraj < 0) {
531  std::cout << "RAT: Dirty hit " << PrintHit(slHit) << " EventsProcessed "
532  << evt.eventsProcessed << " WorkID " << evt.WorkID << "\n";
533  slHit.InTraj = 0;
534  }
535  }
536  unsigned int toWire = jwire;
537  auto& jHit = (*evt.allHits)[slc.slHits[jht].allHitsIndex];
538  if (LongPulseHit(jHit)) continue;
539  float toTick = jHit.PeakTime();
540  float jqtot = jHit.Integral();
541  std::vector<unsigned int> jHitsInMultiplet;
542  if (pass == 0) {
543  // only use the hit on the first pass
544  jHitsInMultiplet.resize(1);
545  jHitsInMultiplet[0] = jht;
546  }
547  else {
548  GetHitMultiplet(slc, jht, jHitsInMultiplet, false);
549  if (jHitsInMultiplet.empty()) continue;
550  // ignore very high multiplicities
551  if (jHitsInMultiplet.size() > 4) continue;
552  }
553  hitsRMSTick = HitsRMSTick(slc, jHitsInMultiplet, kUnusedHits);
554  if (hitsRMSTick == 0) continue;
555  bool fatJHit = (hitsRMSTick > maxHitsRMS);
556  if (pass == 0) {
557  // require both hits to be consistent
558  if ((fatIHit && !fatJHit) || (!fatIHit && fatJHit)) { continue; }
559  }
560  else {
561  // pass > 0
562  if (jHitsInMultiplet.size() > 1)
563  toTick = HitsPosTick(slc, jHitsInMultiplet, jqtot, kUnusedHits);
564  }
565  bool hitsOK = TrajHitsOK(slc, iHitsInMultiplet, jHitsInMultiplet);
566  // Ensure that the hits StartTick and EndTick have the proper overlap
567  if (!hitsOK) continue;
568  // start a trajectory with direction from iht -> jht
569  Trajectory work;
570  if (!StartTraj(slc, work, fromWire, fromTick, toWire, toTick, inCTP, pass)) continue;
571  // check for a major failure
572  if (!slc.isValid) {
573  std::cout << "RAT: StartTraj major failure\n";
574  return;
575  }
576  if (work.Pts.empty()) {
577  if (tcc.dbgStp) mf::LogVerbatim("TC") << "ReconstructAllTraj: StartTraj failed";
578  continue;
579  }
580  work.Pts[0].DeltaRMS = tcc.hitErrFac * tcc.unitsPerTick * hitsRMSTick;
581  // don't include the charge of iht since it will be low if this
582  // is a starting/ending track
583  work.AveChg = jqtot;
584  // try to add close hits
585  bool sigOK;
586  AddHits(slc, work, 0, sigOK);
587  // check for a major failure
588  if (!slc.isValid) {
589  std::cout << "RAT: AddHits major failure\n";
590  return;
591  }
592  if (!sigOK || work.Pts[0].Chg == 0) {
593  if (tcc.dbgStp) mf::LogVerbatim("TC") << " No hits at initial trajectory point ";
594  ReleaseHits(slc, work);
595  continue;
596  }
597  // move the TP position to the hit position but don't mess with the direction
598  work.Pts[0].Pos = work.Pts[0].HitPos;
599  // print the header and the first TP
600  if (tcc.dbgStp) PrintTrajectory("RAT", slc, work, USHRT_MAX);
601  // We can't update the trajectory yet because there is only one TP.
602  work.EndPt[0] = 0;
603  // now try stepping away
604  StepAway(slc, work);
605  // check for a major failure
606  if (!slc.isValid) {
607  std::cout << "RAT: StepAway major failure\n";
608  return;
609  }
610  if (tcc.dbgStp)
611  mf::LogVerbatim("TC") << " After first StepAway. IsGood " << work.IsGood;
612  // Check the quality of the work trajectory
613  CheckTraj(slc, work);
614  // check for a major failure
615  if (!slc.isValid) {
616  std::cout << "RAT: CheckTraj major failure\n";
617  return;
618  }
619  if (tcc.dbgStp)
620  mf::LogVerbatim("TC") << "ReconstructAllTraj: After CheckTraj EndPt " << work.EndPt[0]
621  << "-" << work.EndPt[1] << " IsGood " << work.IsGood;
622  if (tcc.dbgStp)
623  mf::LogVerbatim("TC")
624  << "StepAway done: IsGood " << work.IsGood << " NumPtsWithCharge "
625  << NumPtsWithCharge(slc, work, true) << " cut " << tcc.minPts[work.Pass];
626  // decide if the trajectory is long enough for this pass
627  if (!work.IsGood || NumPtsWithCharge(slc, work, true) < tcc.minPts[work.Pass]) {
628  if (tcc.dbgStp)
629  mf::LogVerbatim("TC")
630  << " xxxxxxx Not enough points " << NumPtsWithCharge(slc, work, true)
631  << " minimum " << tcc.minPts[work.Pass] << " or !IsGood";
632  ReleaseHits(slc, work);
633  continue;
634  }
635  if (!StoreTraj(slc, work)) continue;
636  if (tcc.dbgStp) {
637  auto& tj = slc.tjs[slc.tjs.size() - 1];
638  PrintTrajectory("RAT", slc, tj, USHRT_MAX);
639  if (!InTrajOK(slc, "RAT")) {
640  std::cout << "RAT: InTrajOK major failure. " << tj.ID << "\n";
641  return;
642  }
643  } // dbgStp
644  CheckTrajBeginChg(slc, slc.tjs.size() - 1);
645  BraggSplit(slc, slc.tjs.size() - 1);
646  break;
647  } // jht
648  } // iht
649  } // iwire
650 
651  // See if there are any seed trajectory points that were saved before reverse
652  // propagation and try to make Tjs from them
653  for (auto tp : seeds) {
654  unsigned short nAvailable = 0;
655  for (unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
656  if (!tp.UseHit[ii]) continue;
657  unsigned int iht = tp.Hits[ii];
658  if (slc.slHits[iht].InTraj == 0) ++nAvailable;
659  tcc.dbgStp = (tcc.modes[kDebug] && (slc.slHits[iht].allHitsIndex == debug.Hit));
660  if (tcc.dbgStp) {
661  mf::LogVerbatim("TC") << "+++++++ Seed debug hit " << slices.size() - 1 << ":"
662  << PrintHit(slc.slHits[iht]) << " iht " << iht;
663  }
664  } // ii
665  if (nAvailable == 0) continue;
666  Trajectory work;
667  work.ID = evt.WorkID;
668  for (unsigned short ii = 0; ii < tp.Hits.size(); ++ii) {
669  if (!tp.UseHit[ii]) continue;
670  unsigned int iht = tp.Hits[ii];
671  if (slc.slHits[iht].InTraj == 0) slc.slHits[iht].InTraj = work.ID;
672  } // ii
673  work.Pass = pass;
674  work.StepDir = 1;
675  if (tp.Dir[0] < 0) work.StepDir = -1;
676  work.CTP = tp.CTP;
677  work.ParentID = -1;
678  work.Strategy.reset();
679  work.Strategy[kNormal] = true;
680  // don't allow yet another reverse propagation
681  work.AlgMod[kRvPrp] = true;
682  work.Pts.push_back(tp);
683  StepAway(slc, work);
684  CheckTraj(slc, work);
685  // check for a major failure
686  if (!slc.isValid) {
687  std::cout << "RAT: CheckTraj major failure\n";
688  return;
689  }
690  // decide if the trajectory is long enough for this pass
691  if (!work.IsGood || NumPtsWithCharge(slc, work, true) < tcc.minPts[work.Pass]) {
692  if (tcc.dbgStp)
693  mf::LogVerbatim("TC") << " xxxxxxx Not enough points "
694  << NumPtsWithCharge(slc, work, true) << " minimum "
695  << tcc.minPts[work.Pass] << " or !IsGood";
696  ReleaseHits(slc, work);
697  continue;
698  }
699  if (!StoreTraj(slc, work)) continue;
700  if (tcc.dbgStp) {
701  auto& tj = slc.tjs[slc.tjs.size() - 1];
702  mf::LogVerbatim("TC") << "TRP RAT Stored T" << tj.ID << " using seed TP "
703  << PrintPos(slc, tp);
704  }
705  BraggSplit(slc, slc.tjs.size() - 1);
706  } // seed
707 
708  seeds.resize(0);
709 
710  bool lastPass = (pass == tcc.minPtsFit.size() - 1);
711  // don't use lastPass cuts if we will use LastEndMerge
712  if (tcc.useAlg[kLastEndMerge]) lastPass = false;
713  EndMerge(slc, inCTP, lastPass);
714  if (!slc.isValid) return;
715 
716  Find2DVertices(detProp, slc, inCTP, pass);
717 
718  } // pass
719 
720  // Last attempt to merge long straight Tjs that failed the EndMerge cuts
721  LastEndMerge(slc, inCTP);
722 
723  // make junk trajectories using nearby un-assigned hits
724  FindJunkTraj(slc, inCTP);
725  // dressed muons with halo trajectories
726  if (tcc.muonTag.size() > 4 && tcc.muonTag[4] > 0) {
727  for (auto& tj : slc.tjs) {
728  if (tj.AlgMod[kKilled]) continue;
729  if (tj.PDGCode != 13) continue;
730  MakeHaloTj(slc, tj, tcc.dbgSlc);
731  } // tj
732  } // dressed muons
733 
734  // Tag ShowerLike Tjs
735  if (tcc.showerTag[0] > 0) TagShowerLike("RAT", slc, inCTP);
736  // Set TP Environment bits
737  SetTPEnvironment(slc, inCTP);
738  Find2DVertices(detProp, slc, inCTP, USHRT_MAX);
739  SplitTrajCrossingVertices(slc, inCTP);
740  // Make vertices between long Tjs and junk Tjs
741  MakeJunkVertices(slc, inCTP);
742  // check for a major failure
743  if (!slc.isValid) {
744  std::cout << "RAT: MakeJunkVertices major failure\n";
745  return;
746  }
747 
748  // last attempt to attach Tjs to vertices
749  for (unsigned short ivx = 0; ivx < slc.vtxs.size(); ++ivx) {
750  auto& vx2 = slc.vtxs[ivx];
751  if (vx2.ID == 0) continue;
752  if (vx2.CTP != inCTP) continue;
753  AttachAnyTrajToVertex(slc, ivx, tcc.dbgStp || tcc.dbg2V);
754  } // ivx
755 
756  // Set the kEnvOverlap bit true for all TPs that are close to other
757  // trajectories that are close to vertices. The positions of TPs that
758  // overlap are biased and shouldn't be used in a vertex fit. Also, these
759  // TPs shouldn't be used to calculate dE/dx
760  UpdateVxEnvironment(slc);
761 
762  // Check the Tj <-> vtx associations and define the vertex quality
763  if (!ChkVtxAssociations(slc, inCTP)) {
764  std::cout << "RAT: ChkVtxAssociations found an error. Events processed "
765  << evt.eventsProcessed << " WorkID " << evt.WorkID << "\n";
766  }
767 
768  } // ReconstructAllTraj
769 
770  //////////////////////////////////////////
771  void
773  {
774  // Makes junk trajectories using unassigned hits
775 
776  if (tcc.JTMaxHitSep2 <= 0) return;
777  if (!tcc.useAlg[kJunkTj]) return;
778  unsigned short plane = DecodeCTP(inCTP).Plane;
779  if ((int)slc.lastWire[plane] - 3 < (int)slc.firstWire[plane]) return;
780 
781  // shouldn't have to do this but...
782  for (auto& slHit : slc.slHits)
783  if (slHit.InTraj < 0) slHit.InTraj = 0;
784 
785  bool prt = false;
786 
787  std::vector<unsigned int> tHits;
788  // Stay well away from the last wire in the plane
789  for (unsigned int iwire = slc.firstWire[plane]; iwire < slc.lastWire[plane] - 3; ++iwire) {
790  // skip bad wires or no hits on the wire
791  if (slc.wireHitRange[plane][iwire].first > slc.slHits.size()) continue;
792  if (slc.wireHitRange[plane][iwire].second > slc.slHits.size()) continue;
793  unsigned int jwire = iwire + 1;
794  if (slc.wireHitRange[plane][jwire].first > slc.slHits.size()) continue;
795  if (slc.wireHitRange[plane][jwire].second > slc.slHits.size()) continue;
796  unsigned int ifirsthit = slc.wireHitRange[plane][iwire].first;
797  unsigned int ilasthit = slc.wireHitRange[plane][iwire].second;
798  unsigned int jfirsthit = slc.wireHitRange[plane][jwire].first;
799  unsigned int jlasthit = slc.wireHitRange[plane][jwire].second;
800  for (unsigned int iht = ifirsthit; iht <= ilasthit; ++iht) {
801  if(iht >= slc.slHits.size()) break;
802  auto& islHit = slc.slHits[iht];
803  if (islHit.InTraj != 0) continue;
804  std::vector<unsigned int> iHits;
805  GetHitMultiplet(slc, iht, iHits, true);
806  prt =
807  (tcc.modes[kDebug] && std::find(iHits.begin(), iHits.end(), debug.Hit) != iHits.end());
808  if (prt) mf::LogVerbatim("TC") << "FJT: debug iht multiplet size " << iHits.size();
809  if (iHits.empty()) continue;
810  for (unsigned int jht = jfirsthit; jht <= jlasthit; ++jht) {
811  if(jht >= slc.slHits.size()) break;
812  auto& jslHit = slc.slHits[jht];
813  if (jslHit.InTraj != 0) continue;
814  if (prt && HitSep2(slc, iht, jht) < 100)
815  mf::LogVerbatim("TC") << " use " << PrintHit(jslHit) << " hitSep2 "
816  << HitSep2(slc, iht, jht);
817  if (HitSep2(slc, iht, jht) > tcc.JTMaxHitSep2) continue;
818  std::vector<unsigned int> jHits;
819  GetHitMultiplet(slc, jht, jHits, true);
820  if (jHits.empty()) continue;
821  // check for hit overlap consistency
822  if (!TrajHitsOK(slc, iHits, jHits)) continue;
823  tHits.clear();
824  // add the available hits and flag them
825  for (auto iht : iHits)
826  if (slc.slHits[iht].InTraj == 0) tHits.push_back(iht);
827  for (auto jht : jHits)
828  if (slc.slHits[jht].InTraj == 0) tHits.push_back(jht);
829  for (auto tht : tHits)
830  slc.slHits[tht].InTraj = -4;
831  unsigned int loWire;
832  if (iwire != 0) { loWire = iwire - 1; }
833  else {
834  loWire = 0;
835  }
836  unsigned int hiWire = jwire + 1;
837  if (hiWire > slc.nWires[plane]) break;
838  unsigned short nit = 0;
839  while (nit < 100) {
840  bool hitsAdded = false;
841  for (unsigned int kwire = loWire; kwire <= hiWire; ++kwire) {
842  if (slc.wireHitRange[plane][kwire].first == UINT_MAX) continue;
843  if (slc.wireHitRange[plane][kwire].second == UINT_MAX) continue;
844  unsigned int kfirsthit = slc.wireHitRange[plane][kwire].first;
845  unsigned int klasthit = slc.wireHitRange[plane][kwire].second;
846  for (unsigned int kht = kfirsthit; kht <= klasthit; ++kht) {
847  if(kht >= slc.slHits.size()) continue;
848  if (slc.slHits[kht].InTraj != 0) continue;
849  // this shouldn't be needed but do it anyway
850  if (std::find(tHits.begin(), tHits.end(), kht) != tHits.end()) continue;
851  // re-purpose jHits and check for consistency
852  GetHitMultiplet(slc, kht, jHits, true);
853  if (!TrajHitsOK(slc, tHits, jHits)) continue;
854  // add them all and update the wire range
855  for (auto jht : jHits) {
856  if (slc.slHits[jht].InTraj != 0) continue;
857  tHits.push_back(jht);
858  slc.slHits[jht].InTraj = -4;
859  if (kwire > hiWire) hiWire = kwire;
860  if (kwire < loWire) loWire = kwire;
861  hitsAdded = true;
862  } // jht
863  } // kht
864  } // kwire
865  if (!hitsAdded) break;
866  ++nit;
867  ++hiWire;
868  if (hiWire >= slc.nWires[plane]) break;
869  } // nit < 100
870  // clear InTraj
871  for (auto iht : tHits)
872  slc.slHits[iht].InTraj = 0;
873  if (tHits.size() < 3) continue;
874  if (prt) {
875  mf::LogVerbatim myprt("TC");
876  myprt << "FJT: tHits";
877  for (auto tht : tHits)
878  myprt << " " << PrintHit(slc.slHits[tht]);
879  myprt << "\n";
880  } // prt
881  // See if this is a ghost trajectory
882  if (IsGhost(slc, tHits)) break;
883  if (!MakeJunkTraj(slc, tHits)) {
884  if (prt) mf::LogVerbatim() << "FJT: MakeJunkTraj failed";
885  break;
886  }
887  if (slc.slHits[jht].InTraj > 0) break;
888  } // jht
889  } // iht
890  } // iwire
891  } // FindJunkTraj
892 
893  ////////////////////////////////////////////////
894  void
895  TrajClusterAlg::ChkInTraj(std::string someText, TCSlice& slc)
896  {
897  // Check slc.tjs -> InTraj associations
898 
899  if (!tcc.useAlg[kChkInTraj]) return;
900 
902 
903  int tID;
904  unsigned int iht;
905  unsigned short itj = 0;
906  std::vector<unsigned int> tHits;
907  std::vector<unsigned int> atHits;
908  for (auto& tj : slc.tjs) {
909  // ignore abandoned trajectories
910  if (tj.AlgMod[kKilled]) continue;
911  tID = tj.ID;
912  for (auto& tp : tj.Pts) {
913  if (tp.Hits.size() > 16) {
914  tj.AlgMod[kKilled] = true;
915  mf::LogVerbatim("TC")
916  << "ChkInTraj: More than 16 hits created a UseHit bitset overflow\n";
917  slc.isValid = false;
918  std::cout << "ChkInTraj major failure\n";
919  return;
920  }
921  } // tp
922  if (tj.AlgMod[kKilled]) {
923  std::cout << someText << " ChkInTraj hit size mis-match in tj ID " << tj.ID
924  << " AlgBitNames";
925  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib)
926  if (tj.AlgMod[ib]) std::cout << " " << AlgBitNames[ib];
927  std::cout << "\n";
928  continue;
929  }
930  tHits = PutTrajHitsInVector(tj, kUsedHits);
931  if (tHits.size() < 2) {
932  mf::LogVerbatim("TC") << someText << " ChkInTraj: Insufficient hits in traj " << tj.ID;
933  PrintTrajectory("CIT", slc, tj, USHRT_MAX);
934  tj.AlgMod[kKilled] = true;
935  continue;
936  }
937  std::sort(tHits.begin(), tHits.end());
938  atHits.clear();
939  for (iht = 0; iht < slc.slHits.size(); ++iht) {
940  if (slc.slHits[iht].InTraj == tID) atHits.push_back(iht);
941  } // iht
942  if (atHits.size() < 2) {
943  mf::LogVerbatim("TC") << someText << " ChkInTraj: Insufficient hits in atHits in traj "
944  << tj.ID << " Killing it";
945  tj.AlgMod[kKilled] = true;
946  continue;
947  }
948  if (!std::equal(tHits.begin(), tHits.end(), atHits.begin())) {
949  mf::LogVerbatim myprt("TC");
950  myprt << someText << " ChkInTraj failed: inTraj - UseHit mis-match for tj ID " << tID
951  << " tj.WorkID " << tj.WorkID << " atHits size " << atHits.size() << " tHits size "
952  << tHits.size() << " in CTP " << tj.CTP << "\n";
953  myprt << "AlgMods: ";
954  for (unsigned short ib = 0; ib < AlgBitNames.size(); ++ib)
955  if (tj.AlgMod[ib]) myprt << " " << AlgBitNames[ib];
956  myprt << "\n";
957  myprt << "index inTraj UseHit \n";
958  for (iht = 0; iht < atHits.size(); ++iht) {
959  myprt << "iht " << iht << " " << PrintHit(slc.slHits[atHits[iht]]);
960  if (iht < tHits.size()) myprt << " " << PrintHit(slc.slHits[tHits[iht]]);
961  if (atHits[iht] != tHits[iht]) myprt << " <<< " << atHits[iht] << " != " << tHits[iht];
962  myprt << "\n";
963  slc.isValid = false;
964  } // iht
965  if (tHits.size() > atHits.size()) {
966  for (iht = atHits.size(); iht < atHits.size(); ++iht) {
967  myprt << "atHits " << iht << " " << PrintHit(slc.slHits[atHits[iht]]) << "\n";
968  } // iht
969  PrintTrajectory("CIT", slc, tj, USHRT_MAX);
970  } // tHit.size > atHits.size()
971  }
972  // check the VtxID
973  for (unsigned short end = 0; end < 2; ++end) {
974  if (tj.VtxID[end] > slc.vtxs.size()) {
975  mf::LogVerbatim("TC") << someText << " ChkInTraj: Bad VtxID " << tj.ID;
976  std::cout << someText << " ChkInTraj: Bad VtxID " << tj.ID << " vtx size "
977  << slc.vtxs.size() << "\n";
978  tj.AlgMod[kKilled] = true;
979  PrintTrajectory("CIT", slc, tj, USHRT_MAX);
980  slc.isValid = false;
981  return;
982  }
983  } // end
984  ++itj;
985  if (!slc.isValid) return;
986  } // tj
987 
988  } // ChkInTraj
989 
990  //////////////////////////////////////////
991  void
992  TrajClusterAlg::MergeTPHits(std::vector<unsigned int>& tpHits,
993  std::vector<recob::Hit>& newHitCol,
994  std::vector<unsigned int>& newHitAssns) const
995  {
996  // merge the hits indexed by tpHits into one or more hits with the requirement that the hits
997  // are on different wires
998 
999  if (tpHits.empty()) return;
1000 
1001  // no merge required. Just put a close copy of the single hit in the output hit collection
1002  if (tpHits.size() == 1) {
1003  if (tpHits[0] > (*evt.allHits).size() - 1) {
1004  std::cout << "MergeTPHits Bad input hit index " << tpHits[0] << " allHits size "
1005  << (*evt.allHits).size() << "\n";
1006  return;
1007  }
1008  newHitCol.push_back(MergeTPHitsOnWire(tpHits));
1009  newHitAssns[tpHits[0]] = newHitCol.size() - 1;
1010  return;
1011  } // tpHits.size() == 1
1012 
1013  // split the hit list into sub-lists of hits on a single wire
1014  std::vector<unsigned int> wires;
1015  std::vector<std::vector<unsigned int>> wireHits;
1016  auto& firstHit = (*evt.allHits)[tpHits[0]];
1017  wires.push_back(firstHit.WireID().Wire);
1018  std::vector<unsigned int> tmp(1, tpHits[0]);
1019  wireHits.push_back(tmp);
1020  for (unsigned short ii = 1; ii < tpHits.size(); ++ii) {
1021  auto& hit = (*evt.allHits)[tpHits[ii]];
1022  unsigned int wire = hit.WireID().Wire;
1023  unsigned short indx = 0;
1024  for (indx = 0; indx < wires.size(); ++indx)
1025  if (wires[indx] == wire) break;
1026  if (indx == wires.size()) {
1027  wires.push_back(wire);
1028  wireHits.resize(wireHits.size() + 1);
1029  }
1030  wireHits[indx].push_back(tpHits[ii]);
1031  } // ii
1032 
1033  // now merge hits in each sub-list.
1034  for (unsigned short indx = 0; indx < wireHits.size(); ++indx) {
1035  auto& hitsOnWire = wireHits[indx];
1036  newHitCol.push_back(MergeTPHitsOnWire(hitsOnWire));
1037  for (unsigned short ii = 0; ii < hitsOnWire.size(); ++ii) {
1038  newHitAssns[hitsOnWire[ii]] = newHitCol.size() - 1;
1039  }
1040  } // hitsOnWire
1041 
1042  return;
1043 
1044  } // MergeTPHits
1045 
1046  //////////////////////////////////////////
1047  recob::Hit
1048  TrajClusterAlg::MergeTPHitsOnWire(std::vector<unsigned int>& tpHits) const
1049  {
1050  // merge the hits indexed by tpHits into one hit
1051 
1052  if (tpHits.empty()) return recob::Hit();
1053 
1054  // no merge required. Just return a slightly modified copy of the single hit
1055  if (tpHits.size() == 1) {
1056  if (tpHits[0] > (*evt.allHits).size() - 1) {
1057  std::cout << "MergeTPHits Bad input hit index " << tpHits[0] << " allHits size "
1058  << (*evt.allHits).size() << "\n";
1059  return recob::Hit();
1060  }
1061  auto& oldHit = (*evt.allHits)[tpHits[0]];
1062  raw::TDCtick_t startTick = oldHit.PeakTime() - 3 * oldHit.RMS();
1063  raw::TDCtick_t endTick = oldHit.PeakTime() + 3 * oldHit.RMS();
1064 
1065  return recob::Hit(oldHit.Channel(),
1066  startTick,
1067  endTick,
1068  oldHit.PeakTime(),
1069  oldHit.SigmaPeakTime(),
1070  oldHit.RMS(),
1071  oldHit.PeakAmplitude(),
1072  oldHit.SigmaPeakAmplitude(),
1073  oldHit.SummedADC(),
1074  oldHit.Integral(),
1075  oldHit.SigmaIntegral(),
1076  1,
1077  0, // Multiplicity, LocalIndex
1078  1,
1079  0, // GoodnessOfFit, DOF
1080  oldHit.View(),
1081  oldHit.SignalType(),
1082  oldHit.WireID());
1083  } // tpHits.size() == 1
1084 
1085  double integral = 0;
1086  double sIntegral = 0;
1087  double peakTime = 0;
1088  double sPeakTime = 0;
1089  double peakAmp = 0;
1090  double sPeakAmp = 0;
1091  float sumADC = 0;
1092  raw::TDCtick_t startTick = INT_MAX;
1093  raw::TDCtick_t endTick = 0;
1094  for (auto allHitsIndex : tpHits) {
1095  if (allHitsIndex > (*evt.allHits).size() - 1) return recob::Hit();
1096  auto& hit = (*evt.allHits)[allHitsIndex];
1097  if (hit.StartTick() < startTick) startTick = hit.StartTick();
1098  if (hit.EndTick() > endTick) endTick = hit.EndTick();
1099  double intgrl = hit.Integral();
1100  sPeakTime += intgrl * hit.SigmaPeakTime();
1101  sPeakAmp += intgrl * hit.SigmaPeakAmplitude();
1102  sumADC += hit.SummedADC();
1103  integral += intgrl;
1104  sIntegral += intgrl * hit.SigmaIntegral();
1105  // Get the charge normalization from an input hit
1106  } // tpHit
1107  if (integral <= 0) {
1108  std::cout << "MergeTPHits found bad hit integral " << integral << "\n";
1109  return recob::Hit();
1110  }
1111 
1112  // Create a signal shape vector to find the rms and peak tick
1113  std::vector<double> shape(endTick - startTick + 1, 0.);
1114  for (auto allHitsIndex : tpHits) {
1115  auto& hit = (*evt.allHits)[allHitsIndex];
1116  double peakTick = hit.PeakTime();
1117  double rms = hit.RMS();
1118  double peakAmp = hit.PeakAmplitude();
1119  for (raw::TDCtick_t tick = startTick; tick <= endTick; ++tick) {
1120  double arg = ((double)tick - peakTick) / rms;
1121  unsigned short indx = tick - startTick;
1122  shape[indx] += peakAmp * exp(-0.5 * arg * arg);
1123  } // tick
1124  } // allHitsIndex
1125 
1126  // find the peak tick
1127  double sigsum = 0;
1128  double sigsumt = 0;
1129  for (raw::TDCtick_t tick = startTick; tick <= endTick; ++tick) {
1130  unsigned short indx = tick - startTick;
1131  sigsum += shape[indx];
1132  sigsumt += shape[indx] * tick;
1133  } // tick
1134 
1135  peakTime = sigsumt / sigsum;
1136  // Use the sigma peak time calculated in the first loop
1137  sPeakTime /= integral;
1138 
1139  // find the RMS
1140  sigsumt = 0.;
1141  for (raw::TDCtick_t tick = startTick; tick <= endTick; ++tick) {
1142  double dTick = tick - peakTime;
1143  unsigned short indx = tick - startTick;
1144  sigsumt += shape[indx] * dTick * dTick;
1145  }
1146  double rms = std::sqrt(sigsumt / sigsum);
1147  // get a reference to the first hit to get the charge normalization, channel, view, etc
1148  auto& firstHit = (*evt.allHits)[tpHits[0]];
1149  double chgNorm = 2.507 * firstHit.PeakAmplitude() * firstHit.RMS() / firstHit.Integral();
1150  // find the amplitude from the integrated charge and the RMS
1151  peakAmp = (float)(integral * chgNorm / (2.507 * rms));
1152  // Use the sigma integral calculated in the first loop
1153  sPeakAmp /= integral;
1154  // reset the start and end tick
1155  startTick = peakTime - 3 * rms;
1156  endTick = peakTime + 3 * rms;
1157 
1158  // construct the hit
1159  return recob::Hit(firstHit.Channel(),
1160  startTick,
1161  endTick,
1162  peakTime,
1163  sPeakTime,
1164  rms,
1165  peakAmp,
1166  sPeakAmp,
1167  sumADC,
1168  integral,
1169  sIntegral,
1170  1,
1171  0, // Multiplicity, LocalIndex
1172  1,
1173  0, // GoodnessOfFit, DOF
1174  firstHit.View(),
1175  firstHit.SignalType(),
1176  firstHit.WireID());
1177 
1178  } // MergeTPHits
1179 
1180  /////////////////////////////////////////
1181  void
1183  {
1184  showertree = t;
1185 
1186  showertree->Branch("run", &evt.run, "run/I");
1187  showertree->Branch("subrun", &evt.subRun, "subrun/I");
1188  showertree->Branch("event", &evt.event, "event/I");
1189 
1190  showertree->Branch("BeginWir", &stv.BeginWir);
1191  showertree->Branch("BeginTim", &stv.BeginTim);
1192  showertree->Branch("BeginAng", &stv.BeginAng);
1193  showertree->Branch("BeginChg", &stv.BeginChg);
1194  showertree->Branch("BeginVtx", &stv.BeginVtx);
1195 
1196  showertree->Branch("EndWir", &stv.EndWir);
1197  showertree->Branch("EndTim", &stv.EndTim);
1198  showertree->Branch("EndAng", &stv.EndAng);
1199  showertree->Branch("EndChg", &stv.EndChg);
1200  showertree->Branch("EndVtx", &stv.EndVtx);
1201 
1202  showertree->Branch("MCSMom", &stv.MCSMom);
1203 
1204  showertree->Branch("PlaneNum", &stv.PlaneNum);
1205  showertree->Branch("TjID", &stv.TjID);
1206  showertree->Branch("IsShowerTj", &stv.IsShowerTj);
1207  showertree->Branch("ShowerID", &stv.ShowerID);
1208  showertree->Branch("IsShowerParent", &stv.IsShowerParent);
1209  showertree->Branch("StageNum", &stv.StageNum);
1210  showertree->Branch("StageName", &stv.StageName);
1211 
1212  showertree->Branch("Envelope", &stv.Envelope);
1213  showertree->Branch("EnvPlane", &stv.EnvPlane);
1214  showertree->Branch("EnvStage", &stv.EnvStage);
1215  showertree->Branch("EnvShowerID", &stv.EnvShowerID);
1216 
1217  showertree->Branch("nStages", &stv.nStages);
1218  showertree->Branch("nPlanes", &stv.nPlanes);
1219 
1220  } // end DefineShTree
1221 
1222  /////////////////////////////////////////
1223  bool
1226  std::vector<unsigned int>& hitsInSlice,
1227  int sliceID)
1228  {
1229  // Defines a TCSlice struct and pushes the slice onto slices.
1230  // Sets the isValid flag true if successful.
1231  if ((*evt.allHits).empty()) return false;
1232  if (hitsInSlice.size() < 2) return false;
1233 
1234  TCSlice slc;
1235  slc.ID = sliceID;
1236  slc.slHits.resize(hitsInSlice.size());
1237  bool first = true;
1238  unsigned int cstat = 0;
1239  unsigned int tpc = UINT_MAX;
1240  unsigned int cnt = 0;
1241  std::vector<unsigned int> nHitsInPln;
1242  for (auto iht : hitsInSlice) {
1243  if (iht >= (*evt.allHits).size()) return false;
1244  auto& hit = (*evt.allHits)[iht];
1245  if (first) {
1246  cstat = hit.WireID().Cryostat;
1247  tpc = hit.WireID().TPC;
1248  slc.TPCID = geo::TPCID(cstat, tpc);
1249  nHitsInPln.resize(tcc.geom->Nplanes(slc.TPCID));
1250  first = false;
1251  }
1252  if (hit.WireID().Cryostat != cstat || hit.WireID().TPC != tpc) return false;
1253  slc.slHits[cnt].allHitsIndex = iht;
1254  ++nHitsInPln[hit.WireID().Plane];
1255  ++cnt;
1256  } // iht
1257  // require at least two hits in each plane
1258  for (auto hip : nHitsInPln)
1259  if (hip < 2) return false;
1260  // Define the TCEvent wire hit range vector for this new TPC for ALL hits
1261  FillWireHitRange(slc.TPCID);
1262  // next define the Slice wire hit range vectors, UnitsPerTick, etc for this
1263  // slice
1264  if (!FillWireHitRange(clockData, detProp, slc)) return false;
1265  slc.isValid = true;
1266  slices.push_back(slc);
1267  if (tcc.modes[kDebug] && debug.Slice >= 0 && !tcc.dbgSlc) {
1268  tcc.dbgSlc = ((int)(slices.size() - 1) == debug.Slice);
1269  if (tcc.dbgSlc) std::cout << "Enabled debugging in sub-slice " << slices.size() - 1 << "\n";
1270  if (tcc.modes[kDebug] && (unsigned int)debug.Cryostat == cstat &&
1271  (unsigned int)debug.TPC == tpc && debug.Plane >= 0) {
1272  debug.CTP = EncodeCTP(
1273  (unsigned int)debug.Cryostat, (unsigned int)debug.TPC, (unsigned int)debug.Plane);
1274  }
1275  }
1276  // do a sanity check
1277  for (unsigned int iht = 0; iht < slc.slHits.size(); ++iht) {
1278  unsigned int ahi = slc.slHits[iht].allHitsIndex;
1279  if (ahi >= (*evt.allHits).size()) {
1280  std::cout << "CreateSlice: Bad allHitsIndex " << ahi << " " << (*evt.allHits).size()
1281  << "\n";
1282  return false;
1283  }
1284  } // iht
1285  return true;
1286  } // CreateSlice
1287 
1288  /////////////////////////////////////////
1289  void
1291  {
1292  // final steps that involve correlations between slices
1293  // Stitch PFParticles between TPCs
1294 
1295  // define the PFP TjUIDs vector before calling StitchPFPs
1296  for (auto& slc : slices) {
1297  if (!slc.isValid) continue;
1298  MakePFPTjs(slc);
1299  for (auto& pfp : slc.pfps) {
1300  if (pfp.ID <= 0) continue;
1301  pfp.TjUIDs.resize(pfp.TjIDs.size());
1302  for (unsigned short ii = 0; ii < pfp.TjIDs.size(); ++ii) {
1303  // do a sanity check while we are here
1304  if (pfp.TjIDs[ii] <= 0 || pfp.TjIDs[ii] > (int)slc.tjs.size()) {
1305  std::cout << "FinishEvent found an invalid T" << pfp.TjIDs[ii] << " in P" << pfp.UID
1306  << "\n";
1307  slc.isValid = false;
1308  continue;
1309  } // sanity check
1310  auto& tj = slc.tjs[pfp.TjIDs[ii] - 1];
1311  pfp.TjUIDs[ii] = tj.UID;
1312  } // ii
1313  } // pfp
1314  } // slc
1315 
1316  StitchPFPs();
1317  // Ensure that all PFParticles have a start vertex
1318  for (auto& slc : slices)
1319  PFPVertexCheck(slc);
1320  } // FinishEvent
1321 
1322 } // namespace cluster
Expect tracks entering from the front face. Don&#39;t create neutrino PFParticles.
Definition: DataStructs.h:532
calo::CalorimetryAlg * caloAlg
Definition: DataStructs.h:577
void ClearResults()
Deletes all the results.
void CheckTrajBeginChg(TCSlice &slc, unsigned short itj)
Definition: Utils.cxx:1337
float AveChg
Calculated using ALL hits.
Definition: DataStructs.h:197
void ReleaseHits(TCSlice &slc, Trajectory &tj)
Definition: Utils.cxx:1062
std::vector< int > EnvStage
Definition: DataStructs.h:411
std::vector< int > IsShowerParent
Definition: DataStructs.h:404
std::vector< Trajectory > tjs
vector of all trajectories in each plane
Definition: DataStructs.h:670
void StepAway(TCSlice &slc, Trajectory &tj)
Definition: StepUtils.cxx:30
void ConfigureMVA(TCConfig &tcc, std::string fMVAShowerParentWeights)
Definition: TCShower.cxx:35
bool printHelp
then if[["$THISISATEST"==1]]
Definition: neoSmazza.sh:95
bool TrajHitsOK(TCSlice &slc, const std::vector< unsigned int > &iHitsInMultiplet, const std::vector< unsigned int > &jHitsInMultiplet)
Definition: Utils.cxx:1873
std::vector< float > kinkCuts
kink finder algorithm
Definition: DataStructs.h:559
bool IsGhost(TCSlice &slc, Trajectory &tj)
Definition: StepUtils.cxx:2865
unsigned int event
Definition: DataStructs.h:634
Utilities related to art service access.
bool InTrajOK(TCSlice &slc, std::string someText)
Definition: Utils.cxx:1276
std::vector< float > EndWir
Definition: DataStructs.h:391
std::vector< float > EndAng
Definition: DataStructs.h:393
std::vector< unsigned int > PutTrajHitsInVector(const Trajectory &tj, HitStatus_t hitRequest)
Definition: Utils.cxx:2754
const std::vector< std::string > AlgBitNames
Definition: DataStructs.cxx:16
unsigned int run
Definition: DataStructs.h:635
short recoTPC
only reconstruct in the seleted TPC
Definition: DataStructs.h:589
std::vector< unsigned short > minPtsFit
Reconstruct in several passes.
Definition: DataStructs.h:565
std::vector< float > vtx3DCuts
2D vtx -&gt; 3D vtx matching cuts
Definition: DataStructs.h:551
std::vector< float > qualityCuts
Min points/wire, min consecutive pts after a gap.
Definition: DataStructs.h:563
void Find3DVertices(detinfo::DetectorPropertiesData const &detProp, TCSlice &slc)
Definition: TCVertex.cxx:1268
std::vector< float > BeginTim
Definition: DataStructs.h:387
void AddHits(TCSlice &slc, Trajectory &tj, unsigned short ipt, bool &sigOK)
Definition: StepUtils.cxx:1039
TCConfig tcc
Definition: DataStructs.cxx:9
std::vector< float > BeginAng
Definition: DataStructs.h:388
void PrintTrajectory(std::string someText, const TCSlice &slc, const Trajectory &tj, unsigned short tPoint)
Definition: Utils.cxx:6195
void SplitTrajCrossingVertices(TCSlice &slc, CTP_t inCTP)
Definition: TCVertex.cxx:923
std::vector< std::vector< std::pair< unsigned int, unsigned int > > > wireHitRange
Definition: DataStructs.h:675
void Reconcile2Vs(TCSlice &slc)
Definition: TCVertex.cxx:1067
int ParentID
ID of the parent, or the ID of the Tj this one was merged with if it is killed.
Definition: DataStructs.h:195
step from US -&gt; DS (true) or DS -&gt; US (false)
Definition: DataStructs.h:531
bool StoreTraj(TCSlice &slc, Trajectory &tj)
Definition: Utils.cxx:1089
void RunTrajClusterAlg(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< unsigned int > &hitsInSlice, int sliceID)
calo::CalorimetryAlg fCaloAlg
float maxWireSkipWithSignal
max number of wires to skip with a signal on them
Definition: DataStructs.h:582
call study functions to develop cuts, etc
Definition: DataStructs.h:536
std::string PrintPos(const TCSlice &slc, const TrajPoint &tp)
Definition: Utils.cxx:6526
std::size_t size(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:561
void FillWireHitRange(geo::TPCID inTPCID)
Definition: Utils.cxx:4461
bool AttachAnyTrajToVertex(TCSlice &slc, unsigned short ivx, bool prt)
Definition: TCVertex.cxx:1683
std::vector< std::pair< unsigned int, unsigned int > > tpcSrcHitRange
Definition: DataStructs.h:628
bool MakeJunkTraj(TCSlice &slc, std::vector< unsigned int > tHits)
Definition: StepUtils.cxx:3868
std::vector< float > electronTag
Definition: DataStructs.h:556
bool FindShowers3D(detinfo::DetectorPropertiesData const &detProp, TCSlice &slc)
Definition: TCShower.cxx:289
bool dbgSlc
debug only in the user-defined slice? default is all slices
Definition: DataStructs.h:590
bool StartTraj(TCSlice &slc, Trajectory &tj, unsigned int fromhit, unsigned int tohit, unsigned short pass)
Definition: Utils.cxx:5001
process_name hit
Definition: cheaterreco.fcl:51
std::vector< unsigned int > lastWire
the last wire with a hit
Definition: DataStructs.h:655
bool CreateSlice(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, std::vector< unsigned int > &hitsInSlice, int sliceID)
bool LongPulseHit(const recob::Hit &hit)
Definition: Utils.cxx:4452
unsigned int eventsProcessed
Definition: DataStructs.h:637
bool IsGood
set false if there is a failure or the Tj fails quality cuts
Definition: DataStructs.h:215
bool doForecast
See TCMode_t above.
Definition: DataStructs.h:608
void MakePFPTjs(TCSlice &slc)
Definition: PFPUtils.cxx:513
std::vector< float > angleRanges
list of max angles for each angle range
Definition: DataStructs.h:569
const std::vector< std::string > EndFlagNames
Definition: DataStructs.cxx:88
std::vector< float > showerTag
shower-like trajectory tagging + shower reconstruction
Definition: DataStructs.h:558
unsigned short Pass
the pass on which it was created
Definition: DataStructs.h:209
int TDCtick_t
Type representing a TDC tick.
Definition: RawTypes.h:25
std::vector< float > EndTim
Definition: DataStructs.h:392
std::vector< int > ShowerID
Definition: DataStructs.h:403
ShowerTreeVars stv
Definition: DataStructs.cxx:11
std::vector< unsigned short > maxAngleCode
max allowed angle code for each pass
Definition: DataStructs.h:567
bool SetInputHits(std::vector< recob::Hit > const &inputHits, unsigned int run, unsigned int event)
void DefineShTree(TTree *t)
std::vector< unsigned int > fAlgModCount
float projectionErrFactor
Definition: DataStructs.h:583
unsigned int Hit
set to the hit index in evt.allHits if a Plane:Wire:Tick match is found
Definition: DebugStruct.h:26
save shower tree
Definition: DataStructs.h:540
std::vector< std::string > StageName
Definition: DataStructs.h:406
float HitSep2(const TCSlice &slc, unsigned int iht, unsigned int jht)
Definition: Utils.cxx:2538
int Cryostat
Select Cryostat.
Definition: DebugStruct.h:20
float HitsRMSTick(const TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, HitStatus_t hitRequest)
Definition: Utils.cxx:4246
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
short nPtsAve
dump trajectory points
Definition: DataStructs.h:606
std::vector< int > TjID
Definition: DataStructs.h:401
void PFPVertexCheck(TCSlice &slc)
Definition: PFPUtils.cxx:2845
bool dbgStp
debug stepping using debug.Cryostat, debug.TPC, etc
Definition: DataStructs.h:591
recob::Hit MergeTPHitsOnWire(std::vector< unsigned int > &tpHits) const
don&#39;t mess with this line
Definition: DataStructs.h:515
float unitsPerTick
scale factor from Tick to WSE equivalent units
Definition: DataStructs.h:571
std::vector< short > minMCSMom
Min MCSMom for each pass.
Definition: DataStructs.h:568
bool BraggSplit(TCSlice &slc, unsigned short itj)
Definition: Utils.cxx:1444
std::vector< short > BeginVtx
Definition: DataStructs.h:390
DebugStuff debug
Definition: DebugStruct.cxx:4
CTP_t CTP
Cryostat, TPC, Plane code.
Definition: DataStructs.h:192
void DumpTj()
Definition: Utils.cxx:5400
bool dbg2V
debug 2D vertex finding
Definition: DataStructs.h:593
void GetHitMultiplet(const TCSlice &slc, unsigned int theHit, std::vector< unsigned int > &hitsInMultiplet, bool useLongPulseHits)
Definition: StepUtils.cxx:1415
std::vector< float > aveHitRMS
average RMS of an isolated hit
Definition: DataStructs.h:638
void TagShowerLike(std::string inFcnLabel, TCSlice &slc, const CTP_t &inCTP)
Definition: TCShower.cxx:3276
std::vector< TrajPoint > Pts
Trajectory points.
Definition: DataStructs.h:191
TMVA::Reader * showerParentReader
Definition: DataStructs.h:578
bool ChkVtxAssociations(TCSlice &slc, const CTP_t &inCTP)
Definition: TCVertex.cxx:2071
int Plane
Select plane.
Definition: DebugStruct.h:22
for($it=0;$it< $RaceTrack_number;$it++)
std::vector< float > neutralVxCuts
Definition: DataStructs.h:553
void MakeHaloTj(TCSlice &slc, Trajectory &muTj, bool prt)
Definition: Utils.cxx:47
std::vector< short > EndVtx
Definition: DataStructs.h:395
auto end(FixedBins< T, C > const &) noexcept
Definition: FixedBins.h:585
std::vector< VtxStore > vtxs
2D vertices
Definition: DataStructs.h:676
std::array< unsigned short, 2 > EndPt
First and last point in the trajectory that has charge.
Definition: DataStructs.h:203
tick_as<> tick
Tick number, represented by std::ptrdiff_t.
Definition: electronics.h:75
std::vector< float > match3DCuts
3D matching cuts
Definition: DataStructs.h:560
void ScoreVertices(TCSlice &slc)
Definition: TCVertex.cxx:2146
std::string PrintHit(const TCHit &tch)
Definition: Utils.cxx:6516
std::vector< float > Envelope
Definition: DataStructs.h:409
call study functions to develop cuts, etc
Definition: DataStructs.h:537
const geo::GeometryCore * geom
Definition: DataStructs.h:576
TMVA::Reader fMVAReader
std::vector< unsigned short > minPts
min number of Pts required to make a trajectory
Definition: DataStructs.h:566
PlaneID_t Plane
Index of the plane within its TPC.
Definition: geo_types.h:493
void DefineTjParents(TCSlice &slc, bool prt)
Definition: Utils.cxx:168
float HitsPosTick(const TCSlice &slc, const std::vector< unsigned int > &hitsInMultiplet, float &sum, HitStatus_t hitRequest)
Definition: Utils.cxx:4289
std::vector< unsigned int > firstWire
the first wire with a hit
Definition: DataStructs.h:654
std::vector< float > BeginChg
Definition: DataStructs.h:389
int ID
ID that is local to one slice.
Definition: DataStructs.h:205
std::vector< TCSlice > slices
Definition: DataStructs.cxx:13
std::bitset< 16 > modes
number of points to find AveChg
Definition: DataStructs.h:607
unsigned int NTPC(unsigned int cstat=0) const
Returns the total number of TPCs in the specified cryostat.
std::vector< TCHit > slHits
Definition: DataStructs.h:669
std::vector< float > chargeCuts
Definition: DataStructs.h:562
bool aveHitRMSValid
set true when the average hit RMS is well-known
Definition: DataStructs.h:647
bool equal(double a, double b)
Comparison tolerance, in centimeters.
std::vector< int > EnvPlane
Definition: DataStructs.h:410
std::vector< TrajPoint > seeds
Definition: DataStructs.cxx:14
float maxWireSkipNoSignal
max number of wires to skip w/o a signal on them
Definition: DataStructs.h:581
std::vector< short > MCSMom
Definition: DataStructs.h:397
int TPC
Select TPC.
Definition: DebugStruct.h:21
void CheckTraj(TCSlice &slc, Trajectory &tj)
Definition: StepUtils.cxx:929
std::vector< float > vtxScoreWeights
Definition: DataStructs.h:552
unsigned int CTP_t
Definition: DataStructs.h:47
geo::TPCID TPCID
Definition: DataStructs.h:662
bool DecodeDebugString(std::string strng)
Definition: Utils.cxx:5216
std::vector< int > StageNum
Definition: DataStructs.h:405
std::vector< recob::Hit > const * srcHits
Definition: DataStructs.h:623
std::bitset< 128 > useAlg
Max hit separation for making junk trajectories. &lt; 0 to turn off.
Definition: DataStructs.h:586
bool AnalyzeHits()
Definition: Utils.cxx:4394
Contains all timing reference information for the detector.
std::vector< float > pfpStitchCuts
cuts for stitching between TPCs
Definition: DataStructs.h:564
std::vector< short > deltaRayTag
Definition: DataStructs.h:554
save cosmic ray tree
Definition: DataStructs.h:538
unsigned short nPlanes
Definition: DataStructs.h:415
float VLAStepSize
Definition: DataStructs.h:584
short StepDir
-1 = going US (-&gt; small wire#), 1 = going DS (-&gt; large wire#)
Definition: DataStructs.h:210
std::bitset< 128 > AlgMod
Bit set if algorithm AlgBit_t modifed the trajectory.
Definition: DataStructs.h:193
call study functions to develop cuts, etc
Definition: DataStructs.h:535
void LastEndMerge(TCSlice &slc, CTP_t inCTP)
Definition: StepUtils.cxx:3108
std::vector< short > muonTag
Definition: DataStructs.h:555
void UpdateVxEnvironment(TCSlice &slc)
Definition: Utils.cxx:3862
std::vector< float > BeginWir
Definition: DataStructs.h:386
geo::PlaneID DecodeCTP(CTP_t CTP)
std::vector< float > EndChg
Definition: DataStructs.h:394
TrajClusterAlg(fhicl::ParameterSet const &pset)
std::bitset< 128 > dbgAlg
Allow user to turn on debug printing in algorithms (that print...)
Definition: DataStructs.h:587
std::vector< recob::Hit > const * allHits
Definition: DataStructs.h:622
CTP_t EncodeCTP(unsigned int cryo, unsigned int tpc, unsigned int plane)
Definition: DataStructs.h:52
std::vector< unsigned int > nWires
Definition: DataStructs.h:653
void KillPoorVertices(TCSlice &slc)
Definition: TCVertex.cxx:2174
std::vector< float > chkStopCuts
Bragg peak finder configuration.
Definition: DataStructs.h:557
int ID
ID of the recob::Slice (not the sub-slice)
Definition: DataStructs.h:664
void PrintDebugMode()
Definition: Utils.cxx:5450
void EndMerge(TCSlice &slc, CTP_t inCTP, bool lastPass)
Definition: StepUtils.cxx:3253
unsigned int subRun
Definition: DataStructs.h:636
void MergeTPHits(std::vector< unsigned int > &tpHits, std::vector< recob::Hit > &newHitCol, std::vector< unsigned int > &newHitAssns) const
void DefinePFPParents(TCSlice &slc, bool prt)
Definition: PFPUtils.cxx:2884
std::vector< float > vtx2DCuts
Max position pull, max Position error rms.
Definition: DataStructs.h:550
std::bitset< 8 > Strategy
Definition: DataStructs.h:213
void Finish3DShowers(TCSlice &slc)
Definition: TCShower.cxx:156
IDparameter< geo::TPCID > TPCID
Member type of validated geo::TPCID parameter.
void SetSourceHits(std::vector< recob::Hit > const &srcHits)
void FindPFParticles(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, TCSlice &slc)
Definition: PFPUtils.cxx:191
float multHitSep
preferentially &quot;merge&quot; hits with &lt; this separation
Definition: DataStructs.h:574
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
void ChkInTraj(std::string someText, TCSlice &slc)
void ReconstructAllTraj(detinfo::DetectorPropertiesData const &detProp, TCSlice &slc, CTP_t inCTP)
float JTMaxHitSep2
Definition: DataStructs.h:585
unsigned short NumPtsWithCharge(const TCSlice &slc, const Trajectory &tj, bool includeDeadWires)
Definition: Utils.cxx:2116
std::vector< int > EnvShowerID
Definition: DataStructs.h:412
void MakeJunkVertices(TCSlice &slc, const CTP_t &inCTP)
Definition: TCVertex.cxx:31
TCEvent evt
Definition: DataStructs.cxx:8
call study functions to develop cuts, etc (see TCTruth.cxx)
Definition: DataStructs.h:534
void Find2DVertices(detinfo::DetectorPropertiesData const &detProp, TCSlice &slc, const CTP_t &inCTP, unsigned short pass)
Definition: TCVertex.cxx:132
std::vector< int > IsShowerTj
Definition: DataStructs.h:402
std::vector< short > PlaneNum
Definition: DataStructs.h:399
short recoSlice
only reconstruct the slice with ID (0 = all)
Definition: DataStructs.h:588
void StitchPFPs()
Definition: PFPUtils.cxx:42
bool useChannelStatus
Definition: DataStructs.h:609
master switch for turning on debug mode
Definition: DataStructs.h:533
tag cosmic rays
Definition: DataStructs.h:539
don&#39;t mess with this line
Definition: DataStructs.h:496
art framework interface to geometry description
BEGIN_PROLOG could also be cout
auto const detProp
CTP_t CTP
set to an invalid CTP
Definition: DebugStruct.h:23
void SetTPEnvironment(TCSlice &slc, CTP_t inCTP)
Definition: Utils.cxx:3626
void FindJunkTraj(TCSlice &slc, CTP_t inCTP)