LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
TrackShowerSeparationAlg.cxx
Go to the documentation of this file.
1 // Class: TrackShowerSeparationAlg
3 // File: TrackShowerSeparationAlg.cxx
4 // Author: Mike Wallbank (m.wallbank@sheffield.ac.uk), November 2015
5 //
6 // Track/shower separation class.
7 // Provides methods for removing hits associated with track-like
8 // objects.
9 // To be run after track reconstruction, before shower reconstruction.
11 
13 
15  this->reconfigure(pset);
16 }
17 
19  fConeAngle = pset.get<double>("ConeAngle");
20  fCylinderRadius = pset.get<double>("CylinderRadius");
21  fTrackVertexCut = pset.get<double>("TrackVertexCut");
22  fCylinderCut = pset.get<double>("CylinderCut");
23  fShowerConeCut = pset.get<double>("ShowerConeCut");
24 
25  fDebug = pset.get<int>("Debug",0);
26 }
27 
28 std::vector<art::Ptr<recob::Hit> > shower::TrackShowerSeparationAlg::SelectShowerHits(int event,
30  const std::vector<art::Ptr<recob::Track> >& tracks,
31  const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints,
32  const art::FindManyP<recob::Hit>& fmht,
33  const art::FindManyP<recob::Track>& fmth,
35  const art::FindManyP<recob::Track>& fmtsp) {
36 
37  // Ok, here we are again
38  // Playing the game in which no one wins, but everyone loses
39  // Trying to separate tracks from showers
40  // Ode to track/shower separation
41  // M Wallbank, Oct 2016
42 
43  // Showers are comprised of two topologically different parts:
44  // -- the 'shower track' (the initial part of the shower)
45  // -- the 'shower cone' (the part of the shower after the initial track when showering happens)
46 
47  // -
48  // --
49  // - -- --
50  // -- --- ---
51  // -- ---- --
52  // ----------- ----- - -- ---
53  // --- ---
54  // -- ---
55  // {=========}{==============================}
56  // shower track shower cone
57 
58  std::map<int,std::unique_ptr<ReconTrack> > reconTracks;
59  for (std::vector<art::Ptr<recob::Track> >::const_iterator trackIt = tracks.begin(); trackIt != tracks.end(); ++trackIt) {
60  std::unique_ptr<ReconTrack> track = std::make_unique<ReconTrack>(trackIt->key());
61  track->SetVertex((*trackIt)->Vertex<TVector3>());
62  track->SetEnd((*trackIt)->End<TVector3>());
63  track->SetVertexDir((*trackIt)->VertexDirection<TVector3>());
64  track->SetLength((*trackIt)->Length());
65  track->SetDirection(Gradient(*trackIt));
66  track->SetHits(fmht.at(trackIt->key()));
67  track->SetSpacePoints(fmspt.at(trackIt->key()));
68  const std::vector<art::Ptr<recob::SpacePoint> > spsss = fmspt.at(trackIt->key());
69  // std::cout << "Track " << trackIt->key() << " has " << spsss.size() << " space points and " << (*trackIt)->NumberTrajectoryPoints() << " traj points" << std::endl;
70  // if (trackIt->key() == 5)
71  // for (unsigned int i = 0; i < (*trackIt)->NumberTrajectoryPoints(); ++i)
72  // std::cout << "Traj point " << i << " has position (" << (*trackIt)->LocationAtPoint(i).X() << ", " << (*trackIt)->LocationAtPoint(i).Y() << ", " << (*trackIt)->LocationAtPoint(i).Z() << ")" << std::endl;
73  reconTracks[trackIt->key()] = std::move(track);
74  }
75 
76  // std::vector<int> showerLikeTracks, trackLikeTracks;
77  // std::vector<int> showerTracks = InitialTrackLikeSegment(reconTracks);
78 
79  // Consider the space point cylinder situation
80  double avCylinderSpacePoints = 0;
81  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
82  // Get the 3D properties of the track
83  TVector3 point = trackIt->second->Vertex();
84  TVector3 direction = trackIt->second->Direction();
85  // if (trackIt->second->Vertex().X() > 250 and trackIt->second->Vertex().X() < 252 and
86  // trackIt->second->Vertex().Y() > -440 and trackIt->second->Vertex().Y() < -430 and
87  // trackIt->second->Vertex().Z() > 1080 and trackIt->second->Vertex().Z() < 1090)
88  // std::cout << "Track " << trackIt->first << " begins at the most upstream vertex" << std::endl;
89  // if (trackIt->second->Vertex().X() > 254 and trackIt->second->Vertex().X() < 258 and
90  // trackIt->second->Vertex().Y() > -440 and trackIt->second->Vertex().Y() < -420 and
91  // trackIt->second->Vertex().Z() > 1115 and trackIt->second->Vertex().Z() < 1130)
92  // std::cout << "Track " << trackIt->first << " begins at the supposed vertex" << std::endl;
93  // if (trackIt->second->End().X() > 254 and trackIt->second->End().X() < 258 and
94  // trackIt->second->End().Y() > -440 and trackIt->second->End().Y() < -420 and
95  // trackIt->second->End().Z() > 1115 and trackIt->second->End().Z() < 1130)
96  // std::cout << "Track " << trackIt->first << " ends at the supposed vertex" << std::endl;
97  // std::cout << "Track " << trackIt->first << " has vertex (" << trackIt->second->Vertex().X() << ", " << trackIt->second->Vertex().Y() << ", " << trackIt->second->Vertex().Z() << ") and end (" << trackIt->second->End().X() << ", " << trackIt->second->End().Y() << ", " << trackIt->second->End().Z() << "), with vertex direction (" << trackIt->second->VertexDirection().X() << ", " << trackIt->second->VertexDirection().Y() << ", " << trackIt->second->VertexDirection().Z() << ")" << std::endl;
98  // Count space points in the volume around the track
99  for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
100  const std::vector<art::Ptr<recob::Track> > spTracks = fmtsp.at(spacePointIt->key());
101  if (find_if(spTracks.begin(), spTracks.end(), [&trackIt](const art::Ptr<recob::Track>& t){ return (int)t.key() == trackIt->first; }) != spTracks.end())
102  continue;
103  // Get the properties of this space point
104  TVector3 pos = SpacePointPos(*spacePointIt);
105  TVector3 proj = ProjPoint(pos, direction, point);
106  if ((pos-proj).Mag() < fCylinderRadius)
107  trackIt->second->AddCylinderSpacePoint(spacePointIt->key());
108  // if ((pos-proj).Mag() < fCylinderRadius and
109  // (pos-point)*direction > 0 and
110  // (pos-point)*direction < trackIt->second->Length())
111  // std::cout << "Space point " << spacePointIt->key() << " (" << pos.X() << ", " << pos.Y() << ", " << pos.Z() << ") in cylinder around track " << trackIt->first << " (assocatied with track " << spTracks.at(0).key() << "); point is (" << point.X() << ", " << point.Y() << ", " << point.Z() << "), proj end (" << ((trackIt->second->Length()*trackIt->second->VertexDirection())+point).X() << ", " << ((trackIt->second->Length()*trackIt->second->VertexDirection())+point).Y() << ", " << ((trackIt->second->Length()*trackIt->second->VertexDirection())+point).Z() << ")" << std::endl;
112  }
113  avCylinderSpacePoints += trackIt->second->CylinderSpacePointRatio();
114  }
115  avCylinderSpacePoints /= (double)reconTracks.size();
116 
117  if (fDebug > 1) {
118  std::cout << std::endl << "Cylinder space point ratios:" << std::endl;
119  for (std::map<int,std::unique_ptr<ReconTrack> >::const_iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt)
120  std::cout << " Track " << trackIt->first << " has cylinder space point ratio " << trackIt->second->CylinderSpacePointRatio() << " (event average " << avCylinderSpacePoints << ")" << std::endl;
121  }
122 
123  // Identify tracks
124  if (fDebug > 0)
125  std::cout << std::endl << "Identifying tracks:" << std::endl;
126  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt)
127  if (trackIt->second->CylinderSpacePointRatio() / avCylinderSpacePoints < fCylinderCut) {
128  if (fDebug > 0)
129  std::cout << " Making track " << trackIt->first << " a track (Type I)" << std::endl;
130  trackIt->second->MakeTrack();
131  }
132 
133  // for (std::map<int,std::unique_ptr<ReconTrack> >::const_iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
134  // if (!trackIt->second->IsTrack())
135  // continue;
136  // std::cout << "Track " << trackIt->first << " (tagged as track) is this close to other tracks:" << std::endl;
137  // for (std::map<int,std::unique_ptr<ReconTrack> >::const_iterator otherTrackIt = reconTracks.begin(); otherTrackIt != reconTracks.end(); ++otherTrackIt) {
138  // if (trackIt->first == otherTrackIt->first)
139  // continue;
140  // std::cout << " Other track " << otherTrackIt->first << " from track " << trackIt->first << " vertex: " << (otherTrackIt->second->Vertex()-trackIt->second->Vertex()).Mag() << " (vertex) and " << (otherTrackIt->second->End()-trackIt->second->Vertex()).Mag() << " (end); end: " << (otherTrackIt->second->Vertex()-trackIt->second->End()).Mag() << " (vertex) and " << (otherTrackIt->second->End()-trackIt->second->End()).Mag() << " (end)" << std::endl;
141  // }
142  // }
143 
144  // Identify further tracks
145  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
146  if (trackIt->second->IsTrack())
147  continue;
148  for (std::map<int,std::unique_ptr<ReconTrack> >::const_iterator otherTrackIt = reconTracks.begin(); otherTrackIt != reconTracks.end(); ++otherTrackIt) {
149  if (trackIt->first == otherTrackIt->first or !otherTrackIt->second->IsTrack())
150  continue;
151  if ((trackIt->second->Vertex() - otherTrackIt->second->Vertex()).Mag() < fTrackVertexCut or
152  (trackIt->second->Vertex() - otherTrackIt->second->End()).Mag() < fTrackVertexCut or
153  (trackIt->second->End() - otherTrackIt->second->Vertex()).Mag() < fTrackVertexCut or
154  (trackIt->second->End() - otherTrackIt->second->End()).Mag() < fTrackVertexCut) {
155  if (fDebug > 0)
156  std::cout << " Making track " << trackIt->first << " a track (Type II)" << std::endl;
157  trackIt->second->MakeTrack();
158  }
159  }
160  }
161 
162  // Consider removing false tracks by looking at their closest approach to any other track
163 
164  // Consider the space point cone situation
165  std::vector<art::Ptr<recob::SpacePoint> > showerSpacePoints;
166  for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
167  bool showerSpacePoint = true;
168  const std::vector<art::Ptr<recob::Track> > spacePointTracks = fmtsp.at(spacePointIt->key());
169  for (std::vector<art::Ptr<recob::Track> >::const_iterator trackIt = spacePointTracks.begin(); trackIt != spacePointTracks.end(); ++trackIt)
170  if (reconTracks[trackIt->key()]->IsTrack())
171  showerSpacePoint = false;
172  if (showerSpacePoint)
173  showerSpacePoints.push_back(*spacePointIt);
174  }
175 
176  // Identify tracks which slipped through and shower tracks
177  // For the moment, until the track tagging gets better at least, don't try to identify tracks from this
178  double avConeSize = 0;
179  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
180  for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = showerSpacePoints.begin(); spacePointIt != showerSpacePoints.end(); ++spacePointIt) {
181  bool associatedSpacePoint = false;
182  const std::vector<art::Ptr<recob::Track> > spTracks = fmtsp.at(spacePointIt->key());
183  for (std::vector<art::Ptr<recob::Track> >::const_iterator spTrackIt = spTracks.begin(); spTrackIt != spTracks.end(); ++spTrackIt)
184  if ((int)spTrackIt->key() == trackIt->first)
185  associatedSpacePoint = true;
186  if (associatedSpacePoint)
187  continue;
188  if ((SpacePointPos(*spacePointIt) - trackIt->second->Vertex()).Angle(trackIt->second->Direction()) < fConeAngle * TMath::Pi() / 180) {
189  trackIt->second->AddForwardSpacePoint(spacePointIt->key());
190  trackIt->second->AddForwardTrack(spTracks.at(0).key());
191  }
192  if ((SpacePointPos(*spacePointIt) - trackIt->second->Vertex()).Angle(-1*trackIt->second->Direction()) < fConeAngle * TMath::Pi() / 180) {
193  trackIt->second->AddBackwardSpacePoint(spacePointIt->key());
194  trackIt->second->AddBackwardTrack(spTracks.at(0).key());
195  }
196  }
197  avConeSize += trackIt->second->ConeSize();
198  }
199  avConeSize /= (double)reconTracks.size();
200  if (fDebug > 0)
201  std::cout << std::endl << "Identifying showers:" << std::endl;
202  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
203  // if (trackIt->second->ForwardSpacePoints() == 0)
204  // trackIt->second->MakeTrack();
205  // double distanceFromAverage = (trackIt->second->ConeSize() - avConeSize) / TMath::Abs(avConeSize);
206  // if (fDebug > 1)
207  // std::cout << " Track " << trackIt->first << " has cone size " << trackIt->second->ConeSize() << " (forward " << trackIt->second->ForwardSpacePoints() << ") and tracks " << trackIt->second->TrackConeSize() << " (average " << avConeSize << ", distance from average " << distanceFromAverage << ")" << std::endl;
208  // if (distanceFromAverage > fShowerConeCut) {
209  // trackIt->second->MakeShower();
210  // if (fDebug > 0)
211  // std::cout << " Making track " << trackIt->first << " a shower (Type I)" << std::endl;
212  // }
213  if (fDebug > 1)
214  std::cout << " Track " << trackIt->first << " has space point cone size " << trackIt->second->ConeSize() << " and track cone size " << trackIt->second->TrackConeSize() << std::endl;
215  if (TMath::Abs(trackIt->second->ConeSize()) > 30 and TMath::Abs(trackIt->second->TrackConeSize()) > 3) {
216  trackIt->second->MakeShower();
217  if (fDebug > 0)
218  std::cout << " Making track " << trackIt->first << " a shower (Type I)" << std::endl;
219  if (trackIt->second->ConeSize() < 0)
220  trackIt->second->FlipTrack();
221  }
222  }
223 
224  // Look for shower cones
225  std::cout << std::endl << " Shower cones:" << std::endl;
226  for (std::map<int,std::unique_ptr<ReconTrack> >::const_iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
227  if (trackIt->second->IsShower()) {
228  if (fDebug > 1)
229  std::cout << " Track " << trackIt->first << std::endl;
230  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator otherTrackIt = reconTracks.begin(); otherTrackIt != reconTracks.end(); ++otherTrackIt) {
231  if (trackIt->first == otherTrackIt->first or !otherTrackIt->second->IsUndetermined())
232  continue;
233  if ((otherTrackIt->second->Vertex()-trackIt->second->Vertex()).Angle(trackIt->second->Direction()) < fConeAngle * TMath::Pi() / 180 or
234  (otherTrackIt->second->End()-trackIt->second->Vertex()).Angle(trackIt->second->Direction()) < fConeAngle * TMath::Pi() / 180) {
235  std::cout << " " << otherTrackIt->first << std::endl;
236  otherTrackIt->second->MakeShower();
237  if (fDebug > 0)
238  std::cout << " Making track " << otherTrackIt->first << " a shower (Type II)" << std::endl;
239  }
240  }
241  }
242  }
243 
244  // Look at remaining undetermined tracks
245  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
246  if (trackIt->second->IsUndetermined()) {
247  // std::cout << "Remaining undetermined track " << trackIt->first << std::endl;
248  // std::cout << "Length is " << trackIt->second->Length() << " and rms of space points is " << SpacePointsRMS(trackIt->second->SpacePoints()) << std::endl;
249  trackIt->second->MakeShower();
250  }
251  }
252 
253  std::cout << std::endl << "Event " << event << " track shower separation:" << std::endl;
254  std::cout << "Shower initial tracks are:" << std::endl;
255  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt)
256  if (trackIt->second->IsShowerTrack())
257  std::cout << " " << trackIt->first << std::endl;
258 
259  std::cout << "Track tracks are:" << std::endl;
260  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt)
261  if (trackIt->second->IsTrack())
262  std::cout << " " << trackIt->first << std::endl;
263 
264  // Shower hits -- select all hits which aren't associated with a determined track
265  std::vector<art::Ptr<recob::Hit> > showerHits;
266  for (std::vector<art::Ptr<recob::Hit> >::const_iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt) {
267  bool showerHit = true;
268  const std::vector<art::Ptr<recob::Track> > hitTracks = fmth.at(hitIt->key());
269  for (std::vector<art::Ptr<recob::Track> >::const_iterator hitTrackIt = hitTracks.begin(); hitTrackIt != hitTracks.end(); ++hitTrackIt)
270  if (reconTracks[hitTrackIt->key()]->IsTrack())
271  showerHit = false;
272  if (showerHit)
273  showerHits.push_back(*hitIt);
274  }
275 
276  return showerHits;
277 
278 }
279 
280 std::vector<int> shower::TrackShowerSeparationAlg::InitialTrackLikeSegment(std::map<int,std::unique_ptr<ReconTrack> >& reconTracks) {
281 
282  // Consider the cones for each track
283  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
284 
285  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator otherTrackIt = reconTracks.begin(); otherTrackIt != reconTracks.end(); ++otherTrackIt) {
286 
287  if (trackIt->first == otherTrackIt->first)
288  continue;
289  if ((otherTrackIt->second->Vertex() - trackIt->second->Vertex()).Angle(trackIt->second->VertexDirection()) < fConeAngle * TMath::Pi() / 180 or
290  (otherTrackIt->second->End() - trackIt->second->Vertex()).Angle(trackIt->second->VertexDirection()) < fConeAngle * TMath::Pi() / 180) {
291  trackIt->second->AddForwardTrack(otherTrackIt->first);
292  otherTrackIt->second->AddShowerTrack(trackIt->first);
293  }
294  if ((otherTrackIt->second->Vertex() - trackIt->second->Vertex()).Angle(-1*trackIt->second->VertexDirection()) < fConeAngle * TMath::Pi() / 180 or
295  (otherTrackIt->second->End() - trackIt->second->Vertex()).Angle(-1*trackIt->second->VertexDirection()) < fConeAngle * TMath::Pi() / 180)
296  trackIt->second->AddBackwardTrack(otherTrackIt->first);
297 
298  }
299 
300  }
301 
302  // Determine if any of these tracks are actually shower tracks
303  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
304 
305  if (!trackIt->second->ShowerTrackCandidate())
306  continue;
307 
308  std::cout << "Track " << trackIt->first << " is a candidate, with shower cone tracks:" << std::endl;
309  const std::vector<int>& showerConeTracks = trackIt->second->ForwardConeTracks();
310  for (std::vector<int>::const_iterator showerConeTrackIt = showerConeTracks.begin(); showerConeTrackIt != showerConeTracks.end(); ++showerConeTrackIt)
311  std::cout << " " << *showerConeTrackIt << std::endl;
312 
313  bool isBestCandidate = true;
314  const std::vector<int>& showerTracks = trackIt->second->ShowerTracks();
315  for (std::vector<int>::const_iterator showerTrackIt = showerTracks.begin(); showerTrackIt != showerTracks.end(); ++showerTrackIt) {
316  if (!reconTracks[*showerTrackIt]->ShowerTrackCandidate())
317  continue;
318  if (std::find(showerConeTracks.begin(), showerConeTracks.end(), *showerTrackIt) == showerConeTracks.end())
319  continue;
320  if (reconTracks[*showerTrackIt]->IsShowerTrack())
321  continue;
322  if (trackIt->second->TrackConeSize() < reconTracks[*showerTrackIt]->TrackConeSize())
323  isBestCandidate = false;
324  }
325 
326  if (isBestCandidate)
327  trackIt->second->MakeShowerTrack();
328 
329  }
330 
331  // Determine which tracks are shower cones
332  std::vector<int> showerTracks;
333  for (std::map<int,std::unique_ptr<ReconTrack> >::iterator trackIt = reconTracks.begin(); trackIt != reconTracks.end(); ++trackIt) {
334  if (trackIt->second->IsShowerTrack()) {
335  showerTracks.push_back(trackIt->first);
336  const std::vector<int>& coneTracks = trackIt->second->ForwardConeTracks();
337  for (std::vector<int>::const_iterator coneTrackIt = coneTracks.begin(); coneTrackIt != coneTracks.end(); ++coneTrackIt)
338  reconTracks[*coneTrackIt]->MakeShowerCone();
339  }
340  }
341 
342  return showerTracks;
343 
344 }
345 
346 TVector3 shower::TrackShowerSeparationAlg::Gradient(const std::vector<TVector3>& points, const std::unique_ptr<TVector3>& dir) {
347 
348  int nhits = 0;
349  double sumx=0., sumy=0., sumz=0., sumx2=0., sumy2=0., sumxy=0., sumxz=0., sumyz=0.;
350  for (std::vector<TVector3>::const_iterator pointIt = points.begin(); pointIt != points.end(); ++pointIt) {
351  ++nhits;
352  sumx += pointIt->X();
353  sumy += pointIt->Y();
354  sumz += pointIt->Z();
355  sumx2 += pointIt->X() * pointIt->X();
356  sumy2 += pointIt->Y() * pointIt->Y();
357  sumxy += pointIt->X() * pointIt->Y();
358  sumxz += pointIt->X() * pointIt->Z();
359  sumyz += pointIt->Y() * pointIt->Z();
360  }
361 
362  double dydx = (nhits * sumxy - sumx * sumy) / (nhits * sumx2 - sumx * sumx);
363  double yint = (sumy * sumx2 - sumx * sumxy) / (nhits * sumx2 - sumx * sumx);
364  double dzdx = (nhits * sumxz - sumx * sumz) / (nhits * sumx2 - sumx * sumx);
365  double zint = (sumz * sumx2 - sumx * sumxz) / (nhits * sumx2 - sumx * sumx);
366  TVector2 directionXY = TVector2(1,dydx).Unit(), directionXZ = TVector2(1,dzdx).Unit();
367  TVector3 direction = TVector3(1,dydx,dzdx).Unit();
368  TVector3 intercept = TVector3(0,yint,zint);
369 
370  // Make sure the best fit direction is pointing correctly
371  if (dir and TMath::Abs(direction.Angle(*dir)) > TMath::Pi() / 2.)
372  direction *= -1;
373 
374  return direction;
375 
376 }
377 
379 
380  std::vector<TVector3> points;
381  std::unique_ptr<TVector3> dir;
382 
383  for (unsigned int traj = 0; traj < track->NumberTrajectoryPoints(); ++traj)
384  points.push_back(track->LocationAtPoint<TVector3>(traj));
385  dir = std::make_unique<TVector3>(track->VertexDirection<TVector3>());
386 
387  return Gradient(points, dir);
388 
389 }
390 
392 
393  std::vector<TVector3> points;
394  std::unique_ptr<TVector3> dir;
395 
396  for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt)
397  points.push_back(SpacePointPos(*spacePointIt));
398 
399  return Gradient(points, dir);
400 
401 }
402 
403 TVector3 shower::TrackShowerSeparationAlg::ProjPoint(const TVector3& point, const TVector3& direction, const TVector3& origin) {
404  return (point-origin).Dot(direction) * direction + origin;
405 }
406 
408  const double* xyz = spacePoint->XYZ();
409  return TVector3(xyz[0], xyz[1], xyz[2]);
410 }
411 
413 
414  TVector3 point = SpacePointPos(spacePoints.at(0));
415  TVector3 direction = Gradient(spacePoints);
416 
417  std::vector<double> distances;
418  for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
419  TVector3 pos = SpacePointPos(*spacePointIt);
420  TVector3 proj = ProjPoint(pos, direction, point);
421  distances.push_back((pos-proj).Mag());
422  }
423 
424  double rms = TMath::RMS(distances.begin(), distances.end());
425 
426  return rms;
427 
428 }
429 
430 
431 
432 
433 
434 // // --------------------------- OLD (late 2015) -------------------------------
435 
436 
437 // shower::TrackShowerSeparationAlg::TrackShowerSeparationAlg(fhicl::ParameterSet const& pset) {
438 // this->reconfigure(pset);
439 // // tree
440 // // ftree = tfs->make<TTree>("tree","tree");
441 // // ftree->Branch("Run",&Run);
442 // // ftree->Branch("Event",&Event);
443 // // ftree->Branch("Distance",&Distance);
444 // // ftree->Branch("Angle",&Angle);
445 // // ftree->Branch("Length",&Length);
446 // // ftree->Branch("TrackID",&TrackID);
447 // // ftree->Branch("PDG",&pdg);
448 // // ftree->Branch("NSpacePoints",&NSpacePoints);
449 // // ftree->Branch("AvDistance",&AvDistance);
450 // }
451 
452 // void shower::TrackShowerSeparationAlg::reconfigure(fhicl::ParameterSet const& pset) {
453 // fConeAngle = pset.get<double>("ConeAngle");
454 
455 // // fAngleCut = pset.get<double>("AngleCut");
456 // // fDistanceCut = pset.get<double>("DistanceCut");
457 // // fVertexProximityCut = pset.get<double>("VertexProximityCut");
458 // // fTrackProximityCut = pset.get<double>("TrackProximityCut");
459 // // fAvTrackHitDistance = pset.get<double>("AvTrackHitDistance");
460 // }
461 
462 // void shower::TrackShowerSeparationAlg::IdentifyTracksFromEventCentre(const std::vector<art::Ptr<recob::Track> >& tracks,
463 // const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints,
464 // const art::FindManyP<recob::Track>& fmtsp) {
465 
466 // // Find the charge weighted centre of the entire event!
467 // // ---- except space points don't have charge (could look at associated hits, but cba!)
468 // TVector3 centre = TVector3(0,0,0);
469 // for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt)
470 // centre += TVector3((*spacePointIt)->XYZ()[0], (*spacePointIt)->XYZ()[1], (*spacePointIt)->XYZ()[2]);
471 // centre *= 1/(double)spacePoints.size();
472 
473 // TVector3 trackVertex, trackEnd, trackDirection;
474 
475 // // Look at all tracks
476 // for (std::vector<art::Ptr<recob::Track> >::const_iterator trackIt = tracks.begin(); trackIt != tracks.end(); ++trackIt) {
477 
478 // trackVertex = ( ((*trackIt)->Vertex()-centre).Mag() > ((*trackIt)->End()-centre).Mag() ) ? (*trackIt)->Vertex() : (*trackIt)->End();
479 // trackEnd = ( ((*trackIt)->Vertex()-centre).Mag() > ((*trackIt)->End()-centre).Mag() ) ? (*trackIt)->End() : (*trackIt)->Vertex();
480 // trackDirection = ( ((*trackIt)->Vertex()-centre).Mag() > ((*trackIt)->End()-centre).Mag() ) ? (*trackIt)->VertexDirection() : (-1)*(*trackIt)->EndDirection();
481 
482 // // Get the space points not associated with the current track
483 // std::vector<art::Ptr<recob::SpacePoint> > surroundingSpacePoints = GetSurroundingSpacePoints(spacePoints, fmtsp, (*trackIt)->ID());
484 
485 // // // TRUE -- use truth to find which particle this track is associated with --------
486 // // std::vector<art::Ptr<recob::Hit> > trackHits = fmht.at(trackIt->key());
487 // // int trueTrackID = FindTrueTrack(trackHits);
488 // // const simb::MCParticle* trueParticle = backtracker->TrackIDToParticle(trueTrackID);
489 // // pdg = trueParticle->PdgCode();
490 // // Length = (*trackIt)->Length();
491 // // TrackID = (*trackIt)->ID();
492 // // // -------------------------------------------------------------------------------
493 
494 // bool showerLike = IdentifyShowerLikeTrack(trackEnd, trackDirection, surroundingSpacePoints);
495 
496 // if (showerLike) {
497 // fShowerLikeIDs.push_back((*trackIt)->ID());
498 // continue;
499 // }
500 
501 // else
502 // fTrackLikeIDs.push_back((*trackIt)->ID());
503 
504 // }
505 
506 // return;
507 
508 // }
509 
510 // void shower::TrackShowerSeparationAlg::IdentifyTracksNearTracks(const std::vector<art::Ptr<recob::Track> >& tracks) {
511 
512 // std::vector<art::Ptr<recob::Track> > identifiedTracks;
513 
514 // for (std::vector<art::Ptr<recob::Track> >::const_iterator trackIt = tracks.begin(); trackIt != tracks.end(); ++trackIt)
515 // if (std::find(fTrackLikeIDs.begin(), fTrackLikeIDs.end(), (*trackIt)->ID()) != fTrackLikeIDs.end())
516 // identifiedTracks.push_back(*trackIt);
517 
518 // // Look through tracks
519 // bool allTracksRemoved = false;
520 // while (!allTracksRemoved) {
521 
522 // int tracksRemoved = 0;
523 
524 // // Look through all the tracks
525 // for (std::vector<art::Ptr<recob::Track> >::const_iterator trackIt = tracks.begin(); trackIt != tracks.end(); ++trackIt) {
526 
527 // // Don't consider tracks already tagged as tracks!
528 // if (std::find(fTrackLikeIDs.begin(), fTrackLikeIDs.end(), (*trackIt)->ID()) != fTrackLikeIDs.end())
529 // continue;
530 
531 // bool trackShouldBeRemoved = false;
532 
533 // // Find tracks which are close to previously identified tracks
534 // for (std::vector<art::Ptr<recob::Track> >::iterator identifiedTrackIt = identifiedTracks.begin(); identifiedTrackIt != identifiedTracks.end(); ++identifiedTrackIt) {
535 // if (std::find(fShowerLikeIDs.begin(), fShowerLikeIDs.end(), (*trackIt)->ID()) != fShowerLikeIDs.end())
536 // continue;
537 // if ( ( ((*trackIt)->Vertex() - (*identifiedTrackIt)->Vertex()).Mag() < fTrackProximityCut ) or
538 // ( ((*trackIt)->Vertex() - (*identifiedTrackIt)->End() ).Mag() < fTrackProximityCut ) or
539 // ( ((*trackIt)->End() - (*identifiedTrackIt)->Vertex()).Mag() < fTrackProximityCut ) or
540 // ( ((*trackIt)->End() - (*identifiedTrackIt)->End() ).Mag() < fTrackProximityCut ) )
541 // trackShouldBeRemoved = true;
542 // }
543 
544 // // Tag this track as a 'track-like' object
545 // if (trackShouldBeRemoved) {
546 // fTrackLikeIDs.push_back((*trackIt)->ID());
547 // identifiedTracks.push_back(*trackIt);
548 // ++tracksRemoved;
549 // }
550 
551 // }
552 
553 // // If there were no tracks removed then we'll call it a day
554 // if (tracksRemoved == 0)
555 // allTracksRemoved = true;
556 
557 // }
558 
559 // return;
560 
561 // }
562 
563 // void shower::TrackShowerSeparationAlg::IdentifyTracksNearVertex(const art::Ptr<recob::Vertex>& vertex,
564 // const std::vector<art::Ptr<recob::Track> >& tracks,
565 // const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints,
566 // const art::FindManyP<recob::Track>& fmtsp) {
567 
568 // double xyz[3];
569 // vertex->XYZ(xyz);
570 // TVector3 vertexPos = TVector3(xyz[0], xyz[1], xyz[2]);
571 
572 // // Look at each track
573 // for (std::vector<art::Ptr<recob::Track> >::const_iterator trackIt = tracks.begin(); trackIt != tracks.end(); ++trackIt) {
574 
575 // TVector3 end, direction;
576 
577 // // See if either end is close to the vertex
578 // if ( ((*trackIt)->Vertex() - vertexPos).Mag() < fVertexProximityCut or
579 // ((*trackIt)->End() - vertexPos).Mag() < fVertexProximityCut) {
580 // end = ((*trackIt)->Vertex() - vertexPos).Mag() < ((*trackIt)->End() - vertexPos).Mag() ? (*trackIt)->End() : (*trackIt)->VertexDirection();
581 // direction = ((*trackIt)->Vertex() - vertexPos).Mag() < ((*trackIt)->End() - vertexPos).Mag() ? (*trackIt)->VertexDirection() : (-1)*(*trackIt)->VertexDirection();
582 // }
583 
584 // else
585 // continue;
586 
587 // // Get the space points not associated with the current track
588 // std::vector<art::Ptr<recob::SpacePoint> > surroundingSpacePoints = GetSurroundingSpacePoints(spacePoints, fmtsp, (*trackIt)->ID());
589 
590 // // Make sure this track start isn't a shower start
591 // bool showerLike = IdentifyShowerLikeTrack(end, direction, surroundingSpacePoints);
592 
593 // if (showerLike) {
594 // fShowerLikeIDs.push_back((*trackIt)->ID());
595 // continue;
596 // }
597 
598 // // This track originates from near the interaction vertex and is not shower-like
599 // fTrackLikeIDs.push_back((*trackIt)->ID());
600 
601 // }
602 
603 // return;
604 
605 // }
606 
607 // bool shower::TrackShowerSeparationAlg::IdentifyShowerLikeTrack(const TVector3& end,
608 // const TVector3& direction,
609 // const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints) {
610 
611 // std::vector<art::Ptr<recob::SpacePoint> > spacePointsInCone = GetSpacePointsInCone(spacePoints, end, direction);
612 
613 // if (spacePointsInCone.size() < 2)
614 // return false;
615 
616 // // Get the average spread of these space points
617 // double spread = SpacePointSpread(spacePointsInCone);
618 
619 // if (spread < fAvTrackHitDistance)
620 // return false;
621 
622 // return true;
623 
624 // }
625 
626 // std::vector<art::Ptr<recob::Hit> > shower::TrackShowerSeparationAlg::FillHitsToCluster(const std::vector<art::Ptr<recob::Hit> >& initialHits,
627 // const art::FindManyP<recob::Track>& fmt) {
628 
629 // // Container to fill with shower-like hits
630 // std::vector<art::Ptr<recob::Hit> > hitsToCluster;
631 
632 // for (std::vector<art::Ptr<recob::Hit> >::const_iterator initialHit = initialHits.begin(); initialHit != initialHits.end(); ++initialHit) {
633 // std::vector<art::Ptr<recob::Track> > showerTracks = fmt.at(initialHit->key());
634 // if ( (showerTracks.size() and (std::find(fTrackLikeIDs.begin(), fTrackLikeIDs.end(), showerTracks.at(0)->ID()) == fTrackLikeIDs.end()))//hit on track-like track
635 // || !showerTracks.size() )//hit not on any track
636 // hitsToCluster.push_back(*initialHit);
637 // }
638 
639 // return hitsToCluster;
640 
641 // }
642 
643 // int shower::TrackShowerSeparationAlg::FindTrackID(const art::Ptr<recob::Hit>& hit) {
644 // double particleEnergy = 0;
645 // int likelyTrackID = 0;
646 // std::vector<sim::TrackIDE> trackIDs = backtracker->HitToTrackID(hit);
647 // for (unsigned int idIt = 0; idIt < trackIDs.size(); ++idIt) {
648 // if (trackIDs.at(idIt).energy > particleEnergy) {
649 // particleEnergy = trackIDs.at(idIt).energy;
650 // likelyTrackID = TMath::Abs(trackIDs.at(idIt).trackID);
651 // }
652 // }
653 // return likelyTrackID;
654 // }
655 
656 // int shower::TrackShowerSeparationAlg::FindTrueTrack(const std::vector<art::Ptr<recob::Hit> >& trackHits) {
657 // std::map<int,double> trackMap;
658 // for (std::vector<art::Ptr<recob::Hit> >::const_iterator trackHitIt = trackHits.begin(); trackHitIt != trackHits.end(); ++trackHitIt) {
659 // art::Ptr<recob::Hit> hit = *trackHitIt;
660 // int trackID = FindTrackID(hit);
661 // trackMap[trackID] += hit->Integral();
662 // }
663 // //return std::max_element(trackMap.begin(), trackMap.end(), [](const std::pair<int,double>& p1, const std::pair<int,double>& p2) {return p1.second < p2.second;} )->first;
664 // double highestCharge = 0;
665 // int clusterTrack = 0;
666 // for (std::map<int,double>::iterator trackIt = trackMap.begin(); trackIt != trackMap.end(); ++trackIt)
667 // if (trackIt->second > highestCharge) {
668 // highestCharge = trackIt->second;
669 // clusterTrack = trackIt->first;
670 // }
671 // return clusterTrack;
672 // }
673 
674 // std::vector<art::Ptr<recob::SpacePoint> > shower::TrackShowerSeparationAlg::GetSurroundingSpacePoints(const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints,
675 // const art::FindManyP<recob::Track>& fmt,
676 // unsigned int trackID) {
677 
678 // // The space points to return
679 // std::vector<art::Ptr<recob::SpacePoint> > surroundingSpacePoints;
680 
681 // for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
682 
683 // bool spacePointIsInCurrentTrack = false;
684 
685 // std::vector<art::Ptr<recob::Track> > spacePointTracks = fmt.at(spacePointIt->key());
686 // for (std::vector<art::Ptr<recob::Track> >::iterator spacePointTrackIt = spacePointTracks.begin(); spacePointTrackIt != spacePointTracks.end(); ++spacePointTrackIt)
687 // if (spacePointTrackIt->key() == trackID) spacePointIsInCurrentTrack = true;
688 
689 // if (!spacePointIsInCurrentTrack)
690 // surroundingSpacePoints.push_back(*spacePointIt);
691 
692 // }
693 
694 // return surroundingSpacePoints;
695 
696 // }
697 
698 // std::vector<art::Ptr<recob::SpacePoint> > shower::TrackShowerSeparationAlg::GetSpacePointsInCone(const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints,
699 // const TVector3& trackEnd,
700 // const TVector3& trackDirection) {
701 
702 // // The space points in cone to return
703 // std::vector<art::Ptr<recob::SpacePoint> > spacePointsInCone;
704 
705 // TVector3 spacePointPos, spacePointProj;
706 // double displacementFromAxis, distanceFromTrackEnd, projDistanceFromTrackEnd, angleFromTrackEnd;
707 
708 // for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
709 
710 // // Get the properties of this space point
711 // const double* xyz = (*spacePointIt)->XYZ();
712 // spacePointPos = TVector3(xyz[0], xyz[1], xyz[2]);
713 // spacePointProj = ((spacePointPos-trackEnd).Dot(trackDirection))*trackDirection + trackEnd;
714 // displacementFromAxis = (spacePointProj - spacePointPos).Mag();
715 // distanceFromTrackEnd = (spacePointPos - trackEnd).Mag();
716 // projDistanceFromTrackEnd = (spacePointProj - trackEnd).Mag();
717 // angleFromTrackEnd = TMath::ASin(displacementFromAxis/distanceFromTrackEnd) * 180 / TMath::Pi();
718 
719 // if ( (projDistanceFromTrackEnd < fDistanceCut) and (angleFromTrackEnd < fAngleCut) and ((spacePointProj-trackEnd).Dot(trackDirection) > 0) )
720 // spacePointsInCone.push_back(*spacePointIt);
721 
722 // }
723 
724 // return spacePointsInCone;
725 
726 // }
727 
728 // std::vector<art::Ptr<recob::Hit> > shower::TrackShowerSeparationAlg::RemoveTrackHits(const std::vector<art::Ptr<recob::Hit> >& initialHits,
729 // const std::vector<art::Ptr<recob::Track> >& tracks,
730 // const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints,
731 // const std::vector<art::Ptr<recob::Vertex> >& vertices,
732 // const art::FindManyP<recob::Track>& fmth,
733 // const art::FindManyP<recob::Track>& fmtsp,
734 // const art::FindManyP<recob::Hit>& fmh,
735 // int event,
736 // int run) {
737 
738 // Event = event;
739 // Run = run;
740 
741 // if (spacePoints.size() == 0)
742 // return initialHits;
743 
744 // // Container for shower-like hits
745 // std::vector<art::Ptr<recob::Hit> > hitsToCluster;
746 
747 // fTrackLikeIDs.clear();
748 // fShowerLikeIDs.clear();
749 
750 // // Find the vertex furthest upstream (if it exists)
751 // art::Ptr<recob::Vertex> vertex;
752 // for (std::vector<art::Ptr<recob::Vertex> >::const_iterator vertexIt = vertices.begin(); vertexIt != vertices.end(); ++vertexIt) {
753 // double xyzNew[3], xyzOld[3];
754 // (*vertexIt)->XYZ(xyzNew);
755 // if (vertex.isNull())
756 // vertex = *vertexIt;
757 // else {
758 // vertex->XYZ(xyzOld);
759 // if (xyzNew[2] < xyzOld[2])
760 // vertex = *vertexIt;
761 // }
762 // }
763 
764 // // If we have a vertex then, for the time being, use it to remove tracks which are too close!
765 // if (!vertex.isNull())
766 // this->IdentifyTracksNearVertex(vertex, tracks, spacePoints, fmtsp);
767 
768 // // If no vertex, things are harder
769 // else
770 // this->IdentifyTracksFromEventCentre(tracks, spacePoints, fmtsp);
771 
772 // // Once we've identified some tracks, can look for others at the ends
773 // this->IdentifyTracksNearTracks(tracks);
774 
775 // hitsToCluster = FillHitsToCluster(initialHits, fmth);
776 
777 // return hitsToCluster;
778 
779 // }
780 
781 // std::vector<art::Ptr<recob::Hit> > shower::TrackShowerSeparationAlg::RemoveTrackHits(const std::vector<art::Ptr<recob::Hit> >& hits,
782 // const std::vector<art::Ptr<recob::PFParticle> > pfParticles,
783 // const art::FindManyP<recob::Cluster>& fmc,
784 // const art::FindManyP<recob::Hit>& fmh) {
785 
786 // std::vector<art::Ptr<recob::Hit> > showerHits;
787 
788 // // Use information from Pandora to identify shower-like hits
789 // for (std::vector<art::Ptr<recob::PFParticle> >::const_iterator pfParticleIt = pfParticles.begin(); pfParticleIt != pfParticles.end(); ++pfParticleIt) {
790 
791 // // See if this is a shower particle
792 // if ((*pfParticleIt)->PdgCode() == 11) {
793 // std::vector<art::Ptr<recob::Cluster> > clusters = fmc.at(pfParticleIt->key());
794 // for (std::vector<art::Ptr<recob::Cluster> >::iterator clusterIt = clusters.begin(); clusterIt != clusters.end(); ++clusterIt) {
795 // std::vector<art::Ptr<recob::Hit> > hits = fmh.at(clusterIt->key());
796 // for (std::vector<art::Ptr<recob::Hit> >::iterator hitIt = hits.begin(); hitIt != hits.end(); ++hitIt)
797 // showerHits.push_back(*hitIt);
798 // }
799 // }
800 
801 // }
802 
803 // return showerHits;
804 
805 // }
806 
807 // double shower::TrackShowerSeparationAlg::SpacePointSpread(const std::vector<art::Ptr<recob::SpacePoint> >& spacePoints) {
808 
809 // /// Finds the spread of a set of space points about their central axis
810 
811 // // Find the centre of the space points
812 // TVector3 centre = TVector3(0,0,0);
813 // for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt)
814 // centre += TVector3((*spacePointIt)->XYZ()[0], (*spacePointIt)->XYZ()[1], (*spacePointIt)->XYZ()[2]);
815 // centre *= 1/(double)spacePoints.size();
816 
817 // // Find the central axis of the space points
818 // TPrincipal* pca = new TPrincipal(3,"");
819 // for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt)
820 // pca->AddRow((*spacePointIt)->XYZ());
821 // pca->MakePrincipals();
822 // const TMatrixD* eigenvectors = pca->GetEigenVectors();
823 // TVector3 spacePointDir = TVector3((*eigenvectors)[0][0], (*eigenvectors)[1][0], (*eigenvectors)[2][0]);
824 // delete pca;
825 
826 // // See if the space points form something which may resemble a track (i.e. straight line) or a shower
827 // double avDistanceFromCentralAxis = 0;
828 // for (std::vector<art::Ptr<recob::SpacePoint> >::const_iterator spacePointIt = spacePoints.begin(); spacePointIt != spacePoints.end(); ++spacePointIt) {
829 // const double* xyz = (*spacePointIt)->XYZ();
830 // TVector3 spacePointPos = TVector3(xyz[0], xyz[1], xyz[2]);
831 // TVector3 projectionOntoCentralAxis = ((spacePointPos-centre).Dot(spacePointDir))*spacePointDir + centre;
832 // avDistanceFromCentralAxis += (spacePointPos - projectionOntoCentralAxis).Mag();
833 // }
834 // avDistanceFromCentralAxis /= spacePoints.size();
835 
836 // return avDistanceFromCentralAxis;
837 
838 // }
TVector3 ProjPoint(const TVector3 &point, const TVector3 &direction, const TVector3 &origin=TVector3(0, 0, 0))
TVector3 SpacePointPos(const art::Ptr< recob::SpacePoint > &spacePoint)
Return 3D point of this space point.
void reconfigure(fhicl::ParameterSet const &pset)
Read in configurable parameters from provided parameter set.
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
Definition: Track.h:129
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Definition: Track.h:105
std::vector< art::Ptr< recob::Hit > > SelectShowerHits(int event, const std::vector< art::Ptr< recob::Hit > > &hits, const std::vector< art::Ptr< recob::Track > > &tracks, const std::vector< art::Ptr< recob::SpacePoint > > &spacePoints, const art::FindManyP< recob::Hit > &fmht, const art::FindManyP< recob::Track > &fmth, const art::FindManyP< recob::SpacePoint > &fmspt, const art::FindManyP< recob::Track > &fmtsp)
Vector_t VertexDirection() const
Access to track direction at different points.
Definition: Track.h:135
for(int i=0;i< 401;i++)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
void hits()
Definition: readHits.C:15
intermediate_table::const_iterator const_iterator
TrackShowerSeparationAlg(fhicl::ParameterSet const &pset)
T get(std::string const &key) const
Definition: ParameterSet.h:231
TVector3 Gradient(const std::vector< TVector3 > &points, const std::unique_ptr< TVector3 > &dir)
const Double32_t * XYZ() const
Definition: SpacePoint.h:65
TDirectory * dir
Definition: macro.C:5
Float_t proj
Definition: plot.C:34
double SpacePointsRMS(const std::vector< art::Ptr< recob::SpacePoint > > &spacePoints)
Float_t track
Definition: plot.C:34
std::vector< int > InitialTrackLikeSegment(std::map< int, std::unique_ptr< ReconTrack > > &reconTracks)
constexpr Point origin()
Returns a origin position with a point of the specified type.
Definition: geo_vectors.h:230
Event finding and building.