-
Notifications
You must be signed in to change notification settings - Fork 31
Feature/cerati ng2caf #532
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
eade067
33f56fb
bb1e587
0b5ad31
790ac10
8f0c667
b36ce76
9e274d8
0157111
fcff962
cae5b11
c7343d5
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -95,6 +95,8 @@ | |
#include "lardataobj/RecoBase/Vertex.h" | ||
#include "lardataobj/RecoBase/Shower.h" | ||
#include "lardataobj/RecoBase/MCSFitResult.h" | ||
#include "lardataobj/RecoBase/Cluster.h" | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm only leaving this as comments for now as I have more pieces to look at and so don't want to leave an actual "review" result yet, but I'll put a couple thoughts here. I guess the inclusion of
here as an include too since There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. sure, I'll add this include! There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks for adding! |
||
#include "lardataobj/AnalysisBase/MVAOutput.h" | ||
|
||
#include "nusimdata/SimulationBase/MCFlux.h" | ||
#include "nusimdata/SimulationBase/MCTruth.h" | ||
|
@@ -1731,6 +1733,17 @@ void CAFMaker::produce(art::Event& evt) noexcept { | |
} | ||
} | ||
|
||
// 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; | ||
|
@@ -1787,6 +1800,18 @@ void CAFMaker::produce(art::Event& evt) noexcept { | |
} | ||
} | ||
|
||
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; | ||
|
@@ -1833,6 +1858,25 @@ void CAFMaker::produce(art::Event& evt) noexcept { | |
art::FindManyP<recob::PFParticle> fmSpacePointPFPs = | ||
FindManyPStrict<recob::PFParticle>(slcSpacePoints, evt, fParams.PFParticleLabel() + slice_tag_suff); | ||
|
||
art::FindManyP<recob::Cluster> fmPFPClusters = | ||
FindManyPStrict<recob::Cluster>(fmPFPart, evt, fParams.PFParticleLabel() + slice_tag_suff); | ||
|
||
std::vector<std::vector<art::Ptr<recob::Hit>>> fmPFPartHits; | ||
// 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); | ||
} | ||
} | ||
|
||
Comment on lines
+1861
to
+1879
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I believe we had a quick chat once about using index directly vs using the art Ptr There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. when looping plainly over a collection, the way one would use key is to first create an art::Ptr based on the handle and the index, which guarantees that the key is the same as the index |
||
art::FindManyP<recob::Shower> fmShower = | ||
FindManyPStrict<recob::Shower>(fmPFPart, evt, fParams.RecoShowerLabel() + slice_tag_suff); | ||
|
||
|
@@ -2145,6 +2189,10 @@ void CAFMaker::produce(art::Event& evt) noexcept { | |
FillCNNScores(thisParticle, cnnScores, pfp); | ||
} | ||
|
||
if (ng2_slice_hit_map_handle[producer].isValid()) { | ||
FillPPFNuGraph(*ng2_slice_hit_map_handle[producer], ng2_filter_vec, ng2_semantic_vec, fmPFPartHits.at(iPart), pfp); | ||
} | ||
|
||
if (!thisTrack.empty()) { // it has a track! | ||
assert(thisTrack.size() == 1); | ||
|
||
|
Original file line number | Diff line number | Diff line change | ||||
---|---|---|---|---|---|---|
|
@@ -579,6 +579,26 @@ namespace caf | |||||
} | ||||||
} | ||||||
|
||||||
|
||||||
void FillSliceNuGraph(const std::vector<art::Ptr<recob::Hit>> &inputHits, | ||||||
const std::vector<unsigned int> &sliceHitsMap, | ||||||
const std::vector<art::Ptr<anab::FeatureVector<1>>> &ngFilterResult, | ||||||
const std::vector<art::Ptr<anab::FeatureVector<5>>> &ngSemanticResult, | ||||||
caf::SRSlice &slice) | ||||||
{ | ||||||
|
||||||
//need to double check that the slice processed by NuGraph is the same under consideration | ||||||
//std::cout << "sizes=" << inputHits.size() << " " << sliceHitsMap.size() << " " << ngFilterResult.size() << " " << ngSemanticResult.size() << std::endl; | ||||||
unsigned int nHits = inputHits.size(); | ||||||
if (nHits==0 || nHits!=sliceHitsMap.size() || inputHits[0].key()!=sliceHitsMap[0]) return;//not the same slice! | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. should this be a silent error or would it be a sign of a bigger problem? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It's not an error. We just need to skip the slices that were not considered by NuGraph There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Oh right, since NuGraph only runs on one slice! |
||||||
|
||||||
unsigned int npass = 0; | ||||||
for ( unsigned int i = 0; i < nHits; i++ ) { | ||||||
if (ngFilterResult.at(i)->at(0)>0.5) npass++; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hard-coded There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Usually the cut value is included:
Suggested change
Of course practically it seldom matters, but it would be good to pick a convention and stick with it (below there is a |
||||||
} | ||||||
slice.ng_filt_pass_frac = float(npass)/nHits; | ||||||
} | ||||||
|
||||||
//...................................................................... | ||||||
|
||||||
|
||||||
|
@@ -1004,6 +1024,58 @@ namespace caf | |||||
srpfp.cnnscore.nclusters = cnnscore->nClusters; | ||||||
} | ||||||
|
||||||
void FillPPFNuGraph(const std::vector<unsigned int> &sliceHitsMap, | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I just noticed this is There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. nice catch! |
||||||
const std::vector<art::Ptr<anab::FeatureVector<1>>> &ngFilterResult, | ||||||
const std::vector<art::Ptr<anab::FeatureVector<5>>> &ngSemanticResult, | ||||||
const std::vector<art::Ptr<recob::Hit>> &pfpHits, | ||||||
caf::SRPFP& srpfp, | ||||||
bool allowEmpty) | ||||||
{ | ||||||
|
||||||
// the nugraph elements are ordered the same as the sliceHitsMap | ||||||
std::vector<size_t> mappedhits; | ||||||
for (auto& hit : pfpHits) { | ||||||
auto it = std::find(sliceHitsMap.begin(), sliceHitsMap.end(), hit.key()); | ||||||
if (it != sliceHitsMap.end()) { | ||||||
size_t index = std::distance(sliceHitsMap.begin(), it); | ||||||
mappedhits.push_back(index); | ||||||
} | ||||||
} | ||||||
Comment on lines
+1036
to
+1043
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just double checking my understanding, I assume that the NuGraph producer is filling up the map that you grab above with the hit keys for the slice and so then this is why you grab things in this way from the map? There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes. See icaruscode/NuGraphIcarus/IcarusNuSliceHitsProducer_module.cc being added in the icaruscode PR. NuGraph runs over a hit collection. This hit collection is created based on the hits in the best neutrino slice. This means that NuGraph labels are applied to a hit collection which is a subset of the one used by Pandora. So in order to get the NuGraph label of hits in Pandora PFPs, a mapping is needed |
||||||
|
||||||
if (mappedhits.size()>0) { | ||||||
std::vector<float> ng2sempfpcounts(5,0); | ||||||
size_t ng2bkgpfpcount = 0; | ||||||
for (size_t pos : mappedhits) { | ||||||
auto bkgscore = ngFilterResult.at(pos); | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Avoid unnecessary copies:
Suggested change
(this is probably still fine, since it's implemented as a static array). |
||||||
if (bkgscore->at(0)<0.5) { | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "Is this the same |
||||||
ng2bkgpfpcount++; | ||||||
} else { | ||||||
auto scores = ngSemanticResult.at(pos); | ||||||
std::vector<float> ng2semscores; | ||||||
for (size_t i=0;i<scores->size();i++) ng2semscores.push_back(scores->at(i)); | ||||||
size_t sem_label = std::distance(ng2semscores.begin(), std::max_element(ng2semscores.begin(), ng2semscores.end()));//arg_max(ng2semscores); | ||||||
ng2sempfpcounts[sem_label]++; | ||||||
} | ||||||
} | ||||||
srpfp.ng_sem_cat = std::distance(ng2sempfpcounts.begin(), std::max_element(ng2sempfpcounts.begin(), ng2sempfpcounts.end()));//arg_max(ng2sempfpcounts); | ||||||
srpfp.ng_mip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[0])/(pfpHits.size()-ng2bkgpfpcount) : -1.); | ||||||
srpfp.ng_hip_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[1])/(pfpHits.size()-ng2bkgpfpcount) : -1.); | ||||||
srpfp.ng_shr_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[2])/(pfpHits.size()-ng2bkgpfpcount) : -1.); | ||||||
srpfp.ng_mhl_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[3])/(pfpHits.size()-ng2bkgpfpcount) : -1.); | ||||||
srpfp.ng_dif_frac = (pfpHits.size()>ng2bkgpfpcount ? float(ng2sempfpcounts[4])/(pfpHits.size()-ng2bkgpfpcount) : -1.); | ||||||
srpfp.ng_bkg_frac = float(ng2bkgpfpcount)/pfpHits.size(); | ||||||
} else { | ||||||
srpfp.ng_sem_cat = -1; | ||||||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. See the |
||||||
srpfp.ng_mip_frac = -1.; | ||||||
srpfp.ng_hip_frac = -1.; | ||||||
srpfp.ng_shr_frac = -1.; | ||||||
srpfp.ng_mhl_frac = -1.; | ||||||
srpfp.ng_dif_frac = -1.; | ||||||
srpfp.ng_bkg_frac = -1.; | ||||||
} | ||||||
|
||||||
} | ||||||
|
||||||
void FillHitVars(const recob::Hit& hit, | ||||||
unsigned producer, | ||||||
const recob::SpacePoint& spacepoint, | ||||||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I guess the inclusion of
FillReco
prevents this from being an actual problem, but I am trying to recall if our style guidelines suggest thatshould still be included here too since
FeatureVector
is used directly in CAFMaker_module?