31 #include "larevt/CalibrationDBI/Interface/ChannelStatusProvider.h" 32 #include "larevt/CalibrationDBI/Interface/ChannelStatusService.h" 51 #include "cetlib/pow.h" 57 constexpr
unsigned int int_max_as_unsigned_int{std::numeric_limits<int>::max()};
58 typedef std::pair<unsigned, std::vector<unsigned>> OrganizedHits;
77 Comment(
"Module label for track producer.")};
80 Comment(
"Module label for T0 time producer."),
84 Name(
"PFPModuleLabel"),
85 Comment(
"Module label for PFP producer. To be used to associate T0 with tracks."),
89 Name(
"AssocHitModuleLabel"),
90 Comment(
"Module label for association between tracks and hits. If not set, defaults to " 96 Comment(
"Method used to extract charge from a hit. Options: 0==Amplitude(), 1==Integral(), " 97 "2==SummedADC(), 3==SummedIntegral(). See the ChargeMethod enum.")};
100 Name(
"FieldDistortion"),
101 Comment(
"True if field distortion (i.e. from space charge) is included in the input.")};
104 Name(
"FieldDistortionEfield"),
105 Comment(
"True if field distortion (i.e. from space charge) is included in the input.")};
108 Name(
"TrackIsFieldDistortionCorrected"),
109 Comment(
"Whether the space-points on the input tracks have their points corrected for the " 110 "field distortions. " 111 "I.e. whether the track trajectory points represent charge as seen by wires or the " 112 "3D particle trajectory.")};
115 Comment(
"Which cryostat number the input tracks occupy.")};
118 Name(
"FieldDistortionCorrectionXSign"),
119 Comment(
"Sign of the field distortion correction to be applied in the X direction. " 120 "Positive by default."),
125 Comment(
"Configuration for the calo::CalorimetryAlg")};
129 Comment(
"List of INormalizeCharge tool configurations to use.")};
146 const std::vector<const recob::TrackHitMeta*>& thms,
151 const std::vector<const recob::TrackHitMeta*>& thms,
156 const std::vector<const recob::TrackHitMeta*>& thms,
172 const std::vector<recob::Hit const*>& sharedHits);
190 produces<std::vector<anab::Calorimetry>>();
191 produces<art::Assns<recob::Track, anab::Calorimetry>>();
192 std::vector<fhicl::ParameterSet> norm_tool_configs =
195 fNormTools.push_back(art::make_tool<INormalizeCharge>(p));
204 auto const det_prop =
207 size_t nplanes = geom->
Nplanes();
210 std::unique_ptr<std::vector<anab::Calorimetry>> outputCalo(
new std::vector<anab::Calorimetry>);
211 std::unique_ptr<art::Assns<recob::Track, anab::Calorimetry>> outputCaloAssn(
216 std::vector<art::Ptr<recob::Track>> tracklist;
230 std::vector<art::Ptr<recob::PFParticle>> pfpList;
232 for (std::size_t itrk = 0, sz = fmPFPs.size(); itrk < sz; ++itrk) {
234 pfpList.push_back(fmPFPs.at(itrk).at(0));
243 for (
unsigned trk_i = 0; trk_i < tracklist.size(); trk_i++) {
247 const std::vector<art::Ptr<recob::Hit>>&
hits = fmHits.at(trk_i);
248 const std::vector<const recob::TrackHitMeta*>& thms = fmHits.
data(trk_i);
253 const std::vector<art::Ptr<anab::T0>>& this_t0s = fmPFPT0s.at(trk_i);
254 if (this_t0s.size()) T0 = this_t0s.at(0)->Time();
257 const std::vector<art::Ptr<anab::T0>>& this_t0s = fmT0s.at(trk_i);
258 if (this_t0s.size()) T0 = this_t0s.at(0)->Time();
263 std::vector<std::vector<OrganizedHits>> hit_indices =
OrganizeHits(hits, thms, track, nplanes);
265 for (
unsigned plane_i = 0; plane_i < nplanes; plane_i++) {
267 float kinetic_energy = 0.;
268 std::vector<float> dEdxs;
269 std::vector<float> dQdxs;
270 std::vector<float> resranges;
271 std::vector<float> deadwireresranges;
273 std::vector<float> pitches;
274 std::vector<geo::Point_t> xyzs;
275 std::vector<size_t> tp_indices;
279 plane.
Plane = plane_i;
284 std::vector<float> lengths;
285 for (
unsigned hit_i = 0; hit_i < hit_indices[plane_i].size(); hit_i++) {
286 unsigned hit_index = hit_indices[plane_i][hit_i].first;
288 std::vector<recob::Hit const*> sharedHits = {};
289 sharedHits.reserve(hit_indices[plane_i][hit_i].
second.size());
290 for (
const unsigned shared_hit_index : hit_indices[plane_i][hit_i].
second)
291 sharedHits.push_back(hits[shared_hit_index].
get());
297 double pitch =
GetPitch(track, hits[hit_index], thms[hit_index]);
300 double charge =
GetCharge(hits[hit_index], sharedHits);
303 double EField =
GetEfield(det_prop, track, hits[hit_index], thms[hit_index]);
307 double phi = acos(
abs(direction.x())) * 180 / M_PI;
309 double dQdx = charge / pitch;
324 hits[hit_index]->PeakTime(),
325 hits[hit_index]->WireID().Plane,
332 hits[hit_index]->PeakTime(),
333 hits[hit_index]->WireID().Plane,
339 if (xyzs.size() == 0) { lengths.push_back(0.); }
341 lengths.push_back((location - xyzs.back()).
r());
345 dEdxs.push_back(dEdx);
346 dQdxs.push_back(dQdx);
347 pitches.push_back(pitch);
348 xyzs.push_back(location);
349 kinetic_energy += dEdx * pitch;
358 tp_indices.push_back(hits[hit_index].key());
363 if (lengths.size() > 1) {
364 range = std::accumulate(lengths.begin(), lengths.end(), 0.);
373 resranges.resize(lengths.size());
375 resranges[lengths.size() - 1] = lengths.back() / 2.;
376 for (
int i_len = lengths.size() - 2; i_len >= 0; i_len--) {
377 resranges[i_len] = resranges[i_len + 1] + lengths[i_len + 1];
381 resranges[0] = lengths[1] / 2.;
382 for (
unsigned i_len = 1; i_len < lengths.size(); i_len++) {
383 resranges[i_len] = resranges[i_len - 1] + lengths[i_len];
391 if (lengths.size() > 1) {
404 outputCalo->push_back(
414 evt.
put(std::move(outputCalo));
415 evt.
put(std::move(outputCaloAssn));
422 const std::vector<const recob::TrackHitMeta*>& thms,
439 const std::vector<const recob::TrackHitMeta*>& thms,
443 std::vector<std::vector<OrganizedHits>> ret(nplanes);
444 for (
unsigned i = 0; i <
hits.size(); i++) {
445 if (
HitIsValid(thms[i], track)) { ret[
hits[i]->WireID().Plane].push_back({i, {}}); }
453 const std::vector<const recob::TrackHitMeta*>& thms,
462 struct HitIdentifier {
477 inline bool operator==(
const HitIdentifier& rhs)
const 479 return startTick == rhs.startTick && endTick == rhs.endTick && wire == rhs.wire;
483 inline bool operator>(
const HitIdentifier& rhs)
const {
return integral > rhs.integral; }
486 std::vector<std::vector<OrganizedHits>> ret(nplanes);
487 std::vector<std::vector<HitIdentifier>> hit_idents(nplanes);
488 for (
unsigned i = 0; i <
hits.size(); i++) {
490 HitIdentifier this_ident(*
hits[i]);
493 bool found_snippet =
false;
494 auto const plane =
hits[i]->WireID().Plane;
495 for (
unsigned j = 0; j < ret[plane].size(); j++) {
496 if (this_ident == hit_idents[plane][j]) {
497 found_snippet =
true;
498 if (this_ident > hit_idents[plane][j]) {
499 ret[plane][j].second.push_back(ret[plane][j].first);
500 ret[plane][j].first = i;
501 hit_idents[plane][j] = this_ident;
504 ret[plane][j].second.push_back(i);
509 if (!found_snippet) {
510 ret[plane].push_back({i, {}});
511 hit_idents[plane].push_back(this_ident);
520 if (thm->
Index() == int_max_as_unsigned_int)
return false;
536 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
544 ret.SetY(ret.Y() + offset.Y());
545 ret.SetZ(ret.Z() + offset.Z());
563 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
575 ret.SetY(ret.Y() + offset.Y());
576 ret.SetZ(ret.Z() + offset.Z());
587 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
610 dir = (loc_pdx - loc_mdx) / (loc_mdx - loc_pdx).r();
618 double cosgamma =
std::abs(std::sin(angleToVert) * dir.Y() + std::cos(angleToVert) * dir.Z());
620 if (cosgamma) { pitch = geom->
WirePitch(hit->
View()) / cosgamma; }
631 pitch = (locw_pdx_traj - loc).R();
637 const std::vector<recob::Hit const*>& sharedHits)
644 return std::accumulate(
648 [](
double sum,
recob::Hit const* sharedHit) {
return sum + sharedHit->Integral(); });
663 ret = nt->Normalize(ret, e, h, location, direction, t0);
674 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
676 double EField = dprop.
Efield();
683 EFieldOffsets = EField * EFieldOffsets;
685 EField = EFieldOffsets.r();
code to link reconstructed objects back to the MC truth information
std::vector< std::vector< OrganizedHits > > OrganizeHitsIndividual(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
GnocchiCalorimetry(Parameters const &config)
Functions to help with numbers.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
fhicl::Atom< unsigned > Cryostat
void produce(art::Event &evt) override
constexpr bool operator>(Interval< Q, Cat > const a, Quantity< Args... > const b) noexcept
double GetCharge(const art::Ptr< recob::Hit > hit, const std::vector< recob::Hit const * > &sharedHits)
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Declaration of signal hit object.
fhicl::DelegatedParameter NormTools
fhicl::Atom< float > FieldDistortionCorrectionXSign
Point_t const & LocationAtPoint(size_t i) const
Access to track position at different points.
EDProducer(fhicl::ParameterSet const &pset)
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
bool HasValidPoint(size_t i) const
Various functions related to the presence and the number of (valid) points.
constexpr auto abs(T v)
Returns the absolute value of the argument.
CryostatID_t Cryostat
Index of cryostat.
float Integral() const
Integral under the calibrated signal waveform of the hit, in tick x ADC units.
geo::View_t View() const
View for the plane of the hit.
WireID_t Wire
Index of the wire within its plane.
geo::WireID const & WireID() const
Initial tdc tick for hit.
data_const_reference data(size_type i) const
double Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0)
geo::Point_t GetLocationAtWires(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
Provides recob::Track data product.
float PeakAmplitude() const
The estimated amplitude of the hit at its peak, in ADC units.
double Efield(unsigned int planegap=0) const
kV/cm
fhicl::Atom< std::string > TrackModuleLabel
TPCGeo const & TPC(TPCID const &tpcid=tpc_zero) const
Returns the specified TPC.
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
fhicl::Atom< std::string > T0ModuleLabel
double WireAngleToVertical(View_t view, TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
double dEdx_AMP(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
#define DEFINE_ART_MODULE(klass)
std::vector< std::vector< OrganizedHits > > OrganizeHitsSnippets(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
std::vector< std::unique_ptr< INormalizeCharge > > fNormTools
double GetEfield(const detinfo::DetectorPropertiesData &dprop, const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
fhicl::Atom< bool > FieldDistortion
geo::Point_t WireToTrajectoryPosition(const geo::Point_t &loc, const geo::TPCID &tpc)
constexpr PlaneID const & asPlaneID() const
Conversion to PlaneID (for convenience of notation).
The data type to uniquely identify a TPC.
PlaneID_t Plane
Index of the plane within its TPC.
raw::TDCtick_t StartTick() const
Initial tdc tick for hit.
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
fhicl::Atom< bool > TrackIsFieldDistortionCorrected
Detector simulation of raw signals on wires.
Encapsulate the geometry of a wire.
raw::TDCtick_t EndTick() const
Final tdc tick for hit.
fhicl::Table< calo::CalorimetryAlg::Config > CalorimetryAlgConfig
bool CreateAssn(art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t index=UINT_MAX)
Creates a single one-to-one association.
float ROISummedADC() const
The sum of calibrated ADC counts of the ROI (0. by default)
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Utility object to perform functions of association.
Encapsulate the construction of a single detector plane.
Point_t const & End() const
Returns the position of the last valid point of the trajectory [cm].
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
double GetPitch(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
geo::Point_t TrajectoryToWirePosition(const geo::Point_t &loc, const geo::TPCID &tpc)
fhicl::Atom< std::string > PFPModuleLabel
fhicl::Atom< bool > FieldDistortionEfield
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
Vector_t DirectionAtPoint(size_t i) const
Access to track direction at different points.
constexpr double kBogusD
obviously bogus double value
geo::Point_t GetLocation(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
2D representation of charge deposited in the TDC/wire plane
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
TPCID_t TPC
Index of the TPC within its cryostat.
Collection of Physical constants used in LArSoft.
second_as<> second
Type of time stored in seconds, in double precision.
fhicl::Atom< std::string > AssocHitModuleLabel
Vector_t DriftDir() const
Returns the direction of the drift (vector pointing toward the planes).
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
bool HitIsValid(const recob::TrackHitMeta *thm, const recob::Track &track)
Utility functions to extract information from recob::Track
bool operator==(infinite_endcount_iterator< T > const &, count_iterator< T > const &)
std::vector< std::vector< OrganizedHits > > OrganizeHits(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
Length_t WirePitch(PlaneID const &planeid=plane_zero) const
Returns the distance between two consecutive wires.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
This is an interface for an art Tool which scales charge by some factor given information about its a...