10 #include "art/Framework/Core/EDAnalyzer.h" 
   11 #include "art/Framework/Core/ModuleMacros.h" 
   12 #include "art/Framework/Principal/Event.h" 
   13 #include "art/Framework/Principal/Handle.h" 
   14 #include "art/Framework/Services/Registry/ServiceHandle.h" 
   15 #include "art_root_io/TFileService.h" 
   16 #include "canvas/Persistency/Common/FindManyP.h" 
   17 #include "fhiclcpp/ParameterSet.h" 
   48   void analyze(art::Event 
const& 
e) 
override;
 
   90     e.getByLabel(producer, h);
 
   93       msg += 
"Could not find a data product by: " + producer;
 
  225     msg += 
"\033[93m[ERROR]\033[00m <<";
 
  227     msg += 
">> Producer's name not set!";
 
  229     throw ::showerreco::ShowerRecoException(msg.c_str());
 
  232   art::ServiceHandle<geo::Geometry const> geo;
 
  233   art::ServiceHandle<art::TFileService const> 
tfs;
 
  236   fTree = tfs->make<TTree>(
"fShowerQualityTree", 
"");
 
  243     tfs->make<TH1D>(
"hMatchCorrectness",
 
  244                     "Shower 2D Cluster Matching Correctness; Correctness; Showers",
 
  258     "hVtxDX", 
"Reco - MC Start X [cm] Displacement; #DeltaX [cm]; Showers", 200, -100, 100);
 
  261     "hVtxDY", 
"Reco - MC Start Y [cm] Displacement; #DeltaY [cm]; Showers", 200, -100, 100);
 
  264     "hVtxDZ", 
"Reco - MC Start Z [cm] Displacement; #DeltaZ [cm]; Showers", 200, -100, 100);
 
  267     "hVtxDR", 
"Reco - MC Start 3D Vtx Displacement; #DeltaR [cm]; Showers", 200, -100, 100);
 
  278     "hDCosX", 
"Direction Unit Vector Reco - MC #DeltaX; #DeltaCosX; Showers", 100, -2, 2);
 
  281     "hDCosY", 
"Direction Unit Vector Reco - MC #DeltaY; #DeltaCosY; Showers", 100, -2, 2);
 
  284     "hDCosZ", 
