42 #include "canvas/Persistency/Common/FindManyP.h" 71 Name(
"TrackModuleLabel"),
72 Comment(
"Module label for track producer.")
76 Name(
"T0ModuleLabel"),
77 Comment(
"Module label for T0 time producer."),
82 Name(
"AssocHitModuleLabel"),
83 Comment(
"Module label for association between tracks and hits. If not set, defaults to TrackModuleLabel."),
89 Comment(
"Method used to extract charge from a hit. Options: 0==Amplitude(), 1==Integral(), 2==SummedADC(). See the ChargeMethod enum.")
93 Name(
"FieldDistortion"),
94 Comment(
"True if field distortion (i.e. from space charge) is included in the input.")
98 Name(
"FieldDistortionEfield"),
99 Comment(
"True if field distortion (i.e. from space charge) is included in the input.")
103 Name(
"TrackIsFieldDistortionCorrected"),
104 Comment(
"Whether the space-points on the input tracks have their points corrected for the field distortions. " 105 "I.e. whether the track trajectory points represent charge as seen by wires or the 3D particle trajectory.")
110 Comment(
"Which cryostat number the input tracks occupy.")
114 Name(
"FieldDistortionCorrectionXSign"),
115 Comment(
"Sign of the field distortion correction to be applied in the X direction. Positive by default."),
121 Comment(
"Configuration for the calo::CalorimetryAlg")
139 const std::vector<const recob::TrackHitMeta *> &thms,
142 const std::vector<const recob::TrackHitMeta *> &thms,
145 const std::vector<const recob::TrackHitMeta *> &thms,
165 produces< std::vector<anab::Calorimetry> >();
166 produces< art::Assns<recob::Track, anab::Calorimetry> >();
174 auto const det_prop =
177 size_t nplanes = geom->
Nplanes();
180 std::unique_ptr< std::vector<anab::Calorimetry> > outputCalo(
new std::vector<anab::Calorimetry>);
185 std::vector<art::Ptr<recob::Track> > tracklist;
192 art::FindManyP<recob::Hit, recob::TrackHitMeta> fmHits(trackListHandle, evt, hitLabel);
198 for (
unsigned trk_i = 0; trk_i < tracklist.size(); trk_i++) {
202 const std::vector<art::Ptr<recob::Hit>> &hits = fmHits.at(trk_i);
203 const std::vector<const recob::TrackHitMeta *> &thms = fmHits.data(trk_i);
207 const std::vector<art::Ptr<anab::T0>> &this_t0s = fmT0s.at(trk_i);
208 if (this_t0s.size()) T0 = this_t0s.at(0)->Time();
212 std::vector<std::vector<unsigned>> hit_indices =
OrganizeHits(hits, thms, track, nplanes);
214 for (
unsigned plane_i = 0; plane_i < nplanes; plane_i++) {
216 float kinetic_energy = 0.;
217 std::vector<float> dEdxs;
218 std::vector<float> dQdxs;
219 std::vector<float> resranges;
220 std::vector<float> deadwireresranges;
222 std::vector<float> pitches;
223 std::vector<geo::Point_t> xyzs;
224 std::vector<size_t> tp_indices;
228 plane.
Plane = plane_i;
233 std::vector<float> lengths;
234 for (
unsigned hit_i = 0; hit_i < hit_indices[plane_i].size(); hit_i++) {
235 unsigned hit_index = hit_indices[plane_i][hit_i];
241 double pitch =
GetPitch(track, hits[hit_index], thms[hit_index]);
244 double charge =
GetCharge(hits[hit_index]);
247 double EField =
GetEfield(det_prop, track, hits[hit_index], thms[hit_index]);
249 double dQdx = charge / pitch;
253 fCaloAlg.
dEdx_AMP(clock_data, det_prop, dQdx, hits[hit_index]->PeakTime(), hits[hit_index]->WireID().Plane, T0, EField) : \
254 fCaloAlg.
dEdx_AREA(clock_data, det_prop, dQdx, hits[hit_index]->PeakTime(), hits[hit_index]->WireID().Plane, T0, EField);
257 if (xyzs.size() == 0) {
258 lengths.push_back(0.);
261 lengths.push_back((location - xyzs.back()).
r());
265 dEdxs.push_back(dEdx);
266 dQdxs.push_back(dQdx);
267 pitches.push_back(pitch);
268 xyzs.push_back(location);
269 kinetic_energy += dEdx * pitch;
278 tp_indices.push_back(hits[hit_index].
key());
285 if (lengths.size() > 1) {
286 range = std::accumulate(lengths.begin(), lengths.end(), 0.);
290 bool is_downstream = \
294 resranges.resize(lengths.size());
296 resranges[lengths.size() - 1] = lengths.back() / 2.;
297 for (
int i_len = lengths.size() - 2; i_len >= 0; i_len --) {
298 resranges[i_len] = resranges[i_len+1] + lengths[i_len+1];
302 resranges[0] = lengths[1] / 2.;
303 for (
unsigned i_len = 1; i_len < lengths.size(); i_len ++) {
304 resranges[i_len] = resranges[i_len-1] + lengths[i_len];
312 if (lengths.size() > 1) {
337 util::CreateAssn(*
this, evt, *outputCalo, tracklist[trk_i], *outputCaloAssn);
351 const std::vector<const recob::TrackHitMeta *> &thms,
364 const std::vector<const recob::TrackHitMeta *> &thms,
366 std::vector<std::vector<unsigned>> ret(nplanes);
367 for (
unsigned i = 0; i < hits.size(); i++) {
369 ret[hits[i]->WireID().Plane].push_back(i);
377 const std::vector<const recob::TrackHitMeta *> &thms,
384 struct HitIdentifier {
399 inline bool operator==(
const HitIdentifier& rhs)
const {
400 return startTick == rhs.startTick && endTick == rhs.endTick && wire == rhs.wire;
404 inline bool operator>(
const HitIdentifier& rhs)
const {
405 return integral > rhs.integral;
409 std::vector<std::vector<unsigned>> ret(nplanes);
410 std::vector<std::vector<HitIdentifier>> hit_idents(nplanes);
411 for (
unsigned i = 0; i < hits.size(); i++) {
413 HitIdentifier this_ident(*hits[i]);
416 bool found_snippet =
false;
417 for (
unsigned j = 0; j < ret[hits[i]->WireID().Plane].size(); j++) {
418 if (this_ident == hit_idents[hits[i]->
WireID().Plane][j]) {
419 found_snippet =
true;
420 if (this_ident > hit_idents[hits[i]->
WireID().Plane][j]) {
421 ret[hits[i]->WireID().Plane][j] = i;
422 hit_idents[hits[i]->WireID().Plane][j] = this_ident;
427 if (!found_snippet) {
428 ret[hits[i]->WireID().Plane].push_back(i);
429 hit_idents[hits[i]->WireID().Plane].push_back(this_ident);
437 if (thm->
Index() == int_max_as_unsigned_int)
return false;
448 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
456 ret.SetY(ret.Y() + offset.Y());
457 ret.SetZ(ret.Z() + offset.Z());
470 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
477 int corr = geom->TPC(tpc.
TPC).DriftDir()[0];
482 ret.SetY(ret.Y() + offset.Y());
483 ret.SetZ(ret.Z() + offset.Z());
491 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
512 dir = (loc_pdx - loc_mdx) / (loc_mdx - loc_pdx).r();
520 double cosgamma =
std::abs(std::sin(angleToVert)*dir.Y() + std::cos(angleToVert)*dir.Z());
535 pitch = (locw_pdx_traj -
loc).
R();
555 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
557 double EField = dprop.
Efield();
564 EFieldOffsets = EField * EFieldOffsets;
566 EField = EFieldOffsets.r();
GnocchiCalorimetry(Parameters const &config)
Functions to help with numbers.
bool operator>(ScheduleID const left, ScheduleID const right) noexcept
fhicl::Atom< unsigned > Cryostat
void produce(art::Event &evt) override
geo::WireID WireID() const
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
fhicl::Atom< float > FieldDistortionCorrectionXSign
Point_t const & LocationAtPoint(size_t i) const
EDProducer(fhicl::ParameterSet const &pset)
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
ChannelGroupService::Name Name
bool HasValidPoint(size_t i) const
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.
bool HitIsValid(const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *thm, const recob::Track &track)
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
geo::Length_t WirePitch(geo::PlaneID const &planeid) const
Returns the distance between two consecutive wires.
std::vector< std::vector< unsigned > > OrganizeHitsSnippets(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
geo::Point_t GetLocationAtWires(const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
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
fhicl::Atom< std::string > T0ModuleLabel
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
double dEdx(float dqdx, float Efield)
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
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)
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
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)
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
static int max(int a, int b)
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.
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.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
fhicl::Table< calo::CalorimetryAlg::Config > CalorimetryAlgConfig
std::vector< std::vector< unsigned > > OrganizeHits(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)
Declaration of signal hit object.
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].
Provides recob::Track data product.
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
Interface for experiment-specific channel quality info provider.
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)
float SummedADC() const
The sum of calibrated ADC counts of the hit (0. by default)
fhicl::Atom< bool > FieldDistortionEfield
Vector_t DirectionAtPoint(size_t i) const
double GetCharge(const art::Ptr< recob::Hit > hit)
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.
Interface for experiment-specific service for channel quality info.
Collection of Physical constants used in LArSoft.
fhicl::Atom< std::string > AssocHitModuleLabel
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
Utility functions to extract information from recob::Track
double WireAngleToVertical(geo::View_t view, geo::TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
bool operator==(ModuleKeyAndType const &a, ModuleKeyAndType const &b) noexcept
std::vector< std::vector< unsigned > > OrganizeHitsIndividual(const std::vector< art::Ptr< recob::Hit >> &hits, const std::vector< const recob::TrackHitMeta * > &thms, const recob::Track &track, unsigned nplanes)