All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
Classes | Public Member Functions | Private Member Functions | Private Attributes | List of all members
sbn::TrackSplitter Class Reference
Inheritance diagram for sbn::TrackSplitter:

Classes

struct  PairedHits
 

Public Member Functions

 TrackSplitter (fhicl::ParameterSet const &p)
 
 TrackSplitter (TrackSplitter const &)=delete
 
 TrackSplitter (TrackSplitter &&)=delete
 
TrackSplitteroperator= (TrackSplitter const &)=delete
 
TrackSplitteroperator= (TrackSplitter &&)=delete
 
void produce (art::Event &e) override
 

Private Member Functions

std::pair< int, float > ClosestTrajectoryPoint (const detinfo::DetectorPropertiesData &dprop, const recob::Track &trk, const recob::Hit &hit)
 
std::vector< art::Ptr
< recob::Hit > > 
SplitTrunkHits (const detinfo::DetectorPropertiesData &dprop, const std::vector< art::Ptr< recob::Hit >> &trunk_hits, unsigned main_hit_ind, const std::vector< const recob::TrackHitMeta * > &trunk_hmetas, const recob::Track &trunk_trk, const recob::Track &branch_trk)
 
std::pair< std::vector
< art::Ptr< recob::Hit >
>, std::vector< const
recob::TrackHitMeta * > > 
OrganizeHits (const recob::Track &trk, const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thm, unsigned plane)
 
PairedHits DeMergePlaneHits (const detinfo::DetectorPropertiesData &dprop, const recob::Track &trunk_trk, const recob::Track &new_branch_trk, const recob::Track &old_branch_trk, const std::vector< art::Ptr< recob::Hit >> &trunk_hits, const std::vector< art::Ptr< recob::Hit >> &branch_hits, const std::vector< const recob::TrackHitMeta * > &trunk_hmeta, const std::vector< const recob::TrackHitMeta * > &branch_hmeta, const sbn::MergedTrackInfo &info, unsigned plane)
 
PairedHits DeMergeHits (const detinfo::DetectorPropertiesData &dprop, const recob::Track &trunk_trk, const recob::Track &new_branch_trk, const recob::Track &old_branch_trk, const std::vector< art::Ptr< recob::Hit >> &trunk_hits, const std::vector< art::Ptr< recob::Hit >> &branch_hits, const std::vector< const recob::TrackHitMeta * > &trunk_hmetas, const std::vector< const recob::TrackHitMeta * > &branch_hmetas, const sbn::MergedTrackInfo &info)
 
recob::Track DeMergeTrack (const recob::Track &trunk, const recob::Track &branch, const sbn::MergedTrackInfo &info)
 

Private Attributes

art::InputTag fTrackLabel
 
art::InputTag fMergedPFPLabel
 
const geo::GeometryCorefGeo
 
std::optional
< detinfo::DetectorPropertiesData
fDetProp
 
std::optional
< detinfo::DetectorClocksData
fDetClock
 

Detailed Description

Definition at line 46 of file TrackSplitter_module.cc.

Constructor & Destructor Documentation

sbn::TrackSplitter::TrackSplitter ( fhicl::ParameterSet const &  p)
explicit

Definition at line 119 of file TrackSplitter_module.cc.

120  : EDProducer{p},
121  fTrackLabel(p.get<art::InputTag>("TrackLabel", "pandoraTrack")),
122  fMergedPFPLabel(p.get<art::InputTag>("MergedPFPLabel", "mergeIdent"))
123 {
124  produces<std::vector<recob::Track>>();
125  produces<std::vector<recob::Hit>>();
126  produces<art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>>();
127  produces<art::Assns<recob::PFParticle, recob::Track>>();
128 }
pdgs p
Definition: selectors.fcl:22
art::InputTag fMergedPFPLabel
sbn::TrackSplitter::TrackSplitter ( TrackSplitter const &  )
delete
sbn::TrackSplitter::TrackSplitter ( TrackSplitter &&  )
delete

Member Function Documentation

std::pair< int, float > sbn::TrackSplitter::ClosestTrajectoryPoint ( const detinfo::DetectorPropertiesData dprop,
const recob::Track trk,
const recob::Hit hit 
)
private

Definition at line 130 of file TrackSplitter_module.cc.

