LArSoft  v10_04_05
Liquid Argon Software toolkit - https://larsoft.org/
SpacePts_module.cc
Go to the documentation of this file.
1 //
3 // \file SpacePts_module.cc
4 //
5 // \author echurch@fnal.gov, msoderbe@fnal.gov
6 //
7 // A very ArgoNeuTy module, for now.
9 
10 #include <string>
11 #include <vector>
12 
13 #include <algorithm>
14 #include <cmath>
15 #include <iomanip>
16 
17 // Framework includes
26 #include "fhiclcpp/ParameterSet.h"
28 
29 // LArSoft includes
41 
42 // ROOT includes
43 #include "TF1.h"
44 #include "TGraph.h"
45 #include "TMath.h"
46 #include "TVector2.h"
47 #include "TVector3.h"
48 
49 namespace trkf {
50 
51  class SpacePts : public art::EDProducer {
52  public:
53  explicit SpacePts(fhicl::ParameterSet const& pset);
54 
55  private:
56  void produce(art::Event& evt);
57 
58  int ftmatch; // tolerance for time matching (in time samples)
59  double fPreSamplings; // in ticks
61  std::string fClusterModuleLabel; // label for input cluster collection
62  std::string fEndPoint2DModuleLabel; //label for input EndPoint2D collection
63  }; // class SpacePts
64 
65  struct SortByWire {
67  {
68  return h1->Channel() < h2->Channel();
69  }
70  };
71 
72  //-------------------------------------------------
74  {
75  fPreSamplings = pset.get<double>("TicksOffset");
76  ftmatch = pset.get<int>("TMatch");
77  fClusterModuleLabel = pset.get<std::string>("ClusterModuleLabel");
78  fEndPoint2DModuleLabel = pset.get<std::string>("EndPoint2DModuleLabel");
79  fvertexclusterWindow = pset.get<double>("vertexclusterWindow");
80 
81  produces<std::vector<recob::Track>>();
82  produces<std::vector<recob::SpacePoint>>();
83  produces<art::Assns<recob::Track, recob::SpacePoint>>();
84  produces<art::Assns<recob::Track, recob::Cluster>>();
85  produces<art::Assns<recob::Track, recob::Hit>>();
86  produces<art::Assns<recob::SpacePoint, recob::Hit>>();
87  }
88 
89  //------------------------------------------------------------------------------------//
91  {
93  auto const& wireReadoutGeom = art::ServiceHandle<geo::WireReadout const>()->Get();
94  auto const detProp =
96 
98  // Make a std::unique_ptr<> for the thing you want to put into the event
99  // because that handles the memory management for you
101  auto tcol = std::make_unique<std::vector<recob::Track>>();
102  auto spcol = std::make_unique<std::vector<recob::SpacePoint>>();
103  auto tspassn = std::make_unique<art::Assns<recob::Track, recob::SpacePoint>>();
104  auto tcassn = std::make_unique<art::Assns<recob::Track, recob::Cluster>>();
105  auto thassn = std::make_unique<art::Assns<recob::Track, recob::Hit>>();
106  auto shassn = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
107 
108  // define TPC parameters
109  constexpr geo::TPCID tpcid{0, 0};
110  auto const& tpc = geom->TPC(tpcid);
111  TString tpcName = tpc.ActiveVolume()->GetName();
112 
113  //TPC dimensions
114  double YC = tpc.HalfHeight() * 2.; // TPC height in cm
115  double Angle = wireReadoutGeom.Plane(geo::PlaneID{tpcid, 1}).Wire(0).ThetaZ(false) -
116  TMath::Pi() / 2.; // wire angle with respect to the vertical direction
117  // Parameters temporary defined here, but possibly to be retrieved somewhere in the code
118  double timetick = 0.198; //time sample in us
119  double presamplings = fPreSamplings; // 60.;
120  const double wireShift =
121  50.; // half the number of wires from the Induction(Collection) plane intersecting with a wire from the Collection(Induction) plane.
122  double plane_pitch = wireReadoutGeom.PlanePitch(tpcid); //wire plane pitch in cm
123  double wire_pitch = wireReadoutGeom.FirstPlane(tpcid).WirePitch(); //wire pitch in cm
124  double Efield_drift = 0.5; // Electric Field in the drift region in kV/cm
125  double Efield_SI = 0.7; // Electric Field between Shield and Induction planes in kV/cm
126  double Efield_IC = 0.9; // Electric Field between Induction and Collection planes in kV/cm
127  double Temperature = 90.; // LAr Temperature in K
128 
129  double driftvelocity =
130  detProp.DriftVelocity(Efield_drift, Temperature); //drift velocity in the drift region (cm/us)
131  double driftvelocity_SI = detProp.DriftVelocity(
132  Efield_SI, Temperature); //drift velocity between shield and induction (cm/us)
133  double driftvelocity_IC = detProp.DriftVelocity(
134  Efield_IC, Temperature); //drift velocity between induction and collection (cm/us)
135  double timepitch = driftvelocity * timetick; //time sample (cm)
136  double tSI = plane_pitch / driftvelocity_SI /
137  timetick; //drift time between Shield and Collection planes (time samples)
138  double tIC = plane_pitch / driftvelocity_IC /
139  timetick; //drift time between Induction and Collection planes (time samples)
140 
141  // get input Cluster object(s).
142  art::Handle<std::vector<recob::Cluster>> clusterListHandle;
143  evt.getByLabel(fClusterModuleLabel, clusterListHandle);
144 
145  // get input EndPoint2D object(s).
146  art::Handle<std::vector<recob::EndPoint2D>> endpointListHandle;
147  evt.getByLabel(fEndPoint2DModuleLabel, endpointListHandle);
148 
150  if (evt.getByLabel(fEndPoint2DModuleLabel, endpointListHandle))
151  for (unsigned int i = 0; i < endpointListHandle->size(); ++i) {
152  art::Ptr<recob::EndPoint2D> endpointHolder(endpointListHandle, i);
153  endpointlist.push_back(endpointHolder);
154  }
155 
156  // Declare some vectors..
157  // Induction
158  std::vector<double> Iwirefirsts; // in cm
159  std::vector<double> Iwirelasts; // in cm
160  std::vector<double> Itimefirsts; // in cm
161  std::vector<double> Itimelasts; // in cm
162  std::vector<double> Itimefirsts_line; // in cm
163  std::vector<double> Itimelasts_line; // in cm
164  std::vector<std::vector<art::Ptr<recob::Hit>>> IclusHitlists;
165  std::vector<unsigned int> Icluster_count;
166 
167  // Collection
168  std::vector<double> Cwirefirsts; // in cm
169  std::vector<double> Cwirelasts; // in cm
170  std::vector<double> Ctimefirsts; // in cm
171  std::vector<double> Ctimelasts; // in cm
172  std::vector<double> Ctimefirsts_line; // in cm
173  std::vector<double> Ctimelasts_line; // in cm
174  std::vector<std::vector<art::Ptr<recob::Hit>>> CclusHitlists;
175  std::vector<unsigned int> Ccluster_count;
176 
177  art::FindManyP<recob::Hit> fm(clusterListHandle, evt, fClusterModuleLabel);
178 
179  for (unsigned int ii = 0; ii < clusterListHandle->size(); ++ii) {
180  art::Ptr<recob::Cluster> cl(clusterListHandle, ii);
181 
182  // Figure out which View the cluster belongs to
183  //only consider merged-lines that are associated with the vertex.
184  //this helps get rid of through-going muon background -spitz
185  int vtx2d_w = -99999;
186  double vtx2d_t = -99999;
187  bool found2dvtx = false;
188 
189  for (unsigned int j = 0; j < endpointlist.size(); j++) {
190  if (endpointlist[j]->View() == cl->View()) {
191  vtx2d_w = endpointlist[j]->WireID().Wire; //for update to EndPoint2D ... WK 4/22/13
192  vtx2d_t = endpointlist[j]->DriftTime();
193  found2dvtx = true;
194  break;
195  }
196  }
197  if (found2dvtx) {
198  double w = cl->StartWire();
199  double t = cl->StartTick();
200  double dtdw = std::tan(cl->StartAngle());
201  double t_vtx = t + dtdw * (vtx2d_w - w);
202  double dis = std::abs(vtx2d_t - t_vtx);
203  if (dis > fvertexclusterWindow) continue;
204  }
205  //else continue; //what to do if a 2D vertex is not found? perhaps vertex finder was not even run.
206 
207  // Some variables for the hit
208  float time; //hit time at maximum
209 
210  std::vector<art::Ptr<recob::Hit>> hitlist = fm.at(ii);
211  std::sort(hitlist.begin(), hitlist.end(), trkf::SortByWire());
212 
213  TGraph* the2Dtrack = new TGraph(hitlist.size());
214 
215  std::vector<double> wires;
216  std::vector<double> times;
217 
218  int np = 0;
219  //loop over cluster hits
220  for (std::vector<art::Ptr<recob::Hit>>::const_iterator theHit = hitlist.begin();
221  theHit != hitlist.end();
222  theHit++) {
223  //recover the Hit
224  // recob::Hit* theHit = (recob::Hit*)(*hitIter);
225  time = (*theHit)->PeakTime();
226 
227  time -= presamplings;
228 
229  if (wireReadoutGeom.SignalType((*theHit)->Channel()) == geo::kCollection)
230  time -= tIC; // Collection
231  //transform hit wire and time into cm
232  double wire_cm = 0.;
233  if (wireReadoutGeom.SignalType((*theHit)->Channel()) == geo::kInduction)
234  wire_cm = (double)(((*theHit)->WireID().Wire + 3.95) * wire_pitch);
235  else
236  wire_cm = (double)(((*theHit)->WireID().Wire + 1.84) * wire_pitch);
237 
238  //double time_cm = (double)(time * timepitch);
239  double time_cm;
240  if (time > tSI)
241  time_cm = (double)((time - tSI) * timepitch + tSI * driftvelocity_SI * timetick);
242  else
243  time_cm = time * driftvelocity_SI * timetick;
244 
245  wires.push_back(wire_cm);
246  times.push_back(time_cm);
247 
248  the2Dtrack->SetPoint(np, wire_cm, time_cm);
249  np++;
250  } //end of loop over cluster hits
251 
252  // fit the 2Dtrack and get some info to store
253  try {
254  the2Dtrack->Fit("pol1", "Q");
255  }
256  catch (...) {
257  std::cout << "The 2D track fit failed" << std::endl;
258  continue;
259  }
260 
261  TF1* pol1 = (TF1*)the2Dtrack->GetFunction("pol1");
262  double par[2];
263  pol1->GetParameters(par);
264  double intercept = par[0];
265  double slope = par[1];
266 
267  double w0 = wires.front(); // first hit wire (cm)
268  double w1 = wires.back(); // last hit wire (cm)
269  double t0 = times.front(); // first hit time (cm)
270  double t1 = times.back(); // last hit time (cm)
271  double t0_line = intercept + (w0)*slope; // time coordinate at wire w0 on the fit line (cm)
272  double t1_line = intercept + (w1)*slope; // time coordinate at wire w1 on the fit line (cm)
273 
274  // actually store the 2Dtrack info
275  switch (wireReadoutGeom.SignalType((*hitlist.begin())->Channel())) {
276  case geo::kInduction:
277  Iwirefirsts.push_back(w0);
278  Iwirelasts.push_back(w1);
279  Itimefirsts.push_back(t0);
280  Itimelasts.push_back(t1);
281  Itimefirsts_line.push_back(t0_line);
282  Itimelasts_line.push_back(t1_line);
283  IclusHitlists.push_back(hitlist);
284  Icluster_count.push_back(ii);
285  break;
286  case geo::kCollection:
287  Cwirefirsts.push_back(w0);
288  Cwirelasts.push_back(w1);
289  Ctimefirsts.push_back(t0);
290  Ctimelasts.push_back(t1);
291  Ctimefirsts_line.push_back(t0_line);
292  Ctimelasts_line.push_back(t1_line);
293  CclusHitlists.push_back(hitlist);
294  Ccluster_count.push_back(ii);
295  break;
296  case geo::kMysteryType: break;
297  }
298  delete pol1;
299  } // end of loop over all input clusters
300 
304 
305  for (unsigned int collectionIter = 0; collectionIter < CclusHitlists.size();
306  collectionIter++) { //loop over Collection view 2D tracks
307  // Recover previously stored info
308  double Cw0 = Cwirefirsts[collectionIter];
309  double Cw1 = Cwirelasts[collectionIter];
310  double Ct0_line = Ctimefirsts_line[collectionIter];
311  double Ct1_line = Ctimelasts_line[collectionIter];
312  std::vector<art::Ptr<recob::Hit>> hitsCtrk = CclusHitlists[collectionIter];
313 
314  double collLength =
315  TMath::Sqrt(TMath::Power(Ct1_line - Ct0_line, 2) + TMath::Power(Cw1 - Cw0, 2));
316 
317  for (unsigned int inductionIter = 0; inductionIter < IclusHitlists.size();
318  inductionIter++) { //loop over Induction view 2D tracks
319  // Recover previously stored info
320  double Iw0 = Iwirefirsts[inductionIter];
321  double Iw1 = Iwirelasts[inductionIter];
322  double It0_line = Itimefirsts_line[inductionIter];
323  double It1_line = Itimelasts_line[inductionIter];
324  std::vector<art::Ptr<recob::Hit>> hitsItrk = IclusHitlists[inductionIter];
325 
326  double indLength =
327  TMath::Sqrt(TMath::Power(It1_line - It0_line, 2) + TMath::Power(Iw1 - Iw0, 2));
328 
329  bool forward_match = ((std::abs(Ct0_line - It0_line) < ftmatch * timepitch) &&
330  (std::abs(Ct1_line - It1_line) < ftmatch * timepitch));
331  bool backward_match = ((std::abs(Ct0_line - It1_line) < ftmatch * timepitch) &&
332  (std::abs(Ct1_line - It0_line) < ftmatch * timepitch));
333 
334  if (forward_match || backward_match) {
335 
336  // Reconstruct the 3D track
337  TVector3 XYZ0, XYZ1; // track endpoints
338  if (forward_match) {
339  XYZ0.SetXYZ(Ct0_line,
340  (Cw0 - Iw0) / (2. * TMath::Sin(Angle)),
341  (Cw0 + Iw0) / (2. * TMath::Cos(Angle)) - YC / 2. * TMath::Tan(Angle));
342  XYZ1.SetXYZ(Ct1_line,
343  (Cw1 - Iw1) / (2. * TMath::Sin(Angle)),
344  (Cw1 + Iw1) / (2. * TMath::Cos(Angle)) - YC / 2. * TMath::Tan(Angle));
345  }
346  else {
347  XYZ0.SetXYZ(Ct0_line,
348  (Cw0 - Iw1) / (2. * TMath::Sin(Angle)),
349  (Cw0 + Iw1) / (2. * TMath::Cos(Angle)) - YC / 2. * TMath::Tan(Angle));
350  XYZ1.SetXYZ(Ct1_line,
351  (Cw1 - Iw0) / (2. * TMath::Sin(Angle)),
352  (Cw1 + Iw0) / (2. * TMath::Cos(Angle)) - YC / 2. * TMath::Tan(Angle));
353  }
354 
355  //compute track direction in Local co-ordinate system
356  //WARNING: There is an ambiguity introduced here for the case of backwards-going tracks.
357  //If available, vertex info. could sort this out.
358  TVector3 startpointVec, endpointVec;
359  TVector2 collVtx, indVtx;
360  if (XYZ0.Z() <= XYZ1.Z()) {
361  startpointVec.SetXYZ(XYZ0.X(), XYZ0.Y(), XYZ0.Z());
362  endpointVec.SetXYZ(XYZ1.X(), XYZ1.Y(), XYZ1.Z());
363  if (forward_match) {
364  collVtx.Set(Ct0_line, Cw0);
365  indVtx.Set(It0_line, Iw0);
366  }
367  else {
368  collVtx.Set(Ct0_line, Cw0);
369  indVtx.Set(It1_line, Iw1);
370  }
371  }
372  else {
373  startpointVec.SetXYZ(XYZ1.X(), XYZ1.Y(), XYZ1.Z());
374  endpointVec.SetXYZ(XYZ0.X(), XYZ0.Y(), XYZ0.Z());
375  if (forward_match) {
376  collVtx.Set(Ct1_line, Cw1);
377  indVtx.Set(It1_line, Iw1);
378  }
379  else {
380  collVtx.Set(Ct1_line, Cw1);
381  indVtx.Set(It0_line, Iw0);
382  }
383  }
384 
385  //compute track (normalized) cosine directions in the TPC co-ordinate system
386  TVector3 DirCos = endpointVec - startpointVec;
387 
388  //SetMag casues a crash if the magnitude of the vector is zero
389  try {
390  DirCos.SetMag(1.0); //normalize vector
391  }
392  catch (...) {
393  std::cout << "The Spacepoint is infinitely small" << std::endl;
394  continue;
395  }
396 
397  art::Ptr<recob::Cluster> cl1(clusterListHandle, Icluster_count[inductionIter]);
398  art::Ptr<recob::Cluster> cl2(clusterListHandle, Ccluster_count[collectionIter]);
399  art::PtrVector<recob::Cluster> clustersPerTrack;
400  clustersPerTrack.push_back(cl1);
401  clustersPerTrack.push_back(cl2);
402 
404  // Match hits
406 
407  //create collection of spacepoints that will be used when creating the Track object
408  std::vector<recob::SpacePoint> spacepoints;
409 
410  std::vector<art::Ptr<recob::Hit>> minhits =
411  hitsCtrk.size() <= hitsItrk.size() ? hitsCtrk : hitsItrk;
412  std::vector<art::Ptr<recob::Hit>> maxhits =
413  hitsItrk.size() < hitsCtrk.size() ? hitsCtrk : hitsItrk;
414 
415  std::vector<bool> maxhitsMatch(maxhits.size());
416  for (unsigned int it = 0; it < maxhits.size(); it++)
417  maxhitsMatch[it] = false;
418 
419  std::vector<recob::Hit*> hits3Dmatched;
420  // For the matching start from the view where the track projection presents less hits
421  unsigned int imaximum = 0;
422  size_t spStart = spcol->size();
423  for (unsigned int imin = 0; imin < minhits.size(); imin++) { //loop over hits
424  //get wire - time coordinate of the hit
425  geo::WireID hit1WireID = minhits[imin]->WireID();
426  auto const hitSigType = minhits[imin]->SignalType();
427  double w1 = 0;
428 
429  //the 3.95 and 1.84 below are the ArgoNeuT TPC offsets for the induction and collection plane, respectively and are in units of wire pitch.
430  if (hitSigType == geo::kInduction)
431  w1 = (double)((hit1WireID.Wire + 3.95) * wire_pitch);
432  else
433  w1 = (double)((hit1WireID.Wire + 1.84) * wire_pitch);
434 
435  double temptime1 = minhits[imin]->PeakTime() - presamplings;
436  if (hitSigType == geo::kCollection) temptime1 -= tIC;
437  double t1;
438  if (temptime1 > tSI)
439  t1 = (double)((temptime1 - tSI) * timepitch + tSI * driftvelocity_SI * timetick);
440  else
441  t1 = temptime1 * driftvelocity_SI * timetick;
442 
443  //get the track origin co-ordinates in the two views
444  TVector2 minVtx2D;
445  (hitSigType == geo::kCollection) ? minVtx2D.Set(collVtx.X(), collVtx.Y()) :
446  minVtx2D.Set(indVtx.X(), indVtx.Y());
447  TVector2 maxVtx2D;
448  (hitSigType == geo::kCollection) ? maxVtx2D.Set(indVtx.X(), indVtx.Y()) :
449  maxVtx2D.Set(collVtx.X(), collVtx.Y());
450 
451  double ratio =
452  (collLength > indLength) ? collLength / indLength : indLength / collLength;
453 
454  //compute the distance of the hit (imin) from the relative track origin
455  double minDistance = ratio * TMath::Sqrt(TMath::Power(t1 - minVtx2D.X(), 2) +
456  TMath::Power(w1 - minVtx2D.Y(), 2));
457 
458  //core matching algorithm
459  double difference = 9999999.;
460 
461  for (unsigned int imax = 0; imax < maxhits.size();
462  imax++) { //loop over hits of the other view
463  if (!maxhitsMatch[imax]) {
464  //get wire - time coordinate of the hit
465  geo::WireID hit2WireID = maxhits[imax]->WireID();
466  auto const hit2SigType = maxhits[imax]->SignalType();
467  double w2 = 0.;
468  if (hit2SigType == geo::kInduction)
469  w2 = (double)((hit2WireID.Wire + 3.95) * wire_pitch);
470  else
471  w2 = (double)((hit2WireID.Wire + 1.84) * wire_pitch);
472 
473  double temptime2 = maxhits[imax]->PeakTime() - presamplings;
474  if (hit2SigType == geo::kCollection) temptime2 -= tIC;
475  double t2;
476  if (temptime2 > tSI)
477  t2 = (double)((temptime2 - tSI) * timepitch + tSI * driftvelocity_SI * timetick);
478  else
479  t2 = temptime2 * driftvelocity_SI * timetick;
480 
481  bool timematch = (std::abs(t1 - t2) < ftmatch * timepitch);
482  bool wirematch = (std::abs(w1 - w2) < wireShift * wire_pitch);
483 
484  double maxDistance = TMath::Sqrt(TMath::Power(t2 - maxVtx2D.X(), 2) +
485  TMath::Power(w2 - maxVtx2D.Y(), 2));
486  if (wirematch && timematch && std::abs(maxDistance - minDistance) < difference) {
487  difference = std::abs(maxDistance - minDistance);
488  imaximum = imax;
489  }
490  }
491  }
492  maxhitsMatch[imaximum] = true;
493 
495  if (difference != 9999999.) {
496  sp_hits.push_back(minhits[imin]);
497  sp_hits.push_back(maxhits[imaximum]);
498  }
499 
500  // Get the time-wire co-ordinates of the matched hit
501  geo::WireID hit2WireID = maxhits[imaximum]->WireID();
502  auto const hit2SigType = maxhits[imaximum]->SignalType();
503 
504  double w1_match = 0.;
505  if (hit2SigType == geo::kInduction)
506  w1_match = (double)((hit2WireID.Wire + 3.95) * wire_pitch);
507  else
508  w1_match = (double)((hit2WireID.Wire + 1.84) * wire_pitch);
509 
510  double temptime3 = maxhits[imaximum]->PeakTime() - presamplings;
511  if (hit2SigType == geo::kCollection) temptime3 -= tIC;
512  double t1_match;
513  if (temptime3 > tSI)
514  t1_match =
515  (double)((temptime3 - tSI) * timepitch + tSI * driftvelocity_SI * timetick);
516  else
517  t1_match = temptime3 * driftvelocity_SI * timetick;
518 
519  // create the 3D hit, compute its co-ordinates and add it to the 3D hits list
520  double Ct = hitSigType == geo::kCollection ? t1 : t1_match;
521  double Cw = hit2SigType == geo::kCollection ? w1 : w1_match;
522  double Iw = hit2SigType == geo::kCollection ? w1_match : w1;
523 
524  const TVector3 hit3d(Ct,
525  (Cw - Iw) / (2. * TMath::Sin(Angle)),
526  (Cw + Iw) / (2. * TMath::Cos(Angle)) -
527  YC / 2. * TMath::Tan(Angle));
528 
529  Double_t hitcoord[3];
530  hitcoord[0] = hit3d.X();
531  hitcoord[1] = hit3d.Y();
532  hitcoord[2] = hit3d.Z();
533 
534  double err[6] = {util::kBogusD};
535  recob::SpacePoint mysp(hitcoord,
536  err,
538  spStart + spacepoints.size()); //3d point at end of track
539  // Don't add a spacepoint right on top of the last one.
540  const double eps(0.1); // 1mm
541  if (spacepoints.size() >= 1) {
542  TVector3 magNew(mysp.XYZ()[0], mysp.XYZ()[1], mysp.XYZ()[2]);
543  TVector3 magLast(spacepoints.back().XYZ()[0],
544  spacepoints.back().XYZ()[1],
545  spacepoints.back().XYZ()[2]);
546  if (!(magNew.Mag() >= magLast.Mag() + eps || magNew.Mag() <= magLast.Mag() - eps))
547  continue;
548  }
549  spacepoints.push_back(mysp);
550  spcol->push_back(mysp);
551  util::CreateAssn(evt, *spcol, sp_hits, *shassn);
552 
553  } //loop over min-hits
554 
555  size_t spEnd = spcol->size();
556 
557  // Add the 3D track to the vector of the reconstructed tracks
558  if (spacepoints.size() > 0) {
559 
560  // make a vector of the trajectory points along the track
561  std::vector<TVector3> xyz(spacepoints.size());
562  for (size_t s = 0; s < spacepoints.size(); ++s) {
563  xyz[s] = TVector3(spacepoints[s].XYZ());
564  }
565 
567  std::vector<TVector3> dircos(spacepoints.size(), DirCos);
568 
569  tcol->push_back(
572  recob::Track::Flags_t(xyz.size()),
573  false),
574  0,
575  -1.,
576  0,
579  tcol->size()));
580 
581  // make associations between the track and space points
582  util::CreateAssn(evt, *tcol, *spcol, *tspassn, spStart, spEnd);
583 
584  // now the track and clusters
585  util::CreateAssn(evt, *tcol, clustersPerTrack, *tcassn);
586 
587  // and the hits and track
588  art::FindManyP<recob::Hit> fmh(clustersPerTrack, evt, fClusterModuleLabel);
589  for (size_t cpt = 0; cpt < clustersPerTrack.size(); ++cpt)
590  util::CreateAssn(evt, *tcol, fmh.at(cpt), *thassn);
591  }
592  } //close match 2D tracks
593 
594  } //close loop over Induction view 2D tracks
595 
596  } //close loop over Collection xxview 2D tracks
597 
598  mf::LogVerbatim("Summary") << std::setfill('-') << std::setw(175) << "-" << std::setfill(' ');
599  mf::LogVerbatim("Summary") << "SpacePts Summary:";
600  for (unsigned int i = 0; i < tcol->size(); ++i)
601  mf::LogVerbatim("Summary") << tcol->at(i);
602 
603  evt.put(std::move(tcol));
604  evt.put(std::move(spcol));
605  evt.put(std::move(tspassn));
606  evt.put(std::move(tcassn));
607  evt.put(std::move(thassn));
608  evt.put(std::move(shassn));
609 
610  } // end SpacePts::produce()
611 
613 
614 } // end namespace
code to link reconstructed objects back to the MC truth information
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
TTree * t1
Definition: plottest35.C:26
Who knows?
Definition: geo_types.h:149
double fvertexclusterWindow
std::vector< Vector_t > convertCollToVector(std::vector< Vector > const &coll)
Definition: TrackingTypes.h:78
Declaration of signal hit object.
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.cc:6
The data type to uniquely identify a Plane.
Definition: geo_types.h:364
SpacePts(fhicl::ParameterSet const &pset)
TrackTrajectory::Flags_t Flags_t
Definition: Track.h:67
constexpr auto abs(T v)
Returns the absolute value of the argument.
float StartWire() const
Returns the wire coordinate of the start of the cluster.
Definition: Cluster.h:276
ROOT::Math::SMatrix< Double32_t, 5, 5, ROOT::Math::MatRepSym< Double32_t, 5 >> SMatrixSym55
cout<< "Opened file "<< fin<< " ixs= "<< ixs<< endl;if(ixs==0) hhh=(TH1F *) fff-> Get("h1")
Definition: AddMC.C:8
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:430
float StartAngle() const
Returns the starting angle of the cluster.
Definition: Cluster.h:461
std::string fClusterModuleLabel
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: Event.h:77
void produce(art::Event &evt)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:289
bool SortByWire(art::Ptr< recob::Hit > const &h1, art::Ptr< recob::Hit > const &h2)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:65
void push_back(Ptr< U > const &p)
Definition: PtrVector.h:435
Signal from induction planes.
Definition: geo_types.h:147
A trajectory in space reconstructed from hits.
const TGeoVolume * ActiveVolume() const
Returns the expected drift direction based on geometry.
Definition: TPCGeo.h:114
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
Definition: TrackingTypes.h:68
The data type to uniquely identify a TPC.
Definition: geo_types.h:306
Declaration of cluster object.
size_type size() const
Definition: PtrVector.h:302
TTree * t2
Definition: plottest35.C:36
TH1F * h2
Definition: plot.C:44
Encapsulate the geometry of a wire .
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.
bool operator()(art::Ptr< recob::Hit > const &h1, art::Ptr< recob::Hit > const &h2) const
geo::View_t View() const
Returns the view for this cluster.
Definition: Cluster.h:714
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane .
Provides recob::Track data product.
TH1F * h1
Definition: plot.C:41
constexpr double kBogusD
obviously bogus double value
TCEvent evt
Definition: DataStructs.cxx:8
std::string fEndPoint2DModuleLabel
TPCGeo const & TPC(TPCID const &tpcid=details::tpc_zero) const
Returns the specified TPC.
Definition: GeometryCore.h:448
Float_t w
Definition: plot.C:20
float StartTick() const
Returns the tick coordinate of the start of the cluster.
Definition: Cluster.h:287
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:278
art framework interface to geometry description
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Definition: Track.h:49
Signal from collection planes.
Definition: geo_types.h:148