LArPandoraShowerAlg.cxx
Go to the documentation of this file.
2 
4  : fUseCollectionOnly(pset.get<bool>("UseCollectionOnly"))
5  , fPFParticleLabel(pset.get<art::InputTag>("PFParticleLabel"))
6  , fSCEXFlip(pset.get<bool>("SCEXFlip"))
7  , fSCE(lar::providerFrom<spacecharge::SpaceChargeService>())
8  , fInitialTrackInputLabel(pset.get<std::string>("InitialTrackInputLabel"))
9  , fShowerStartPositionInputLabel(pset.get<std::string>("ShowerStartPositionInputLabel"))
10  , fShowerDirectionInputLabel(pset.get<std::string>("ShowerDirectionInputLabel"))
11  , fInitialTrackSpacePointsInputLabel(pset.get<std::string>("InitialTrackSpacePointsInputLabel"))
12 {}
13 
14 //Order the shower hits with regards to their projected length onto
15 //the shower direction from the shower start position. This is done
16 //in the 2D coordinate system (wire direction, x)
17 void
20  TVector3 const& ShowerStartPosition,
21  TVector3 const& ShowerDirection) const
22 {
23 
24  std::map<double, art::Ptr<recob::Hit>> OrderedHits;
25  art::Ptr<recob::Hit> startHit = hits.front();
26 
27  //Get the wireID
28  const geo::WireID startWireID = startHit->WireID();
29 
30  //Get the plane
31  const geo::PlaneID planeid = startWireID.asPlaneID();
32 
33  //Get the pitch
34  double pitch = fGeom->WirePitch(planeid);
35 
36  TVector2 Shower2DStartPosition = {
37  fGeom->WireCoordinate(ShowerStartPosition, startHit->WireID().planeID()) * pitch,
38  ShowerStartPosition.X()};
39 
40  //Vector of the plane
41  TVector3 PlaneDirection = fGeom->Plane(planeid).GetIncreasingWireDirection();
42 
43  //get the shower 2D direction
44  TVector2 Shower2DDirection = {ShowerDirection.Dot(PlaneDirection), ShowerDirection.X()};
45 
46  Shower2DDirection = Shower2DDirection.Unit();
47 
48  for (auto const& hit : hits) {
49 
50  //Get the wireID
51  const geo::WireID WireID = hit->WireID();
52 
53  if (WireID.asPlaneID() != startWireID.asPlaneID()) { break; }
54 
55  //Get the hit Vector.
56  TVector2 hitcoord = HitCoordinates(detProp, hit);
57 
58  //Order the hits based on the projection
59  TVector2 pos = hitcoord - Shower2DStartPosition;
60  OrderedHits[pos * Shower2DDirection] = hit;
61  }
62 
63  //Transform the shower.
64  std::vector<art::Ptr<recob::Hit>> showerHits;
65  std::transform(OrderedHits.begin(),
66  OrderedHits.end(),
67  std::back_inserter(showerHits),
68  [](std::pair<double, art::Ptr<recob::Hit>> const& hit) { return hit.second; });
69 
70  //Sometimes get the order wrong. Depends on direction compared to the plane Correct for it here:
71  art::Ptr<recob::Hit> frontHit = showerHits.front();
72  art::Ptr<recob::Hit> backHit = showerHits.back();
73 
74  //Get the hit Vector.
75  TVector2 fronthitcoord = HitCoordinates(detProp, frontHit);
76  TVector2 frontpos = fronthitcoord - Shower2DStartPosition;
77 
78  //Get the hit Vector.
79  TVector2 backhitcoord = HitCoordinates(detProp, backHit);
80  TVector2 backpos = backhitcoord - Shower2DStartPosition;
81 
82  double frontproj = frontpos * Shower2DDirection;
83  double backproj = backpos * Shower2DDirection;
84  if (std::abs(backproj) < std::abs(frontproj)) {
85  std::reverse(showerHits.begin(), showerHits.end());
86  }
87 
88  hits = showerHits;
89  return;
90 }
91 
92 //Orders the shower spacepoints with regards to there perpendicular distance from
93 //the shower axis.
94 void
97  TVector3 const& vertex,
98  TVector3 const& direction) const
99 {
100 
101  std::map<double, art::Ptr<recob::SpacePoint>> OrderedSpacePoints;
102 
103  //Loop over the spacepoints and get the pojected distance from the vertex.
104  for (auto const& sp : showersps) {
105 
106  // Get the perpendicular distance
107  double perp = SpacePointPerpendicular(sp, vertex, direction);
108 
109  //Add to the list
110  OrderedSpacePoints[perp] = sp;
111  }
112 
113  //Return an ordered list.
114  showersps.clear();
115  for (auto const& sp : OrderedSpacePoints) {
116  showersps.push_back(sp.second);
117  }
118 }
119 
120 //Orders the shower spacepoints with regards to there prejected length from
121 //the shower start position in the shower direction.
122 void
125  TVector3 const& vertex,
126  TVector3 const& direction) const
127 {
128 
129  std::map<double, art::Ptr<recob::SpacePoint>> OrderedSpacePoints;
130 
131  //Loop over the spacepoints and get the pojected distance from the vertex.
132  for (auto const& sp : showersps) {
133 
134  // Get the projection of the space point along the direction
135  double len = SpacePointProjection(sp, vertex, direction);
136 
137  //Add to the list
138  OrderedSpacePoints[len] = sp;
139  }
140 
141  //Return an ordered list.
142  showersps.clear();
143  for (auto const& sp : OrderedSpacePoints) {
144  showersps.push_back(sp.second);
145  }
146 }
147 
148 void
151  TVector3 const& vertex) const
152 {
153 
154  std::map<double, art::Ptr<recob::SpacePoint>> OrderedSpacePoints;
155 
156  //Loop over the spacepoints and get the pojected distance from the vertex.
157  for (auto const& sp : showersps) {
158 
159  //Get the distance away from the start
160  double mag = (SpacePointPosition(sp) - vertex).Mag();
161 
162  //Add to the list
163  OrderedSpacePoints[mag] = sp;
164  }
165 
166  //Return an ordered list.
167  showersps.clear();
168  for (auto const& sp : OrderedSpacePoints) {
169  showersps.push_back(sp.second);
170  }
171 }
172 
173 TVector3
175  std::vector<art::Ptr<recob::SpacePoint>> const& showersps) const
176 {
177 
178  if (showersps.empty()) return TVector3{};
179 
180  TVector3 centre_position;
181  for (auto const& sp : showersps) {
182  TVector3 pos = SpacePointPosition(sp);
183  centre_position += pos;
184  }
185  centre_position *= (1. / showersps.size());
186 
187  return centre_position;
188 }
189 
190 TVector3
192  detinfo::DetectorClocksData const& clockData,
193  detinfo::DetectorPropertiesData const& detProp,
194  std::vector<art::Ptr<recob::SpacePoint>> const& showerspcs,
195  art::FindManyP<recob::Hit> const& fmh) const
196 {
197 
198  float totalCharge = 0;
200  clockData, detProp, showerspcs, fmh, totalCharge);
201 }
202 
203 //Returns the vector to the shower centre and the total charge of the shower.
204 TVector3
206  detinfo::DetectorPropertiesData const& detProp,
207  std::vector<art::Ptr<recob::SpacePoint>> const& showersps,
208  art::FindManyP<recob::Hit> const& fmh,
209  float& totalCharge) const
210 {
211 
212  TVector3 pos, chargePoint = TVector3(0, 0, 0);
213 
214  //Loop over the spacepoints and get the charge weighted center.
215  for (auto const& sp : showersps) {
216 
217  //Get the position of the spacepoint
218  pos = SpacePointPosition(sp);
219 
220  //Get the associated hits
221  std::vector<art::Ptr<recob::Hit>> const& hits = fmh.at(sp.key());
222 
223  //Average the charge unless sepcified.
224  float charge = 0;
225  float charge2 = 0;
226  for (auto const& hit : hits) {
227 
228  if (fUseCollectionOnly) {
229  if (hit->SignalType() == geo::kCollection) {
230  charge = hit->Integral();
231  //Correct for the lifetime: Need to do other detproperites
232  charge *= std::exp((sampling_rate(clockData) * hit->PeakTime()) /
233  (detProp.ElectronLifetime() * 1e3));
234  break;
235  }
236  }
237  else {
238 
239  //Correct for the lifetime FIX: Need to do other detproperties somehow
240  double Q = hit->Integral() * std::exp((sampling_rate(clockData) * hit->PeakTime()) /
241  (detProp.ElectronLifetime() * 1e3));
242 
243  charge += Q;
244  charge2 += Q * Q;
245  }
246  }
247 
248  if (!fUseCollectionOnly) {
249  //Calculate the unbiased standard deviation and mean.
250  float mean = charge / ((float)hits.size());
251 
252  float rms = 1;
253 
254  if (hits.size() > 1) {
255  rms = std::sqrt((charge2 - charge * charge) / ((float)(hits.size() - 1)));
256  }
257 
258  charge = 0;
259  int n = 0;
260  for (auto const& hit : hits) {
261  double lifetimecorrection = std::exp((sampling_rate(clockData) * hit->PeakTime()) /
262  (detProp.ElectronLifetime() * 1e3));
263  if (hit->Integral() * lifetimecorrection > (mean - 2 * rms) &&
264  hit->Integral() * lifetimecorrection < (mean + 2 * rms)) {
265  charge += hit->Integral() * lifetimecorrection;
266  ++n;
267  }
268  }
269 
270  if (n == 0) {
271  mf::LogWarning("LArPandoraShowerAlg") << "no points used to make the charge value. \n";
272  }
273 
274  charge /= n;
275  }
276 
277  chargePoint += charge * pos;
278  totalCharge += charge;
279 
280  if (charge == 0) {
281  mf::LogWarning("LArPandoraShowerAlg") << "Averaged charge, within 2 sigma, for a spacepoint "
282  "is zero, Maybe this not a good method. \n";
283  }
284  }
285 
286  double intotalcharge = 1 / totalCharge;
287  TVector3 centre = chargePoint * intotalcharge;
288  return centre;
289 }
290 
291 //Return the spacepoint position in 3D cartesian coordinates.
292 TVector3
294 {
295 
296  const Double32_t* sp_xyz = sp->XYZ();
297  return TVector3{sp_xyz[0], sp_xyz[1], sp_xyz[2]};
298 }
299 
300 double
302  art::Ptr<recob::SpacePoint> const& sp_a,
303  art::Ptr<recob::SpacePoint> const& sp_b) const
304 {
305  TVector3 position_a = SpacePointPosition(sp_a);
306  TVector3 position_b = SpacePointPosition(sp_b);
307  return (position_a - position_b).Mag();
308 }
309 
310 //Return the charge of the spacepoint in ADC.
311 double
313  art::FindManyP<recob::Hit> const& fmh) const
314 {
315 
316  double Charge = 0;
317 
318  //Average over the charge even though there is only one
319  std::vector<art::Ptr<recob::Hit>> const& hits = fmh.at(sp.key());
320  for (auto const& hit : hits) {
321  Charge += hit->Integral();
322  }
323 
324  Charge /= (float)hits.size();
325 
326  return Charge;
327 }
328 
329 //Return the spacepoint time.
330 double
332  art::FindManyP<recob::Hit> const& fmh) const
333 {
334 
335  double Time = 0;
336 
337  //Average over the hits
338  std::vector<art::Ptr<recob::Hit>> const& hits = fmh.at(sp.key());
339  for (auto const& hit : hits) {
340  Time += hit->PeakTime();
341  }
342 
343  Time /= (float)hits.size();
344  return Time;
345 }
346 
347 //Return the cooordinates of the hit in cm in wire direction and x.
348 TVector2
350  art::Ptr<recob::Hit> const& hit) const
351 {
352 
353  //Get the pitch
354  const geo::WireID WireID = hit->WireID();
355  const geo::PlaneID planeid = WireID.asPlaneID();
356  double pitch = fGeom->WirePitch(planeid);
357 
358  return TVector2(WireID.Wire * pitch, detProp.ConvertTicksToX(hit->PeakTime(), planeid));
359 }
360 
361 double
363  TVector3 const& vertex,
364  TVector3 const& direction) const
365 {
366 
367  // Get the position of the spacepoint
369 
370  // Get the the projected length
371  return pos.Dot(direction);
372 }
373 
374 double
376  TVector3 const& vertex,
377  TVector3 const& direction) const
378 {
379 
380  // Get the projection of the spacepoint
381  double proj = shower::LArPandoraShowerAlg::SpacePointProjection(sp, vertex, direction);
382 
383  return shower::LArPandoraShowerAlg::SpacePointPerpendicular(sp, vertex, direction, proj);
384 }
385 
386 double
388  TVector3 const& vertex,
389  TVector3 const& direction,
390  double proj) const
391 {
392 
393  // Get the position of the spacepoint
395 
396  // Take away the projection * distance to find the perpendicular vector
397  pos = pos - proj * direction;
398 
399  // Get the the projected length
400  return pos.Mag();
401 }
402 
403 //Function to calculate the RMS at segments of the shower and calculate the gradient of this. If negative then the direction is pointing the opposite way to the correct one
404 double
406  const TVector3& ShowerCentre,
407  const TVector3& Direction,
408  const unsigned int nSegments) const
409 {
410 
411  if (nSegments == 0)
412  throw cet::exception("LArPandoraShowerAlg")
413  << "Unable to calculate RMS Shower Gradient with 0 segments" << std::endl;
414 
415  if (sps.size() < 3) return 0;
416 
417  //Order the spacepoints
418  this->OrderShowerSpacePoints(sps, ShowerCentre, Direction);
419 
420  //Get the length of the shower.
421  const double minProj = this->SpacePointProjection(sps[0], ShowerCentre, Direction);
422  const double maxProj = this->SpacePointProjection(sps[sps.size() - 1], ShowerCentre, Direction);
423 
424  const double length = (maxProj - minProj);
425  const double segmentsize = length / nSegments;
426 
427  if (segmentsize < std::numeric_limits<double>::epsilon()) return 0;
428 
429  std::map<int, std::vector<float>> len_segment_map;
430 
431  //Split the the spacepoints into segments.
432  for (auto const& sp : sps) {
433 
434  //Get the the projected length
435  const double len = this->SpacePointProjection(sp, ShowerCentre, Direction);
436 
437  //Get the length to the projection
438  const double len_perp = this->SpacePointPerpendicular(sp, ShowerCentre, Direction, len);
439 
440  int sg_len = std::round(len / segmentsize);
441  len_segment_map[sg_len].push_back(len_perp);
442  }
443 
444  int counter = 0;
445  float sumx = 0.f;
446  float sumy = 0.f;
447  float sumx2 = 0.f;
448  float sumxy = 0.f;
449 
450  //Get the rms of the segments and caclulate the gradient.
451  for (auto const& segment : len_segment_map) {
452  if (segment.second.size() < 2) continue;
453  float RMS = this->CalculateRMS(segment.second);
454 
455  // Check if the calculation failed
456  if (RMS < 0) continue;
457 
458  //Calculate the gradient using regression
459  sumx += segment.first;
460  sumy += RMS;
461  sumx2 += segment.first * segment.first;
462  sumxy += RMS * segment.first;
463  ++counter;
464  }
465 
466  const float denom = counter * sumx2 - sumx * sumx;
467 
468  return std::abs(denom) < std::numeric_limits<float>::epsilon() ?
469  0 :
470  (counter * sumxy - sumx * sumy) / denom;
471 }
472 
473 double
474 shower::LArPandoraShowerAlg::CalculateRMS(const std::vector<float>& perps) const
475 {
476 
477  if (perps.size() < 2) return std::numeric_limits<double>::lowest();
478 
479  float sum = 0;
480  for (const auto& perp : perps) {
481  sum += perp * perp;
482  }
483 
484  return std::sqrt(sum / (perps.size() - 1));
485 }
486 
487 double
489  TVector3 const& pos,
490  TVector3 const& dir,
491  unsigned int const& TPC) const
492 {
493  const geo::Point_t geoPos{pos.X(), pos.Y(), pos.z()};
494  const geo::Vector_t geoDir{dir.X(), dir.Y(), dir.Z()};
495  return shower::LArPandoraShowerAlg::SCECorrectPitch(pitch, geoPos, geoDir, TPC);
496 }
497 double
499  geo::Point_t const& pos,
500  geo::Vector_t const& dir,
501  unsigned int const& TPC) const
502 {
503 
504  if (!fSCE || !fSCE->EnableCalSpatialSCE()) {
505  throw cet::exception("LArPandoraShowerALG")
506  << "Trying to correct SCE pitch when service is not configured" << std::endl;
507  }
508  // As the input pos is sce corrected already, find uncorrected pos
509  const geo::Point_t uncorrectedPos = pos + fSCE->GetPosOffsets(pos);
510  //Get the size of the correction at pos
511  const geo::Vector_t posOffset = fSCE->GetCalPosOffsets(uncorrectedPos, TPC);
512 
513  //Get the position of next hit
514  const geo::Point_t nextPos = uncorrectedPos + pitch * dir;
515  //Get the offsets at the next pos
516  const geo::Vector_t nextPosOffset = fSCE->GetCalPosOffsets(nextPos, TPC);
517 
518  //Calculate the corrected pitch
519  const int xFlip(fSCEXFlip ? -1 : 1);
520  geo::Vector_t pitchVec{pitch * dir.X() + xFlip * (nextPosOffset.X() - posOffset.X()),
521  pitch * dir.Y() + (nextPosOffset.Y() - posOffset.Y()),
522  pitch * dir.Z() + (nextPosOffset.Z() - posOffset.Z())};
523 
524  return pitchVec.r();
525 }
526 
527 double
528 shower::LArPandoraShowerAlg::SCECorrectEField(double const& EField, TVector3 const& pos) const
529 {
530  const geo::Point_t geoPos{pos.X(), pos.Y(), pos.z()};
531  return shower::LArPandoraShowerAlg::SCECorrectEField(EField, geoPos);
532 }
533 double
535 {
536 
537  // Check the space charge service is properly configured
538  if (!fSCE || !fSCE->EnableSimEfieldSCE()) {
539  throw cet::exception("LArPandoraShowerALG")
540  << "Trying to correct SCE EField when service is not configured" << std::endl;
541  }
542  // Gets relative E field Distortions
543  geo::Vector_t EFieldOffsets = fSCE->GetEfieldOffsets(pos);
544  // Add 1 in X direction as this is the direction of the drift field
545  EFieldOffsets += geo::Vector_t{1, 0, 0};
546  // Convert to Absolute E Field from relative
547  EFieldOffsets *= EField;
548  // We only care about the magnitude for recombination
549  return EFieldOffsets.r();
550 }
551 
552 void
554  art::Event const& Event,
555  reco::shower::ShowerElementHolder const& ShowerEleHolder,
556  std::string const& evd_disp_name_append) const
557 {
558 
559  std::cout << "Making Debug Event Display" << std::endl;
560 
561  //Function for drawing reco showers to check direction and initial track selection
562 
563  // Get run info to make unique canvas names
564  int run = Event.run();
565  int subRun = Event.subRun();
566  int event = Event.event();
567  int PFPID = pfparticle->Self();
568 
569  // Create the canvas
570  TString canvasName = Form("canvas_%i_%i_%i_%i", run, subRun, event, PFPID);
571  if (evd_disp_name_append.length() > 0) canvasName += "_" + evd_disp_name_append;
572  TCanvas* canvas = tfs->make<TCanvas>(canvasName, canvasName);
573 
574  // Initialise variables
575  double x = 0;
576  double y = 0;
577  double z = 0;
578 
582 
583  // Get a bunch of associations (again)
584  // N.B. this is a horribly inefficient way of doing things but as this is only
585  // going to be used to debug I don't care, I would rather have generality in this case
586 
587  auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(fPFParticleLabel);
588 
589  // Get the spacepoint - PFParticle assn
590  art::FindManyP<recob::SpacePoint> fmspp(pfpHandle, Event, fPFParticleLabel);
591  if (!fmspp.isValid()) {
592  throw cet::exception("LArPandoraShowerAlg") << "Trying to get the spacepoint and failed. Somet\
593  hing is not configured correctly. Stopping ";
594  }
595 
596  // Get the SpacePoints
597  std::vector<art::Ptr<recob::SpacePoint>> const& spacePoints = fmspp.at(pfparticle.key());
598 
599  //We cannot progress with no spacepoints.
600  if (spacePoints.empty()) { return; }
601 
602  // Get info from shower property holder
603  TVector3 showerStartPosition = {-999, -999, -999};
604  TVector3 showerDirection = {-999, -999, -999};
605  std::vector<art::Ptr<recob::SpacePoint>> trackSpacePoints;
606 
607  //######################
608  //### Start Position ###
609  //######################
610  double startXYZ[3] = {-999, -999, -999};
611  if (!ShowerEleHolder.CheckElement(fShowerStartPositionInputLabel)) {
612  mf::LogError("LArPandoraShowerAlg") << "Start position not set, returning " << std::endl;
613  // return;
614  }
615  else {
616  ShowerEleHolder.GetElement(fShowerStartPositionInputLabel, showerStartPosition);
617  // Create 3D point at vertex, chosed to be origin for ease of use of display
618  startXYZ[0] = showerStartPosition.X();
619  startXYZ[1] = showerStartPosition.Y();
620  startXYZ[2] = showerStartPosition.Z();
621  }
622  auto startPoly = std::make_unique<TPolyMarker3D>(1, startXYZ);
623 
624  //########################
625  //### Shower Direction ###
626  //########################
627 
628  double xDirPoints[2] = {-999, -999};
629  double yDirPoints[2] = {-999, -999};
630  double zDirPoints[2] = {-999, -999};
631 
632  //initialise counter point
633  int point = 0;
634 
635  // Make 3D points for each spacepoint in the shower
636  auto allPoly = std::make_unique<TPolyMarker3D>(spacePoints.size());
637 
638  if (!ShowerEleHolder.CheckElement(fShowerDirectionInputLabel) &&
639  !ShowerEleHolder.CheckElement("ShowerStartPosition")) {
640  mf::LogError("LArPandoraShowerAlg") << "Direction not set, returning " << std::endl;
641  }
642  else {
643 
644  // Get the min and max projections along the direction to know how long to draw
645  ShowerEleHolder.GetElement(fShowerDirectionInputLabel, showerDirection);
646 
647  // the direction line
648  double minProj = std::numeric_limits<double>::max();
649  double maxProj = -std::numeric_limits<double>::max();
650 
651  //initialise counter point
652  int point = 0;
653 
654  for (auto spacePoint : spacePoints) {
656 
657  x = pos.X();
658  y = pos.Y();
659  z = pos.Z();
660  allPoly->SetPoint(point, x, y, z);
661  ++point;
662 
663  x_min = std::min(x, x_min);
664  x_max = std::max(x, x_max);
665  y_min = std::min(y, y_min);
666  y_max = std::max(y, y_max);
667  z_min = std::min(z, z_min);
668  z_max = std::max(z, z_max);
669 
670  // Calculate the projection of (point-startpoint) along the direction
672  spacePoint, showerStartPosition, showerDirection);
673  maxProj = std::max(proj, maxProj);
674  minProj = std::min(proj, minProj);
675  } // loop over spacepoints
676 
677  xDirPoints[0] = (showerStartPosition.X() + minProj * showerDirection.X());
678  xDirPoints[1] = (showerStartPosition.X() + maxProj * showerDirection.X());
679 
680  yDirPoints[0] = (showerStartPosition.Y() + minProj * showerDirection.Y());
681  yDirPoints[1] = (showerStartPosition.Y() + maxProj * showerDirection.Y());
682 
683  zDirPoints[0] = (showerStartPosition.Z() + minProj * showerDirection.Z());
684  zDirPoints[1] = (showerStartPosition.Z() + maxProj * showerDirection.Z());
685  }
686 
687  auto dirPoly = std::make_unique<TPolyLine3D>(2, xDirPoints, yDirPoints, zDirPoints);
688 
689  //#########################
690  //### Initial Track SPs ###
691  //#########################
692 
693  auto trackPoly = std::make_unique<TPolyMarker3D>(trackSpacePoints.size());
694  if (!ShowerEleHolder.CheckElement(fInitialTrackSpacePointsInputLabel)) {
695  mf::LogError("LArPandoraShowerAlg") << "TrackSpacePoints not set, returning " << std::endl;
696  // return;
697  }
698  else {
699  ShowerEleHolder.GetElement(fInitialTrackSpacePointsInputLabel, trackSpacePoints);
700  point = 0; // re-initialise counter
701  for (auto spacePoint : trackSpacePoints) {
703 
704  x = pos.X();
705  y = pos.Y();
706  z = pos.Z();
707  trackPoly->SetPoint(point, x, y, z);
708  ++point;
709  x_min = std::min(x, x_min);
710  x_max = std::max(x, x_max);
711  y_min = std::min(y, y_min);
712  y_max = std::max(y, y_max);
713  z_min = std::min(z, z_min);
714  z_max = std::max(z, z_max);
715  } // loop over track spacepoints
716  }
717 
718  //#########################
719  //### Other PFParticles ###
720  //#########################
721 
722  // we want to draw all of the PFParticles in the event
723  //Get the PFParticles
724  std::vector<art::Ptr<recob::PFParticle>> pfps;
725  art::fill_ptr_vector(pfps, pfpHandle);
726 
727  // initialse counters
728  // Split into tracks and showers to make it clearer what pandora is doing
729  int pfpTrackCounter = 0;
730  int pfpShowerCounter = 0;
731 
732  // initial loop over pfps to find nuber of spacepoints for tracks and showers
733  for (auto const& pfp : pfps) {
734  std::vector<art::Ptr<recob::SpacePoint>> const& sps = fmspp.at(pfp.key());
735  // If running pandora cheating it will call photons pdg 22
736  int pdg = abs(pfp->PdgCode()); // Track or shower
737  if (pdg == 11 || pdg == 22) { pfpShowerCounter += sps.size(); }
738  else {
739  pfpTrackCounter += sps.size();
740  }
741  }
742 
743  auto pfpPolyTrack = std::make_unique<TPolyMarker3D>(pfpTrackCounter);
744  auto pfpPolyShower = std::make_unique<TPolyMarker3D>(pfpShowerCounter);
745 
746  // initialise counters
747  int trackPoints = 0;
748  int showerPoints = 0;
749 
750  for (auto const& pfp : pfps) {
751  std::vector<art::Ptr<recob::SpacePoint>> const& sps = fmspp.at(pfp.key());
752  int pdg = abs(pfp->PdgCode()); // Track or shower
753  for (auto sp : sps) {
754  //TVector3 pos = shower::LArPandoraShowerAlg::SpacePointPosition(sp) - showerStartPosition;
756 
757  x = pos.X();
758  y = pos.Y();
759  z = pos.Z();
760  x_min = std::min(x, x_min);
761  x_max = std::max(x, x_max);
762  y_min = std::min(y, y_min);
763  y_max = std::max(y, y_max);
764  z_min = std::min(z, z_min);
765  z_max = std::max(z, z_max);
766 
767  // If running pandora cheating it will call photons pdg 22
768  if (pdg == 11 || pdg == 22) {
769  pfpPolyShower->SetPoint(showerPoints, x, y, z);
770  ++showerPoints;
771  }
772  else {
773  pfpPolyTrack->SetPoint(trackPoints, x, y, z);
774  ++trackPoints;
775  }
776  } // loop over sps
777 
778  //pfpPolyTrack->Draw();
779 
780  } // if (fDrawAllPFPs)
781 
782  //#################################
783  //### Initial Track Traj Points ###
784  //#################################
785 
786  auto TrackTrajPoly = std::make_unique<TPolyMarker3D>(TPolyMarker3D(1));
787  auto TrackInitTrajPoly = std::make_unique<TPolyMarker3D>(TPolyMarker3D(1));
788 
789  if (ShowerEleHolder.CheckElement(fInitialTrackInputLabel)) {
790 
791  //Get the track
792  recob::Track InitialTrack;
793  ShowerEleHolder.GetElement(fInitialTrackInputLabel, InitialTrack);
794 
795  if (InitialTrack.NumberTrajectoryPoints() != 0) {
796 
797  point = 0;
798  // Make 3D points for each trajectory point in the track stub
799  for (unsigned int traj = 0; traj < InitialTrack.NumberTrajectoryPoints(); ++traj) {
800 
801  //ignore bogus info.
802  auto flags = InitialTrack.FlagsAtPoint(traj);
803  if (flags.isSet(recob::TrajectoryPointFlagTraits::NoPoint)) { continue; }
804 
805  geo::Point_t TrajPositionPoint = InitialTrack.LocationAtPoint(traj);
806  TVector3 TrajPosition = {
807  TrajPositionPoint.X(), TrajPositionPoint.Y(), TrajPositionPoint.Z()};
808 
809  TVector3 pos = TrajPosition;
810 
811  x = pos.X();
812  y = pos.Y();
813  z = pos.Z();
814  TrackTrajPoly->SetPoint(point, x, y, z);
815  ++point;
816  } // loop over trajectory points
817 
818  geo::Point_t TrajInitPositionPoint = InitialTrack.LocationAtPoint(0);
819  TVector3 TrajPosition = {
820  TrajInitPositionPoint.X(), TrajInitPositionPoint.Y(), TrajInitPositionPoint.Z()};
821  TVector3 pos = TrajPosition;
822  x = pos.X();
823  y = pos.Y();
824  z = pos.Z();
825  TrackInitTrajPoly->SetPoint(TrackInitTrajPoly->GetN(), x, y, z);
826  }
827  }
828 
829  gStyle->SetOptStat(0);
830  TH3F axes("axes", "", 1, x_min, x_max, 1, y_min, y_max, 1, z_min, z_max);
831  axes.SetDirectory(0);
832  axes.GetXaxis()->SetTitle("X");
833  axes.GetYaxis()->SetTitle("Y");
834  axes.GetZaxis()->SetTitle("Z");
835  axes.Draw();
836 
837  // Draw all of the things
838  pfpPolyShower->SetMarkerStyle(20);
839  pfpPolyShower->SetMarkerColor(4);
840  pfpPolyShower->Draw();
841  pfpPolyTrack->SetMarkerStyle(20);
842  pfpPolyTrack->SetMarkerColor(6);
843  pfpPolyTrack->Draw();
844  allPoly->SetMarkerStyle(20);
845  allPoly->Draw();
846  trackPoly->SetMarkerStyle(20);
847  trackPoly->SetMarkerColor(2);
848  trackPoly->Draw();
849  startPoly->SetMarkerStyle(21);
850  startPoly->SetMarkerSize(0.5);
851  startPoly->SetMarkerColor(3);
852  startPoly->Draw();
853  dirPoly->SetLineWidth(1);
854  dirPoly->SetLineColor(6);
855  dirPoly->Draw();
856  TrackTrajPoly->SetMarkerStyle(22);
857  TrackTrajPoly->SetMarkerColor(7);
858  TrackTrajPoly->Draw();
859  TrackInitTrajPoly->SetMarkerStyle(22);
860  TrackInitTrajPoly->SetMarkerColor(4);
861  TrackInitTrajPoly->Draw();
862 
863  // Save the canvas. Don't usually need this when using TFileService but this in the alg
864  // not a module and didn't work without this so im going with it.
865  canvas->Write();
866 }
void OrderShowerSpacePointsPerpendicular(std::vector< art::Ptr< recob::SpacePoint >> &showersps, TVector3 const &vertex, TVector3 const &direction) const
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
virtual bool EnableSimEfieldSCE() const =0
double SCECorrectPitch(double const &pitch, TVector3 const &pos, TVector3 const &dir, unsigned int const &TPC) const
double DistanceBetweenSpacePoints(art::Ptr< recob::SpacePoint > const &sp_a, art::Ptr< recob::SpacePoint > const &sp_b) const
EventNumber_t event() const
Definition: DataViewImpl.cc:85
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
size_t Self() const
Returns the index of this particle.
Definition: PFParticle.h:92
double rms(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:40
void DebugEVD(art::Ptr< recob::PFParticle > const &pfparticle, art::Event const &Event, const reco::shower::ShowerElementHolder &ShowerEleHolder, std::string const &evd_disp_name_append="") const
static constexpr Flag_t NoPoint
The trajectory point is not defined.
double CalculateRMS(const std::vector< float > &perps) const
std::string string
Definition: nybbler.cc:12
virtual geo::Vector_t GetCalPosOffsets(geo::Point_t const &point, int const &TPCid) const =0
void OrderShowerSpacePoints(std::vector< art::Ptr< recob::SpacePoint >> &showersps, TVector3 const &vertex, TVector3 const &direction) const
geo::WireID WireID() const
Definition: Hit.h:233
art::ServiceHandle< geo::Geometry const > fGeom
Point_t const & LocationAtPoint(size_t i) const
Definition: Track.h:126
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
struct vector vector
const std::string fInitialTrackInputLabel
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:102
STL namespace.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
double RMSShowerGradient(std::vector< art::Ptr< recob::SpacePoint >> &sps, const TVector3 &ShowerCentre, const TVector3 &Direction, const unsigned int nSegments) const
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
Definition: geo_vectors.h:164
string dir
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
double SpacePointTime(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
Vector GetIncreasingWireDirection() const
Returns the direction of increasing wires.
Definition: PlaneGeo.h:457
double SCECorrectEField(double const &EField, TVector3 const &pos) const
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
T abs(T value)
LArPandoraShowerAlg(const fhicl::ParameterSet &pset)
virtual geo::Vector_t GetPosOffsets(geo::Point_t const &point) const =0
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
std::void_t< T > n
const std::string fInitialTrackSpacePointsInputLabel
key_type key() const noexcept
Definition: Ptr.h:216
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
Definition: DataViewImpl.h:441
bool CheckElement(const std::string &Name) const
const std::string fShowerDirectionInputLabel
SubRunNumber_t subRun() const
Definition: DataViewImpl.cc:78
constexpr PlaneID const & asPlaneID() const
Conversion to PlaneID (for convenience of notation).
Definition: geo_types.h:534
double SpacePointProjection(art::Ptr< recob::SpacePoint > const &sp, TVector3 const &vertex, TVector3 const &direction) const
RunNumber_t run() const
Definition: DataViewImpl.cc:71
static int max(int a, int b)
int GetElement(const std::string &Name, T &Element) const
const std::string fShowerStartPositionInputLabel
Detector simulation of raw signals on wires.
double ConvertTicksToX(double ticks, int p, int t, int c) const
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Definition: geo_vectors.h:184
double SpacePointCharge(art::Ptr< recob::SpacePoint > const &sp, art::FindManyP< recob::Hit > const &fmh) const
art::ServiceHandle< art::TFileService > tfs
virtual geo::Vector_t GetEfieldOffsets(geo::Point_t const &point) const =0
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
virtual bool EnableCalSpatialSCE() const =0
T min(sqlite3 *const db, std::string const &table_name, std::string const &column_name)
Definition: statistics.h:55
LArSoft-specific namespace.
Contains all timing reference information for the detector.
static unsigned int reverse(QString &chars, unsigned char *level, unsigned int a, unsigned int b)
Definition: qstring.cpp:11649
TVector2 HitCoordinates(detinfo::DetectorPropertiesData const &detProp, art::Ptr< recob::Hit > const &hit) const
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
const Double32_t * XYZ() const
Definition: SpacePoint.h:76
PointFlags_t const & FlagsAtPoint(size_t i) const
Definition: Track.h:118
TVector3 ShowerCentre(std::vector< art::Ptr< recob::SpacePoint >> const &showersps) const
T::provider_type const * providerFrom()
Returns a constant pointer to the provider of specified service.
Definition: ServiceUtil.h:63
list x
Definition: train.py:276
double SpacePointPerpendicular(art::Ptr< recob::SpacePoint > const &sp, TVector3 const &vertex, TVector3 const &direction) const
Direction
Definition: AssnsIter.h:13
constexpr PlaneID const & planeID() const
Definition: geo_types.h:638
auto const & get(AssnsNode< L, R, D > const &r)
Definition: AssnsNode.h:115
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:297
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
int bool
Definition: qglobal.h:345
spacecharge::SpaceCharge const * fSCE
double mean(sqlite3 *db, std::string const &table_name, std::string const &column_name)
Definition: statistics.cc:16
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
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
QTextStream & endl(QTextStream &s)
Event finding and building.
TVector3 SpacePointPosition(art::Ptr< recob::SpacePoint > const &sp) const
Signal from collection planes.
Definition: geo_types.h:146
void OrderShowerHits(detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> &hits, TVector3 const &ShowerDirection, TVector3 const &ShowerPosition) const
vertex reconstruction