10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "canvas/Utilities/InputTag.h"
17 #include "fhiclcpp/ParameterSet.h"
18 #include "messagefacility/MessageLogger/MessageLogger.h"
59 void produce(art::Event&
e)
override;
69 std::optional<detinfo::DetectorPropertiesData>
fDetProp;
70 std::optional<detinfo::DetectorClocksData>
fDetClock;
76 const std::vector<art::Ptr<recob::Hit>> &trunk_hits,
77 unsigned main_hit_ind,
78 const std::vector<const recob::TrackHitMeta *> &trunk_hmetas,
82 std::pair<std::vector<art::Ptr<recob::Hit>>, std::vector<const recob::TrackHitMeta *>>
OrganizeHits(
83 const recob::Track &trk,
const std::vector<art::Ptr<recob::Hit>> &hits,
const std::vector<const recob::TrackHitMeta *> &thm,
unsigned plane);
98 const std::vector<art::Ptr<recob::Hit>> &trunk_hits,
99 const std::vector<art::Ptr<recob::Hit>> &branch_hits,
100 const std::vector<const recob::TrackHitMeta *> &trunk_hmeta,
101 const std::vector<const recob::TrackHitMeta *> &branch_hmeta,
110 const std::vector<art::Ptr<recob::Hit>> &trunk_hits,
111 const std::vector<art::Ptr<recob::Hit>> &branch_hits,
112 const std::vector<const recob::TrackHitMeta *> &trunk_hmetas,
113 const std::vector<const recob::TrackHitMeta *> &branch_hmetas,
121 fTrackLabel(
p.get<art::InputTag>(
"TrackLabel",
"pandoraTrack")),
122 fMergedPFPLabel(
p.get<art::InputTag>(
"MergedPFPLabel",
"mergeIdent"))
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>>();
132 float hit_w = hit.
WireID().
Wire * fGeo->WirePitch();
143 float pos_x = pos.X();
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) {
164 const std::vector<art::Ptr<recob::Hit>> &trunk_hits,
165 unsigned main_hit_ind,
166 const std::vector<const recob::TrackHitMeta *> &trunk_hmetas,
170 std::vector<art::Ptr<recob::Hit>> split_trunk_hits;
174 for (
unsigned i = 0; i < trunk_hits.size(); i++) {
175 art::Ptr<recob::Hit>
h = trunk_hits[i];
177 if (i != main_hit_ind
179 && h->WireID() == wire) {
188 std::pair<int, float> trunk_dist = ClosestTrajectoryPoint(dprop, trunk_trk, *h);
190 std::pair<int, float> branch_dist = ClosestTrajectoryPoint(dprop, branch_trk, *h);
194 if (trunk_dist.first >= 0 && branch_dist.first > 0 && branch_dist.second < trunk_dist.second) {
195 split_trunk_hits.push_back(h);
200 return split_trunk_hits;
208 const std::vector<art::Ptr<recob::Hit>> &trunk_hits,
209 const std::vector<art::Ptr<recob::Hit>> &branch_hits,
210 const std::vector<const recob::TrackHitMeta *> &trunk_hmeta,
211 const std::vector<const recob::TrackHitMeta *> &branch_hmeta,
219 unsigned n_new_points = n_new_branch_trajpoints - n_old_branch_trajpoints;
221 unsigned n_hits = trunk_hits.size();
229 unsigned i_hit_trunk = 0;
230 for (; i_hit_trunk < n_hits; i_hit_trunk++) {
235 if (thm->
Index() == std::numeric_limits<unsigned int>::max() || !trunk_trk.
HasValidPoint(thm->
Index()))
continue;
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]);
260 bool valid_tp =
false;
261 unsigned i_hit_branch = 0;
262 if (branch_wire_hits.size()) {
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())) {
276 if (this_point_past_branch_start && valid_tp) {
284 if (!branch_wire_hits.size()) {
285 branch_wire_hits = SplitTrunkHits(dprop, trunk_hits, i_hit_trunk, trunk_hmeta, trunk_trk, new_branch_trk);
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]);
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;
315 unsigned i_tp = (unsigned)ClosestTrajectoryPoint(dprop, new_branch_trk, *new_branch_hit).first;
336 unsigned branch_tp = ClosestTrajectoryPoint(dprop, new_branch_trk, halfhit).first;
349 for (; i_hit_trunk < n_hits; i_hit_trunk++) {
354 if (thm->
Index() == std::numeric_limits<unsigned int>::max() || !trunk_trk.
HasValidPoint(thm->
Index()))
continue;
362 for (
unsigned i_hit_branch = 0; i_hit_branch < branch_hits.size(); i_hit_branch++) {
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())) {
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()) {
382 ret.
branch_hits.push_back(*branch_hits[i_hit_branch]);
390 const recob::Track &trk,
const std::vector<art::Ptr<recob::Hit>> &hits,
const std::vector<const recob::TrackHitMeta *> &thm,
unsigned plane) {
392 std::pair<std::vector<art::Ptr<recob::Hit>>, std::vector<const recob::TrackHitMeta *>> ret;
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]);
406 int first_valid_hit = -1;
407 int last_valid_hit = -1;
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;
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;
423 bool reverse_hits =
false;
427 if (first_valid_hit >= 0 && last_valid_hit >= 0 && first_valid_hit != last_valid_hit) {
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();
436 TVector3 start = trk.
Start<TVector3>();
440 bool trk_is_ascending = fGeo->WireCoordinate(trk.
Start<
geo::Point_t>(), thisplane) <
442 int wire0 = ret.first[0]->WireID().Wire;
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;
450 bool wire_is_ascending = (wire1 >= 0) ? wire1 > wire0 : trk_is_ascending;
452 reverse_hits = trk_is_ascending != wire_is_ascending;
456 std::reverse(ret.first.begin(), ret.first.end());
457 std::reverse(ret.second.begin(), ret.second.end());
468 const std::vector<art::Ptr<recob::Hit>> &trunk_hits,
469 const std::vector<art::Ptr<recob::Hit>> &branch_hits,
470 const std::vector<const recob::TrackHitMeta *> &trunk_hmetas,
471 const std::vector<const recob::TrackHitMeta *> &branch_hmetas,
476 for (
unsigned plane = 0; plane < 3; 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);
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);
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);
501 std::vector<TVector3> add_p;
502 std::vector<TVector3> add_m;
503 std::vector<recob::TrajectoryPointFlags> add_f;
519 if (add_p.size() >= 2) {
520 std::vector<TVector3> add_p_old = add_p;
523 TVector3 diff = branch.
Start<TVector3>() - add_p_old[add_p_old.size()-1];
525 for (
unsigned i = 1; i < add_p_old.size(); i++) {
527 add_p[i] = add_p_old[i] + diff * (this_dist /
dist);
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();
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();
538 add_m[0] = (branch.
Start<TVector3>() - add_p[0]).Unit();
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());
571 return recob::Track(std::move(positions), std::move(momenta), std::move(flags),
578 fGeo = lar::providerFrom<geo::Geometry>();
580 auto const &dclock = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
581 auto const &dprop = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, dclock);
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>);
589 art::PtrMaker<recob::Track> trkPtrMaker{e};
590 art::PtrMaker<recob::Hit> hitPtrMaker{e};
593 art::Handle<std::vector<sbn::MergedTrackInfo>> mergedtrack_handle;
594 e.getByLabel(fMergedPFPLabel, mergedtrack_handle);
596 std::vector<art::Ptr<sbn::MergedTrackInfo>> mergedtracks;
597 art::fill_ptr_vector(mergedtracks, mergedtrack_handle);
599 art::FindManyP<recob::PFParticle> mergedPFPs(mergedtracks, e, fMergedPFPLabel);
601 for (
unsigned i_mrg = 0; i_mrg < mergedtracks.size(); i_mrg++) {
603 const std::vector<art::Ptr<recob::PFParticle>> pfps = mergedPFPs.at(i_mrg);
604 art::FindManyP<recob::Track> fmTracks(pfps, e, fTrackLabel);
606 assert(pfps.size() == 2);
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()) {
614 trunk_trk = fmTracks.at(0).at(0);
615 branch_pfp = pfps[1];
616 branch_trk = fmTracks.at(1).at(0);
620 trunk_trk = fmTracks.at(1).at(0);
621 branch_pfp = pfps[0];
622 branch_trk = fmTracks.at(0).at(0);
628 recob::Track demerge = DeMergeTrack(*trunk_trk, *branch_trk, merge_info);
631 art::FindManyP<recob::Hit, recob::TrackHitMeta> hits({trunk_trk, branch_trk},
e, fTrackLabel);
634 *trunk_trk, demerge, *branch_trk,
635 hits.at(0), hits.at(1), hits.data(0), hits.data(1),
639 outTracks->push_back(demerge);
640 art::Ptr<recob::Track> branchTrackPtr = trkPtrMaker(outTracks->size()-1);
641 trkAssn->addSingle(branch_pfp, branchTrackPtr);
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]);
651 outTracks->push_back(trunk_copy);
652 art::Ptr<recob::Track> trunkTrackPtr = trkPtrMaker(outTracks->size()-1);
653 trkAssn->addSingle(trunk_pfp, trunkTrackPtr);
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]);
664 e.put(std::move(outTracks));
665 e.put(std::move(trkAssn));
666 e.put(std::move(outHits));
667 e.put(std::move(hitAssn));
short int LocalIndex() const
How well do we believe we know this hit?
Data product for reconstructed trajectory in space.
geo::SigType_t SignalType() const
Signal type for the plane of the hit.
Utilities related to art service access.
tracking::Momenta_t Momenta_t
std::optional< detinfo::DetectorPropertiesData > fDetProp
geo::WireID WireID() const
float RMS() const
RMS of the hit shape, in tick units.
Declaration of signal hit object.
Point_t const & LocationAtPoint(size_t i) const
std::vector< recob::TrackHitMeta > trunk_hmetas
The data type to uniquely identify a 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)
float SigmaPeakAmplitude() const
Uncertainty on estimated amplitude of the hit at its peak, in ADC units.
TrackTrajectory::Flags_t Flags_t
float SigmaIntegral() const
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
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
geo::View_t View() const
View for the plane of the hit.
WireID_t Wire
Index of the wire within its plane.
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
float GoodnessOfFit() const
Degrees of freedom in the determination of the hit signal shape (-1 by default)
std::vector< recob::TrackHitMeta > branch_hmetas
short int Multiplicity() const
How many hits could this one be shared with.
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.
std::optional< detinfo::DetectorClocksData > fDetClock
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)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of detector geometry.
const SMatrixSym55 & EndCovariance() const
Collection of exceptions for Geometry system.
tracking::Positions_t Positions_t
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
void produce(art::Event &e) override
Point_t const & Start() const
Access to track position at different points.
art::InputTag fTrackLabel
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)
Data product for reconstructed trajectory in space.
Description of geometry of one entire detector.
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
const geo::GeometryCore * fGeo
Provides recob::Track data product.
double ConvertTicksToX(double ticks, int p, int t, int c) const
tracking::SMatrixSym55 SMatrixSym55
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
size_t FirstValidPoint() const
float PeakTime() const
Time of the signal peak, in tick units.
size_t NextValidPoint(size_t index) const
constexpr double dist(const TReal *x, const TReal *y, const unsigned int dimension)
TrackSplitter & operator=(TrackSplitter const &)=delete
art::InputTag fMergedPFPLabel
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
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)
PointFlags_t const & FlagsAtPoint(size_t i) const
recob::Track DeMergeTrack(const recob::Track &trunk, const recob::Track &branch, const sbn::MergedTrackInfo &info)
constexpr WireID()=default
Default constructor: an invalid TPC ID.
Declaration of basic channel signal object.
Vector_t DirectionAtPoint(size_t i) const
TrackCollectionProxyElement< TrackCollProxy > Track
Proxy to an element of a proxy collection of recob::Track objects.
float SigmaPeakTime() const
Uncertainty for the signal peak, in tick units.
2D representation of charge deposited in the TDC/wire plane
Class defining a sparse vector (holes are zeroes)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
art framework interface to geometry description
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
std::vector< recob::Hit > branch_hits
TrackSplitter(fhicl::ParameterSet const &p)
const SMatrixSym55 & StartCovariance() const
Access to covariance matrices.