-
Notifications
You must be signed in to change notification settings - Fork 39
Feature/sungbino caf calo updates 2025 a #559
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from 6 commits
ba72c99
90cdf65
98b624d
aa5484c
5b70b40
455cb8d
b15f1f8
e70f014
2feb51f
c6a3c29
035418f
a6b090a
1e0a36f
46e144f
6df0c30
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change | ||||||
|---|---|---|---|---|---|---|---|---|
|
|
@@ -10,6 +10,10 @@ | |||||||
| #include "FillReco.h" | ||||||||
| #include "RecoUtils/RecoUtils.h" | ||||||||
|
|
||||||||
| #include "larevt/SpaceCharge/SpaceCharge.h" | ||||||||
| #include "larevt/SpaceChargeServices/SpaceChargeService.h" | ||||||||
| #include "larcore/CoreUtils/ServiceUtil.h" | ||||||||
|
|
||||||||
| namespace caf | ||||||||
| { | ||||||||
| const float ng_filter_cut = 0.5; | ||||||||
|
|
@@ -794,8 +798,28 @@ namespace caf | |||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
| // Helper function: get the e field | ||||||||
| double GetEfield(const detinfo::DetectorPropertiesData& dprop, const geo::Point_t loc) { | ||||||||
| auto const* sce = lar::providerFrom<spacecharge::SpaceChargeService>(); | ||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I am sorry, this is frustrating me and I am sure it will frustrate you too... somehow a comment on this function was not received by GitHub.
Suggested change
Notes:
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done! |
||||||||
|
|
||||||||
| double EField = dprop.Efield(); | ||||||||
| if (sce->EnableSimEfieldSCE()) { | ||||||||
| // Gets relative E field Distortions | ||||||||
| geo::Vector_t EFieldOffsets = sce->GetEfieldOffsets(loc); | ||||||||
| // Add 1 in X direction as this is the direction of the drift field | ||||||||
| EFieldOffsets = EFieldOffsets + geo::Vector_t{1, 0, 0}; | ||||||||
|
sungbinoh marked this conversation as resolved.
Outdated
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. It is not clear from
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thank you, added more words in the comments! |
||||||||
| // Convert to Absolute E Field from relative | ||||||||
| EFieldOffsets = EField * EFieldOffsets; | ||||||||
|
sungbinoh marked this conversation as resolved.
Outdated
|
||||||||
| // We only care about the magnitude for recombination | ||||||||
| EField = EFieldOffsets.r(); | ||||||||
| } | ||||||||
| return EField; | ||||||||
| } | ||||||||
|
|
||||||||
| void FillTrackPlaneCalo(const anab::Calorimetry &calo, | ||||||||
| const recob::Track& track, | ||||||||
| const std::vector<art::Ptr<recob::Hit>> &hits, | ||||||||
| const std::vector<const recob::TrackHitMeta*>& thms, | ||||||||
| bool fill_calo_points, float fillhit_rrstart, float fillhit_rrend, | ||||||||
| const detinfo::DetectorPropertiesData &dprop, | ||||||||
| caf::SRTrackCalo &srcalo) { | ||||||||
|
|
@@ -832,7 +856,8 @@ namespace caf | |||||||
|
|
||||||||
| // lookup the wire -- the Calorimery object makes this | ||||||||
| // __way__ harder than it should be | ||||||||
| for (const art::Ptr<recob::Hit> &h: hits) { | ||||||||
| for (unsigned i_hit = 0; i_hit < hits.size(); i_hit++) { | ||||||||
| const art::Ptr<recob::Hit> &h = hits[i_hit]; | ||||||||
| if (h.key() == tps[i]) { | ||||||||
| p.wire = h->WireID().Wire; | ||||||||
| p.tpc = h->WireID().TPC; | ||||||||
|
|
@@ -844,6 +869,21 @@ namespace caf | |||||||
| p.mult = h->Multiplicity(); | ||||||||
| p.start = h->StartTick(); | ||||||||
| p.end = h->EndTick(); | ||||||||
|
|
||||||||
|
|
||||||||
| // Get the trajectory point index from this hit. Again -- this is too hard. | ||||||||
| // | ||||||||
| // Use this to get the (SCE corrected) efield and the angle to the drift direction | ||||||||
| unsigned traj_point_index = thms.at(i_hit)->Index(); | ||||||||
| unsigned int int_max_as_unsigned_int{std::numeric_limits<int>::max()}; | ||||||||
| if (traj_point_index != int_max_as_unsigned_int && // invalid | ||||||||
| track.HasValidPoint(traj_point_index)) { | ||||||||
|
sungbinoh marked this conversation as resolved.
Outdated
|
||||||||
| float costh_drift = track.DirectionAtPoint(traj_point_index).X(); | ||||||||
| float phi = acos(abs(costh_drift)) * 180. / M_PI; | ||||||||
| float efield = GetEfield(dprop, track.LocationAtPoint(traj_point_index)); | ||||||||
| p.efield = efield; | ||||||||
| p.phi = phi; | ||||||||
|
sungbinoh marked this conversation as resolved.
Outdated
|
||||||||
| } | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
|
|
@@ -897,7 +937,9 @@ namespace caf | |||||||
| } | ||||||||
|
|
||||||||
| void FillTrackCalo(const std::vector<art::Ptr<anab::Calorimetry>> &calos, | ||||||||
| const recob::Track& track, | ||||||||
| const std::vector<art::Ptr<recob::Hit>> &hits, | ||||||||
| const std::vector<const recob::TrackHitMeta*>& thms, | ||||||||
| bool fill_calo_points, float fillhit_rrstart, float fillhit_rrend, | ||||||||
| const detinfo::DetectorPropertiesData &dprop, | ||||||||
| caf::SRTrack& srtrack, | ||||||||
|
|
@@ -912,7 +954,7 @@ namespace caf | |||||||
| if (calo.PlaneID()) { | ||||||||
| unsigned plane_id = calo.PlaneID().Plane; | ||||||||
| assert(plane_id < 3); | ||||||||
| FillTrackPlaneCalo(calo, hits, fill_calo_points, fillhit_rrstart, fillhit_rrend, dprop, srtrack.calo[plane_id]); | ||||||||
| FillTrackPlaneCalo(calo, track, hits, thms, fill_calo_points, fillhit_rrstart, fillhit_rrend, dprop, srtrack.calo[plane_id]); | ||||||||
| } | ||||||||
| } | ||||||||
|
|
||||||||
|
|
||||||||
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -40,6 +40,13 @@ namespace caf | |
| float totE; | ||
| }; | ||
|
|
||
| struct ParticleIDE { | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This class has not much to to with a particle. It has more to do with the TPC readout. Please consider a better name ("
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Agree! Updated the ParticleIDE to ReadoutIDE, I think that it is a good naming! |
||
| geo::WireID wire; | ||
| unsigned short tick; | ||
| const sim::IDE *ide; | ||
|
sungbinoh marked this conversation as resolved.
Outdated
sungbinoh marked this conversation as resolved.
Outdated
|
||
| }; | ||
|
|
||
|
|
||
| // Helpers | ||
| caf::Wall_t GetWallCross( const geo::BoxBoundedGeo &volume, | ||
| const TVector3 p0, | ||
|
|
@@ -73,7 +80,7 @@ namespace caf | |
| void FillTrueG4Particle(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<caf::ParticleIDE>> &id_to_ide_map, | ||
| const std::map<int, std::vector<art::Ptr<recob::Hit>>> &id_to_truehit_map, | ||
| const cheat::BackTrackerService &backtracker, | ||
| const cheat::ParticleInventoryService &inventory_service, | ||
|
|
@@ -103,7 +110,7 @@ namespace caf | |
| caf::SRTrack& srtrack, | ||
| bool allowEmpty = false); | ||
|
|
||
| void FillTrackCaloTruth(const std::map<int, std::vector<std::pair<geo::WireID, const sim::IDE*>>> &id_to_ide_map, | ||
| void FillTrackCaloTruth(const std::map<int, std::vector<ParticleIDE>> &id_to_ide_map, | ||
| const std::vector<simb::MCParticle> &mc_particles, | ||
| const geo::GeometryCore & geometry, | ||
| const geo::WireReadoutGeom& wireReadout, | ||
|
|
@@ -133,7 +140,7 @@ namespace caf | |
| CLHEP::HepRandomEngine &rand, | ||
| std::vector<caf::SRFakeReco> &srfakereco); | ||
|
|
||
| std::map<int, std::vector<std::pair<geo::WireID, const sim::IDE*>>> PrepSimChannels(const std::vector<art::Ptr<sim::SimChannel>> &simchannels, const geo::WireReadoutGeom &wireReadout); | ||
| std::map<int, std::vector<ParticleIDE>> PrepSimChannels(const std::vector<art::Ptr<sim::SimChannel>> &simchannels, const geo::WireReadoutGeom &wireReadout); | ||
| 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); | ||
| std::map<int, caf::HitsEnergy> SetupIDHitEnergyMap(const std::vector<art::Ptr<recob::Hit>> &allHits, const detinfo::DetectorClocksData &clockData, | ||
|
|
||
| Original file line number | Diff line number | Diff line change | ||||
|---|---|---|---|---|---|---|
|
|
@@ -64,6 +64,7 @@ | |||||
| #include "sbnobj/Common/CRT/CRTHitT0TaggingInfo.hh" | ||||||
| #include "sbnobj/Common/CRT/CRTHitT0TaggingTruthInfo.hh" | ||||||
|
|
||||||
| #include "sbncode/CAFMaker/FillTrue.h" | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This functionality should not depend on CAF making (see the general review comment). |
||||||
| #include "ITCSSelectionTool.h" | ||||||
|
|
||||||
| namespace sbn { | ||||||
|
|
@@ -161,7 +162,7 @@ class sbn::TrackCaloSkimmer : public art::EDAnalyzer { | |||||
| 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<caf::ParticleIDE>> id_to_ide_map, | ||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Object parameters should be passed by reference unless there are explicit reasons to do otherwise (
Suggested change
|
||||||
| const std::map<int, std::vector<art::Ptr<recob::Hit>>> id_to_truehit_map, | ||||||
| const detinfo::DetectorPropertiesData &dprop, | ||||||
| const geo::GeometryCore *geo, | ||||||
|
|
||||||
| Original file line number | Diff line number | Diff line change | ||||||||||||||||||||
|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|---|
|
|
@@ -289,7 +289,7 @@ void sbn::TrackCaloSkimmer::analyze(art::Event const& e) | |||||||||||||||||||||
| // Prep truth-to-reco-matching info | ||||||||||||||||||||||
| // | ||||||||||||||||||||||
| // Use helper functions from CAFMaker/FillTrue | ||||||||||||||||||||||
| std::map<int, std::vector<std::pair<geo::WireID, const sim::IDE*>>> id_to_ide_map; | ||||||||||||||||||||||
| std::map<int, std::vector<caf::ParticleIDE>> id_to_ide_map; | ||||||||||||||||||||||
| std::map<int, std::vector<art::Ptr<recob::Hit>>> id_to_truehit_map; | ||||||||||||||||||||||
| const cheat::BackTrackerService *bt = NULL; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
|
|
@@ -545,14 +545,14 @@ geo::Point_t WireToTrajectoryPosition(const geo::Point_t &loc, const geo::TPCID | |||||||||||||||||||||
| 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<caf::ParticleIDE>> &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, | ||||||||||||||||||||||
| const geo::WireReadoutGeom *wireReadout) { | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| std::vector<std::pair<geo::WireID, const sim::IDE *>> empty; | ||||||||||||||||||||||
| 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; | ||||||||||||||||||||||
| std::vector<caf::ParticleIDE> empty; | ||||||||||||||||||||||
| const std::vector<caf::ParticleIDE> &particle_ides = id_to_ide_map.count(particle.TrackId()) ? id_to_ide_map.at(particle.TrackId()) : empty; | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The current implementation performs the same query twice, and that would be better avoided. A way to avoid it, wrapped in a lambda function:
Suggested change
This is a suggestion.
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I think it's ok as is -- this would be a small optimization at the cost of readability. |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| std::vector<art::Ptr<recob::Hit>> emptyHits; | ||||||||||||||||||||||
| const std::vector<art::Ptr<recob::Hit>> &particle_hits = id_to_truehit_map.count(particle.TrackId()) ? id_to_truehit_map.at(particle.TrackId()) : emptyHits; | ||||||||||||||||||||||
|
|
@@ -569,9 +569,9 @@ sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, | |||||||||||||||||||||
| trueparticle.plane0nhit = 0; | ||||||||||||||||||||||
| trueparticle.plane1nhit = 0; | ||||||||||||||||||||||
| trueparticle.plane2nhit = 0; | ||||||||||||||||||||||
| for (auto const &ide_pair: particle_ides) { | ||||||||||||||||||||||
| const geo::WireID &w = ide_pair.first; | ||||||||||||||||||||||
| const sim::IDE *ide = ide_pair.second; | ||||||||||||||||||||||
| for (auto const &ide_p: particle_ides) { | ||||||||||||||||||||||
| const geo::WireID &w = ide_p.wire; | ||||||||||||||||||||||
| const sim::IDE *ide = ide_p.ide; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| if (w.Plane == 0) { | ||||||||||||||||||||||
| trueparticle.plane0VisE += ide->energy / 1000. /* MeV -> GeV*/; | ||||||||||||||||||||||
|
|
@@ -720,10 +720,11 @@ sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, | |||||||||||||||||||||
| // Organize deposition info into per-wire true "Hits" -- key is the Channel Number | ||||||||||||||||||||||
| std::map<unsigned, sbn::TrueHit> truehits; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| for (auto const &ide_pair: particle_ides) { | ||||||||||||||||||||||
| const geo::WireID &w = ide_pair.first; | ||||||||||||||||||||||
| for (auto const &ide_part: particle_ides) { | ||||||||||||||||||||||
| const geo::WireID &w = ide_part.wire; | ||||||||||||||||||||||
| unsigned c = wireReadout->PlaneWireToChannel(w); | ||||||||||||||||||||||
| const sim::IDE *ide = ide_pair.second; | ||||||||||||||||||||||
| const sim::IDE *ide = ide_part.ide; | ||||||||||||||||||||||
| unsigned short tick = ide_part.tick; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Set stuff | ||||||||||||||||||||||
| truehits[c].cryo = w.Cryostat; | ||||||||||||||||||||||
|
|
@@ -739,6 +740,8 @@ sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, | |||||||||||||||||||||
| truehits[c].p.y = (truehits[c].p.y*old_elec + ide->y*ide->numElectrons) / new_elec; | ||||||||||||||||||||||
| truehits[c].p.z = (truehits[c].p.z*old_elec + ide->z*ide->numElectrons) / new_elec; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| truehits[c].time = (truehits[c].time*old_elec + tick*ide->numElectrons) / new_elec; | ||||||||||||||||||||||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This way of processing leaves me puzzled. I think it originates in 12-year old code that was written that way while interfacing with GEANT4 steps (so, at the same time when the true hits were being created) so that the information would be always valid. But here, in a single loop, it's just a waste times the 6 lines it's used in (7 now).
Contributor
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This is written purposefully. The number of electrons can get quite large, so you get numerical stability issues if you do a weighted sum the naive way. (sum p_i * w_i / sum w_i). I'm not sure if you mean something else, but in any case I think this is ok as is.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I do mean that.
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. (I actually do have my answer, but it assumes the internal precision of the FPU stack/registers is larger than the output CPU registry, plus some compiler optimisation) |
||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Also get the position with space charge un-done | ||||||||||||||||||||||
| geo::Point_t ide_p(ide->x, ide->y, ide->z); | ||||||||||||||||||||||
| geo::Point_t ide_p_scecorr = WireToTrajectoryPosition(ide_p, w); | ||||||||||||||||||||||
|
|
@@ -754,10 +757,10 @@ sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, | |||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Compute widths | ||||||||||||||||||||||
| for (auto const &ide_pair: particle_ides) { | ||||||||||||||||||||||
| const geo::WireID &w = ide_pair.first; | ||||||||||||||||||||||
| for (auto const &ide_part: particle_ides) { | ||||||||||||||||||||||
| const geo::WireID &w = ide_part.wire; | ||||||||||||||||||||||
| unsigned c = wireReadout->PlaneWireToChannel(w); | ||||||||||||||||||||||
| const sim::IDE *ide = ide_pair.second; | ||||||||||||||||||||||
| const sim::IDE *ide = ide_part.ide; | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| geo::Point_t ide_p(ide->x, ide->y, ide->z); | ||||||||||||||||||||||
| geo::Point_t ide_p_scecorr = WireToTrajectoryPosition(ide_p, w); | ||||||||||||||||||||||
|
|
@@ -782,8 +785,6 @@ sbn::TrueParticle TrueParticleInfo(const simb::MCParticle &particle, | |||||||||||||||||||||
|
|
||||||||||||||||||||||
| // Compute the time of each hit | ||||||||||||||||||||||
| for (sbn::TrueHit &h: truehits_v) { | ||||||||||||||||||||||
| h.time = dprop.ConvertXToTicks(h.p.x, h.plane, h.tpc, h.cryo); | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
| double xdrift = abs(h.p.x - wireReadout->Plane(geo::PlaneID(h.cryo, h.tpc, 0)).GetCenter().X()); | ||||||||||||||||||||||
| h.tdrift = xdrift / dprop.DriftVelocity(); | ||||||||||||||||||||||
| } | ||||||||||||||||||||||
|
|
@@ -1010,7 +1011,7 @@ void sbn::TrackCaloSkimmer::FillTrackTruth(const detinfo::DetectorClocksData &cl | |||||||||||||||||||||
| 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<caf::ParticleIDE>> 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, | ||||||||||||||||||||||
|
|
||||||||||||||||||||||
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
These will not be needed after the change below.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Done! And moved
#include "larevt/SpaceCharge/SpaceCharge.h"intoFillReco.hfromFillReco.cxx.