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;
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;
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;
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)
static bool IsNeutrino(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as a neutrino.
std::size_t size(FixedBins< T, C > const &) noexcept
bool IsPrimary(const caf::SRTrueParticleProxy &p)
Whether this is a primary particle or generated by a secondary interaction.
Description of geometry of one entire detector.
std::vector< TCSlice > slices
static bool IsTrack(const art::Ptr< recob::PFParticle > particle)
Determine whether a particle has been reconstructed as track-like.
art::InputTag fTrackLabel