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"
45 class MergedTrackIdentifier;
62 void produce(art::Event&
e)
override;
79 fPFPLabel(
p.get<art::InputTag>(
"PFPLabel",
"pandora")),
80 fTrackLabel(
p.get<art::InputTag>(
"TrackLabel",
"pandoraTrack"))
82 produces<std::vector<sbn::MergedTrackInfo>>();
83 produces<art::Assns<sbn::MergedTrackInfo, recob::PFParticle>>();
91 TVector3 avg_dir(0., 0., 0.);
95 avg_dir += (p - start).Unit();
98 return avg_dir.Unit();
118 const recob::Track &trunk_trk = (a_is_trunk) ? Atrk : Btrk;
119 const recob::Track &branch_trk = (a_is_trunk) ? Btrk : Atrk;
141 float trunk_min = -1;
142 float trunk_max = -1;
146 if (!set || proj < trunk_min) trunk_min = proj;
147 if (!set || proj > trunk_max) trunk_max = proj;
151 unsigned n_point = 0;
152 unsigned n_overlap_point = 0;
155 if (proj > trunk_min && proj < trunk_max) {
170 std::unique_ptr<std::vector<sbn::MergedTrackInfo>> infos(
new std::vector<sbn::MergedTrackInfo>);
171 std::unique_ptr<art::Assns<sbn::MergedTrackInfo, recob::PFParticle>> assn(
new art::Assns<sbn::MergedTrackInfo, recob::PFParticle>);
173 art::PtrMaker<sbn::MergedTrackInfo> infoPtrMaker {e};
176 art::Handle<std::vector<recob::Slice>> slice_handle;
177 e.getByLabel(fPFPLabel, slice_handle);
179 std::vector<art::Ptr<recob::Slice>>
slices;
180 art::fill_ptr_vector(slices, slice_handle);
182 art::FindManyP<recob::PFParticle> slicePFPs(slices, e, fPFPLabel);
187 for (
unsigned i_slc = 0; i_slc < slices.size(); i_slc++) {
189 const std::vector<art::Ptr<recob::PFParticle>> &this_slice_pfps = slicePFPs.at(i_slc);
191 art::FindManyP<recob::Vertex> slicePFPVtxs(this_slice_pfps, e, fPFPLabel);
193 art::Ptr<recob::Vertex> vtx;
194 art::Ptr<recob::PFParticle> primary;
196 for (
unsigned i_pfp = 0; i_pfp < this_slice_pfps.size(); i_pfp++) {
197 if (this_slice_pfps[i_pfp]->
IsPrimary() && slicePFPVtxs.at(i_pfp).size()) {
198 primary = this_slice_pfps[i_pfp];
199 vtx = slicePFPVtxs.at(i_pfp).at(0);
205 if (!primary)
continue;
207 std::vector<art::Ptr<recob::PFParticle>> topTracks;
211 for (
unsigned d: primary->Daughters()) {
212 for (
unsigned i_pfp = 0; i_pfp < this_slice_pfps.size(); i_pfp++) {
213 if (this_slice_pfps[i_pfp]->Self() == d) {
222 topTracks.push_back(primary);
225 art::FindManyP<recob::Track> topTrackTracks(topTracks, e, fTrackLabel);
227 std::map<art::Ptr<recob::PFParticle>, std::vector<std::pair<art::Ptr<recob::PFParticle>,
sbn::MergedTrackInfo>>> possible_merge_parents;
228 std::map<art::Ptr<recob::PFParticle>, std::vector<std::pair<art::Ptr<recob::PFParticle>,
sbn::MergedTrackInfo>>> possible_merge_children;
231 for (
unsigned i = 0; i < topTracks.size(); i++) {
232 for (
unsigned j = i+1; j < topTracks.size(); j++) {
233 if (!topTrackTracks.at(i).size() || !topTrackTracks.at(j).size())
continue;
235 sbn::MergedTrackInfo info = BuildTrackInfo(geo, *vtx, *topTracks[i], *topTrackTracks.at(i).at(0), *topTracks[j], *topTrackTracks.at(j).at(0));
244 if ((
unsigned)info.
trunk == topTracks[i]->Self()) {
245 possible_merge_parents[topTracks[i]].push_back({topTracks[j], info});
246 possible_merge_children[topTracks[j]].push_back({topTracks[i], info});
250 possible_merge_parents[topTracks[j]].push_back({topTracks[i], info});
251 possible_merge_children[topTracks[i]].push_back({topTracks[j], info});
258 for (
unsigned i = 0; i < topTracks.size(); i++) {
259 std::vector<art::Ptr<recob::PFParticle>> daughters;
260 for (
unsigned d: topTracks[i]->Daughters()) {
261 for (
unsigned i_pfp = 0; i_pfp < this_slice_pfps.size(); i_pfp++) {
262 if (this_slice_pfps[i_pfp]->Self() == d) {
269 art::FindManyP<recob::Track> daughterTracks(daughters, e, fTrackLabel);
270 for (
unsigned j = 0; j < daughters.size(); j++) {
271 if (!topTrackTracks.at(i).size() || !daughterTracks.at(j).size())
continue;
273 sbn::MergedTrackInfo info = BuildTrackInfo(geo, *vtx, *topTracks[i], *topTrackTracks.at(i).at(0), *daughters[j], *daughterTracks.at(j).at(0),
true);
279 possible_merge_parents[topTracks[i]].push_back({daughters[j], info});
280 possible_merge_children[daughters[j]].push_back({topTracks[j], info});
286 for (
auto const &pair: possible_merge_parents) {
293 if (pair.second.size() == 1 && possible_merge_children[pair.first].size() == 0) {
294 art::Ptr<recob::PFParticle> branch = pair.second[0].first;
295 if (possible_merge_parents[branch].
size() == 0 && possible_merge_children[branch].size() == 1) {
296 infos->push_back(pair.second[0].second);
297 art::Ptr<sbn::MergedTrackInfo> infoPtr = infoPtrMaker(infos->size()-1);
298 assn->addSingle(infoPtr, pair.first);
299 assn->addSingle(infoPtr, branch);
305 e.put(std::move(infos));
306 e.put(std::move(assn));
sbn::MergedTrackInfo BuildTrackInfo(const geo::GeometryCore *geo, const recob::Vertex &vtx, const recob::PFParticle &A, const recob::Track &Atrk, const recob::PFParticle &B, const recob::Track &Btrk, bool assume_a_is_trunk=false)
Data product for reconstructed trajectory in space.
Utilities related to art service access.
size_t Self() const
Returns the index of this particle.
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
Declaration of signal hit object.
Point_t const & LocationAtPoint(size_t i) const
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
std::size_t size(FixedBins< T, C > const &) noexcept
MergedTrackIdentifier(fhicl::ParameterSet const &p)
bool IsPrimary(const caf::SRTrueParticleProxy &p)
Whether this is a primary particle or generated by a secondary interaction.
Definition of vertex object for LArSoft.
Access the description of detector geometry.
Collection of exceptions for Geometry system.
Point_t const & Start() const
Access to track position at different points.
Data product for reconstructed trajectory in space.
Description of geometry of one entire detector.
Provides recob::Track data product.
std::vector< TCSlice > slices
size_t FirstValidPoint() const
Hierarchical representation of particle flow.
size_t NextValidPoint(size_t index) const
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
MergedTrackIdentifier & operator=(MergedTrackIdentifier const &)=delete
Declaration of basic channel signal object.
Vector_t DirectionAtPoint(size_t i) const
TVector3 MeanDirection(const recob::Vertex &vtx, const recob::Track &trk)
Class defining a sparse vector (holes are zeroes)
art::InputTag fTrackLabel
helper function for LArPandoraInterface producer module
const Point_t & position() const
Return vertex 3D position.
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:
void produce(art::Event &e) override