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