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();
792 double mcdx = mctime * 1.e-3 *
detProp.DriftVelocity();
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);
861 mchists.fHmcstartx->Fill(mcstart.X());
862 mchists.fHmcstarty->Fill(mcstart.Y());
863 mchists.fHmcstartz->Fill(mcstart.Z());
864 mchists.fHmcendx->Fill(mcend.X());
865 mchists.fHmcendy->Fill(mcend.Y());
866 mchists.fHmcendz->Fill(mcend.Z());
867 mchists.fHmctheta->Fill(mcstartmom.Theta());
868 mchists.fHmcphi->Fill(mcstartmom.Phi());
869 mchists.fHmctheta_xz->Fill(mctheta_xz);
870 mchists.fHmctheta_yz->Fill(mctheta_yz);
871 mchists.fHmcmom->Fill(mcmom);
872 mchists.fHmcmoml->Fill(mcmom);
873 mchists.fHmcke->Fill(mcke);
874 mchists.fHmckel->Fill(mcke);
875 mchists.fHmclen->Fill(plen);
876 mchists.fHmclens->Fill(plen);
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());
961 rhists.fHstartx->Fill(pos.X());
962 rhists.fHstarty->Fill(pos.Y());
963 rhists.fHstartz->Fill(pos.Z());
964 rhists.fHstartd->Fill(dpos);
965 rhists.fHendx->Fill(end.X());
966 rhists.fHendy->Fill(end.Y());
967 rhists.fHendz->Fill(end.Z());
968 rhists.fHendd->Fill(dend);
969 rhists.fHtheta->Fill(dir.Theta());
970 rhists.fHphi->Fill(dir.Phi());
971 rhists.fHtheta_xz->Fill(theta_xz);
972 rhists.fHtheta_yz->Fill(theta_yz);
976 rhists.fHmom->Fill(mom);
977 rhists.fHmoml->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();
1042 double mcdx = mctime * 1.e-3 *
detProp.DriftVelocity();
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);
1081 mchists.fHduvcosth->Fill(colinearity, uv0);
1087 mchists.fHmcdudw->Fill(dudw);
1088 mchists.fHmcdvdw->Fill(dvdw);
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);
1147 mchists.fHHitEff->Fill(hiteff);
1148 mchists.fHHitPurity->Fill(hitpurity);
1152 mchists.fHgstartx->Fill(mcstart.X());
1153 mchists.fHgstarty->Fill(mcstart.Y());
1154 mchists.fHgstartz->Fill(mcstart.Z());
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());
1160 mchists.fHgtheta_xz->Fill(mctheta_xz);
1161 mchists.fHgtheta_yz->Fill(mctheta_yz);
1162 mchists.fHgmom->Fill(mcmom);
1163 mchists.fHgmoml->Fill(mcmom);
1164 mchists.fHgke->Fill(mcke);
1165 mchists.fHgkel->Fill(mcke);
1166 mchists.fHglen->Fill(plen);
1167 mchists.fHglens->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);
1191 sTick =
detProp.ConvertXToTicks(mcstart[0], ipl, 0, 0);
1192 eWire = geom->NearestWire(mcend, ipl, 0, 0);
1193 eTick =
detProp.ConvertXToTicks(mcend[0], 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";
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;
1259 double mcdx = mctrk.
Start().
T() * 1.e-3 *
detProp.DriftVelocity();
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)
1267 int sWire, sTick, eWire, eTick;
1269 for (
unsigned short ipl = 0; ipl < geom->Nplanes(); ++ipl) {
1270 sWire = geom->NearestWire(mcstart, ipl, 0, 0);
1271 sTick =
detProp.ConvertXToTicks(mcstart[0], ipl, 0, 0);
1272 eWire = geom->NearestWire(mcend, ipl, 0, 0);
1273 eTick =
detProp.ConvertXToTicks(mcend[0], ipl, 0, 0);
1274 mf::LogVerbatim(
"TrackAna") <<
" Wire:Tick in Pln " << ipl <<
" W:T " << sWire <<
":"
1275 << sTick <<
" - " << eWire <<
":" << eTick;
simb::Origin_t Origin() const
double EndMomentum() const
double VertexMomentum() const
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::string fStitchModuleLabel
process_name use argoneut_mc_hitfinder track
std::map< int, MCHists > fMCHistMap
3-dimensional objects, potentially hits, clusters, prongs, etc.
Rotation_t GlobalToLocalRotationAtPoint(size_t p) const
const SMatrixSym55 & EndCovariance() const
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
std::string fMCTrackModuleLabel
const TLorentzVector & Momentum() const
simb::Origin_t fOriginValue
Vector_t EndDirection() const
std::map< int, RecoHists > fRecoHistMap
Point_t const & End() const
const MCStep & Start() const
std::string fTrackModuleLabel
unsigned int TrackID() const
std::string fHitModuleLabel
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track: