187 art::ServiceHandle<geo::Geometry const> geom;
188 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(
evt);
189 auto const det_prop =
190 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(
evt, clock_data);
192 size_t nplanes = geom->Nplanes();
195 std::unique_ptr< std::vector<anab::Calorimetry> > outputCalo(
new std::vector<anab::Calorimetry>);
196 std::unique_ptr< art::Assns<recob::Track, anab::Calorimetry> > outputCaloAssn(
new art::Assns<recob::Track, anab::Calorimetry>);
199 art::Handle< std::vector<recob::Track> > trackListHandle;
200 std::vector<art::Ptr<recob::Track> > tracklist;
202 art::fill_ptr_vector(tracklist, trackListHandle);
207 art::FindManyP<recob::Hit, recob::TrackHitMeta> fmHits(trackListHandle,
evt, hitLabel);
213 for (
unsigned trk_i = 0; trk_i < tracklist.size(); trk_i++) {
217 const std::vector<art::Ptr<recob::Hit>> &hits = fmHits.at(trk_i);
218 const std::vector<const recob::TrackHitMeta *> &thms = fmHits.data(trk_i);
222 const std::vector<art::Ptr<anab::T0>> &this_t0s = fmT0s.at(trk_i);
223 if (this_t0s.size()) T0 = this_t0s.at(0)->Time();
227 std::vector<std::vector<unsigned>> hit_indices =
OrganizeHits(hits, thms, track, nplanes);
229 for (
unsigned plane_i = 0; plane_i < nplanes; plane_i++) {
231 float kinetic_energy = 0.;
232 std::vector<float> dEdxs;
233 std::vector<float> dQdxs;
234 std::vector<float> resranges;
235 std::vector<float> deadwireresranges;
237 std::vector<float> pitches;
238 std::vector<geo::Point_t> xyzs;
239 std::vector<size_t> tp_indices;
243 plane.
Plane = plane_i;
248 std::vector<float> lengths;
249 for (
unsigned hit_i = 0; hit_i < hit_indices[plane_i].size(); hit_i++) {
250 unsigned hit_index = hit_indices[plane_i][hit_i];
256 double pitch =
GetPitch(track, hits[hit_index], thms[hit_index]);
259 double charge =
GetCharge(hits[hit_index]);
262 double EField =
GetEfield(det_prop, track, hits[hit_index], thms[hit_index]);
264 double dQdx = charge / pitch;
272 fCaloAlg.
dEdx_AMP(clock_data, det_prop, dQdx, hits[hit_index]->PeakTime(), hits[hit_index]->WireID().Plane,
T0, EField) : \
273 fCaloAlg.
dEdx_AREA(clock_data, det_prop, dQdx, hits[hit_index]->PeakTime(), hits[hit_index]->WireID().Plane,
T0, EField);
276 if (xyzs.size() == 0) {
277 lengths.push_back(0.);
280 lengths.push_back((location - xyzs.back()).
r());
284 dEdxs.push_back(dEdx);
285 dQdxs.push_back(dQdx);
286 pitches.push_back(pitch);
287 xyzs.push_back(location);
288 kinetic_energy += dEdx * pitch;
297 tp_indices.push_back(hits[hit_index].key());
304 if (lengths.size() > 1) {
305 range = std::accumulate(lengths.begin(), lengths.end(), 0.);
309 bool is_downstream = \
313 resranges.resize(lengths.size());
315 resranges[lengths.size() - 1] = lengths.back() / 2.;
316 for (
int i_len = lengths.size() - 2; i_len >= 0; i_len --) {
317 resranges[i_len] = resranges[i_len+1] + lengths[i_len+1];
321 resranges[0] = lengths[1] / 2.;
322 for (
unsigned i_len = 1; i_len < lengths.size(); i_len ++) {
323 resranges[i_len] = resranges[i_len-1] + lengths[i_len];
331 if (lengths.size() > 1) {
362 evt.put(std::move(outputCalo));
363 evt.put(std::move(outputCaloAssn));
fhicl::Atom< unsigned > Cryostat
const recob::TrackTrajectory & Trajectory() const
Access to the stored recob::TrackTrajectory.
Point_t const & LocationAtPoint(size_t i) const
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
CryostatID_t Cryostat
Index of cryostat.
process_name use argoneut_mc_hitfinder track
double Normalize(double dQdx, const art::Event &e, const recob::Hit &h, const geo::Point_t &location, const geo::Vector_t &direction, double t0)
fhicl::Atom< std::string > TrackModuleLabel
fhicl::Atom< std::string > T0ModuleLabel
double dEdx_AMP(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
double GetEfield(const detinfo::DetectorPropertiesData &dprop, const recob::Track &track, const art::Ptr< recob::Hit > hit, const recob::TrackHitMeta *meta)
PlaneID_t Plane
Index of the plane within its TPC.
float dEdx(detinfo::DetectorClocksData const &clockData, detinfo::DetectorPropertiesData const &detProp, const TCSlice &slc, TP3D &tp3d)
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.
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)
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)
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)
TPCID_t TPC
Index of the TPC within its cryostat.
fhicl::Atom< std::string > AssocHitModuleLabel
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
Point_t const & Start() const
Returns the position of the first valid point of the trajectory [cm].
Track from a non-cascading particle.A recob::Track consists of a recob::TrackTrajectory, plus additional members relevant for a "fitted" track:
process_name opdaq physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator physics producers generator T0