130  {
131  float hit_x = dprop.ConvertTicksToX(hit.PeakTime(), hit.WireID());
132  float hit_w = hit.WireID().Wire * fGeo->WirePitch();
133 
134  // std::cout << "Hit time: " << hit.PeakTime() << std::endl;
135  // std::cout << "Hit X: " << hit_x << std::endl;
136  // std::cout << "Hit W: " << hit_w << std::endl;
137 
138  float dist = -1000.;
139  int ret = -1;
140 
141  for (unsigned i_tp = trk.FirstValidPoint(); i_tp < trk.NumberTrajectoryPoints(); i_tp = trk.NextValidPoint(i_tp+1)) {
142  TVector3 pos = trk.LocationAtPoint<TVector3>(i_tp);
143  float pos_x = pos.X();
144  float pos_w = fGeo->WireCoordinate(trk.LocationAtPoint<geo::Point_t>(i_tp), hit.WireID()) * fGeo->WirePitch();
145  float this_dist = sqrt((pos_x - hit_x) *(pos_x - hit_x) + (pos_w - hit_w) *(pos_w - hit_w));
146  if (ret < 0 || this_dist < dist) {
147  dist = this_dist;
148  ret = i_tp;
149  }
150  }
151 
152  // if (ret == -1) std::cout << "No SP :(\n";
153  // else {
154  // TVector3 pos = trk.LocationAtPoint<TVector3>(ret);
155  // std::cout << "Closest TP X: " << pos.X() << std::endl;
156  // std::cout << "Closest TP W: " << fGeo->WireCoordinate(pos.Y(), pos.Z(), hit.WireID()) * fGeo->WirePitch() << std::endl;
157  // }
158 
159  return {ret, dist};
160 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
geo::WireID WireID() const
Definition: Hit.h:233
Point_t const & LocationAtPoint(size_t i) const
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
WireID_t Wire
Index of the wire within its plane.
Definition: geo_types.h:580
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
const geo::GeometryCore * fGeo
double ConvertTicksToX(double ticks, int p, int t, int c) const
size_t FirstValidPoint() const
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
size_t NextValidPoint(size_t index) const
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
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
sbn::TrackSplitter::PairedHits sbn::TrackSplitter::DeMergeHits ( const detinfo::DetectorPropertiesData dprop,
const recob::Track trunk_trk,
const recob::Track new_branch_trk,
const recob::Track old_branch_trk,
const std::vector< art::Ptr< recob::Hit >> &  trunk_hits,
const std::vector< art::Ptr< recob::Hit >> &  branch_hits,
const std::vector< const recob::TrackHitMeta * > &  trunk_hmetas,
const std::vector< const recob::TrackHitMeta * > &  branch_hmetas,
const sbn::MergedTrackInfo info 
)
private

Definition at line 463 of file TrackSplitter_module.cc.

472  {
473 
475 
476  for (unsigned plane = 0; plane < 3; plane++) {
477  // collect the valid hits on each plane
478  std::pair<std::vector<art::Ptr<recob::Hit>>, std::vector<const recob::TrackHitMeta *>> trunkPlaneHits = \
479  OrganizeHits(trunk_trk, trunk_hits, trunk_hmetas, plane);
480 
481  std::pair<std::vector<art::Ptr<recob::Hit>>, std::vector<const recob::TrackHitMeta *>> branchPlaneHits = \
482  OrganizeHits(old_branch_trk, branch_hits, branch_hmetas, plane);
483 
484  // Split
485  sbn::TrackSplitter::PairedHits paired_hits = DeMergePlaneHits(dprop, trunk_trk, new_branch_trk, old_branch_trk, trunkPlaneHits.first, branchPlaneHits.first,
486  trunkPlaneHits.second, branchPlaneHits.second, info, plane);
487 
488  // Save
489  ret.trunk_hits.insert(ret.trunk_hits.end(), paired_hits.trunk_hits.begin(), paired_hits.trunk_hits.end());
490  ret.trunk_hmetas.insert(ret.trunk_hmetas.end(), paired_hits.trunk_hmetas.begin(), paired_hits.trunk_hmetas.end());
491  ret.branch_hits.insert(ret.branch_hits.end(), paired_hits.branch_hits.begin(), paired_hits.branch_hits.end());
492  ret.branch_hmetas.insert(ret.branch_hmetas.end(), paired_hits.branch_hmetas.begin(), paired_hits.branch_hmetas.end());
493  }
494 
495  return ret;
496 
497 }
std::vector< recob::TrackHitMeta > trunk_hmetas
std::vector< recob::TrackHitMeta > branch_hmetas
std::vector< recob::Hit > trunk_hits
std::pair< std::vector< art::Ptr< recob::Hit > >, std::vector< const recob::TrackHitMeta * > > OrganizeHits(const recob::Track &trk, const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thm, unsigned plane)
PairedHits DeMergePlaneHits(const detinfo::DetectorPropertiesData &dprop, const recob::Track &trunk_trk, const recob::Track &new_branch_trk, const recob::Track &old_branch_trk, const std::vector< art::Ptr< recob::Hit >> &trunk_hits, const std::vector< art::Ptr< recob::Hit >> &branch_hits, const std::vector< const recob::TrackHitMeta * > &trunk_hmeta, const std::vector< const recob::TrackHitMeta * > &branch_hmeta, const sbn::MergedTrackInfo &info, unsigned plane)
std::vector< recob::Hit > branch_hits
sbn::TrackSplitter::PairedHits sbn::TrackSplitter::DeMergePlaneHits ( const detinfo::DetectorPropertiesData dprop,
const recob::Track trunk_trk,
const recob::Track new_branch_trk,
const recob::Track old_branch_trk,
const std::vector< art::Ptr< recob::Hit >> &  trunk_hits,
const std::vector< art::Ptr< recob::Hit >> &  branch_hits,
const std::vector< const recob::TrackHitMeta * > &  trunk_hmeta,
const std::vector< const recob::TrackHitMeta * > &  branch_hmeta,
const sbn::MergedTrackInfo info,
unsigned  plane 
)
private

Definition at line 203 of file TrackSplitter_module.cc.

213  {
214 
216 
217  unsigned n_new_branch_trajpoints = new_branch_trk.NumberTrajectoryPoints();
218  unsigned n_old_branch_trajpoints = old_branch_trk.NumberTrajectoryPoints();
219  unsigned n_new_points = n_new_branch_trajpoints - n_old_branch_trajpoints;
220 
221  unsigned n_hits = trunk_hits.size();
222 
223  // std::cout << "De-merging plane: " << plane << std::endl;
224 
225  // std::cout << "Branch start: " << info.branch_start << std::endl;
226 
227  // consider the energy depositions in the trunk before the branch starts
228  // Consider the hits in the trunk before the branch starts
229  unsigned i_hit_trunk = 0;
230  for (; i_hit_trunk < n_hits; i_hit_trunk++) {
231  const recob::Hit &hit = *trunk_hits[i_hit_trunk];
232  const recob::TrackHitMeta *thm = trunk_hmeta[i_hit_trunk];
233 
234  // ignore hits not used in the trunk trajectory
235  if (thm->Index() == std::numeric_limits<unsigned int>::max() || !trunk_trk.HasValidPoint(thm->Index())) continue;
236 
237  // Are we past the track start?
238  TVector3 loc = trunk_trk.LocationAtPoint<TVector3>(thm->Index());
239  bool this_point_past_branch_start = (loc - info.vertex).Dot(info.direction) > info.branch_start;
240  // bool this_point_past_branch_start = info.trunk_wire_direction_is_ascending[plane] ?
241  // (int)hit.WireID().Wire >= info.branch_wire_start[plane] :
242  // (int)hit.WireID().Wire <= info.branch_wire_start[plane];
243 
244  // std::cout << "This wire: " << hit.WireID().Wire << std::endl;
245  // std::cout << "This point: " << (loc - info.vertex).Dot(info.direction) << std::endl;
246 
247  // lookup if the branch has a hit on this wire
248  std::vector<art::Ptr<recob::Hit>> branch_wire_hits;
249  std::vector<const recob::TrackHitMeta *> branch_wire_hmetas;
250  for (unsigned i_hit_branch = 0; i_hit_branch < branch_hits.size(); i_hit_branch++) {
251  art::Ptr<recob::Hit> b_hit = branch_hits[i_hit_branch];
252  if (b_hit->WireID() == hit.WireID()) {
253  branch_wire_hits.push_back(b_hit);
254  branch_wire_hmetas.push_back(branch_hmeta[i_hit_branch]);
255  }
256  }
257 
258  // std::cout << "Number of branch hits on this wire: " << branch_wire_hits.size() << std::endl;
259 
260  bool valid_tp = false;
261  unsigned i_hit_branch = 0;
262  if (branch_wire_hits.size()) {
263  // Check any hits on the branch already have a valid trajectory point.
264  for (; i_hit_branch < branch_wire_hits.size(); i_hit_branch++) {
265  if (branch_wire_hmetas[i_hit_branch]->Index() != std::numeric_limits<unsigned int>::max() &&
266  old_branch_trk.HasValidPoint(branch_wire_hmetas[i_hit_branch]->Index())) {
267  valid_tp = true;
268  break;
269  }
270  }
271  }
272 
273  // std::cout << "Valid traj-point: " << valid_tp << std::endl;
274 
275  // Past the start of the branch track! We should be all set now
276  if (this_point_past_branch_start && valid_tp) {
277  ret.trunk_hits.push_back(hit);
278  ret.trunk_hmetas.push_back(*thm);
279  break;
280  }
281 
282  // No hit lurking on the branch -- we'll have to split the trunk
283  // First see if we can find a stray hit on the trunk
284  if (!branch_wire_hits.size()) {
285  branch_wire_hits = SplitTrunkHits(dprop, trunk_hits, i_hit_trunk, trunk_hmeta, trunk_trk, new_branch_trk);
286  }
287 
288  // std::cout << "Number split trunk hits: " << branch_wire_hits.size() << std::endl;
289 
290  // Ok! Now we have all the information we need to determine what hit to assign
291  // to the branch on this wire. There are three possiblities:
292  //
293  // 1. The branch has a valid hit/traj-point on this wire.
294  // 2. There is a spare hit on the branch or trunk we can associate to the branch trajectory
295  // 3. There are no spare hits on the branch and we need to split the trunk hit.
296  //
297  // These three possibilties are handled in order below:
298  if (valid_tp) {
299  // Valid hit on this wire! Save it and go onto the next trunk hit
300  //
301  // Make a new TrackHitMeta that updates the traj point to the new correct place
302  recob::TrackHitMeta new_branch_meta(branch_wire_hmetas[i_hit_branch]->Index() + n_new_points);
303  ret.branch_hits.push_back(*branch_wire_hits[i_hit_branch]);
304  ret.branch_hmetas.push_back(new_branch_meta);
305 
306  ret.trunk_hits.push_back(hit);
307  ret.trunk_hmetas.push_back(*thm);
308  }
309  // Found a stray hit! We can work with that one
310  else if (branch_wire_hits.size()) {
311  art::Ptr<recob::Hit> new_branch_hit = *std::max_element(branch_wire_hits.begin(), branch_wire_hits.end(),
312  [this, dprop, new_branch_trk](auto const &lhs, auto const &rhs) {
313  return ClosestTrajectoryPoint(dprop, new_branch_trk, *lhs).second < ClosestTrajectoryPoint(dprop, new_branch_trk, *rhs).second;
314  });
315  unsigned i_tp = (unsigned)ClosestTrajectoryPoint(dprop, new_branch_trk, *new_branch_hit).first;
316 
317  recob::TrackHitMeta new_meta(i_tp);
318 
319  // save this hit
320  ret.branch_hits.push_back(*new_branch_hit);
321  ret.branch_hmetas.push_back(new_meta);
322 
323  // save the main hit for the trunk
324  ret.trunk_hits.push_back(hit);
325  ret.trunk_hmetas.push_back(*thm);
326  }
327  // No stray hit -- we'll have to split the tracks single hit on this wire in 2
328  else {
329  recob::Hit halfhit(hit.Channel(), hit.StartTick(), hit.EndTick(), hit.PeakTime(),
330  hit.SigmaPeakTime(), hit.RMS(),
331  hit.PeakAmplitude() / 2., hit.SigmaPeakAmplitude() / 2., hit.SummedADC() / 2.,
332  hit.Integral() / 2., hit.SigmaIntegral() / 2.,
333  hit.Multiplicity(), hit.LocalIndex(), hit.GoodnessOfFit(), hit.DegreesOfFreedom(), hit.View(),
334  hit.SignalType(), hit.WireID());
335 
336  unsigned branch_tp = ClosestTrajectoryPoint(dprop, new_branch_trk, halfhit).first;
337  recob::TrackHitMeta branch_meta(branch_tp);
338 
339  // save the half-hit for the branch and the trunk
340  ret.branch_hits.push_back(halfhit);
341  ret.branch_hmetas.push_back(branch_meta);
342 
343  ret.trunk_hits.push_back(halfhit);
344  ret.trunk_hmetas.push_back(*thm);
345  }
346  }
347 
348  // fill in the rest of the trunk hits
349  for (; i_hit_trunk < n_hits; i_hit_trunk++) {
350  const recob::Hit &hit = *trunk_hits[i_hit_trunk];
351  const recob::TrackHitMeta *thm = trunk_hmeta[i_hit_trunk];
352 
353  // ignore hits not used in the trunk trajectory
354  if (thm->Index() == std::numeric_limits<unsigned int>::max() || !trunk_trk.HasValidPoint(thm->Index())) continue;
355 
356  ret.trunk_hits.push_back(hit);
357  ret.trunk_hmetas.push_back(*thm);
358  }
359 
360  // fill in the rest of the branch hits
361  unsigned n_split_hits = ret.branch_hits.size();
362  for (unsigned i_hit_branch = 0; i_hit_branch < branch_hits.size(); i_hit_branch++) {
363 
364  // don't save invalid hits
365  if (branch_hmeta[i_hit_branch]->Index() == std::numeric_limits<unsigned int>::max() ||
366  !old_branch_trk.HasValidPoint(branch_hmeta[i_hit_branch]->Index())) {
367  continue;
368  }
369 
370  // don't save hits that were already added to the track
371  bool found = false;
372  for (unsigned j_hit_branch = 0; j_hit_branch < n_split_hits; j_hit_branch++) {
373  if (ret.branch_hits[j_hit_branch].WireID() == branch_hits[i_hit_branch]->WireID()) {
374  found = true;
375  break;
376  }
377  }
378  if (found) continue;
379 
380  // Make a new TrackHitMeta that updates the traj point to the new correct place
381  recob::TrackHitMeta new_branch_meta(branch_hmeta[i_hit_branch]->Index() + n_new_points);
382  ret.branch_hits.push_back(*branch_hits[i_hit_branch]);
383  ret.branch_hmetas.push_back(new_branch_meta);
384  }
385 
386  return ret;
387 }
short int LocalIndex() const
How well do we believe we know this hit?
Definition: Hit.h:227
geo::SigType_t SignalType() const
Signal type for the plane of the hit.
Definition: Hit.h:231
geo::WireID WireID() const
Definition: Hit.h:233
float RMS() const
RMS of the hit shape, in tick units.
Definition: Hit.h:220
Point_t const & LocationAtPoint(size_t i) const
std::vector< recob::TrackHitMeta > trunk_hmetas
float SigmaPeakAmplitude() const
Uncertainty on estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:222
float SigmaIntegral() const
Definition: Hit.h:225
bool HasValidPoint(size_t i) const
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
int DegreesOfFreedom() const
Definition: Hit.h:229
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
Definition: Hit.h:224
geo::View_t View() const
View for the plane of the hit.
Definition: Hit.h:232
Data related to recob::Hit associated with recob::Track.The purpose is to collect several variables t...
Definition: TrackHitMeta.h:43
process_name hit
Definition: cheaterreco.fcl:51
float GoodnessOfFit() const
Degrees of freedom in the determination of the hit signal shape (-1 by default)
Definition: Hit.h:228
std::vector< recob::TrackHitMeta > branch_hmetas
short int Multiplicity() const
How many hits could this one be shared with.
Definition: Hit.h:226
std::pair< int, float > ClosestTrajectoryPoint(const detinfo::DetectorPropertiesData &dprop, const recob::Track &trk, const recob::Hit &hit)
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
Definition: Hit.h:221
std::vector< recob::Hit > trunk_hits
std::vector< art::Ptr< recob::Hit > > SplitTrunkHits(const detinfo::DetectorPropertiesData &dprop, const std::vector< art::Ptr< recob::Hit >> &trunk_hits, unsigned main_hit_ind, const std::vector< const recob::TrackHitMeta * > &trunk_hmetas, const recob::Track &trunk_trk, const recob::Track &branch_trk)
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
Definition: Hit.h:216
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
Definition: Hit.h:217
float PeakTime() const
Time of the signal peak, in tick units.
Definition: Hit.h:218
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
Definition: Hit.h:223
unsigned int Index() const
Hit index along the track trajectory.
Definition: TrackHitMeta.h:55
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
Definition: Hit.h:219
2D representation of charge deposited in the TDC/wire plane
Definition: Hit.h:48
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
Definition: Hit.h:230
std::vector< recob::Hit > branch_hits
recob::Track sbn::TrackSplitter::DeMergeTrack ( const recob::Track trunk,
const recob::Track branch,
const sbn::MergedTrackInfo info 
)
private

Definition at line 499 of file TrackSplitter_module.cc.

499  {
500  // add points from the trunk-track
501  std::vector<TVector3> add_p;
502  std::vector<TVector3> add_m;
503  std::vector<recob::TrajectoryPointFlags> add_f;
504 
505  for (unsigned i = 0; i < trunk.NumberTrajectoryPoints(); i++) {
506  if (!trunk.HasValidPoint(i)) continue;
507 
508  TVector3 p = trunk.LocationAtPoint<TVector3>(i);
509  float p_proj = (p - info.vertex).Dot(info.direction);
510 
511  if (p_proj >= info.branch_start) break;
512 
513  add_p.push_back(p);
514  add_m.push_back(trunk.DirectionAtPoint<TVector3>(i));
515  add_f.push_back(trunk.FlagsAtPoint(i));
516  }
517 
518  // smooth the addded points to avoid big jump between trunk and branch
519  if (add_p.size() >= 2) {
520  std::vector<TVector3> add_p_old = add_p;
521 
522  float dist = info.branch_start;
523  TVector3 diff = branch.Start<TVector3>() - add_p_old[add_p_old.size()-1];
524 
525  for (unsigned i = 1; i < add_p_old.size(); i++) {
526  float this_dist = (add_p_old[i] - info.vertex).Dot(info.direction);
527  add_p[i] = add_p_old[i] + diff * (this_dist / dist);
528  }
529 
530  for (int i = 0; i < (int)add_m.size() - 1; i++) {
531  add_m[i] = (add_p[i+1] - add_p[i]).Unit();
532  if (i > 0) add_m[i] = (add_m[i] + (add_p[i] - add_p[i-1]).Unit()).Unit();
533  }
534  add_m[add_p.size()-1] = ((branch.Start<TVector3>() - add_p[add_p.size()-1]).Unit() +
535  (add_p[add_p.size()-1] - add_p[add_p.size()-2])).Unit();
536 
537  // TODO: fix what the initial direction gets set to
538  add_m[0] = (branch.Start<TVector3>() - add_p[0]).Unit();
539  }
540 
541  /*
542  TVector3 p = trunk.Start<TVector3>();
543  float p_proj = (p - info.vertex).Dot(info.direction);
544 
545  if (p_proj < info.branch_start) {
546  add_p.push_back(p);
547  add_m.push_back((branch.Start<TVector3>() - p).Unit());
548  add_f.push_back(trunk.FlagsAtPoint(trunk.FirstValidPoint()));
549  }
550  */
551 
552  // Save the new points
553  recob::Track::Positions_t positions;
554  recob::Track::Momenta_t momenta;
555  recob::Track::Flags_t flags = std::move(add_f);
556 
557  for (unsigned i = 0; i < add_p.size(); i++) {
558  positions.emplace_back(add_p[i].X(), add_p[i].Y(), add_p[i].Z());
559  momenta.emplace_back(add_m[i].X(), add_m[i].Y(), add_m[i].Z());
560  }
561 
562  // copy the starting info from the branch-track
563  for (unsigned i_tp = 0; i_tp < branch.NumberTrajectoryPoints(); i_tp += 1) {
564  positions.push_back(branch.LocationAtPoint(i_tp));
565  momenta.push_back(branch.DirectionAtPoint(i_tp));
566  flags.push_back(branch.FlagsAtPoint(i_tp));
567  }
568 
569  recob::Track::SMatrixSym55 cov_start = trunk.StartCovariance();
570  recob::Track::SMatrixSym55 cov_end = branch.EndCovariance();
571  return recob::Track(std::move(positions), std::move(momenta), std::move(flags),
572  branch.HasMomentum(), branch.ParticleId(), branch.Chi2(), branch.Ndof(), std::move(cov_start), std::move(cov_end), branch.ID());
573 }
tracking::Momenta_t Momenta_t
Point_t const & LocationAtPoint(size_t i) const
pdgs p
Definition: selectors.fcl:22
TrackTrajectory::Flags_t Flags_t
bool HasValidPoint(size_t i) const
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
then echo echo For and will not be changed by echo further linking echo echo B echo The symbol is in the uninitialized data multiple common symbols may appear with the echo same name If the symbol is defined the common echo symbols are treated as undefined references For more echo details on common see the discussion of warn common echo in *Note Linker see the discussion of warn common echo in *Note Linker such as a global int variable echo as opposed to a large global array echo echo I echo The symbol is an indirect reference to another symbol This echo is a GNU extension to the a out object file format which is echo rarely used echo echo N echo The symbol is a debugging symbol echo echo R echo The symbol is in a read only data section echo echo S echo The symbol is in an uninitialized data section for small echo objects echo echo T echo The symbol is in the the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo W echo The symbol is a weak symbol that has not been specifically echo tagged as a weak object symbol When a weak defined symbol echo is linked with a normal defined the normal defined echo symbol is used with no error When a weak undefined symbol echo is linked and the symbol is not the value of the echo weak symbol becomes zero with no error echo echo echo The symbol is a stabs symbol in an a out object file In echo this the next values printed are the stabs other echo the stabs desc and the stab type Stabs symbols are echo used to hold debugging information For more echo see *Note or object file format specific echo echo For Mac OS X
const SMatrixSym55 & EndCovariance() const
tracking::Positions_t Positions_t
Point_t const & Start() const
Access to track position at different points.
tracking::SMatrixSym55 SMatrixSym55
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
PointFlags_t const & FlagsAtPoint(size_t i) const
Vector_t DirectionAtPoint(size_t i) const
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
const SMatrixSym55 & StartCovariance() const
Access to covariance matrices.
TrackSplitter& sbn::TrackSplitter::operator= ( TrackSplitter const &  )
delete
TrackSplitter& sbn::TrackSplitter::operator= ( TrackSplitter &&  )
delete
std::pair< std::vector< art::Ptr< recob::Hit > >, std::vector< const recob::TrackHitMeta * > > sbn::TrackSplitter::OrganizeHits ( const recob::Track trk,
const std::vector< art::Ptr< recob::Hit >> &  hits,
const std::vector< const recob::TrackHitMeta * > &  thm,
unsigned  plane 
)
private

Definition at line 389 of file TrackSplitter_module.cc.

390  {
391 
392  std::pair<std::vector<art::Ptr<recob::Hit>>, std::vector<const recob::TrackHitMeta *>> ret;
393 
394  // Collect the hits on the provided plane
395  for (unsigned i_hit = 0; i_hit < hits.size(); i_hit++) {
396  if (hits[i_hit]->WireID().Plane == plane) {
397  ret.first.push_back(hits[i_hit]);
398  ret.second.push_back(thm[i_hit]);
399  }
400  }
401 
402  // Now decide if the hit order needs to be reversed
403  //
404  // DeMergePlaneHits will assume hits are ordered start -> end
405 
406  int first_valid_hit = -1;
407  int last_valid_hit = -1;
408 
409  for (unsigned i_hit = 0; i_hit < ret.first.size(); i_hit++) {
410  if (ret.second[i_hit]->Index() != std::numeric_limits<unsigned int>::max() && trk.HasValidPoint(ret.second[i_hit]->Index())) {
411  first_valid_hit = i_hit;
412  break;
413  }
414  }
415 
416  for (int i_hit = ret.first.size()-1; i_hit >= 0; i_hit--) {
417  if (ret.second[i_hit]->Index() != std::numeric_limits<unsigned int>::max() && trk.HasValidPoint(ret.second[i_hit]->Index())) {
418  last_valid_hit = i_hit;
419  break;
420  }
421  }
422 
423  bool reverse_hits = false;
424 
425  // If there are two valid hits/traj-point's, then we can decide to re-order using which
426  // is closer to the start
427  if (first_valid_hit >= 0 && last_valid_hit >= 0 && first_valid_hit != last_valid_hit) {
428  reverse_hits = \
429  (trk.LocationAtPoint<TVector3>(ret.second[first_valid_hit]->Index()) - trk.Start<TVector3>()).Mag() >
430  (trk.LocationAtPoint<TVector3>(ret.second[last_valid_hit]->Index()) - trk.Start<TVector3>()).Mag();
431  }
432  // Otherwise, try to see if we can at least determine whether wires and traj-points are ascending or descending
433  //
434  // If not enough info, assume the order is correct
435  else if (ret.first.size() && trk.NumberTrajectoryPoints() >= 2) {
436  TVector3 start = trk.Start<TVector3>();
437  TVector3 start_p1 = trk.LocationAtPoint<TVector3>(trk.NextValidPoint(trk.FirstValidPoint()+1));
438 
439  geo::PlaneID thisplane(0, 0, plane);
440  bool trk_is_ascending = fGeo->WireCoordinate(trk.Start<geo::Point_t>(), thisplane) <
442  int wire0 = ret.first[0]->WireID().Wire;
443  int wire1 = -1;
444  for (unsigned i_hit = 1; i_hit < ret.first.size(); i_hit++) {
445  if ((int)ret.first[i_hit]->WireID().Wire != wire0) {
446  wire1 = ret.first[i_hit]->WireID().Wire;
447  break;
448  }
449  }
450  bool wire_is_ascending = (wire1 >= 0) ? wire1 > wire0 : trk_is_ascending;
451 
452  reverse_hits = trk_is_ascending != wire_is_ascending;
453  }
454 
455  if (reverse_hits) {
456  std::reverse(ret.first.begin(), ret.first.end());
457  std::reverse(ret.second.begin(), ret.second.end());
458  }
459 
460  return ret;
461 }
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
Point_t const & LocationAtPoint(size_t i) const
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
bool HasValidPoint(size_t i) const
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
Point_t const & Start() const
Access to track position at different points.
const geo::GeometryCore * fGeo
size_t FirstValidPoint() const
size_t NextValidPoint(size_t index) 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
void sbn::TrackSplitter::produce ( art::Event &  e)
override

Definition at line 575 of file TrackSplitter_module.cc.

576 {
577  // update services
578  fGeo = lar::providerFrom<geo::Geometry>();
579 
580  auto const &dclock = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
581  auto const &dprop = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, dclock);
582 
583  // output data products
584  std::unique_ptr<art::Assns<recob::PFParticle, recob::Track>> trkAssn(new art::Assns<recob::PFParticle, recob::Track>);
585  std::unique_ptr<art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>> hitAssn(new art::Assns<recob::Track, recob::Hit, recob::TrackHitMeta>);
586  std::unique_ptr<std::vector<recob::Track>> outTracks(new std::vector<recob::Track>);
587  std::unique_ptr<std::vector<recob::Hit>> outHits(new std::vector<recob::Hit>);
588 
589  art::PtrMaker<recob::Track> trkPtrMaker{e};
590  art::PtrMaker<recob::Hit> hitPtrMaker{e};
591 
592  // input data
593  art::Handle<std::vector<sbn::MergedTrackInfo>> mergedtrack_handle;
594  e.getByLabel(fMergedPFPLabel, mergedtrack_handle);
595 
596  std::vector<art::Ptr<sbn::MergedTrackInfo>> mergedtracks;
597  art::fill_ptr_vector(mergedtracks, mergedtrack_handle);
598 
599  art::FindManyP<recob::PFParticle> mergedPFPs(mergedtracks, e, fMergedPFPLabel);
600 
601  for (unsigned i_mrg = 0; i_mrg < mergedtracks.size(); i_mrg++) {
602  const sbn::MergedTrackInfo &merge_info = *mergedtracks[i_mrg];
603  const std::vector<art::Ptr<recob::PFParticle>> pfps = mergedPFPs.at(i_mrg);
604  art::FindManyP<recob::Track> fmTracks(pfps, e, fTrackLabel);
605 
606  assert(pfps.size() == 2);
607 
608  art::Ptr<recob::PFParticle> trunk_pfp;
609  art::Ptr<recob::PFParticle> branch_pfp;
610  art::Ptr<recob::Track> trunk_trk;
611  art::Ptr<recob::Track> branch_trk;
612  if ((unsigned)merge_info.trunk == pfps[0]->Self()) {
613  trunk_pfp = pfps[0];
614  trunk_trk = fmTracks.at(0).at(0);
615  branch_pfp = pfps[1];
616  branch_trk = fmTracks.at(1).at(0);
617  }
618  else {
619  trunk_pfp = pfps[1];
620  trunk_trk = fmTracks.at(1).at(0);
621  branch_pfp = pfps[0];
622  branch_trk = fmTracks.at(0).at(0);
623  }
624 
625  // std::cout << "Splitting branch: " << branch_pfp->Self() << " from trunk: " << trunk_pfp->Self() << std::endl;
626 
627  // De-merge with the provided match
628  recob::Track demerge = DeMergeTrack(*trunk_trk, *branch_trk, merge_info);
629 
630  // look-up the track hits
631  art::FindManyP<recob::Hit, recob::TrackHitMeta> hits({trunk_trk, branch_trk}, e, fTrackLabel);
632 
633  sbn::TrackSplitter::PairedHits demerged_hits = DeMergeHits(dprop,
634  *trunk_trk, demerge, *branch_trk,
635  hits.at(0), hits.at(1), hits.data(0), hits.data(1),
636  merge_info);
637 
638  // Save
639  outTracks->push_back(demerge);
640  art::Ptr<recob::Track> branchTrackPtr = trkPtrMaker(outTracks->size()-1);
641  trkAssn->addSingle(branch_pfp, branchTrackPtr);
642 
643  for (unsigned i_hit = 0; i_hit < demerged_hits.branch_hits.size(); i_hit++) {
644  outHits->push_back(demerged_hits.branch_hits[i_hit]);
645  art::Ptr<recob::Hit> thisHitPtr = hitPtrMaker(outHits->size()-1);
646  hitAssn->addSingle(branchTrackPtr, thisHitPtr, demerged_hits.branch_hmetas[i_hit]);
647  }
648 
649  // Also make a new track for the trunk
650  recob::Track trunk_copy = *trunk_trk;
651  outTracks->push_back(trunk_copy);
652  art::Ptr<recob::Track> trunkTrackPtr = trkPtrMaker(outTracks->size()-1);
653  trkAssn->addSingle(trunk_pfp, trunkTrackPtr);
654 
655  for (unsigned i_hit = 0; i_hit < demerged_hits.trunk_hits.size(); i_hit++) {
656  outHits->push_back(demerged_hits.trunk_hits[i_hit]);
657  art::Ptr<recob::Hit> thisHitPtr = hitPtrMaker(outHits->size()-1);
658  hitAssn->addSingle(trunkTrackPtr, thisHitPtr, demerged_hits.trunk_hmetas[i_hit]);
659  }
660 
661  } // end iterate over merged PFParticles
662 
663  // Save into event
664  e.put(std::move(outTracks));
665  e.put(std::move(trkAssn));
666  e.put(std::move(outHits));
667  e.put(std::move(hitAssn));
668 }
PairedHits DeMergeHits(const detinfo::DetectorPropertiesData &dprop, const recob::Track &trunk_trk, const recob::Track &new_branch_trk, const recob::Track &old_branch_trk, const std::vector< art::Ptr< recob::Hit >> &trunk_hits, const std::vector< art::Ptr< recob::Hit >> &branch_hits, const std::vector< const recob::TrackHitMeta * > &trunk_hmetas, const std::vector< const recob::TrackHitMeta * > &branch_hmetas, const sbn::MergedTrackInfo &info)
const geo::GeometryCore * fGeo
art::InputTag fMergedPFPLabel
do i e
recob::Track DeMergeTrack(const recob::Track &trunk, const recob::Track &branch, const sbn::MergedTrackInfo &info)
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a &quot;fitted&quot; track:
std::vector< art::Ptr< recob::Hit > > sbn::TrackSplitter::SplitTrunkHits ( const detinfo::DetectorPropertiesData dprop,
const std::vector< art::Ptr< recob::Hit >> &  trunk_hits,
unsigned  main_hit_ind,
const std::vector< const recob::TrackHitMeta * > &  trunk_hmetas,
const recob::Track trunk_trk,
const recob::Track branch_trk 
)
private

