15 #include "art/Utilities/make_tool.h"
65 fPFPproducer =
p.get< art::InputTag > (
"PFPproducer",
"pandoraGausCryo0");
66 fT0producers =
p.get< std::vector<art::InputTag> > (
"T0producers", {
"pandoraGausCryo0"} );
67 fCALOproducer =
p.get< art::InputTag > (
"CALOproducer");
68 fTRKproducer =
p.get< art::InputTag > (
"TRKproducer" );
69 fTRKHMproducer=
p.get< art::InputTag > (
"TRKHMproducer",
"");
70 fHITproducer =
p.get< art::InputTag > (
"HITproducer" );
71 fG4producer =
p.get< std::string > (
"G4producer" );
72 fSimChannelproducer =
p.get< std::string > (
"SimChannelproducer" );
73 fRequireT0 =
p.get<
bool>(
"RequireT0",
false);
74 fDoTailFit =
p.get<
bool>(
"DoTailFit",
true);
75 fVerbose =
p.get<
bool>(
"Verbose",
false);
76 fSilenceMissingDataProducts =
p.get<
bool>(
"SilenceMissingDataProducts",
false);
77 fHitRawDigitsTickCollectWidth =
p.get<
double>(
"HitRawDigitsTickCollectWidth", 50.);
78 fHitRawDigitsWireCollectWidth =
p.get<
int>(
"HitRawDigitsWireCollectWidth", 5);
79 fTailFitResidualRange =
p.get<
double>(
"TailFitResidualRange", 5.);
80 if (fTailFitResidualRange > 10.) {
81 std::cout <<
"sbn::TrackCaloSkimmer: Bad tail fit residual range config :(" << fTailFitResidualRange <<
"). Fits will not be meaningful.\n";
83 fFillTrackEndHits =
p.get<
bool>(
"FillTrackEndHits",
true);
84 fTrackEndHitWireBox =
p.get<
float>(
"TrackEndHitWireBox", 60);
85 fTrackEndHitTimeBox =
p.get<
float>(
"TrackEndHitTimeBox", 300);
87 fRawDigitproducers =
p.get<std::vector<art::InputTag>>(
"RawDigitproducers", {});
89 std::vector<fhicl::ParameterSet> selection_tool_configs(
p.get<std::vector<fhicl::ParameterSet>>(
"SelectionTools"), {});
90 for (
const fhicl::ParameterSet &
p: selection_tool_configs) {
91 fSelectionTools.push_back(art::make_tool<sbn::ITCSSelectionTool>(
p));
97 const char *process_str = std::getenv(
"PROCESS");
100 fMeta.iproc = std::stoi(process_str);
108 art::ServiceHandle<art::TFileService>
tfs;
109 fTree = tfs->make<TTree>(
"TrackCaloSkim",
"Calo Tree");
110 fTree->Branch(
"trk", &fTrack);
116 unsigned sub = e.subRun();
117 unsigned run = e.run();
119 std::cout <<
"[TrackCaloSkimmer::analyzeEvent] Run: " << run <<
", SubRun: " << sub <<
", Event: "<< evt <<
", Is Data: " << e.isRealData() << std::endl;
125 fMeta.time = e.time().value();
129 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(e);
131 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(e, clock_data);
136 gdml = basename(gdml.c_str());
138 for(
unsigned int i = 0; i <gdml.size(); ++i) gdml[i] = std::tolower(gdml[i]);
142 const bool hasSBND = ((gdml.find(
"sbnd") != std::string::npos) ||
143 (geometry->
DetectorName().find(
"sbnd") != std::string::npos));
145 const bool hasICARUS = ((gdml.find(
"icarus") != std::string::npos) ||
146 (geometry->
DetectorName().find(
"icarus") != std::string::npos));
148 if(hasSBND == hasICARUS) {
149 std::cout <<
"TrackCaloSkimmer: Unable to automatically determine either SBND or ICARUS!" << std::endl;
153 if(hasSBND) det =
kSBND;
157 std::vector<std::vector<geo::BoxBoundedGeo>> TPCVols;
158 std::vector<geo::BoxBoundedGeo> AVs;
163 tend = geometry->
end_TPC(cryo.ID());
164 std::vector<geo::BoxBoundedGeo> this_tpc_volumes;
165 while (iTPC != tend) {
170 TPCVols.push_back(std::move(this_tpc_volumes));
173 for (
const std::vector<geo::BoxBoundedGeo> &tpcs: TPCVols) {
174 double XMin = std::min_element(tpcs.begin(), tpcs.end(), [](
auto &lhs,
auto &rhs) {
return lhs.MinX() < rhs.MinX(); })->MinX();
175 double YMin = std::min_element(tpcs.begin(), tpcs.end(), [](
auto &lhs,
auto &rhs) {
return lhs.MinY() < rhs.MinY(); })->MinY();
176 double ZMin = std::min_element(tpcs.begin(), tpcs.end(), [](
auto &lhs,
auto &rhs) {
return lhs.MinZ() < rhs.MinZ(); })->MinZ();
178 double XMax = std::max_element(tpcs.begin(), tpcs.end(), [](
auto &lhs,
auto &rhs) {
return lhs.MaxX() < rhs.MaxX(); })->MaxX();
179 double YMax = std::max_element(tpcs.begin(), tpcs.end(), [](
auto &lhs,
auto &rhs) {
return lhs.MaxY() < rhs.MaxY(); })->MaxY();
180 double ZMax = std::max_element(tpcs.begin(), tpcs.end(), [](
auto &lhs,
auto &rhs) {
return lhs.MaxZ() < rhs.MaxZ(); })->MaxZ();
182 AVs.emplace_back(XMin, XMax, YMin, YMax, ZMin, ZMax);
186 std::vector<art::Ptr<simb::MCParticle>> mcparticles;
187 if (fG4producer.size()) {
188 art::ValidHandle<std::vector<simb::MCParticle>> mcparticle_handle = e.getValidHandle<std::vector<simb::MCParticle>>(fG4producer);
189 art::fill_ptr_vector(mcparticles, mcparticle_handle);
192 std::vector<art::Ptr<sim::SimChannel>> simchannels;
193 if (fSimChannelproducer.size()) {
194 art::ValidHandle<std::vector<sim::SimChannel>> simchannel_handle = e.getValidHandle<std::vector<sim::SimChannel>>(fSimChannelproducer);
195 art::fill_ptr_vector(simchannels, simchannel_handle);
199 std::vector<art::Ptr<recob::PFParticle>> PFParticleList;
201 art::ValidHandle<std::vector<recob::PFParticle>> pfparticles = e.getValidHandle<std::vector<recob::PFParticle>>(fPFPproducer);
202 art::fill_ptr_vector(PFParticleList, pfparticles);
205 std::cout <<
"PFP's with tag: " << fPFPproducer <<
" not present.\n";
207 if (fSilenceMissingDataProducts)
return;
212 std::vector<art::FindManyP<anab::T0>> fmT0;
213 for (
unsigned i_label = 0; i_label < fT0producers.size(); i_label++) {
214 fmT0.emplace_back(PFParticleList, e, fT0producers[i_label]);
216 art::FindManyP<recob::SpacePoint> PFParticleSPs(PFParticleList, e, fPFPproducer);
219 art::ValidHandle<std::vector<recob::Track>>
tracks = e.getValidHandle<std::vector<recob::Track>>(fTRKproducer);
222 art::FindManyP<recob::Track> fmTracks(PFParticleList, e, fTRKproducer);
224 art::InputTag thm_label = fTRKHMproducer.empty() ? fTRKproducer : fTRKHMproducer;
225 art::FindManyP<recob::Hit, recob::TrackHitMeta> fmtrkHits(tracks, e, thm_label);
226 art::FindManyP<anab::Calorimetry> fmCalo(tracks, e, fCALOproducer);
229 std::vector<art::Ptr<raw::RawDigit>> rawdigitlist;
230 for (
const art::InputTag &t: fRawDigitproducers) {
231 art::ValidHandle<std::vector<raw::RawDigit>> thisdigits = e.getValidHandle<std::vector<raw::RawDigit>>(t);
232 art::fill_ptr_vector(rawdigitlist, thisdigits);
236 std::map<geo::WireID, art::Ptr<raw::RawDigit>> rawdigits;
237 for (
const art::Ptr<raw::RawDigit> &d: rawdigitlist) {
239 std::vector<geo::WireID> wids;
249 if (wids.size() == 0)
continue;
252 if (rawdigits.count(wids[0]))
continue;
254 rawdigits[wids[0]] = d;
258 art::ValidHandle<std::vector<recob::Hit>> allhit_handle = e.getValidHandle<std::vector<recob::Hit>>(fHITproducer);
259 std::vector<art::Ptr<recob::Hit>> allHits;
260 art::fill_ptr_vector(allHits, allhit_handle);
263 art::FindManyP<recob::SpacePoint> allHitSPs(allHits, e, fPFPproducer);
268 std::map<int, std::vector<std::pair<geo::WireID, const sim::IDE*>>> id_to_ide_map;
269 std::map<int, std::vector<art::Ptr<recob::Hit>>> id_to_truehit_map;
272 if (simchannels.size()) {
273 art::ServiceHandle<cheat::BackTrackerService> bt_serv;
282 std::vector<GlobalTrackInfo> track_infos;
284 track_infos.push_back({
285 t.Start(), t.End(), t.StartDirection(), t.EndDirection(), t.ID()
289 for (art::Ptr<recob::PFParticle> p_pfp: PFParticleList) {
292 const std::vector<art::Ptr<recob::Track>> thisTrack = fmTracks.at(p_pfp.key());
293 if (thisTrack.size() != 1)
296 art::Ptr<recob::Track> trkPtr = thisTrack.at(0);
298 std::vector<art::Ptr<anab::Calorimetry>> emptyCaloVector;
299 const std::vector<art::Ptr<anab::Calorimetry>> &
calo = fmCalo.isValid() ? fmCalo.at(trkPtr.key()) : emptyCaloVector;
301 std::vector<art::Ptr<recob::Hit>> emptyHitVector;
302 const std::vector<art::Ptr<recob::Hit>> &trkHits = fmtrkHits.isValid() ? fmtrkHits.at(trkPtr.key()) : emptyHitVector;
304 art::FindManyP<recob::SpacePoint> fmtrkHitSPs(trkHits, e, fPFPproducer);
306 std::vector<const recob::TrackHitMeta*> emptyTHMVector;
307 const std::vector<const recob::TrackHitMeta*> &trkHitMetas = fmtrkHits.isValid() ? fmtrkHits.data(trkPtr.key()) : emptyTHMVector;
309 art::Ptr<recob::SpacePoint> nullSP;
310 std::vector<art::Ptr<recob::SpacePoint>> trkHitSPs;
311 if (fmtrkHitSPs.isValid()) {
312 for (
unsigned i_hit = 0; i_hit < trkHits.size(); i_hit++) {
313 const std::vector<art::Ptr<recob::SpacePoint>> &h_sp = fmtrkHitSPs.at(i_hit);
315 trkHitSPs.push_back(h_sp.at(0));
318 trkHitSPs.push_back(nullSP);
324 float t0 = std::numeric_limits<float>::signaling_NaN();
325 for (
unsigned i_t0 = 0; i_t0 < fmT0.size(); i_t0++) {
326 if (fmT0[i_t0].isValid() && fmT0[i_t0].at(p_pfp.key()).
size()) {
327 t0 = fmT0[i_t0].at(p_pfp.key()).at(0)->Time();
330 if (fVerbose)
std::cout <<
"Track: " << trkPtr->ID() <<
" Has T0 (" << fT0producers[i_t0] <<
")\n";
336 if (fRequireT0 && whicht0 < 0) {
340 if (fVerbose)
std::cout <<
"Processing new track! ID: " << trkPtr->ID() <<
" time: " << t0 << std::endl;
346 fSnippetCount.clear();
347 fWiresToSave.clear();
350 FillTrack(*trkPtr, pfp, t0, trkHits, trkHitMetas, trkHitSPs, calo, rawdigits, track_infos, geometry, clock_data, bt, det);
351 fTrack->whicht0 = whicht0;
353 FillTrackDaughterRays(*trkPtr, pfp, PFParticleList, PFParticleSPs);
355 if (fFillTrackEndHits) FillTrackEndHits(geometry, dprop, *trkPtr, allHits, allHitSPs);
358 if (simchannels.size())
FillTrackTruth(clock_data, trkHits, mcparticles, AVs, TPCVols, id_to_ide_map, id_to_truehit_map, dprop, geometry);
362 if (!fSelectionTools.size()) select =
true;
366 for (
const std::unique_ptr<sbn::ITCSSelectionTool> &t: fSelectionTools) {
367 if (t->DoSelect(*fTrack)) {
369 fTrack->selected = i_select;
370 fTrack->nprescale = t->GetPrescale();
378 if (fVerbose)
std::cout <<
"Track Selected! By tool: " << i_select << std::endl;
392 bool hit_is_TPCE = -1;
402 if (
h.oncalo && hit_is_TPCE == TPCE) {
403 if (min < 0. ||
h.h.time < min) min =
h.h.time;
416 bool hit_is_TPCE = -1;
426 if (
h.oncalo && hit_is_TPCE == TPCE) {
427 if (max < 0. || h.h.time > max) max =
h.h.time;
445 auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
446 art::ServiceHandle<geo::Geometry const> geom;
451 int corr = geom->TPC(tpc.
TPC).DriftDir()[0];
453 if (sce && sce->EnableSimSpatialSCE()) {
456 ret.SetX(ret.X() + corr * offset.X());
457 ret.SetY(ret.Y() + offset.Y());
458 ret.SetZ(ret.Z() + offset.Z());
466 auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>();
470 if (sce && sce->EnableSimSpatialSCE()) {
473 ret.SetX(ret.X() + offset.X());
474 ret.SetY(ret.Y() + offset.Y());
475 ret.SetZ(ret.Z() + offset.Z());
484 const std::vector<geo::BoxBoundedGeo> &active_volumes,
485 const std::vector<std::vector<geo::BoxBoundedGeo>> &tpc_volumes,
486 const std::map<
int,
std::vector<std::pair<geo::WireID, const sim::IDE *>>> &id_to_ide_map,
487 const std::map<
int,
std::vector<art::Ptr<recob::Hit>>> &id_to_truehit_map,
491 std::vector<std::pair<geo::WireID, const sim::IDE *>>
empty;
492 const std::vector<std::pair<geo::WireID, const sim::IDE *>> &particle_ides = id_to_ide_map.count(particle.TrackId()) ? id_to_ide_map.at(particle.TrackId()) : empty;
494 std::vector<art::Ptr<recob::Hit>> emptyHits;
495 const std::vector<art::Ptr<recob::Hit>> &particle_hits = id_to_truehit_map.count(particle.TrackId()) ? id_to_truehit_map.at(particle.TrackId()) : emptyHits;
509 for (
auto const &ide_pair: particle_ides) {
511 const sim::IDE *ide = ide_pair.second;
516 else if (w.
Plane == 1) {
519 else if (w.
Plane == 2) {
524 for (
const art::Ptr<recob::Hit>
h: particle_hits) {
530 else if (w.
Plane == 1) {
533 else if (w.
Plane == 2) {
540 trueparticle.
cont_tpc = particle.NumberTrajectoryPoints() > 0;
541 trueparticle.
contained = particle.NumberTrajectoryPoints() > 0;
544 int entry_point = -1;
546 int cryostat_index = -1;
549 for (
unsigned j = 0; j < particle.NumberTrajectoryPoints(); j++) {
550 for (
unsigned i = 0; i < active_volumes.size(); i++) {
551 if (active_volumes.at(i).ContainsPosition(particle.Position(j).Vect())) {
557 if (entry_point != -1)
break;
561 if (entry_point > 0) {
562 trueparticle.
wallin = (int)
caf::GetWallCross(active_volumes.at(cryostat_index), particle.Position(entry_point).Vect(), particle.Position(entry_point-1).Vect());
568 std::vector<geo::BoxBoundedGeo> volumes;
569 if (entry_point >= 0) {
570 volumes = tpc_volumes.at(cryostat_index);
571 for (
unsigned i = 0; i < volumes.size(); i++) {
572 if (volumes[i].ContainsPosition(particle.Position(entry_point).Vect())) {
574 trueparticle.
cont_tpc = entry_point == 0;
578 trueparticle.
contained = entry_point == 0;
591 if (entry_point >= 0) {
593 const simb::MCTrajectory &trajectory = particle.Trajectory();
594 TVector3 pos = trajectory.Position(entry_point).Vect();
595 for (
unsigned i = entry_point+1; i < particle.NumberTrajectoryPoints(); i++) {
596 TVector3 this_point = trajectory.Position(i).Vect();
601 for (
unsigned j = 0; j < volumes.size(); j++) {
602 if (volumes[j].ContainsPosition(this_point) && tpc_index >= 0 && j != ((unsigned)tpc_index)) {
610 trueparticle.
cont_tpc = volumes[tpc_index].ContainsPosition(this_point);
614 trueparticle.
contained = active_volumes.at(cryostat_index).ContainsPosition(this_point);
617 trueparticle.
length += (this_point - pos).Mag();
619 if (!active_volumes.at(cryostat_index).ContainsPosition(this_point) && active_volumes.at(cryostat_index).ContainsPosition(pos)) {
623 pos = trajectory.Position(i).Vect();
626 if (exit_point < 0 && entry_point >= 0) {
627 exit_point = particle.NumberTrajectoryPoints() - 1;
629 if (exit_point >= 0 && ((
unsigned)exit_point) < particle.NumberTrajectoryPoints() - 1) {
630 trueparticle.
wallout = (int)
caf::GetWallCross(active_volumes.at(cryostat_index), particle.Position(exit_point).Vect(), particle.Position(exit_point+1).Vect());
634 trueparticle.
pdg = particle.PdgCode();
636 trueparticle.
gen =
ConvertTVector(particle.NumberTrajectoryPoints() ? particle.Position().Vect() : TVector3(-9999, -9999, -9999));
637 trueparticle.
genT = particle.NumberTrajectoryPoints() ? particle.Position().T() / 1000. : -9999;
638 trueparticle.
genp =
ConvertTVector(particle.NumberTrajectoryPoints() ? particle.Momentum().Vect(): TVector3(-9999, -9999, -9999));
639 trueparticle.
genE = particle.NumberTrajectoryPoints() ? particle.Momentum().E(): -9999;
641 trueparticle.
start =
ConvertTVector((entry_point >= 0) ? particle.Position(entry_point).Vect(): TVector3(-9999, -9999, -9999));
642 trueparticle.
startT = (entry_point >= 0) ? particle.Position(entry_point).T() / 1000. : -9999;
643 trueparticle.
end =
ConvertTVector((exit_point >= 0) ? particle.Position(exit_point).Vect(): TVector3(-9999, -9999, -9999));
644 trueparticle.
endT = (exit_point >= 0) ? particle.Position(exit_point).T() / 1000. : -9999;
646 trueparticle.
startp =
ConvertTVector((entry_point >= 0) ? particle.Momentum(entry_point).Vect() : TVector3(-9999, -9999, -9999));
647 trueparticle.
startE = (entry_point >= 0) ? particle.Momentum(entry_point).E() : -9999.;
648 trueparticle.
endp =
ConvertTVector((exit_point >= 0) ? particle.Momentum(exit_point).Vect() : TVector3(-9999, -9999, -9999));
649 trueparticle.
endE = (exit_point >= 0) ? particle.Momentum(exit_point).E() : -9999.;
654 trueparticle.
G4ID = particle.TrackId();
655 trueparticle.
parent = particle.Mother();
658 std::map<unsigned, sbn::TrueHit> truehits;
660 for (
auto const &ide_pair: particle_ides) {
663 const sim::IDE *ide = ide_pair.second;
667 truehits[c].tpc = w.
TPC;
668 truehits[c].plane = w.
Plane;
669 truehits[c].wire = w.
Wire;
670 truehits[c].channel = c;
673 float old_elec = truehits[c].nelec;
675 truehits[c].p.x = (truehits[c].p.x*old_elec + ide->
x*ide->
numElectrons) / new_elec;
676 truehits[c].p.y = (truehits[c].p.y*old_elec + ide->
y*ide->
numElectrons) / new_elec;
677 truehits[c].p.z = (truehits[c].p.z*old_elec + ide->
z*ide->
numElectrons) / new_elec;
683 truehits[c].p_scecorr.x = (truehits[c].p_scecorr.x*old_elec + ide_p_scecorr.x()*ide->
numElectrons) / new_elec;
684 truehits[c].p_scecorr.y = (truehits[c].p_scecorr.y*old_elec + ide_p_scecorr.y()*ide->
numElectrons) / new_elec;
685 truehits[c].p_scecorr.z = (truehits[c].p_scecorr.z*old_elec + ide_p_scecorr.z()*ide->
numElectrons) / new_elec;
689 truehits[c].e += ide->
energy;
690 truehits[c].ndep += 1;
694 for (
auto const &ide_pair: particle_ides) {
697 const sim::IDE *ide = ide_pair.second;
705 truehits[c].p_width.x += (ide_p.x() - truehits[c].p.x) * (ide_p.x() - truehits[c].p.x) * this_elec / truehits[c].nelec;
706 truehits[c].p_width.y += (ide_p.y() - truehits[c].p.y) * (ide_p.y() - truehits[c].p.y) * this_elec / truehits[c].nelec;
707 truehits[c].p_width.z += (ide_p.z() - truehits[c].p.z) * (ide_p.z() - truehits[c].p.z) * this_elec / truehits[c].nelec;
709 truehits[c].p_scecorr_width.x += (ide_p_scecorr.x() - truehits[c].p_scecorr.x) * (ide_p_scecorr.x() - truehits[c].p_scecorr.x) * this_elec / truehits[c].nelec;
710 truehits[c].p_scecorr_width.y += (ide_p_scecorr.y() - truehits[c].p_scecorr.y) * (ide_p_scecorr.y() - truehits[c].p_scecorr.y) * this_elec / truehits[c].nelec;
711 truehits[c].p_scecorr_width.z += (ide_p_scecorr.z() - truehits[c].p_scecorr.z) * (ide_p_scecorr.z() - truehits[c].p_scecorr.z) * this_elec / truehits[c].nelec;
715 std::vector<sbn::TrueHit> truehits_v;
716 for (
auto const &
p: truehits) {
717 truehits_v.push_back(
p.second);
731 TVector3 h_p(
h.p_scecorr.x,
h.p_scecorr.y,
h.p_scecorr.z);
734 float closest_dist = -1.;
736 for (
unsigned i_traj = 0; i_traj < particle.NumberTrajectoryPoints(); i_traj++) {
737 if (closest_dist < 0. || (particle.Position(i_traj).Vect() - h_p).Mag() < closest_dist) {
738 direction = particle.Momentum(i_traj).Vect().Unit();
739 closest_dist = (particle.Position(i_traj).Vect() - h_p).Mag();
745 if (closest_dist >= 0. && direction.Mag() > 1
e-4) {
748 float cosgamma =
abs(cos(angletovert) * direction.Z() + sin(angletovert) * direction.Y());
749 float pitch = geo->
WirePitch(plane) / cosgamma;
756 if (closest_dist >= 0. && direction.Mag() > 1
e-4) {
760 TVector3 loc_mdx_v = h_p - direction * (geo->
WirePitch(geo->
View(plane) / 2.));
761 TVector3 loc_pdx_v = h_p + direction * (geo->
WirePitch(geo->
View(plane) / 2.));
764 geo::Point_t loc_mdx(loc_mdx_v.X(), loc_mdx_v.Y(), loc_mdx_v.Z());
765 geo::Point_t loc_pdx(loc_pdx_v.X(), loc_pdx_v.Y(), loc_pdx_v.Z());
775 double cosgamma =
std::abs(std::sin(angletovert)*dir.Y() + std::cos(angletovert)*dir.Z());
790 h.pitch_sce = (locw_pdx_traj -
loc).R();
797 h.itraj = traj_index;
801 if (traj_index >= 0) {
802 for (
int i_traj = traj_index+1; i_traj < (int)particle.NumberTrajectoryPoints(); i_traj++) {
803 h.rr += (particle.Position(i_traj).Vect() - particle.Position(i_traj-1).Vect()).Mag();
807 double hit_distance_along_particle = (h_p - particle.Position(traj_index).Vect()).Dot(particle.Momentum(traj_index).Vect().Unit());
808 h.rr += -hit_distance_along_particle;
814 std::sort(truehits_v.begin(), truehits_v.end(),
815 [](
auto const &lhs,
auto const &rhs) {
816 return lhs.itraj < rhs.itraj;
824 else if (
h.plane == 1) {
827 else if (
h.plane == 2) {
839 const art::FindManyP<recob::SpacePoint> &allHitSPs) {
844 if (!tpc_end)
return;
850 float end_t = -1000.;
851 float closest_wire_dist = -1.;
854 if (h.
oncalo && (closest_wire_dist < 0. ||
abs(h.
h.
wire - end_w) < closest_wire_dist)) {
855 closest_wire_dist =
abs(h.
h.
wire - end_w);
860 for (
const art::Ptr<recob::Hit> &
hit: allHits) {
862 if (h_p != plane_end)
continue;
865 float h_w = (float)
hit->WireID().Wire;
866 float h_t =
hit->PeakTime();
868 if (
abs(h_w - end_w) < fTrackEndHitWireBox &&
869 abs(h_t - end_t) < fTrackEndHitTimeBox) {
879 hinfo.
mult =
hit->Multiplicity();
880 hinfo.
wire =
hit->WireID().Wire;
882 hinfo.
tpc =
hit->WireID().TPC;
883 hinfo.
end =
hit->EndTick();
885 hinfo.
id =
hit.key();
887 const std::vector<art::Ptr<recob::SpacePoint>> &h_sp = allHitSPs.at(
hit.key());
900 fTrack->endhits.push_back(hinfo);
909 const std::vector<art::Ptr<simb::MCParticle>> &mcparticles,
910 const std::vector<geo::BoxBoundedGeo> &active_volumes,
911 const std::vector<std::vector<geo::BoxBoundedGeo>> &tpc_volumes,
912 const std::map<
int,
std::vector<std::pair<geo::WireID, const sim::IDE*>>> id_to_ide_map,
913 const std::map<
int,
std::vector<art::Ptr<recob::Hit>>> id_to_truehit_map,
921 fTrack->truth.depE = total_energy / 1000. ;
924 std::sort(matches.begin(), matches.end(),
925 [](
const auto &
a,
const auto &b) {
926 return a.second > b.second;
931 if (matches.size()) {
932 std::pair<int, float> bestmatch = matches[0];
934 fTrack->truth.pur = bestmatch.second / total_energy;
936 for (
const art::Ptr<simb::MCParticle> &p_mcp: mcparticles) {
937 if (p_mcp->TrackId() == bestmatch.first) {
938 if (fVerbose)
std::cout <<
"Matched! Track ID: " << p_mcp->TrackId() <<
" pdg: " << p_mcp->PdgCode() <<
" process: " << p_mcp->EndProcess() << std::endl;
939 fTrack->truth.p =
TrueParticleInfo(*p_mcp, active_volumes, tpc_volumes, id_to_ide_map, id_to_truehit_map, dprop, geo);
940 fTrack->truth.eff = fTrack->truth.depE / (fTrack->truth.p.plane0VisE + fTrack->truth.p.plane1VisE + fTrack->truth.p.plane2VisE);
943 for (
const art::Ptr<simb::MCParticle> &d_mcp: mcparticles) {
944 if (d_mcp->Mother() == p_mcp->TrackId() &&
945 (d_mcp->Process() ==
"Decay" || d_mcp->Process() ==
"muMinusCaptureAtRest") &&
946 abs(d_mcp->PdgCode()) == 11) {
948 fTrack->truth.michel =
TrueParticleInfo(*d_mcp, active_volumes, tpc_volumes, id_to_ide_map, id_to_truehit_map, dprop, geo);
962 const std::vector<art::Ptr<recob::PFParticle>> &PFParticleList,
963 const art::FindManyP<recob::SpacePoint> &PFParticleSPs) {
968 fTrack->daughter_pdg.push_back(d_pfp.
PdgCode());
971 float min_distance = -1.;
972 for (
const art::Ptr<recob::SpacePoint> &sp: PFParticleSPs.at(d)) {
973 if (min_distance < 0. || (sp->position() - trk.
End()).
r() < min_distance) {
974 min_distance = (sp->position() - trk.
End()).
r();
979 fTrack->daughter_sp_toend_dist.push_back(min_distance);
980 fTrack->daughter_nsp.push_back(nsp);
988 const std::vector<const recob::TrackHitMeta*> &thms,
989 const std::vector<art::Ptr<recob::SpacePoint>> &sps,
991 const std::map<
geo::WireID, art::Ptr<raw::RawDigit>> &rawdigits,
992 const std::vector<GlobalTrackInfo> &
tracks,
999 fTrack->meta = fMeta;
1001 fTrack->id = track.
ID();
1004 fTrack->length = track.
Length();
1005 fTrack->start.x = track.
Start().X();
1006 fTrack->start.y = track.
Start().Y();
1007 fTrack->start.z = track.
Start().Z();
1008 fTrack->end.x = track.
End().X();
1009 fTrack->end.y = track.
End().Y();
1010 fTrack->end.z = track.
End().Z();
1015 if (hits.size() > 0) {
1016 fTrack->cryostat = hits[0]->WireID().Cryostat;
1020 for (
unsigned i_hit = 0; i_hit < hits.size(); i_hit++) {
1021 sbn::TrackHitInfo hinfo = MakeHit(*hits[i_hit], hits[i_hit].key(), *thms[i_hit], track, sps[i_hit],
calo, geo, clock_data, bt_serv);
1022 if (hinfo.
h.
plane == 0) {
1023 fTrack->hits0.push_back(hinfo);
1025 else if (hinfo.
h.
plane == 1) {
1026 fTrack->hits1.push_back(hinfo);
1028 else if (hinfo.
h.
plane == 2) {
1029 fTrack->hits2.push_back(hinfo);
1034 fTrack->hit_min_time_p0_tpcE =
HitMinTime(fTrack->hits0,
true, det);
1035 fTrack->hit_max_time_p0_tpcE =
HitMaxTime(fTrack->hits0,
true, det);
1036 fTrack->hit_min_time_p0_tpcW =
HitMinTime(fTrack->hits0,
false, det);
1037 fTrack->hit_max_time_p0_tpcW =
HitMaxTime(fTrack->hits0,
false, det);
1038 fTrack->hit_min_time_p1_tpcE =
HitMinTime(fTrack->hits1,
true, det);
1039 fTrack->hit_max_time_p1_tpcE =
HitMaxTime(fTrack->hits1,
true, det);
1040 fTrack->hit_min_time_p1_tpcW =
HitMinTime(fTrack->hits1,
false, det);
1041 fTrack->hit_max_time_p1_tpcW =
HitMaxTime(fTrack->hits1,
false, det);
1042 fTrack->hit_min_time_p2_tpcE =
HitMinTime(fTrack->hits2,
true, det);
1043 fTrack->hit_max_time_p2_tpcE =
HitMaxTime(fTrack->hits2,
true, det);
1044 fTrack->hit_min_time_p2_tpcW =
HitMinTime(fTrack->hits2,
false, det);
1045 fTrack->hit_max_time_p2_tpcW =
HitMaxTime(fTrack->hits2,
false, det);
1048 if (fDoTailFit) DoTailFit();
1051 for (
auto const &w_pair: fWiresToSave) {
1054 if (rawdigits.count(wire)) {
1056 int min_tick = std::max(0, w_pair.second.first);
1057 int max_tick = std::min((
int)thisdigit.
NADC(), w_pair.second.second);
1060 std::vector<short> adcs;
1061 for (
int t = min_tick; t < max_tick; t++) {
1062 adcs.push_back(thisdigit.
ADC(t));
1070 winfo.
tdc0 = min_tick;
1073 if (winfo.
plane == 0) {
1074 fTrack->wires0.push_back(winfo);
1076 else if (winfo.
plane == 1) {
1077 fTrack->wires1.push_back(winfo);
1079 else if (winfo.
plane == 2) {
1080 fTrack->wires2.push_back(winfo);
1085 std::sort(fTrack->wires0.begin(), fTrack->wires0.end(), [](
auto const &lhs,
auto const &rhs) {
return lhs.wire < rhs.wire;});
1086 std::sort(fTrack->wires1.begin(), fTrack->wires1.end(), [](
auto const &lhs,
auto const &rhs) {
return lhs.wire < rhs.wire;});
1087 std::sort(fTrack->wires2.begin(), fTrack->wires2.end(), [](
auto const &lhs,
auto const &rhs) {
return lhs.wire < rhs.wire;});
1091 if (othr.ID == track.
ID())
continue;
1093 if ((track.
End() - othr.start).
r() < 50. || (track.
End() - othr.end).
r() < 50.) {
1094 fTrack->tracks_near_end_dist.push_back(std::min((track.
End() - othr.start).
r(), (track.
End() - othr.end).
r()));
1095 fTrack->tracks_near_end_costh.push_back(
1096 (track.
End() - othr.start).
r() < (track.
End() - othr.end).
r() ?
1102 if (othr.ID == track.
ID())
continue;
1104 if ((track.
Start() - othr.start).
r() < 50. || (track.
Start() - othr.end).
r() < 50.) {
1105 fTrack->tracks_near_start_dist.push_back(std::min((track.
Start() - othr.start).
r(), (track.
Start() - othr.end).
r()));
1106 fTrack->tracks_near_start_costh.push_back(
1107 (track.
Start() - othr.start).
r() < (track.
Start() - othr.end).
r() ?
1116 std::vector<double> fit_rr;
1117 std::vector<double> fit_dqdx;
1120 if (h.
oncalo && h.
rr > 0. && h.
rr < fTailFitResidualRange) {
1121 fit_rr.push_back(h.
rr);
1122 fit_dqdx.push_back(h.
dqdx);
1130 throw cet::exception(
"sbn::TrackCaloSkimmer::DoTailFit: More fitting points required ("
1135 for (
unsigned i = 0; i < fit_rr.size() && i <
MAX_N_FIT_DATA; i++) {
1142 if (fTrack->n_fit_point > 2) {
1145 fFitExp.SetParameter(0,
"A", *std::max_element(fit_dqdx.begin(), fit_dqdx.end()), 200, 0, 5000);
1146 fFitExp.SetParameter(1,
"R", 10., 0.5, 0, 1000);
1147 fFitExp.ExecuteCommand(
"MIGRAD", 0, 0);
1149 double A = fFitExp.GetParameter(0);
1150 double R = fFitExp.GetParameter(1);
1153 double param[2] {
A, R};
1154 double residuals = -1;
1157 fTrack->exp_fit_A =
A;
1158 fTrack->exp_fit_R = R;
1159 fTrack->exp_fit_residuals = residuals;
1163 fFitConst.SetParameter(0,
"C", std::accumulate(fit_dqdx.begin(), fit_dqdx.end(), 0.), 200, 0, 5000);
1164 fFitConst.ExecuteCommand(
"MIGRAD", 0, 0);
1166 double C = fFitConst.GetParameter(0);
1168 double cresiduals = -1;
1171 fTrack->const_fit_C = C;
1172 fTrack->const_fit_residuals = cresiduals;
1181 const art::Ptr<recob::SpacePoint> &sp,
1202 hinfo.
h.
id = (int)hkey;
1224 hinfo.
h.
truth.
e += ide.energy;
1235 if (!fSnippetCount.count(snippet)) {
1236 fSnippetCount[snippet] = 0;
1240 fSnippetCount[snippet] ++;
1241 hinfo.
i_snippet = fSnippetCount[snippet];
1245 int min_tick = (int)std::floor(hit.
PeakTime() - fHitRawDigitsTickCollectWidth);
1246 int max_tick = (int)std::ceil(hit.
PeakTime() + fHitRawDigitsTickCollectWidth);
1247 for (
int wire = hinfo.
h.
wire - fHitRawDigitsWireCollectWidth; wire <= hinfo.
h.
wire + fHitRawDigitsWireCollectWidth; wire++) {
1250 if (fWiresToSave.count(
w)) {
1251 fWiresToSave.at(
w).first = std::min(fWiresToSave.at(
w).first, min_tick);
1252 fWiresToSave.at(
w).second = std::max(fWiresToSave.at(
w).second, max_tick);
1255 fWiresToSave[
w] = {min_tick, max_tick};
1260 bool badhit = (thm.
Index() == std::numeric_limits<unsigned int>::max()) ||
1268 hinfo.
tp.
x = loc.X();
1269 hinfo.
tp.
y = loc.Y();
1270 hinfo.
tp.
z = loc.Z();
1273 hinfo.
dir.
x = dir.X();
1274 hinfo.
dir.
y = dir.Y();
1275 hinfo.
dir.
z = dir.Z();
1278 for (
const art::Ptr<anab::Calorimetry> &c:
calo) {
1279 if (c->PlaneID().Plane != hinfo.
h.
plane)
continue;
1282 for (
unsigned i_calo = 0; i_calo < c->dQdx().size(); i_calo++) {
1283 if (c->TpIndices()[i_calo] == hkey) {
1286 hinfo.
pitch = c->TrkPitchVec()[i_calo];
1287 hinfo.
dqdx = c->dQdx()[i_calo];
1288 hinfo.
rr = c->ResidualRange()[i_calo];
1298 hinfo.
h.
sp.
x = sp->position().x();
1299 hinfo.
h.
sp.
y = sp->position().y();
1300 hinfo.
h.
sp.
z = sp->position().z();
geo::Length_t WireCoordinate(double YPos, double ZPos, geo::PlaneID const &planeid) const
Returns the index of the nearest wire to the specified position.
void analyze(art::Event const &e) override
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
std::map< int, std::vector< std::pair< geo::WireID, const sim::IDE * > > > PrepSimChannels(const std::vector< art::Ptr< sim::SimChannel >> &simchannels, const geo::GeometryCore &geo)
const std::vector< size_t > & Daughters() const
Returns the collection of daughter particles.
int end_process
End G4 process of the particle. Values defined as enum in StandardRecord.
float z
z position of ionization [cm]
BEGIN_PROLOG TPC Trig offset(g4 rise time) ProjectToHeight
sbn::Vector3D ConvertTVector(const TVector3 &tv)
Collection of charge vs time digitized from a single readout channel.
int wallout
Wall of cryostat particle exits (wNone if stopping in detector)
ClusterModuleLabel join with tracks
static double FIT_RR[MAX_N_FIT_DATA]
short ADC(int i) const
ADC vector element number i; no decompression is applied.
const geo::GeometryCore * geometry
uint16_t plane
Plane number.
Vector3D endp
Momentum at last point in the active TPC volume [GeV/c].
Vector3D sp
Space-Point Position of hit [cm].
uint16_t tpc
TPC number of hit.
static constexpr size_t kPFParticlePrimary
Define index to signify primary particle.
Vector3D genp
Momentum at generation point [GeV/c].
then echo unknown compiler flag
HitInfo h
Hit information by itself.
geo::WireID WireID() const
float RMS() const
RMS of the hit shape, in tick units.
Vector3D gen
Generation position [cm].
Point_t const & LocationAtPoint(size_t i) const
void ConstResiduals(int &npar, double *g, double &result, double *par, int flag)
void FillTrackEndHits(const geo::GeometryCore *geometry, const detinfo::DetectorPropertiesData &dprop, const recob::Track &track, const std::vector< art::Ptr< recob::Hit >> &allHits, const art::FindManyP< recob::SpacePoint > &allHitSPs)
float HitMinTime(const std::vector< sbn::TrackHitInfo > &hits, bool TPCE, sbn::EDet det)
uint16_t channel
Channel number of hit.
The data type to uniquely identify a Plane.
Geometry information for a single TPC.
geo::Point_t position() const
Returns the position of the point in world coordinates [cm].
bool HasValidPoint(size_t i) const
geo::BoxBoundedGeo const & ActiveBoundingBox() const
Returns the box of the active volume of this TPC.
std::vector< geo::WireID > ChannelToWire(raw::ChannelID_t const channel) const
Returns a list of wires connected to the specified TPC channel.
CryostatID_t Cryostat
Index of cryostat.
std::size_t size(FixedBins< T, C > const &) noexcept
int PdgCode() const
Return the type of particle as a PDG ID.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
int16_t tdc0
TDC tick of the first ADC value.
WireID_t Wire
Index of the wire within its plane.
process_name use argoneut_mc_hitfinder track
uint16_t plane
Plane number of hit.
void FillTrackDaughterRays(const recob::Track &trk, const recob::PFParticle &pfp, const std::vector< art::Ptr< recob::PFParticle >> &PFParticleList, const art::FindManyP< recob::SpacePoint > &PFParticleSPs)
float integral
Integral of gaussian fit to ADC values in hit [ADC].
float pitch
Pitch of track across wire the hit is on [cm].
void ExpResiduals(int &npar, double *g, double &result, double *par, int flag)
std::vector< TrueHit > truehits0
List of True "hits" of this particle on Plane 0.
short int Multiplicity() const
How many hits could this one be shared with.
float x
x position of ionization [cm]
unsigned plane1nhit
Number of hits on plane 1 (2nd Ind.)
int wallin
Wall of cryostat particle enters (wNone if starting in detector)
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::vector< TrueHit > truehits2
List of True "hits" of this particle on Plane 2.
uint16_t mult
Multiplicity of hit.
Vector3D dir
Direction of track at hit location.
void FillTrackTruth(const detinfo::DetectorClocksData &clock_data, const std::vector< art::Ptr< recob::Hit >> &trkHits, const std::vector< art::Ptr< simb::MCParticle >> &mcparticles, const std::vector< geo::BoxBoundedGeo > &active_volumes, const std::vector< std::vector< geo::BoxBoundedGeo >> &tpc_volumes, const std::map< int, std::vector< std::pair< geo::WireID, const sim::IDE * >>> id_to_ide_map, const std::map< int, std::vector< art::Ptr< recob::Hit >>> id_to_truehit_map, const detinfo::DetectorPropertiesData &dprop, const geo::GeometryCore *geo)
uint16_t wire
Wire number of hit.
TPC_iterator begin_TPC() const
Returns an iterator pointing to the first TPC in the detector.
float genE
Energy at generation pt [GeV].
int16_t start
Start tick of hit [ticks].
float dqdx
Initial computed dq/dx of hit [ADC/cm].
geo::TPCID FindTPCAtPosition(double const worldLoc[3]) const
Returns the ID of the TPC at specified location.
sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, const std::vector< geo::BoxBoundedGeo > &active_volumes, const std::vector< std::vector< geo::BoxBoundedGeo >> &tpc_volumes, const std::map< int, std::vector< std::pair< geo::WireID, const sim::IDE * >>> &id_to_ide_map, const std::map< int, std::vector< art::Ptr< recob::Hit >>> &id_to_truehit_map, const detinfo::DetectorPropertiesData &dprop, const geo::GeometryCore *geo)
process_name can override from command line with o or output calo
std::string GDMLFile() const
Returns the full directory path to the GDML file source.
std::vector< std::pair< int, float > > AllTrueParticleIDEnergyMatches(const detinfo::DetectorClocksData &clockData, const std::vector< art::Ptr< recob::Hit > > &hits, bool rollup_unsaved_ids=1)
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
const size_t MAX_N_FIT_DATA
TrackHitInfo MakeHit(const recob::Hit &hit, unsigned hkey, const recob::TrackHitMeta &thm, const recob::Track &trk, const art::Ptr< recob::SpacePoint > &sp, const std::vector< art::Ptr< anab::Calorimetry >> &calo, const geo::GeometryCore *geo, const detinfo::DetectorClocksData &dclock, const cheat::BackTrackerService *bt_serv)
geo::Point_t WireToTrajectoryPosition(const geo::Point_t &loc, const geo::TPCID &tpc)
unsigned plane0nhit
Number of hits on plane 0 (1st Ind.)
float plane2VisE
Sum of energy deposited on plane 2 (Col.) [GeV].
Vector_t StartDirection() const
Access to track direction at different points.
double Length(size_t p=0) const
Access to various track properties.
static double FIT_DQDX[MAX_N_FIT_DATA]
TrackCaloSkimmer(fhicl::ParameterSet const &p)
void FillTrack(const recob::Track &track, const recob::PFParticle &pfp, float t0, const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const std::vector< art::Ptr< recob::SpacePoint >> &sps, const std::vector< art::Ptr< anab::Calorimetry >> &calo, const std::map< geo::WireID, art::Ptr< raw::RawDigit >> &rawdigits, const std::vector< GlobalTrackInfo > &tracks, const geo::GeometryCore *geo, const detinfo::DetectorClocksData &clock_data, const cheat::BackTrackerService *bt_serv, const sbn::EDet det)
uint16_t channel
Channel number.
std::string DetectorName() const
Returns a string with the name of the detector, as configured.
Point_t const & Start() const
Access to track position at different points.
Vector3D tp
Track Trajectory position of hit [cm].
caf::g4_process_ GetG4ProcessID(const std::string &name)
Ionization at a point of the TPC sensitive volume.
bool contained
Whether the particle is contained in a single active volume.
float endT
End time last point in the active [mus – t=0 is spill time].
Vector3D start
Start position in the active TPC volume [cm].
bool crosses_tpc
Whether the particle crosses a TPC boundary.
bool cont_tpc
Whether the particle is contained in a single TPC.
float energy
energy deposited by ionization by this track ID and time [MeV]
std::vector< TrueHit > truehits1
List of True "hits" of this particle on Plane 1.
size_t NADC() const
Number of elements in the compressed ADC sample vector.
double ConvertXToTicks(double X, int p, int t, int c) const
geo::Point_t TrajectoryToWirePosition(const geo::Point_t &loc, const geo::TPCID &tpc)
float time
Peak time of hit [ticks].
double DriftVelocity(double efield=0., double temperature=0.) const
cm/us
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
Description of geometry of one entire detector.
float sumadc
"SummedADC" – sum of ADC values under gaussian fit [ADC]
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
View_t View(geo::PlaneID const &pid) const
Returns the view (wire orientation) on the channels of specified TPC plane.
float plane1VisE
Sum of energy deposited on plane 1 (2nd Ind.) [GeV].
float rr
Residual range of hit along track [cm].
float endE
Energy at last pt in active TPC volume [GeV].
Vector3D end
End position in the active TPC volume [cm].
float startT
Start time of first TPC point [mus – t=0 is spill time].
float y
y position of ionization [cm]
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
IteratorBox< cryostat_iterator,&GeometryCore::begin_cryostat,&GeometryCore::end_cryostat > IterateCryostats() const
Enables ranged-for loops on all cryostats of the detector.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
float PeakTime() const
Time of the signal peak, in tick units.
float HitMaxTime(const std::vector< sbn::TrackHitInfo > &hits, bool TPCE, sbn::EDet det)
Hierarchical representation of particle flow.
void FillTrackTruth(const std::vector< art::Ptr< recob::Hit >> &hits, const std::map< int, caf::HitsEnergy > &id_hits_map, const std::vector< caf::SRTrueParticle > &particles, const detinfo::DetectorClocksData &clockData, caf::SRTrack &srtrack, bool allowEmpty)
Contains all timing reference information for the detector.
float length
Trajectory length in active TPC volume the particle first enters [cm].
std::string to_string(WindowPattern const &pattern)
std::map< int, std::vector< art::Ptr< recob::Hit > > > PrepTrueHits(const std::vector< art::Ptr< recob::Hit >> &allHits, const detinfo::DetectorClocksData &clockData, const cheat::BackTrackerService &backtracker)
Vector_t EndDirection() const
uint16_t i_snippet
Index of hit into snippet.
float startE
Energy at first pt in active TPC volume [GeV].
float plane0VisE
Sum of energy deposited on plane 0 (1st Ind.) [GeV].
bool hasSP
Whether the hit has a SpacePoint.
float genT
Start time of gen point [mus – t=0 is spill time].
unsigned plane2nhit
Number of hits on plane 2 (Col.)
int G4ID
ID of the particle (taken from G4 – -1 if this particle is not propogated by G4)
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
Point_t const & End() const
float TotalHitEnergy(const detinfo::DetectorClocksData &clockData, const std::vector< art::Ptr< recob::Hit > > &hits)
Vector_t DirectionAtPoint(size_t i) const
TPCGeo const & TPC(unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified TPC.
float width
Width of fitted gaussian hit [ticks].
uint16_t wire
Wire number.
2D representation of charge deposited in the TDC/wire plane
art::ServiceHandle< art::TFileService > tfs
TPCID_t TPC
Index of the TPC within its cryostat.
Forward iterator browsing all geometry elements in the detector.
int16_t end
End tick of hit [ticks].
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
bool empty(FixedBins< T, C > const &) noexcept
Ionization energy from a Geant4 track.
raw::ChannelID_t Channel() const
ID of the readout channel the hit was extracted from.
int start_process
Start G4 process of the particle. Values defned as enum in StandardRecord.
bool oncalo
Whether the hit is on the track calorimetry.
const double * PlaneLocation(unsigned int p) const
bool ontraj
Whether the hit is on the track trajectory.
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
std::vector< short > adcs
List of ADC values.
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:
std::vector< sim::TrackIDE > ChannelToTrackIDEs(detinfo::DetectorClocksData const &clockData, raw::ChannelID_t channel, const double hit_start_time, const double hit_end_time) const
int parent
ID of parent particle.
float numElectrons
number of electrons at the readout for this track ID and time
TPC_iterator end_TPC() const
Returns an iterator pointing after the last TPC in the detector.
std::string sub(const std::string &a, const std::string &b)
caf::Wall_t GetWallCross(const geo::BoxBoundedGeo &volume, const TVector3 p0, const TVector3 p1)
Vector3D startp
Momentum at first point in the active TPC volume [GeV/c].