"Direction Unit Vector Reco - MC #DeltaZ; #DeltaCosZ; Showers", 100, -2, 2);
 
  287     tfs->make<TH1D>(
"h3DAngleDiff",
 
  288                     "3D Opening Angle Between Reco & MC; Opening Angle [degrees]; Showers",
 
  301     tfs->make<TH2D>(
"hEnergyCorr",
 
  302                     "Reco (x) vs. MC (y) Energy Comparison; Reco Energy [MeV]; MC Energy [MeV]",
 
  311                                  "MC - Reco Energy Fractional Difference; Assymetry; Showers",
 
  317     "hEnergyDiff", 
"MC - Reco Energy Difference; Energy Difference [MeV]; Showers", 200, 0, 1000);
 
  326     tfs->make<TH1D>(
"hMatchedClusterEff_PlaneCombo",
 
  327                     "Matched Shower Cluster's Charge Efficiency; Efficiency; Clusters",
 
  333                                        "Matched Shower Cluster's Charge Purity; Purity; Clusters",
 
  342                                "Best Plane (for energy & dE/dx estimate); Plane ID; Showers",
 
  345                                geo->Nplanes() - 0.5);
 
  355   auto resHandle = GetDataOrDie<std::vector<recob::Shower>>(
e, 
fShowerProducer);
 
  357   const std::vector<sim::MCShower>& ev_mcs(*mcsHandle);
 
  358   const std::vector<recob::Shower>& ev_shower(*resHandle);
 
  359   const std::vector<sim::SimChannel>& ev_simch(*schHandle);
 
  361   if (!(ev_shower.size())) 
return;
 
  364   art::Handle<std::vector<recob::Cluster>> clsHandle;
 
  365   art::FindManyP<recob::Cluster> cluster_m(resHandle, e, 
fShowerProducer);
 
  366   e.get(cluster_m.at(0).front().id(), clsHandle);
 
  367   if (!clsHandle.isValid())
 
  368     throw ::showerreco::ShowerRecoException(
"Failed to retrieve cluster handle!");
 
  369   const std::vector<recob::Cluster>& ev_cluster(*clsHandle);
 
  372   art::FindManyP<recob::Hit> hit_m(clsHandle, e, clsHandle.provenance()->moduleLabel());
 
  373   std::vector<std::vector<art::Ptr<recob::Hit>>> ev_cluster_hit;
 
  374   ev_cluster_hit.reserve(clsHandle->size());
 
  375   std::map<art::Ptr<recob::Cluster>, 
size_t> cluster_ptr_map;
 
  376   for (
size_t i = 0; i < ev_cluster.size(); ++i) {
 
  377     const art::Ptr<recob::Cluster> cluster_ptr(clsHandle, i);
 
  378     cluster_ptr_map[cluster_ptr] = ev_cluster_hit.size();
 
  379     ev_cluster_hit.push_back(hit_m.at(i));
 
  383   std::vector<std::vector<unsigned int>> ass_cluster_v;
 
  384   ass_cluster_v.reserve(ev_shower.size());
 
  385   for (
size_t shower_index = 0; shower_index < ev_shower.size(); ++shower_index) {
 
  386     ass_cluster_v.push_back(std::vector<unsigned int>());
 
  387     for (
auto const& 
p : cluster_m.at(shower_index))
 
  388       ass_cluster_v.back().push_back(cluster_ptr_map[
p]);
 
  392   std::vector<std::vector<unsigned int>> g4_trackid_v;
 
  393   std::vector<unsigned int> mc_index_v;
 
  394   g4_trackid_v.reserve(ev_mcs.size());
 
  395   for (
size_t mc_index = 0; mc_index < ev_mcs.size(); ++mc_index) {
 
  396     auto const& mcs = ev_mcs[mc_index];
 
  397     double energy = mcs.DetProfile().E();
 
  398     std::vector<unsigned int> id_v;
 
  399     id_v.reserve(mcs.DaughterTrackID().size());
 
  401       for (
auto const& 
id : mcs.DaughterTrackID()) {
 
  402         if (
id == mcs.TrackID()) 
continue;
 
  405       id_v.push_back(mcs.TrackID());
 
  406       g4_trackid_v.push_back(id_v);
 
  407       mc_index_v.push_back(mc_index);
 
  411   auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
 
  412   if (!
fBTAlg.
BuildMap(clockData, g4_trackid_v, ev_simch, ev_cluster_hit)) {
 
  413     std::cerr << 
"\033[93m[ERROR]\033[00m <<ShowerQuality::analyze>> Failed to " 
  414                  "build back-tracking map for MC..." 
  420   std::vector<std::vector<double>> shower_mcq_vv(ev_shower.size(),
 
  421                                                  std::vector<double>(mc_index_v.size(), 0));
 
  423   for (
size_t shower_index = 0; shower_index < ass_cluster_v.size(); ++shower_index) {
 
  425     auto const& ass_cluster = ass_cluster_v[shower_index];
 
  427     std::vector<::btutil::WireRange_t> w_v;
 
  429     for (
auto const& cluster_index : ass_cluster) {
 
  431       auto const& ass_hit = ev_cluster_hit[cluster_index];
 
  433       w_v.reserve(ass_hit.size() + w_v.size());
 
  435       for (
auto const& hit_ptr : ass_hit) {
 
  436         w_v.emplace_back(hit_ptr->Channel(), hit_ptr->StartTick(), hit_ptr->EndTick());
 
  442     auto& shower_mcq_v = shower_mcq_vv[shower_index];
 
  444     for (
size_t mcs_index = 0; mcs_index < (mcq_v.size() - 1); ++mcs_index) {
 
  446       shower_mcq_v[mcs_index] = mcq_v[mcs_index];
 
  451   for (
size_t mcs_index = 0; mcs_index < mc_index_v.size(); ++mcs_index) {
 
  453     auto const& mc_shower = ev_mcs[mc_index_v[mcs_index]];
 
  456     size_t best_shower_index = shower_mcq_vv.size();
 
  458     for (
size_t shower_index = 0; shower_index < shower_mcq_vv.size(); ++shower_index) {
 
  460       if (shower_mcq_vv[shower_index][mcs_index] > max_mcq) best_shower_index = shower_index;
 
  463     if (best_shower_index == shower_mcq_vv.size()) {
 
  465       std::cerr << 
"\033[93m[ERROR]\033[00m <<ShowerQuality::analyze>> " 
  466                 << 
"Failed to find a corresponding shower for MCShower " << mc_index_v[mcs_index]
 
  471     auto const& reco_shower = ev_shower[best_shower_index];
 
  478       std::cerr << 
"\033[93m[ERROR]\033[00m <<ShowerQuality::analyze>> " 
  479                 << 
"Failed to find a corresponding MCShower for shower " << best_shower_index
 
  514                                     3.14159265359 * 180.;
 
  523     for (
auto const& cluster_index : ass_cluster_v[best_shower_index]) {
 
  525       if (ep.first == 0 && ep.second == 0) 
continue;
 
  584       mDEDX.insert(std::make_pair(
 
TH1D * hMatchedClusterPur
Matched 3D shower's cluster purity (combined across planes) 
TH1D * hVtxDR
3D vtx distance between reco to MC in cm 
void SetSimChannelProducer(const std::string name)
void SetMinEnergyCut(const double energy)
Set minimum energy for MCShowers to be considered. 
BEGIN_PROLOG could also be cerr
TH1D * h3DAngleDiff
Opening angle between reco & MC 3D direction. 
Class def header for a class MCMatchAlg. 
Declaration of signal hit object. 
ShowerQuality(fhicl::ParameterSet const &p)
std::map< int, TH1D * > mDEDX
dEdx per particle per PDG code 
const MCBTAlg & BTAlg() const 
BTAlgo getter. 
TH1D * hVtxDZ
Z difference (reco-MC) in cm. 
std::string fMCShowerProducer
MCShower Producer's Name. 
TH1D * hVtxDX
X difference (reco-MC) in cm. 
bool BuildMap(detinfo::DetectorClocksData const &clockData, const std::vector< unsigned int > &g4_trackid_v, const std::vector< sim::SimChannel > &simch_v, const std::vector< std::vector< art::Ptr< recob::Hit >>> &cluster_v)
Constructs needed information for Reco=>MC matching. 
TH1D * hDCosX
Direction unit vector X component difference. 
TH1D * hVtxDY
Y difference (reco-MC) in cm. 
void SetShowerProducer(const std::string name)
TH1D * hEnergyAssym
Energy assym. parameter: (reco E - MC E) / (reco E + MC E) * 2. 
std::pair< double, double > ClusterEP(const size_t cluster_index, const size_t mcshower_index) const 
For a specified cluster, compute cluster efficiency and purity in terms of specified MC object...
TH1D * hEnergyDiff
Energy difference: reco E - MC E. 
std::string fShowerProducer
Shower Producer's Name. 
std::vector< double > MCQ(detinfo::DetectorClocksData const &clockData, const WireRange_t &hit) const 
::btutil::MCMatchAlg fBTAlg
Shower back tracking algorithm. 
art::Handle< T > GetDataOrDie(art::Event const &e, std::string producer)
double _mc_energy_min
Minimum MC shower energy cut. 
For convenience: struct to define a set of parameters per shower to be stored in TTree. 
void SetMaxEnergyCut(const double energy)
Set maximum energy for MCShowers to be considered. 
Declaration of cluster object. 
TH2D * hEnergyCorr
Energy correlation reco (x) vs. MC (y) 
ShowerQuality & operator=(ShowerQuality const &)=delete
struct ShowerQuality::TreeParams_t fTreeParams
void InitializeAnaTree()
Function to prepare TTree. 
void SetMCShowerProducer(const std::string name)
Class def header for MCShower data container. 
TTree * fTree
Analysis TTree. 
TH1D * hMatchCorrectness
Matching correctness. 
TH1D * hDCosZ
Direction unit vector Z component difference. 
double _mc_energy_max
Maximum MC shower energy cut. 
TH1D * hMatchedClusterEff
Matched 3D shower's cluster efficiency (combined across planes) 
art::ServiceHandle< art::TFileService > tfs
std::pair< size_t, double > ShowerCorrectness(const std::vector< unsigned int > cluster_indices) const 
TH1D * hDCosY
Direction unit vector Y component difference. 
std::string fSimChannelProducer
SimChannel Producer's Name. 
void analyze(art::Event const &e) override
TH1D * hBestPlane
Best plane id. 
art framework interface to geometry description 
BEGIN_PROLOG could also be cout
Class def header for exception classes in ShowerReco3D package.