Definition at line 162 of file TrackSplitter_module.cc.

168  {
169 
170  std::vector<art::Ptr<recob::Hit>> split_trunk_hits;
171 
172  geo::WireID wire = trunk_hits[main_hit_ind]->WireID();
173 
174  for (unsigned i = 0; i < trunk_hits.size(); i++) {
175  art::Ptr<recob::Hit> h = trunk_hits[i];
176  const recob::TrackHitMeta *hmeta = trunk_hmetas[i];
177  if (i != main_hit_ind // different hit
178  && (hmeta->Index() == std::numeric_limits<unsigned int>::max() || !trunk_trk.HasValidPoint(hmeta->Index())) // not used in trunk traj.
179  && h->WireID() == wire) { // on same wire
180 
181  // Found a hit! So there are two hits on the trunk on this wire
182  // and one may belong on the branch
183  //
184  // We'll say this hit "belongs" to the branch if it closer to the projection
185  // of the branch on the plane
186 
187  // std::cout << "TRUNK\n";
188  std::pair<int, float> trunk_dist = ClosestTrajectoryPoint(dprop, trunk_trk, *h);
189  // std::cout << "BRANCH\n";
190  std::pair<int, float> branch_dist = ClosestTrajectoryPoint(dprop, branch_trk, *h);
191 
192  // std::cout << "Possible split trunk hit on wire: " << h->WireID().Wire << ". Trunk dist: " << trunk_dist.second << " branch dist: " << branch_dist.second << std::endl;
193 
194  if (trunk_dist.first >= 0 && branch_dist.first > 0 && branch_dist.second < trunk_dist.second) {
195  split_trunk_hits.push_back(h);
196  }
197  }
198  }
199 
200  return split_trunk_hits;
201 }
bool HasValidPoint(size_t i) const
Data related to recob::Hit associated with recob::Track.The purpose is to collect several variables t...
Definition: TrackHitMeta.h:43
std::pair< int, float > ClosestTrajectoryPoint(const detinfo::DetectorPropertiesData &dprop, const recob::Track &trk, const recob::Hit &hit)
while getopts h
unsigned int Index() const
Hit index along the track trajectory.
Definition: TrackHitMeta.h:55

Member Data Documentation

std::optional<detinfo::DetectorClocksData> sbn::TrackSplitter::fDetClock
private

Definition at line 70 of file TrackSplitter_module.cc.

std::optional<detinfo::DetectorPropertiesData> sbn::TrackSplitter::fDetProp
private

Definition at line 69 of file TrackSplitter_module.cc.

const geo::GeometryCore* sbn::TrackSplitter::fGeo
private

Definition at line 68 of file TrackSplitter_module.cc.

art::InputTag sbn::TrackSplitter::fMergedPFPLabel
private

Definition at line 65 of file TrackSplitter_module.cc.

art::InputTag sbn::TrackSplitter::fTrackLabel
private

Definition at line 64 of file TrackSplitter_module.cc.


The documentation for this class was generated from the following file: