267 art::ServiceHandle<cheat::BackTrackerService> backtracker;
268 art::ServiceHandle<cheat::ParticleInventoryService> inventory_service;
270 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(ev);
272 art::ValidHandle<std::vector<simb::MCTruth>> mctruth_handle = ev.getValidHandle<std::vector<simb::MCTruth>>(
"generator");
273 const std::vector<simb::MCTruth> &mctruth_list = *mctruth_handle;
274 std::vector<art::Ptr<simb::MCTruth>> mctruth_ptrs;
275 art::fill_ptr_vector(mctruth_ptrs, mctruth_handle);
277 art::FindManyP<simb::MCParticle, sim::GeneratedParticleInfo> truth_to_particles(mctruth_handle, ev,
"largeant");
278 const std::vector<simb::MCParticle> &g4_particles = *ev.getValidHandle<std::vector<simb::MCParticle>>(
"largeant");
279 std::map<int, const simb::MCParticle*> g4_particle_map;
280 for (
unsigned i_g4 = 0; i_g4 < g4_particles.size(); i_g4++) {
281 g4_particle_map[g4_particles[i_g4].TrackId()] = &g4_particles[i_g4];
284 std::vector<int> truth_to_numucc;
285 std::vector<simb::MCTruth> numucc;
286 std::vector<simb::MCParticle> G4muons;
288 for (
unsigned i = 0; i < mctruth_list.size(); i++) {
289 const simb::MCTruth &truth = mctruth_list[i];
290 TVector3
vertex(truth.GetNeutrino().Nu().Position().X(), truth.GetNeutrino().Nu().Position().Y(), truth.GetNeutrino().Nu().Position().Z());
292 if (
InFV(
vertex) && truth.GetNeutrino().CCNC() == 0 &&
abs(truth.GetNeutrino().Nu().PdgCode()) == 14) {
294 const simb::MCParticle *G4muon =
Genie2G4MCParticle(truth.GetNeutrino().Lepton(), truth, truth_to_particles.at(i), truth_to_particles.data(i));
296 numucc.push_back(truth);
297 G4muons.push_back(*G4muon);
298 truth_to_numucc.push_back(numucc.size()-1);
300 else truth_to_numucc.push_back(-1);
304 if (numucc.size() == 0)
return;
307 std::vector<float> muonVisE(G4muons.size(), 0.);
308 for (
unsigned i = 0; i < G4muons.size(); i++) {
309 std::vector<const sim::IDE*> particle_ides(backtracker->TrackIdToSimIDEs_Ps(G4muons[i].TrackId()));
310 for (
const sim::IDE *ide: particle_ides) muonVisE[i] += ide->energy / 1000.;
314 std::vector<float> numuVisE(numucc.size(), 0.);
315 for (
unsigned i_g4 = 0; i_g4 < g4_particles.size(); i_g4++) {
316 const simb::MCParticle &particle = g4_particles[i_g4];
317 if (particle.Process() !=
"primary")
continue;
318 art::Ptr<simb::MCTruth> truth = inventory_service->TrackIdToMCTruth_P(particle.TrackId());
319 for (
unsigned i_truth = 0; i_truth < mctruth_ptrs.size(); i_truth++) {
320 if (truth == mctruth_ptrs[i_truth]) {
321 if (truth_to_numucc[i_truth] != -1) {
322 std::vector<const sim::IDE*> particle_ides(backtracker->TrackIdToSimIDEs_Ps(particle.TrackId()));
323 for (
const sim::IDE *ide: particle_ides) numuVisE[truth_to_numucc[i_truth]] += ide->energy / 1000.;
333 std::vector<int> matching_track(G4muons.size(), -1);
334 std::vector<float> track_purity(G4muons.size(), -1);
335 std::vector<float> track_completeness(G4muons.size(), -1);
337 art::ValidHandle<std::vector<recob::PFParticle>> particle_handle = ev.getValidHandle<std::vector<recob::PFParticle>>(
"pandora");
338 art::FindManyP<recob::Track>
tracks(particle_handle, ev,
"pandoraTrack");
339 art::FindManyP<larpandoraobj::PFParticleMetadata> metadatas(particle_handle, ev,
"pandora");
340 art::FindManyP<recob::Vertex> particles_to_vertex(particle_handle, ev,
"pandora");
341 for (
unsigned i_part = 0; i_part < particle_handle->size(); i_part++) {
342 if (!
tracks.at(i_part).size())
continue;
343 art::FindManyP<recob::Hit> fmHits(
tracks.at(i_part), ev,
"pandoraTrack");
344 const std::vector<art::Ptr<recob::Hit>> &this_hits = fmHits.at(0);
349 std::sort(matches.begin(), matches.end(),
350 [] (
auto const &lhs,
auto const &rhs) {
return lhs.second > rhs.second; });
352 for (
unsigned i_cc = 0; i_cc < G4muons.size(); i_cc++) {
353 if (matches.size() && matches[0].first == G4muons[i_cc].TrackId() && matches[0].second / muonVisE[i_cc] > 0.5) {
354 matching_track[i_cc] = particle_handle->at(i_part).Self();
355 track_purity[i_cc] = matches[0].second /
356 std::accumulate(matches.begin(), matches.end(), 0.f,
357 [](
auto &
a,
auto &b){
return a + b.second;});
358 track_completeness[i_cc] = matches[0].second / muonVisE[i_cc];
364 std::vector<int> matching_slice(numucc.size(), -1);
365 std::vector<float> matching_purity(numucc.size(), -1);
366 std::vector<float> matching_completeness(numucc.size(), -1);
368 art::ValidHandle<std::vector<recob::Slice>> slice_handle = ev.getValidHandle<std::vector<recob::Slice>>(
"pandora");
369 art::FindManyP<recob::Hit> slice_hits(slice_handle, ev,
"pandora");
370 art::FindManyP<recob::PFParticle> slice_particles(slice_handle, ev,
"pandora");
372 for (
unsigned i_slice = 0; i_slice < slice_handle->size(); i_slice++) {
373 std::vector<float> matchingE(numuVisE.size(), 0.);
374 std::vector<float> matchingPrimaryE(numuVisE.size(), 0.);
378 for (
unsigned i_match = 0; i_match < matches.size(); i_match++) {
379 totalE += matches[i_match].second / 1000.;
382 for (
unsigned i_match = 0; i_match < matches.size(); i_match++) {
383 if (g4_particle_map.count(matches[i_match].first)) {
384 const simb::MCParticle &part = *g4_particle_map.at(matches[i_match].
first);
385 art::Ptr<simb::MCTruth> truth = inventory_service->TrackIdToMCTruth_P(part.TrackId());
386 for (
unsigned i_truth = 0; i_truth < mctruth_ptrs.size(); i_truth++) {
387 if (truth == mctruth_ptrs[i_truth]) {
388 if (truth_to_numucc[i_truth] != -1) {
389 if (part.Process() ==
"primary") matchingPrimaryE[truth_to_numucc[i_truth]] += matches[i_match].
second / 1000.;
390 matchingE[truth_to_numucc[i_truth]] += matches[i_match].second / 1000.;
398 unsigned best_match =
std::distance(matchingE.begin(), std::max_element(matchingE.begin(), matchingE.end()));
399 if (matchingPrimaryE[best_match] / numuVisE[best_match] > 0.5) {
400 matching_slice[best_match] = i_slice;
401 matching_purity[best_match] = matchingE[best_match] / totalE;
402 matching_completeness[best_match] = matchingPrimaryE[best_match] / numuVisE[best_match];
407 for (
unsigned i = 0; i < numucc.size(); i++) {
408 bool has_muon_track = matching_track[i] != -1;
409 bool has_slice = matching_slice[i] != -1;
411 bool has_pure_slice = has_slice && matching_purity[i] > 0.5;
413 bool muon_is_reco =
false;
414 bool muon_is_fid =
false;
415 if (has_muon_track) {
419 for (
auto pair: properties)
std::cout << pair.first << std::endl;
420 if (properties.count(
"IsClearCosmic")) {
421 muon_is_reco =
false;
427 auto muon_vert =
tracks.at(matching_track[i]).at(0)->Start();
428 TVector3 muon_vert_v(muon_vert.X(), muon_vert.Y(), muon_vert.Z());
430 muon_is_fid =
InFV(muon_vert_v);
433 bool slice_is_neutrino =
false;
434 bool slice_is_reco =
false;
435 bool slice_is_fiducial =
false;
436 bool slice_has_muon =
false;
438 const std::vector<art::Ptr<recob::PFParticle>> &this_slice_particles = slice_particles.at(matching_slice[i]);
439 for (art::Ptr<recob::PFParticle> pfp: this_slice_particles) {
440 if (pfp->IsPrimary()) {
444 for (
auto pair: properties)
std::cout << pair.first <<
" " << pair.second << std::endl;
446 if (properties.count(
"IsNeutrino")) slice_is_neutrino =
true;
447 if (properties.count(
"IsNeutrino") && pfp->PdgCode() == 14) slice_is_reco =
true;
450 if (particles_to_vertex.at(pfp.key()).
size()) {
451 const recob::Vertex &vert = *particles_to_vertex.at(pfp.key()).at(0);
453 slice_is_fiducial =
InFV(vect);
456 if (has_muon_track && matching_track[i] == (
int)pfp->Self()) {
457 slice_has_muon =
true;
462 bool has_pure_nu_slice = has_pure_slice && slice_is_neutrino;
463 bool has_fid_nu_slice = slice_is_fiducial && slice_is_neutrino;
464 bool has_fid_pure_slice = slice_is_fiducial && has_pure_slice;
465 bool has_reco_fid_slice = slice_is_fiducial && slice_is_reco;
466 bool slice_has_reco_muon = slice_has_muon && muon_is_reco;
468 std::array<bool, n_reco_eff> pass = {has_muon_track, muon_is_reco, muon_is_fid, has_slice, has_pure_slice, slice_is_reco, slice_is_fiducial, slice_has_muon, has_fid_pure_slice, has_reco_fid_slice, slice_has_reco_muon, has_fid_nu_slice, has_pure_nu_slice, slice_is_neutrino};
471 if (pass[j] && pass[
k]) {
void FillMatchingSlc(Histos &h, float purity, float completeness)
ClusterModuleLabel join with tracks
std::size_t size(FixedBins< T, C > const &) noexcept
Definition of vertex object for LArSoft.
std::vector< std::pair< int, float > > AllTrueParticleIDEnergyMatches(const detinfo::DetectorClocksData &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
double distance(geo::Point_t const &point, CathodeDesc_t const &cathode)
Returns the distance of a point from the cathode.
Metadata associated to PFParticles.
Ionization at a point of the TPC sensitive volume.
const PropertiesMap & GetPropertiesMap() const
void FillMatchingMu(Histos &h, float purity, float completeness)
void FillTrue(Histos &h, const simb::MCTruth &interaction, const simb::MCParticle &G4lepton)
const simb::MCParticle * Genie2G4MCParticle(const simb::MCParticle &genie_part, const simb::MCTruth &mctruth, const std::vector< art::Ptr< simb::MCParticle >> &g4_mcparticles, const std::vector< const sim::GeneratedParticleInfo * > infos)
std::vector< Histos > fReco
static const unsigned n_reco_eff
const Point_t & position() const
Return vertex 3D position.
BEGIN_PROLOG could also be cout