15 #include "art_root_io/TFileService.h" 189 msg +=
"\033[93m[ERROR]\033[00m <<";
191 msg +=
">> Producer's name not set!";
192 std::cout << msg.c_str() << std::endl;
193 throw ::showerreco::ShowerRecoException(msg.c_str());
200 fTree = tfs->make<TTree>(
"fShowerQualityTree",
"");
207 tfs->make<TH1D>(
"hMatchCorrectness",
208 "Shower 2D Cluster Matching Correctness; Correctness; Showers",
222 "hVtxDX",
"Reco - MC Start X [cm] Displacement; #DeltaX [cm]; Showers", 200, -100, 100);
225 "hVtxDY",
"Reco - MC Start Y [cm] Displacement; #DeltaY [cm]; Showers", 200, -100, 100);
228 "hVtxDZ",
"Reco - MC Start Z [cm] Displacement; #DeltaZ [cm]; Showers", 200, -100, 100);
231 "hVtxDR",
"Reco - MC Start 3D Vtx Displacement; #DeltaR [cm]; Showers", 200, -100, 100);
242 "hDCosX",
"Direction Unit Vector Reco - MC #DeltaX; #DeltaCosX; Showers", 100, -2, 2);
245 "hDCosY",
"Direction Unit Vector Reco - MC #DeltaY; #DeltaCosY; Showers", 100, -2, 2);
248 "hDCosZ",
"Direction Unit Vector Reco - MC #DeltaZ; #DeltaCosZ; Showers", 100, -2, 2);
251 tfs->make<TH1D>(
"h3DAngleDiff",
252 "3D Opening Angle Between Reco & MC; Opening Angle [degrees]; Showers",
265 tfs->make<TH2D>(
"hEnergyCorr",
266 "Reco (x) vs. MC (y) Energy Comparison; Reco Energy [MeV]; MC Energy [MeV]",
275 "MC - Reco Energy Fractional Difference; Assymetry; Showers",
281 "hEnergyDiff",
"MC - Reco Energy Difference; Energy Difference [MeV]; Showers", 200, 0, 1000);
290 tfs->make<TH1D>(
"hMatchedClusterEff_PlaneCombo",
291 "Matched Shower Cluster's Charge Efficiency; Efficiency; Clusters",
297 "Matched Shower Cluster's Charge Purity; Purity; Clusters",
306 "Best Plane (for energy & dE/dx estimate); Plane ID; Showers",
309 geo->Nplanes() - 0.5);
320 const std::vector<sim::MCShower>& ev_mcs(*mcsHandle);
321 const std::vector<recob::Shower>& ev_shower(*resHandle);
322 const std::vector<sim::SimChannel>& ev_simch(*schHandle);
324 if (ev_shower.empty())
return;
329 const std::vector<recob::Cluster>& ev_cluster = cluster_m.at(0).front().parentAs<
std::vector>();
333 std::vector<std::vector<art::Ptr<recob::Hit>>> ev_cluster_hit;
334 ev_cluster_hit.reserve(clsHandle->size());
335 std::map<art::Ptr<recob::Cluster>,
size_t> cluster_ptr_map;
336 for (
size_t i = 0; i < ev_cluster.size(); ++i) {
338 cluster_ptr_map[cluster_ptr] = ev_cluster_hit.size();
339 ev_cluster_hit.push_back(hit_m.at(i));
343 std::vector<std::vector<unsigned int>> ass_cluster_v;
344 ass_cluster_v.reserve(ev_shower.size());
345 for (
size_t shower_index = 0; shower_index < ev_shower.size(); ++shower_index) {
346 ass_cluster_v.push_back(std::vector<unsigned int>());
347 for (
auto const& p : cluster_m.at(shower_index))
348 ass_cluster_v.back().push_back(cluster_ptr_map[p]);
352 std::vector<std::vector<unsigned int>> g4_trackid_v;
353 std::vector<unsigned int> mc_index_v;
354 g4_trackid_v.reserve(ev_mcs.size());
355 for (
size_t mc_index = 0; mc_index < ev_mcs.size(); ++mc_index) {
356 auto const& mcs = ev_mcs[mc_index];
357 double energy = mcs.DetProfile().E();
358 std::vector<unsigned int> id_v;
359 id_v.reserve(mcs.DaughterTrackID().size());
361 for (
auto const&
id : mcs.DaughterTrackID()) {
362 if (
id == mcs.TrackID())
continue;
365 id_v.push_back(mcs.TrackID());
366 g4_trackid_v.push_back(id_v);
367 mc_index_v.push_back(mc_index);
372 if (!
fBTAlg.
BuildMap(clockData, g4_trackid_v, ev_simch, ev_cluster_hit)) {
373 std::cerr <<
"\033[93m[ERROR]\033[00m <<ShowerQuality::analyze>> Failed to " 374 "build back-tracking map for MC..." 380 std::vector<std::vector<double>> shower_mcq_vv(ev_shower.size(),
381 std::vector<double>(mc_index_v.size(), 0));
383 for (
size_t shower_index = 0; shower_index < ass_cluster_v.size(); ++shower_index) {
385 auto const& ass_cluster = ass_cluster_v[shower_index];
387 std::vector<::btutil::WireRange_t> w_v;
389 for (
auto const& cluster_index : ass_cluster) {
391 auto const& ass_hit = ev_cluster_hit[cluster_index];
393 w_v.reserve(ass_hit.size() + w_v.size());
395 for (
auto const& hit_ptr : ass_hit) {
396 w_v.emplace_back(hit_ptr->Channel(), hit_ptr->StartTick(), hit_ptr->EndTick());
402 auto& shower_mcq_v = shower_mcq_vv[shower_index];
404 for (
size_t mcs_index = 0; mcs_index < (mcq_v.size() - 1); ++mcs_index) {
406 shower_mcq_v[mcs_index] = mcq_v[mcs_index];
411 for (
size_t mcs_index = 0; mcs_index < mc_index_v.size(); ++mcs_index) {
413 auto const& mc_shower = ev_mcs[mc_index_v[mcs_index]];
416 size_t best_shower_index = shower_mcq_vv.size();
418 for (
size_t shower_index = 0; shower_index < shower_mcq_vv.size(); ++shower_index) {
420 if (shower_mcq_vv[shower_index][mcs_index] > max_mcq) best_shower_index = shower_index;
423 if (best_shower_index == shower_mcq_vv.size()) {
425 std::cerr <<
"\033[93m[ERROR]\033[00m <<ShowerQuality::analyze>> " 426 <<
"Failed to find a corresponding shower for MCShower " << mc_index_v[mcs_index]
431 auto const& reco_shower = ev_shower[best_shower_index];
438 std::cerr <<
"\033[93m[ERROR]\033[00m <<ShowerQuality::analyze>> " 439 <<
"Failed to find a corresponding MCShower for shower " << best_shower_index
474 3.14159265359 * 180.;
483 for (
auto const& cluster_index : ass_cluster_v[best_shower_index]) {
485 if (ep.first == 0 && ep.second == 0)
continue;
544 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.
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.
EDAnalyzer(fhicl::ParameterSet const &pset)
TH1D * hDCosX
Direction unit vector X component difference.
TH1D * hVtxDY
Y difference (reco-MC) in cm.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
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.
#define DEFINE_ART_MODULE(klass)
std::vector< double > MCQ(detinfo::DetectorClocksData const &clockData, const WireRange_t &hit) const
::btutil::MCMatchAlg fBTAlg
Shower back tracking algorithm.
Provenance const * provenance() const
T get(std::string const &key) const
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
ValidHandle< PROD > getValidHandle(InputTag const &tag) const
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)
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.
Namespace collecting geometry-related classes utilities.
void analyze(art::Event const &e) override
TH1D * hBestPlane
Best plane id.
art framework interface to geometry description
Class def header for exception classes in ShowerReco3D package.