26 #include "art/Framework/Core/EDAnalyzer.h"
27 #include "art/Framework/Core/ModuleMacros.h"
28 #include "art/Framework/Principal/Event.h"
29 #include "art/Framework/Services/Registry/ServiceHandle.h"
30 #include "art_root_io/TFileService.h"
31 #include "canvas/Persistency/Common/FindManyP.h"
32 #include "cetlib_except/exception.h"
33 #include "messagefacility/MessageLogger/MessageLogger.h"
45 #include "nusimdata/SimulationBase/MCParticle.h"
56 bdist(
const TVector3& pos,
unsigned int = 0,
unsigned int = 0)
60 art::ServiceHandle<geo::Geometry const> geom;
63 double d2 = 2. * geom->DetHalfWidth() - pos.X();
64 double d3 = pos.Y() + geom->DetHalfHeight();
65 double d4 = geom->DetHalfHeight() - pos.Y();
67 double d6 = geom->DetLength() - pos.Z();
69 return std::min({d1, d2, d3, d4, d5, d6});
85 const simb::MCParticle& part,
92 art::ServiceHandle<geo::Geometry const> geom;
96 double xmax = 2. * geom->DetHalfWidth();
97 double ymin = -geom->DetHalfHeight();
98 double ymax = geom->DetHalfHeight();
100 double zmax = geom->DetLength();
103 int n = part.NumberTrajectoryPoints();
106 for (
int i = 0; i <
n; ++i) {
107 TVector3 pos = part.Position(i).Vect();
113 if (pos.X() >= xmin && pos.X() <= xmax && pos.Y() >= ymin && pos.Y() <= ymax &&
114 pos.Z() >= zmin && pos.Z() <= zmax) {
120 startmom = part.Momentum(i).Vect();
124 result += disp.Mag();
129 endmom = part.Momentum(i).Vect();
151 art::ServiceHandle<geo::Geometry const> geom;
156 double xmax = 2. * geom->DetHalfWidth();
157 double ymin = -geom->DetHalfHeight();
158 double ymax = geom->DetHalfHeight();
160 double zmax = geom->DetLength();
163 int n = mctrk.size();
166 for (
int i = 0; i <
n; ++i) {
167 TVector3 pos = mctrk[i].Position().Vect();
173 if (pos.X() >= xmin && pos.X() <= xmax && pos.Y() >= ymin && pos.Y() <= ymax &&
174 pos.Z() >= zmin && pos.Z() <= zmax) {
180 startmom = 0.001 * mctrk[i].Momentum().Vect();
184 result += disp.Mag();
189 endmom = 0.001 * mctrk[i].Momentum().Vect();
200 effcalc(
const TH1* hnum,
const TH1* hden, TH1* heff)
202 int nbins = hnum->GetNbinsX();
203 if (nbins != hden->GetNbinsX())
204 throw cet::exception(
"TrackAna") <<
"effcalc[" __FILE__
"]: incompatible histograms (I)\n";
205 if (nbins != heff->GetNbinsX())
206 throw cet::exception(
"TrackAna") <<
"effcalc[" __FILE__
"]: incompatible histograms (II)\n";
210 for (
int ibin = 0; ibin <= nbins + 1; ++ibin) {
211 double num = hnum->GetBinContent(ibin);
212 double den = hden->GetBinContent(ibin);
214 heff->SetBinContent(ibin, 0.);
215 heff->SetBinError(ibin, 0.);
218 double eff = num / den;
219 if (eff < 0.) eff = 0.;
220 if (eff > 1.) eff = 1.;
221 double err = std::sqrt(eff * (1. - eff) / den);
222 heff->SetBinContent(ibin, eff);
223 heff->SetBinError(ibin, err);
227 heff->SetMinimum(0.);
228 heff->SetMaximum(1.05);
229 heff->SetMarkerStyle(20);
232 class flattener :
public std::vector<unsigned int> {
235 flattener() :
std::
vector<unsigned int>(){};
237 flattener(
const std::vector<std::vector<unsigned int>>& input) { Convert(input); }
242 Convert(
const std::vector<std::vector<unsigned int>>& input)
246 for (
auto const& vec : input)
247 length += vec.size();
250 for (
auto const& vec : input)
251 for (
auto const&
value : vec)
267 explicit RecoHists(
const std::string& subdir);
303 explicit MCHists(
const std::string& subdir);
398 explicit TrackAna(fhicl::ParameterSet
const& pset);
408 std::vector<size_t>
fsort_indexes(
const std::vector<double>& v);
453 art::ServiceHandle<geo::Geometry const> geom;
454 art::ServiceHandle<art::TFileService>
tfs;
458 art::TFileDirectory topdir = tfs->mkdir(
"trkana",
"TrackAna histograms");
459 art::TFileDirectory
dir = topdir.mkdir(subdir);
463 fHstartx = dir.make<TH1F>(
464 "xstart",
"X Start Position", 100, -2. * geom->DetHalfWidth(), 4. * geom->DetHalfWidth());
465 fHstarty = dir.make<TH1F>(
466 "ystart",
"Y Start Position", 100, -geom->DetHalfHeight(), geom->DetHalfHeight());
467 fHstartz = dir.make<TH1F>(
"zstart",
"Z Start Position", 100, 0., geom->DetLength());
468 fHstartd = dir.make<TH1F>(
469 "dstart",
"Start Position Distance to Boundary", 100, -10., geom->DetHalfWidth());
470 fHendx = dir.make<TH1F>(
471 "xend",
"X End Position", 100, -2. * geom->DetHalfWidth(), 4. * geom->DetHalfWidth());
473 dir.make<TH1F>(
"yend",
"Y End Position", 100, -geom->DetHalfHeight(), geom->DetHalfHeight());
474 fHendz = dir.make<TH1F>(
"zend",
"Z End Position", 100, 0., geom->DetLength());
476 dir.make<TH1F>(
"dend",
"End Position Distance to Boundary", 100, -10., geom->DetHalfWidth());
477 fHtheta = dir.make<TH1F>(
"theta",
"Theta", 100, 0., 3.142);
478 fHphi = dir.make<TH1F>(
"phi",
"Phi", 100, -3.142, 3.142);
479 fHtheta_xz = dir.make<TH1F>(
"theta_xz",
"Theta_xz", 100, -3.142, 3.142);
480 fHtheta_yz = dir.make<TH1F>(
"theta_yz",
"Theta_yz", 100, -3.142, 3.142);
481 fHmom = dir.make<TH1F>(
"mom",
"Momentum", 100, 0., 10.);
482 fHmoml = dir.make<TH1F>(
"moml",
"Momentum", 100, 0., 1.);
483 fHlen = dir.make<TH1F>(
"len",
"Track Length", 100, 0., 1.1 * geom->DetLength());
484 fHlens = dir.make<TH1F>(
"lens",
"Track Length", 100, 0., 0.1 * geom->DetLength());
485 fHHitChg = dir.make<TH1F>(
"hchg",
"Hit Charge (ADC counts)", 100, 0., 4000.);
486 fHHitWidth = dir.make<TH1F>(
"hwid",
"Hit Width (ticks)", 40, 0., 20.);
487 fHHitPdg = dir.make<TH1F>(
"hpdg",
"Hit Pdg code", 5001, -2500.5, +2500.5);
488 fHHitTrkId = dir.make<TH1F>(
"htrkid",
"Hit Track ID", 401, -200.5, +200.5);
490 dir.make<TH1F>(
"hmodefrac",
491 "quasi-Purity: Fraction of component tracks with the Track mode value",
496 dir.make<TH1F>(
"hntrkids",
497 "quasi-Efficiency: Number of stitched tracks in which TrkId appears",
501 fNTrkIdTrks2 = dir.make<TH2F>(
"hntrkids2",
502 "Number of stitched tracks in which TrkId appears vs KE [GeV]",
509 fNTrkIdTrks3 = dir.make<TH2F>(
"hntrkids3",
510 "MC Track vs Reco Track, wtd by nhits on Collection Plane",
517 fNTrkIdTrks3->GetXaxis()->SetTitle(
"Sorted-by-Descending-CPlane-Hits outer Track Number");
518 fNTrkIdTrks3->GetYaxis()->SetTitle(
"Sorted-by-Descending-True-Length G4Track");
527 art::ServiceHandle<geo::Geometry const> geom;
528 art::ServiceHandle<art::TFileService>
tfs;
532 art::TFileDirectory topdir = tfs->mkdir(
"trkana",
"TrackAna histograms");
533 art::TFileDirectory
dir = topdir.mkdir(subdir);
538 dir.make<TH2F>(
"duvcosth",
"Delta(uv) vs. Colinearity", 100, 0.95, 1., 100, 0., 1.);
539 fHcosth = dir.make<TH1F>(
"colin",
"Colinearity", 100, 0.95, 1.);
540 fHmcu = dir.make<TH1F>(
"mcu",
"MC Truth U", 100, -5., 5.);
541 fHmcv = dir.make<TH1F>(
"mcv",
"MC Truth V", 100, -5., 5.);
542 fHmcw = dir.make<TH1F>(
"mcw",
"MC Truth W", 100, -20., 20.);
543 fHupull = dir.make<TH1F>(
"dupull",
"U Pull", 100, -20., 20.);
544 fHvpull = dir.make<TH1F>(
"dvpull",
"V Pull", 100, -20., 20.);
545 fHmcdudw = dir.make<TH1F>(
"mcdudw",
"MC Truth U Slope", 100, -0.2, 0.2);
546 fHmcdvdw = dir.make<TH1F>(
"mcdvdw",
"MV Truth V Slope", 100, -0.2, 0.2);
547 fHdudwpull = dir.make<TH1F>(
"dudwpull",
"U Slope Pull", 100, -10., 10.);
548 fHdvdwpull = dir.make<TH1F>(
"dvdwpull",
"V Slope Pull", 100, -10., 10.);
549 fHHitEff = dir.make<TH1F>(
"hiteff",
"MC Hit Efficiency", 100, 0., 1.0001);
550 fHHitPurity = dir.make<TH1F>(
"hitpurity",
"MC Hit Purity", 100, 0., 1.0001);
551 fHstartdx = dir.make<TH1F>(
"startdx",
"Start Delta x", 100, -10., 10.);
552 fHstartdy = dir.make<TH1F>(
"startdy",
"Start Delta y", 100, -10., 10.);
553 fHstartdz = dir.make<TH1F>(
"startdz",
"Start Delta z", 100, -10., 10.);
554 fHenddx = dir.make<TH1F>(
"enddx",
"End Delta x", 100, -10., 10.);
555 fHenddy = dir.make<TH1F>(
"enddy",
"End Delta y", 100, -10., 10.);
556 fHenddz = dir.make<TH1F>(
"enddz",
"End Delta z", 100, -10., 10.);
557 fHlvsl = dir.make<TH2F>(
"lvsl",
558 "Reco Length vs. MC Truth Length",
561 1.1 * geom->DetLength(),
564 1.1 * geom->DetLength());
565 fHdl = dir.make<TH1F>(
"dl",
"Track Length Minus MC Particle Length", 100, -50., 50.);
567 dir.make<TH2F>(
"pvsp",
"Reco Momentum vs. MC Truth Momentum", 100, 0., 5., 100, 0., 5.);
569 "pvspc",
"Reco Momentum vs. MC Truth Momentum (Contained Tracks)", 100, 0., 5., 100, 0., 5.);
570 fHdp = dir.make<TH1F>(
"dp",
"Reco-MC Momentum Difference", 100, -5., 5.);
571 fHdpc = dir.make<TH1F>(
"dpc",
"Reco-MC Momentum Difference (Contained Tracks)", 100, -5., 5.);
572 fHppull = dir.make<TH1F>(
"ppull",
"Momentum Pull", 100, -10., 10.);
573 fHppullc = dir.make<TH1F>(
"ppullc",
"Momentum Pull (Contained Tracks)", 100, -10., 10.);
576 "mcxstart",
"MC X Start Position", 10, -2. * geom->DetHalfWidth(), 4. * geom->DetHalfWidth());
578 "mcystart",
"MC Y Start Position", 10, -geom->DetHalfHeight(), geom->DetHalfHeight());
579 fHmcstartz = dir.make<TH1F>(
"mczstart",
"MC Z Start Position", 10, 0., geom->DetLength());
581 "mcxend",
"MC X End Position", 10, -2. * geom->DetHalfWidth(), 4. * geom->DetHalfWidth());
583 "mcyend",
"MC Y End Position", 10, -geom->DetHalfHeight(), geom->DetHalfHeight());
584 fHmcendz = dir.make<TH1F>(
"mczend",
"MC Z End Position", 10, 0., geom->DetLength());
585 fHmctheta = dir.make<TH1F>(
"mctheta",
"MC Theta", 20, 0., 3.142);
586 fHmcphi = dir.make<TH1F>(
"mcphi",
"MC Phi", 10, -3.142, 3.142);
587 fHmctheta_xz = dir.make<TH1F>(
"mctheta_xz",
"MC Theta_xz", 40, -3.142, 3.142);
588 fHmctheta_yz = dir.make<TH1F>(
"mctheta_yz",
"MC Theta_yz", 40, -3.142, 3.142);
589 fHmcmom = dir.make<TH1F>(
"mcmom",
"MC Momentum", 10, 0., 10.);
590 fHmcmoml = dir.make<TH1F>(
"mcmoml",
"MC Momentum", 10, 0., 1.);
591 fHmcke = dir.make<TH1F>(
"mcke",
"MC Kinetic Energy", 10, 0., 10.);
592 fHmckel = dir.make<TH1F>(
"mckel",
"MC Kinetic Energy", 10, 0., 1.);
593 fHmclen = dir.make<TH1F>(
"mclen",
"MC Particle Length", 10, 0., 1.1 * geom->DetLength());
594 fHmclens = dir.make<TH1F>(
"mclens",
"MC Particle Length", 10, 0., 0.1 * geom->DetLength());
597 "Good X Start Position",
599 -2. * geom->DetHalfWidth(),
600 4. * geom->DetHalfWidth());
602 "gystart",
"Good Y Start Position", 10, -geom->DetHalfHeight(), geom->DetHalfHeight());
603 fHgstartz = dir.make<TH1F>(
"gzstart",
"Good Z Start Position", 10, 0., geom->DetLength());
605 "gxend",
"Good X End Position", 10, -2. * geom->DetHalfWidth(), 4. * geom->DetHalfWidth());
607 "gyend",
"Good Y End Position", 10, -geom->DetHalfHeight(), geom->DetHalfHeight());
608 fHgendz = dir.make<TH1F>(
"gzend",
"Good Z End Position", 10, 0., geom->DetLength());
609 fHgtheta = dir.make<TH1F>(
"gtheta",
"Good Theta", 20, 0., 3.142);
610 fHgphi = dir.make<TH1F>(
"gphi",
"Good Phi", 10, -3.142, 3.142);
611 fHgtheta_xz = dir.make<TH1F>(
"gtheta_xz",
"Good Theta_xz", 40, -3.142, 3.142);
612 fHgtheta_yz = dir.make<TH1F>(
"gtheta_yz",
"Good Theta_yz", 40, -3.142, 3.142);
613 fHgmom = dir.make<TH1F>(
"gmom",
"Good Momentum", 10, 0., 10.);
614 fHgmoml = dir.make<TH1F>(
"gmoml",
"Good Momentum", 10, 0., 1.);
615 fHgke = dir.make<TH1F>(
"gke",
"Good Kinetic Energy", 10, 0., 10.);
616 fHgkel = dir.make<TH1F>(
"gkel",
"Good Kinetic Energy", 10, 0., 1.);
617 fHglen = dir.make<TH1F>(
"glen",
"Good Particle Length", 10, 0., 1.1 * geom->DetLength());
618 fHglens = dir.make<TH1F>(
"glens",
"Good Particle Length", 10, 0., 0.1 * geom->DetLength());
621 "Efficiency vs. X Start Position",
623 -2. * geom->DetHalfWidth(),
624 4. * geom->DetHalfWidth());
626 "Efficiency vs. Y Start Position",
628 -geom->DetHalfHeight(),
629 geom->DetHalfHeight());
631 dir.make<TH1F>(
"ezstart",
"Efficiency vs. Z Start Position", 10, 0., geom->DetLength());
632 fHeendx = dir.make<TH1F>(
"exend",
633 "Efficiency vs. X End Position",
635 -2. * geom->DetHalfWidth(),
636 4. * geom->DetHalfWidth());
638 "eyend",
"Efficiency vs. Y End Position", 10, -geom->DetHalfHeight(), geom->DetHalfHeight());
639 fHeendz = dir.make<TH1F>(
"ezend",
"Efficiency vs. Z End Position", 10, 0., geom->DetLength());
640 fHetheta = dir.make<TH1F>(
"etheta",
"Efficiency vs. Theta", 20, 0., 3.142);
641 fHephi = dir.make<TH1F>(
"ephi",
"Efficiency vs. Phi", 10, -3.142, 3.142);
642 fHetheta_xz = dir.make<TH1F>(
"etheta_xz",
"Efficiency vs. Theta_xz", 40, -3.142, 3.142);
643 fHetheta_yz = dir.make<TH1F>(
"etheta_yz",
"Efficiency vs. Theta_yz", 40, -3.142, 3.142);
644 fHemom = dir.make<TH1F>(
"emom",
"Efficiency vs. Momentum", 10, 0., 10.);
645 fHemoml = dir.make<TH1F>(
"emoml",
"Efficiency vs. Momentum", 10, 0., 1.);
646 fHeke = dir.make<TH1F>(
"eke",
"Efficiency vs. Kinetic Energy", 10, 0., 10.);
647 fHekel = dir.make<TH1F>(
"ekel",
"Efficiency vs. Kinetic Energy", 10, 0., 1.);
649 dir.make<TH1F>(
"elen",
"Efficiency vs. Particle Length", 10, 0., 1.1 * geom->DetLength());
651 dir.make<TH1F>(
"elens",
"Efficiency vs. Particle Length", 10, 0., 0.1 * geom->DetLength());
685 if (
fOrigin.find(
"Beam") != std::string::npos) {
689 else if (
fOrigin.find(
"Cosmic") != std::string::npos) {
693 else if (
fOrigin.find(
"Super") != std::string::npos) {
697 else if (
fOrigin.find(
"Single") != std::string::npos) {
704 mf::LogInfo(
"TrackAna") <<
"TrackAna configured with the following parameters:\n"
711 <<
" Dump = " <<
fDump <<
"\n"
712 <<
" MinMCKE = " <<
fMinMCKE <<
"\n"
720 art::ServiceHandle<cheat::BackTrackerService const> bt_serv;
721 art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
722 art::ServiceHandle<geo::Geometry const> geom;
728 std::unique_ptr<mf::LogInfo> pdump;
731 pdump = std::make_unique<mf::LogInfo>(
"TrackAna");
736 bool mc = !evt.isRealData();
740 art::Handle<std::vector<sim::MCTrack>> mctrackh;
743 std::vector<std::pair<const sim::MCTrack*, int>> selected_mctracks;
745 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
747 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
749 if (mc && mctrackh.isValid()) {
751 selected_mctracks.reserve(mctrackh->size());
756 *pdump <<
"MC Tracks\n"
757 <<
" Id pdg x y z dx dy dz "
759 <<
"--------------------------------------------------------------------------------"
767 for (std::vector<sim::MCTrack>::const_iterator imctrk = mctrackh->begin();
768 imctrk != mctrackh->end();
791 double mctime = mctrk.
Start().
T();
801 length(clockData, detProp, mctrk, mcdx, mcstart, mcend, mcstartmom, mcendmom);
810 selected_mctracks.push_back(std::make_pair(&mctrk, -1));
815 double pstart = mcstartmom.Mag();
816 double pend = mcendmom.Mag();
817 *pdump <<
"\nOffset" << std::setw(3) << mctrk.
TrackID() << std::setw(6)
818 << mctrk.
PdgCode() <<
" " << std::fixed << std::setprecision(2)
819 << std::setw(10) << mcdx <<
"\nStart " << std::setw(3) << mctrk.
TrackID()
820 << std::setw(6) << mctrk.
PdgCode() <<
" " << std::fixed
821 << std::setprecision(2) << std::setw(10) << mcstart[0] << std::setw(10)
822 << mcstart[1] << std::setw(10) << mcstart[2];
824 *pdump <<
" " << std::fixed << std::setprecision(3) << std::setw(10)
825 << mcstartmom[0] / pstart << std::setw(10) << mcstartmom[1] / pstart
826 << std::setw(10) << mcstartmom[2] / pstart;
829 *pdump << std::setw(32) <<
" ";
830 *pdump << std::setw(12) << std::fixed << std::setprecision(3) << pstart;
831 *pdump <<
"\nEnd " << std::setw(3) << mctrk.
TrackID() << std::setw(6)
832 << mctrk.
PdgCode() <<
" " << std::fixed << std::setprecision(2)
833 << std::setw(10) << mcend[0] << std::setw(10) << mcend[1] << std::setw(10)
836 *pdump <<
" " << std::fixed << std::setprecision(3) << std::setw(10)
837 << mcendmom[0] / pend << std::setw(10) << mcendmom[1] / pend
838 << std::setw(10) << mcendmom[2] / pend;
841 *pdump << std::setw(32) <<
" ";
842 *pdump << std::setw(12) << std::fixed << std::setprecision(3) << pend
843 <<
"\nLength: " << plen <<
"\n";
849 std::ostringstream ostr;
855 double mctheta_xz = std::atan2(mcstartmom.X(), mcstartmom.Z());
856 double mctheta_yz = std::atan2(mcstartmom.Y(), mcstartmom.Z());
857 double mcmom = mcstartmom.Mag();
859 double mcke = mcmom * mcmom / (std::hypot(mcmom, mcmass) + mcmass);
867 mchists.
fHmctheta->Fill(mcstartmom.Theta());
868 mchists.
fHmcphi->Fill(mcstartmom.Phi());
873 mchists.
fHmcke->Fill(mcke);
884 art::Handle<std::vector<recob::Track>> trackh;
885 art::Handle<std::vector<art::PtrVector<recob::Track>>> trackvh;
886 art::Handle<std::vector<recob::Hit>> hith;
894 std::vector<art::Ptr<recob::Hit>> allhits;
895 if (hith.isValid()) {
896 allhits.reserve(hith->size());
897 for (
unsigned int i = 0; i < hith->size(); ++i) {
898 allhits.emplace_back(hith, i);
911 mf::LogDebug(
"TrackAna") <<
"TrackAna read " << trackvh->size()
912 <<
" vectors of Stitched PtrVectorsof tracks.";
916 if (trackh.isValid()) {
919 *pdump <<
"\nReconstructed Tracks\n"
920 <<
" Id MCid x y z dx dy dz "
922 <<
"--------------------------------------------------------------------------------"
928 int ntrack = trackh->size();
929 for (
int i = 0; i < ntrack; ++i) {
930 art::Ptr<recob::Track> ptrack(trackh, i);
935 std::vector<art::Ptr<recob::Hit>> trackhits;
936 tkhit_find.get(i, trackhits);
946 TVector3 pos = track.
Vertex<TVector3>();
948 TVector3 end = track.
End<TVector3>();
952 double dpos = bdist(pos);
953 double dend = bdist(end);
954 double tlen = length(track);
955 double theta_xz = std::atan2(dir.X(), dir.Z());
956 double theta_yz = std::atan2(dir.Y(), dir.Z());
965 rhists.
fHendx->Fill(end.X());
966 rhists.
fHendy->Fill(end.Y());
967 rhists.
fHendz->Fill(end.Z());
968 rhists.
fHendd->Fill(dend);
976 rhists.
fHmom->Fill(mom);
978 rhists.
fHlen->Fill(tlen);
979 rhists.
fHlens->Fill(tlen);
987 for (
int swap = 0; swap < 2; ++swap) {
997 int start_point = (swap == 0 ? 0 : ntraj - 1);
1003 rot(1, 0) = -rot(1, 0);
1004 rot(2, 0) = -rot(2, 0);
1005 rot(1, 1) = -rot(1, 1);
1006 rot(2, 1) = -rot(2, 1);
1007 rot(1, 2) = -rot(1, 2);
1008 rot(2, 2) = -rot(2, 2);
1010 pos = track.
End<TVector3>();
1012 end = track.
Vertex<TVector3>();
1018 theta_xz = std::atan2(dir.X(), dir.Z());
1019 theta_yz = std::atan2(dir.Y(), dir.Z());
1030 for (
unsigned int imc = 0; imc < selected_mctracks.size(); ++imc) {
1031 const sim::MCTrack& mctrk = *selected_mctracks[imc].first;
1036 throw cet::exception(
"TrackAna") <<
"no particle with ID=" << pdg <<
"\n";
1037 const MCHists& mchists = iMCHistMap->second;
1041 double mctime = mctrk.
Start().
T();
1049 TVector3 mcstartmom;
1052 length(clockData, detProp, mctrk, mcdx, mcstart, mcend, mcstartmom, mcendmom);
1056 TVector3 mcpos = mcstart - pos;
1061 TVector3 mcmoml = rot * mcstartmom;
1062 TVector3 mcposl = rot * mcpos;
1064 double colinearity = mcmoml.Z() / mcmoml.Mag();
1066 double u = mcposl.X();
1067 double v = mcposl.Y();
1068 double w = mcposl.Z();
1070 double pu = mcmoml.X();
1071 double pv = mcmoml.Y();
1072 double pw = mcmoml.Z();
1074 double dudw = pu /
pw;
1075 double dvdw = pv /
pw;
1077 double u0 = u - w * dudw;
1078 double v0 = v - w * dvdw;
1079 double uv0 = std::hypot(u0, v0);
1089 mchists.
fHdudwpull->Fill(dudw / std::sqrt(cov(2, 2)));
1090 mchists.
fHdvdwpull->Fill(dvdw / std::sqrt(cov(3, 3)));
1092 mchists.
fHcosth->Fill(colinearity);
1097 mchists.
fHmcu->Fill(u0);
1098 mchists.
fHmcv->Fill(v0);
1099 mchists.
fHmcw->Fill(w);
1100 mchists.
fHupull->Fill(u0 / std::sqrt(cov(0, 0)));
1101 mchists.
fHvpull->Fill(v0 / std::sqrt(cov(1, 1)));
1107 double mctheta_xz = std::atan2(mcstartmom.X(), mcstartmom.Z());
1108 double mctheta_yz = std::atan2(mcstartmom.Y(), mcstartmom.Z());
1109 double mcmom = mcstartmom.Mag();
1111 double mcke = mcmom * mcmom / (std::hypot(mcmom, mcmass) + mcmass);
1113 mchists.
fHstartdx->Fill(pos.X() - mcstart.X());
1114 mchists.
fHstartdy->Fill(pos.Y() - mcstart.Y());
1115 mchists.
fHstartdz->Fill(pos.Z() - mcstart.Z());
1116 mchists.
fHenddx->Fill(end.X() - mcend.X());
1117 mchists.
fHenddy->Fill(end.Y() - mcend.Y());
1118 mchists.
fHenddz->Fill(end.Z() - mcend.Z());
1119 mchists.
fHlvsl->Fill(plen, tlen);
1120 mchists.
fHdl->Fill(tlen - plen);
1121 mchists.
fHpvsp->Fill(mcmom, mom);
1122 double dp = mom - mcmom;
1123 mchists.
fHdp->Fill(dp);
1124 mchists.
fHppull->Fill(dp / std::sqrt(cov(4, 4)));
1126 mchists.
fHpvspc->Fill(mcmom, mom);
1127 mchists.
fHdpc->Fill(dp);
1128 mchists.
fHppullc->Fill(dp / std::sqrt(cov(4, 4)));
1142 std::set<int> tkidset;
1143 tkidset.insert(mcid);
1144 double hiteff = bt_serv->HitCollectionEfficiency(
1145 clockData, tkidset, trackhits, allhits,
geo::k3D);
1146 double hitpurity = bt_serv->HitCollectionPurity(clockData, tkidset, trackhits);
1155 mchists.
fHgendx->Fill(mcend.X());
1156 mchists.
fHgendy->Fill(mcend.Y());
1157 mchists.
fHgendz->Fill(mcend.Z());
1158 mchists.
fHgtheta->Fill(mcstartmom.Theta());
1159 mchists.
fHgphi->Fill(mcstartmom.Phi());
1162 mchists.
fHgmom->Fill(mcmom);
1164 mchists.
fHgke->Fill(mcke);
1165 mchists.
fHgkel->Fill(mcke);
1166 mchists.
fHglen->Fill(plen);
1170 selected_mctracks[imc].second = i;
1173 const simb::MCParticle* ptkl = pi_serv->TrackIdToParticle_P(mcid);
1174 float KE = ptkl->E() - ptkl->Mass();
1175 std::string KEUnits =
" GeV";
1181 mf::LogVerbatim(
"TrackAna")
1182 << evt.run() <<
"." << evt.event() <<
" Match MCTkID " << std::setw(6)
1183 << mctrk.
TrackID() <<
" Origin " << mctrk.
Origin() <<
" PDG" << std::setw(5)
1184 << mctrk.
PdgCode() <<
" KE" << std::setw(4) << (int)KE << KEUnits
1185 <<
" RecoTrkID " << track.
ID() <<
" hitEff " << std::setprecision(2)
1186 << hiteff <<
" hitPur " << hitpurity;
1187 int sWire, sTick, eWire, eTick;
1189 for (
unsigned short ipl = 0; ipl < geom->Nplanes(); ++ipl) {
1190 sWire = geom->NearestWire(mcstart, ipl, 0, 0);
1192 eWire = geom->NearestWire(mcend, ipl, 0, 0);
1194 mf::LogVerbatim(
"TrackAna")
1195 <<
" Wire:Tick in Pln " << ipl <<
" W:T " << sWire <<
":" << sTick
1196 <<
" - " << eWire <<
":" << eTick;
1208 TVector3 pos = track.
Vertex<TVector3>();
1210 TVector3 end = track.
End<TVector3>();
1216 *pdump <<
"\nOffset" << std::setw(3) << track.
ID() << std::setw(6) << mcid <<
" "
1217 << std::fixed << std::setprecision(2) << std::setw(10) << trackdx <<
"\nStart "
1218 << std::setw(3) << track.
ID() << std::setw(6) << mcid <<
" " << std::fixed
1219 << std::setprecision(2) << std::setw(10) << pos[0] << std::setw(10) << pos[1]
1220 << std::setw(10) << pos[2];
1222 *pdump <<
" " << std::fixed << std::setprecision(3) << std::setw(10) << dir[0]
1223 << std::setw(10) << dir[1] << std::setw(10) << dir[2];
1226 *pdump << std::setw(32) <<
" ";
1227 *pdump << std::setw(12) << std::fixed << std::setprecision(3) << pstart;
1228 *pdump <<
"\nEnd " << std::setw(3) << track.
ID() << std::setw(6) << mcid <<
" "
1229 << std::fixed << std::setprecision(2) << std::setw(10) << end[0] << std::setw(10)
1230 << end[1] << std::setw(10) << end[2];
1232 *pdump <<
" " << std::fixed << std::setprecision(3) << std::setw(10) << enddir[0]
1233 << std::setw(10) << enddir[1] << std::setw(10) << enddir[2];
1236 *pdump << std::setw(32) <<
" ";
1237 *pdump << std::setw(12) << std::fixed << std::setprecision(3) << pend
1238 <<
"\nLength: " << tlen <<
"\n";
1245 if (fPrintLevel > 0) {
1246 for (
unsigned int imc = 0; imc < selected_mctracks.size(); ++imc) {
1247 if (selected_mctracks[imc].
second >= 0)
continue;
1248 const sim::MCTrack& mctrk = *selected_mctracks[imc].first;
1249 const simb::MCParticle* ptkl = pi_serv->TrackIdToParticle_P(mctrk.
TrackID());
1250 float KE = ptkl->E() - ptkl->Mass();
1251 std::string KEUnits =
" GeV";
1258 TVector3 mcstart, mcend, mcstartmom, mcendmom;
1260 double plen = length(clockData, detProp, mctrk, mcdx, mcstart, mcend, mcstartmom, mcendmom);
1261 mf::LogVerbatim(
"TrackAna")
1263 <<
" Origin " << mctrk.
Origin() <<
" PDG" << std::setw(5) << mctrk.
PdgCode() <<
" KE"
1264 << std::setw(4) << (int)KE << KEUnits <<
" Length " << std::fixed << std::setprecision(1)
1266 if (fPrintLevel > 1) {
1267 int sWire, sTick, eWire, eTick;
1269 for (
unsigned short ipl = 0; ipl < geom->Nplanes(); ++ipl) {
1270 sWire = geom->NearestWire(mcstart, ipl, 0, 0);
1272 eWire = geom->NearestWire(mcend, ipl, 0, 0);
1274 mf::LogVerbatim(
"TrackAna") <<
" Wire:Tick in Pln " << ipl <<
" W:T " << sWire <<
":"
1275 << sTick <<
" - " << eWire <<
":" << eTick;
1283 TrackAna::anaStitch(
const art::Event&
evt,
1287 art::ServiceHandle<cheat::BackTrackerService const> bt_serv;
1288 art::ServiceHandle<cheat::ParticleInventoryService const> pi_serv;
1289 art::ServiceHandle<geo::Geometry const> geom;
1291 std::map<int, std::map<int, art::PtrVector<recob::Hit>>> hitmap;
1292 std::map<int, int> KEmap;
1293 bool mc = !evt.isRealData();
1294 art::Handle<std::vector<recob::Track>> trackh;
1295 art::Handle<std::vector<recob::SpacePoint>> sppth;
1296 art::Handle<std::vector<art::PtrVector<recob::Track>>> trackvh;
1298 evt.getByLabel(fTrackModuleLabel, trackh);
1299 evt.getByLabel(fSpacepointModuleLabel, sppth);
1300 evt.getByLabel(fStitchModuleLabel, trackvh);
1301 int ntv(trackvh->size());
1303 std::vector<art::PtrVector<recob::Track>>::const_iterator cti = trackvh->begin();
1305 if (trackh.isValid()) {
1306 art::FindManyP<recob::SpacePoint> fswhole(trackh, evt, fTrkSpptAssocModuleLabel);
1307 int nsppts_assnwhole = fswhole.size();
1308 std::cout <<
"TrackAna: Number of clumps of Spacepoints from Assn for all Tracks: "
1309 << nsppts_assnwhole << std::endl;
1312 if (fRecoHistMap.count(0) == 0) {
1313 fRecoHistMap.emplace(0,
RecoHists{
"Reco"});
1315 <<
"\t\t TrkAna: Fresh fRecoHistMap[0] ******* \n"
1318 const RecoHists& rhistsStitched = fRecoHistMap.at(0);
1320 std::vector<std::vector<unsigned int>> NtrkIdsAll;
1321 std::vector<double> ntvsorted;
1326 for (
int o = 0; o < ntv; ++o)
1328 const art::PtrVector<recob::Track> pvtrack(*(cti++));
1329 int ntrack = pvtrack.size();
1330 std::vector<std::vector<unsigned int>> NtrkId_Hit;
1331 std::vector<unsigned int> vecMode;
1332 art::FindManyP<recob::SpacePoint> fs(pvtrack, evt, fTrkSpptAssocModuleLabel);
1334 for (
int i = 0; i < ntrack; ++i) {
1343 int nsppts_assn = fs.at(i).size();
1345 const auto& sppt = fs.at(i);
1348 art::FindManyP<recob::Hit> fh(sppt, evt, fHitSpptAssocModuleLabel);
1355 std::vector<unsigned int> vecNtrkIds;
1356 for (
int is = 0; is < nsppts_assn; ++is) {
1357 int nhits = fh.at(is).size();
1358 for (
int ih = 0; ih < nhits; ++ih) {
1359 const auto&
hit = fh.at(is).at(ih);
1364 std::vector<sim::TrackIDE> tids = bt_serv->HitToTrackIDEs(clockData,
hit);
1368 for (std::vector<sim::TrackIDE>::const_iterator itid = tids.begin();
1371 int trackID =
std::abs(itid->trackID);
1372 hitmap[trackID][o].push_back(
hit);
1375 vecNtrkIds.push_back(trackID);
1380 const simb::MCParticle* part = pi_serv->TrackIdToParticle_P(trackID);
1383 rhistsStitched.
fHHitPdg->Fill(part->PdgCode());
1388 TVector3 mcstartmom;
1390 double mctime = part->T();
1394 length(clockData, detProp, *part, mcdx, mcstart, mcend, mcstartmom, mcendmom);
1396 KEmap[(int)(1e6 * plen)] = trackID;
1406 NtrkId_Hit.push_back(vecNtrkIds);
1409 int max(-12),
n(1), ind(0);
1410 std::sort(vecNtrkIds.begin(), vecNtrkIds.end());
1411 std::vector<unsigned int> strkIds(vecNtrkIds);
1412 while (ii < vecNtrkIds.size()) {
1413 if (strkIds.at(ii) != strkIds.at(ii - 1)) { n = 1; }
1424 if (strkIds.begin() != strkIds.end()) mode = strkIds.at(ind);
1425 vecMode.push_back(mode);
1427 if (strkIds.size() != 0)
1428 rhistsStitched.
fModeFrac->Fill((
double)max / (
double)strkIds.size());
1434 catch (cet::exception&
x) {
1437 if (!assns)
throw cet::exception(
"TrackAna") <<
"Bad Associations. \n";
1443 NtrkIdsAll.push_back(vecMode);
1445 std::unique(NtrkIdsAll.back().begin(), NtrkIdsAll.back().end());
1447 for (
auto const val : NtrkIdsAll.back()) {
1448 sum += hitmap[val][o].size();
1450 ntvsorted.push_back(sum);
1458 for (
auto it = KEmap.rbegin(); it != KEmap.rend(); ++it) {
1463 for (
auto const o : fsort_indexes(ntvsorted)) {
1466 for (
auto it = KEmap.rbegin(); it != KEmap.rend(); ++it) {
1467 int val = it->second;
1475 flattener flat(NtrkIdsAll);
1476 std::vector<unsigned int>& v = flat;
1479 for (
auto const val : v) {
1481 const simb::MCParticle* part = pi_serv->TrackIdToParticle_P(val);
1482 double T(part->E() - 0.001 * part->Mass());
1497 mf::LogInfo(
"TrackAna") <<
"TrackAna statistics:\n"
1498 <<
" Number of events = " << fNumEvent;
1502 for (std::map<int, MCHists>::const_iterator i = fMCHistMap.begin(); i != fMCHistMap.end();
1504 const MCHists& mchists = i->second;
1526 TrackAna::fsort_indexes(
const std::vector<double>& v)
1529 std::vector<size_t> idx(v.size());
1530 for (
size_t i = 0; i != idx.size(); ++i)
1533 std::sort(idx.begin(), idx.end(), [&v](
size_t i1,
size_t i2) {
1534 return v[i1] > v[i2];
double std(const std::vector< short > &wf, const double ped_mean, size_t start, size_t nsample)
simb::Origin_t Origin() const
double EndMomentum() const
double VertexMomentum() const
process_name opflash particleana ie x
std::string fHitSpptAssocModuleLabel
std::string fTrkSpptAssocModuleLabel
std::string fSpacepointModuleLabel
Declaration of signal hit object.
EResult err(const char *call)
size_t NumberTrajectoryPoints() const
Various functions related to the presence and the number of (valid) points.
Vector_t VertexDirection() const
const SMatrixSym55 & VertexCovariance() const
std::size_t size(FixedBins< T, C > const &) noexcept
unsigned int ReadOutWindowSize() const
std::string fStitchModuleLabel
TrackAna(fhicl::ParameterSet const &pset)
process_name use argoneut_mc_hitfinder track
tick ticks
Alias for common language habits.
std::map< int, MCHists > fMCHistMap
3-dimensional objects, potentially hits, clusters, prongs, etc.
Rotation_t GlobalToLocalRotationAtPoint(size_t p) const
process_name pandoraGausCryo1 vertexChargeCryo1 vertexStubCryo1 xmin
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
const SMatrixSym55 & EndCovariance() const
MCHists(const std::string &subdir)
double Length(size_t p=0) const
Access to various track properties.
std::vector< size_t > fsort_indexes(const std::vector< double > &v)
RecoHists(const std::string &subdir)
static const int NoParticleId
void anaStitch(const art::Event &evt, detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp)
Point_t const & Vertex() const
auto end(FixedBins< T, C > const &) noexcept
double ConvertXToTicks(double X, int p, int t, int c) const
std::string fMCTrackModuleLabel
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
Class def header for mctrack data container.
Provides recob::Track data product.
void analyze(const art::Event &evt) override
const TLorentzVector & Momentum() const
simb::Origin_t fOriginValue
Contains all timing reference information for the detector.
Vector_t EndDirection() const
std::map< int, RecoHists > fRecoHistMap
Point_t const & End() const
const MCStep & Start() const
art::ServiceHandle< art::TFileService > tfs
std::string fTrackModuleLabel
unsigned int TrackID() const
std::size_t count(Cont const &cont)
std::string fHitModuleLabel
Tools and modules for checking out the basics of the Monte Carlo.
art framework interface to geometry description
BEGIN_PROLOG could also be cout
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
Signal from collection planes.