Skip to content
32 changes: 28 additions & 4 deletions sbncode/CAFMaker/CAFMakerParams.h
Original file line number Diff line number Diff line change
Expand Up @@ -350,10 +350,10 @@ namespace caf
"" //Empty by default, configured in icaruscode cafmaker_defs
};

Atom<art::InputTag> NuGraphSliceHitLabel {
Name("NuGraphSliceHitLabel"),
Comment("Label of NuGraph slice hit map."),
"" //Empty by default, please set to e.g. art::InputTag("nuslhits")
Atom<art::InputTag> NuGraphSlicesLabel {
Name("NuGraphSlicesLabel"),
Comment("Label of slices that have NuGraph inference."),
"" //Empty by default, please set to e.g. art::InputTag("NCCSlices")
};

Atom<art::InputTag> NuGraphFilterLabel {
Expand All @@ -368,6 +368,30 @@ namespace caf
"" //Empty by default, please set to e.g. art::InputTag("NuGraph","semantic")
};

Atom<bool> UsePandoraAfterNuGraph {
Name("UsePandoraAfterNuGraph"),
Comment("Whether to use the second pass Pandora outputs for NuGraph reco."),
false
};

Atom<float> NuGraphFilterCut {
Name("NuGraphFilterCut"),
Comment("Cut on the NuGraph2 filter score to define hit as signal or noise."),
0.5
};

Atom<float> NuGraphHIPTagWireDist {
Name("NuGraphHIPTagWireDist"),
Comment("TPC wire distance from the vertex used to count NuGraph2–tagged HIP hits."),
10
};

Atom<float> NuGraphHIPTagTickDist {
Name("NuGraphHIPTagTickDist"),
Comment("TPC tick distance from the vertex used to count NuGraph-2–tagged HIP hits."),
50
};

Atom<string> OpFlashLabel {
Name("OpFlashLabel"),
Comment("Label of PMT flash."),
Expand Down
125 changes: 89 additions & 36 deletions sbncode/CAFMaker/CAFMaker_module.cc
Original file line number Diff line number Diff line change
Expand Up @@ -1717,33 +1717,30 @@ void CAFMaker::produce(art::Event& evt) noexcept {

// collect the TPC slices
std::vector<art::Ptr<recob::Slice>> slices;
std::vector<art::Ptr<recob::Slice>> nuGraphSlices;
std::vector<std::string> slice_tag_suffixes;
std::vector<unsigned> slice_tag_indices;
for (unsigned i_tag = 0; i_tag < pandora_tag_suffixes.size(); i_tag++) {
const std::string &pandora_tag_suffix = pandora_tag_suffixes[i_tag];

// Get a handle on the slices
art::Handle<std::vector<recob::Slice>> thisSlices;
GetByLabelStrict(evt, fParams.PFParticleLabel() + pandora_tag_suffix, thisSlices);

if (thisSlices.isValid()) {
art::fill_ptr_vector(slices, thisSlices);
if (fParams.UsePandoraAfterNuGraph()) {
nuGraphSlices = slices;
} else {
nuGraphSlices = evt.getProduct<std::vector<art::Ptr<recob::Slice>>>(fParams.NuGraphSlicesLabel().label() + pandora_tag_suffix);
}
for (unsigned i = 0; i < thisSlices->size(); i++) {
slice_tag_suffixes.push_back(pandora_tag_suffix);
slice_tag_indices.push_back(i_tag);
}
}
}

// nu graph
std::vector< art::Handle<std::vector<unsigned int>> > ng2_slice_hit_map_handle(pandora_tag_suffixes.size());
std::vector< art::Handle<std::vector<anab::FeatureVector<1>>> > ng2_filter_handle(pandora_tag_suffixes.size());
std::vector< art::Handle<std::vector<anab::FeatureVector<5>>> > ng2_semantic_handle(pandora_tag_suffixes.size());
for (unsigned i_tag = 0; i_tag < pandora_tag_suffixes.size(); i_tag++) {
const std::string &pandora_tag_suffix = pandora_tag_suffixes[i_tag];
GetByLabelIfExists(evt, fParams.NuGraphSliceHitLabel().encode() + pandora_tag_suffix, ng2_slice_hit_map_handle[i_tag]);
GetByLabelIfExists(evt, fParams.NuGraphFilterLabel().label() + pandora_tag_suffix + ":" + fParams.NuGraphFilterLabel().instance(), ng2_filter_handle[i_tag]);
GetByLabelIfExists(evt, fParams.NuGraphSemanticLabel().label() + pandora_tag_suffix + ":" + fParams.NuGraphSemanticLabel().instance(), ng2_semantic_handle[i_tag]);
}

// The Standard Record
// Branch entry definition -- contains list of slices, CRT information, and truth information
StandardRecord rec;
Expand Down Expand Up @@ -1799,19 +1796,7 @@ void CAFMaker::produce(art::Event& evt) noexcept {
fmatch_assn_map.emplace(std::make_pair(fname_opdet, sfm_assn));
}
}

std::vector<art::Ptr<anab::FeatureVector<1>>> ng2_filter_vec;
std::vector<art::Ptr<anab::FeatureVector<5>>> ng2_semantic_vec;
if (ng2_filter_handle[producer].isValid()) {
art::fill_ptr_vector(ng2_filter_vec,ng2_filter_handle[producer]);
}
if (ng2_semantic_handle[producer].isValid()) {
art::fill_ptr_vector(ng2_semantic_vec,ng2_semantic_handle[producer]);
}
if (ng2_slice_hit_map_handle[producer].isValid()) {
FillSliceNuGraph(slcHits,*ng2_slice_hit_map_handle[producer],ng2_filter_vec,ng2_semantic_vec,recslc);
}


art::FindManyP<sbn::OpT0Finder> fmOpT0 =
FindManyPStrict<sbn::OpT0Finder>(sliceList, evt, fParams.OpT0Label() + slice_tag_suff);
std::vector<art::Ptr<sbn::OpT0Finder>> slcOpT0;
Expand Down Expand Up @@ -1865,15 +1850,15 @@ void CAFMaker::produce(art::Event& evt) noexcept {
// make Ptr's to clusters for cluster -> other object associations
if (fmPFPClusters.isValid()) {
for (size_t ipf=0; ipf<fmPFPart.size();++ipf) {
std::vector<art::Ptr<recob::Hit>> pfphits;
std::vector<art::Ptr<recob::Cluster>> pfclusters = fmPFPClusters.at(ipf);
art::FindManyP<recob::Hit> fmCluHits = FindManyPStrict<recob::Hit>(pfclusters, evt, fParams.PFParticleLabel() + slice_tag_suff);
for (size_t icl=0; icl<fmCluHits.size();icl++) {
for (auto hit : fmCluHits.at(icl)) {
pfphits.push_back(hit);
}
}
fmPFPartHits.push_back(pfphits);
std::vector<art::Ptr<recob::Hit>> pfphits;
std::vector<art::Ptr<recob::Cluster>> pfclusters = fmPFPClusters.at(ipf);
art::FindManyP<recob::Hit> fmCluHits = FindManyPStrict<recob::Hit>(pfclusters, evt, fParams.PFParticleLabel() + slice_tag_suff);
for (size_t icl=0; icl<fmCluHits.size();icl++) {
for (auto hit : fmCluHits.at(icl)) {
pfphits.push_back(hit);
}
}
fmPFPartHits.push_back(pfphits);
}
}

Expand Down Expand Up @@ -2043,8 +2028,8 @@ void CAFMaker::produce(art::Event& evt) noexcept {
// primary particle and meta-data
const recob::PFParticle *primary = (iPart == fmPFPart.size()) ? NULL : fmPFPart[iPart].get();
const larpandoraobj::PFParticleMetadata *primary_meta = (iPart == fmPFPart.size()) ? NULL : fmPFPMeta.at(iPart).at(0).get();
// get the flash match

// get the flash match
std::map<std::string, const sbn::SimpleFlashMatch*> fmatch_map;
std::map<std::string, art::FindManyP<sbn::SimpleFlashMatch>>::iterator fmatch_it;
for(fmatch_it = fmatch_assn_map.begin();fmatch_it != fmatch_assn_map.end();fmatch_it++) {
Expand All @@ -2060,12 +2045,56 @@ void CAFMaker::produce(art::Event& evt) noexcept {
}
}
}

// get the primary vertex
const recob::Vertex *vertex = (iPart == fmPFPart.size() || !fmVertex.at(iPart).size()) ? NULL : fmVertex.at(iPart).at(0).get();

//#######################################################
// Add slice info.
//#######################################################
if (std::find(nuGraphSlices.begin(), nuGraphSlices.end(), slice) != nuGraphSlices.end()) {
std::vector<art::Ptr<anab::FeatureVector<1>>> ng2_filter_vec;
std::vector<art::Ptr<anab::FeatureVector<5>>> ng2_semantic_vec;
art::FindOneP<anab::FeatureVector<1>> findOneFilter(slcHits, evt, fParams.NuGraphFilterLabel().label() + slice_tag_suff + ":" + fParams.NuGraphFilterLabel().instance());
art::FindOneP<anab::FeatureVector<5>> findOneSemantic(slcHits, evt, fParams.NuGraphSemanticLabel().label() + slice_tag_suff + ":" + fParams.NuGraphSemanticLabel().instance());

// filter
if (findOneFilter.isValid()) {
ng2_filter_vec.reserve(slcHits.size());
for (size_t hitIdx = 0; hitIdx < slcHits.size(); ++hitIdx) {
ng2_filter_vec.emplace_back(findOneFilter.at(hitIdx));
}
}

// semantic tagging
if (findOneSemantic.isValid()) {
ng2_semantic_vec.reserve(slcHits.size());
for (size_t hitIdx = 0; hitIdx < slcHits.size(); ++hitIdx) {
ng2_semantic_vec.emplace_back(findOneSemantic.at(hitIdx));
}
}

// vertex projection onto the three wire planes
float vtx_wire[3];
float vtx_tick[3];

if (vertex != NULL) {
auto const& tpcID = geom->FindTPCAtPosition(vertex->position());
for (geo::PlaneID const& p : wireReadout.Iterate<geo::PlaneID>()) {
auto const& planeID = geo::PlaneID{tpcID, p.Plane};
const geo::PlaneGeo& planeGeo = wireReadout.Plane(planeID);
vtx_wire[p.Plane] = planeGeo.WireCoordinate(vertex->position()); ///< wire projection
vtx_tick[p.Plane] = dprop.ConvertXToTicks(vertex->position().X(), planeID); ///< drift projection
}
}

if (ng2_filter_vec.size() > 0 || ng2_semantic_vec.size() > 0) {
FillSliceNuGraph(slcHits, ng2_filter_vec, ng2_semantic_vec, fmPFPartHits,
vtx_wire, vtx_tick, fParams.NuGraphHIPTagWireDist(), fParams.NuGraphHIPTagTickDist(),
fParams.NuGraphFilterCut(), recslc);
}
}

FillSliceVars(*slice, primary, producer, recslc);
FillSliceMetadata(primary_meta, recslc);
FillSliceFlashMatch(fmatch_map["fmatch"], recslc.fmatch);
Expand Down Expand Up @@ -2189,8 +2218,32 @@ void CAFMaker::produce(art::Event& evt) noexcept {
FillCNNScores(thisParticle, cnnScores, pfp);
}

if (ng2_slice_hit_map_handle[producer].isValid()) {
FillPFPNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp);
if (std::find(nuGraphSlices.begin(), nuGraphSlices.end(), slice) != nuGraphSlices.end()) {
std::vector<art::Ptr<recob::Hit>>& PFPHits = fmPFPartHits.at(iPart);
art::FindOneP<anab::FeatureVector<1>> findOneFilter(PFPHits, evt, fParams.NuGraphFilterLabel().label() + slice_tag_suff + ":" + fParams.NuGraphFilterLabel().instance());
art::FindOneP<anab::FeatureVector<5>> findOneSemantic(PFPHits, evt, fParams.NuGraphSemanticLabel().label() + slice_tag_suff + ":" + fParams.NuGraphSemanticLabel().instance());
std::vector<art::Ptr<anab::FeatureVector<1>>> ng2_filter_vec;
std::vector<art::Ptr<anab::FeatureVector<5>>> ng2_semantic_vec;

// filter
if (findOneFilter.isValid()) {
ng2_filter_vec.reserve(PFPHits.size());
for (size_t hitIdx = 0; hitIdx < PFPHits.size(); ++hitIdx) {
ng2_filter_vec.emplace_back(findOneFilter.at(hitIdx));
}
}

// semantic tagging
if (findOneSemantic.isValid()) {
ng2_semantic_vec.reserve(PFPHits.size());
for (size_t hitIdx = 0; hitIdx < PFPHits.size(); ++hitIdx) {
ng2_semantic_vec.emplace_back(findOneSemantic.at(hitIdx));
}
}

if (ng2_filter_vec.size() > 0 || ng2_semantic_vec.size() > 0) {
FillPFPNuGraph(PFPHits, ng2_filter_vec, ng2_semantic_vec, fParams.NuGraphFilterCut(), pfp);
}
}

if (!thisTrack.empty()) { // it has a track!
Expand Down
Loading