161 auto const det_prop =
163 auto const*
sce = lar::providerFrom<spacecharge::SpaceChargeService>();
166 std::vector<art::Ptr<recob::Track>> tracklist;
174 lariov::ChannelStatusProvider
const& channelStatus =
177 size_t nplanes = geom->
Nplanes();
180 std::unique_ptr<std::vector<anab::Calorimetry>> calorimetrycol(
181 new std::vector<anab::Calorimetry>);
182 std::unique_ptr<art::Assns<recob::Track, anab::Calorimetry>> assn(
192 for (
size_t trkIter = 0; trkIter < tracklist.size(); ++trkIter) {
194 decltype(
auto) larEnd = tracklist[trkIter]->Trajectory().End();
200 uint32_t channel = 0;
201 unsigned int cstat = 0;
202 unsigned int tpc = 0;
203 unsigned int wire = 0;
204 unsigned int plane = 0;
209 if (fmt0.isValid()) {
210 std::vector<art::Ptr<anab::T0>> allT0 = fmt0.at(trkIter);
211 if (allT0.size()) T0 = allT0[0]->Time();
215 std::vector<std::vector<unsigned int>>
hits(nplanes);
218 for (
size_t ah = 0; ah < allHits.size(); ++ah) {
219 hits[allHits[ah]->WireID().Plane].push_back(ah);
222 for (
unsigned int ipl = 0; ipl < nplanes; ++ipl) {
239 float Trk_Length = 0.;
240 std::vector<float> vdEdx;
241 std::vector<float> vresRange;
242 std::vector<float> vdQdx;
243 std::vector<float> deadwire;
244 std::vector<TVector3> vXYZ;
250 <<
"Only one hit in plane " << ipl <<
" associated with track id " << trkIter;
266 unsigned int wire0 = 100000;
267 unsigned int wire1 = 0;
277 std::vector<double> spdelta;
279 std::vector<double> ChargeBeg;
280 std::stack<double> ChargeEnd;
283 double fTrkPitch = 0;
284 for (
size_t itp = 0; itp < tracklist[trkIter]->NumberTrajectoryPoints(); ++itp) {
286 const auto& pos = tracklist[trkIter]->LocationAtPoint(itp);
287 const auto&
dir = tracklist[trkIter]->DirectionAtPoint(itp);
299 if (
sce->EnableCalSpatialSCE() &&
fSCE) {
300 posOffsets =
sce->GetCalPosOffsets(pos, tpcid.
TPC);
301 dirOffsets =
sce->GetCalPosOffsets(pos + fTrkPitch *
dir, tpcid.
TPC);
303 TVector3 dir_corr = {fTrkPitch *
dir.X() - dirOffsets.X() + posOffsets.X(),
304 fTrkPitch *
dir.Y() + dirOffsets.Y() - posOffsets.Y(),
305 fTrkPitch *
dir.Z() + dirOffsets.Z() - posOffsets.Z()};
307 fTrkPitch = dir_corr.Mag();
311 <<
"caught exception " << e <<
"\n setting pitch (C) to " <<
util::kBogusD;
318 double xx = 0., yy = 0.,
zz = 0.;
321 std::vector<double> trkx;
322 std::vector<double> trky;
323 std::vector<double> trkz;
324 std::vector<double> trkw;
325 std::vector<double> trkx0;
326 for (
size_t i = 0; i <
hits[ipl].size(); ++i) {
328 std::vector<art::Ptr<recob::SpacePoint>> sptv = fmspts.at(
hits[ipl][i]);
329 for (
size_t j = 0; j < sptv.size(); ++j) {
331 double t = allHits[
hits[ipl][i]]->PeakTime() -
333 double x = det_prop.ConvertTicksToX(t,
337 double w = allHits[
hits[ipl][i]]->WireID().Wire;
339 trkx.push_back(sptv[j]->XYZ()[0] -
340 det_prop.ConvertTicksToX(TickT0,
341 allHits[
hits[ipl][i]]->WireID().Plane,
342 allHits[
hits[ipl][i]]->WireID().TPC,
343 allHits[
hits[ipl][i]]->WireID().Cryostat));
346 trkx.push_back(sptv[j]->XYZ()[0]);
348 trky.push_back(sptv[j]->XYZ()[1]);
349 trkz.push_back(sptv[j]->XYZ()[2]);
354 for (
size_t ihit = 0; ihit <
hits[ipl].size();
358 plane = allHits[
hits[ipl][ihit]]->WireID().Plane;
359 tpc = allHits[
hits[ipl][ihit]]->WireID().TPC;
360 cstat = allHits[
hits[ipl][ihit]]->WireID().Cryostat;
363 planeID.
Plane = plane;
367 wire = allHits[
hits[ipl][ihit]]->WireID().Wire;
368 time = allHits[
hits[ipl][ihit]]->PeakTime();
369 stime = allHits[
hits[ipl][ihit]]->PeakTimeMinusRMS();
370 etime = allHits[
hits[ipl][ihit]]->PeakTimePlusRMS();
371 const size_t& hitIndex = allHits[
hits[ipl][ihit]].key();
373 double charge = allHits[
hits[ipl][ihit]]->PeakAmplitude();
374 if (
fUseArea) charge = allHits[
hits[ipl][ihit]]->Integral();
379 bool fBadhit =
false;
380 if (fmthm.isValid()) {
381 auto vhit = fmthm.at(trkIter);
382 auto vmeta = fmthm.data(trkIter);
383 for (
size_t ii = 0; ii < vhit.size(); ++ii) {
384 if (vhit[ii].key() == allHits[
hits[ipl][ihit]].key()) {
385 if (vmeta[ii]->Index() == int_max_as_unsigned_int) {
389 if (vmeta[ii]->Index() >= tracklist[trkIter]->NumberTrajectoryPoints()) {
391 <<
"Requested track trajectory index " << vmeta[ii]->Index()
392 <<
" exceeds the total number of trajectory points " 393 << tracklist[trkIter]->NumberTrajectoryPoints() <<
" for track index " << trkIter
394 <<
". Something is wrong with the track reconstruction. Please contact " 397 if (!tracklist[trkIter]->HasValidPoint(vmeta[ii]->Index())) {
403 geo::Point_t const loc = tracklist[trkIter]->LocationAtPoint(vmeta[ii]->Index());
405 if (
sce->EnableCalSpatialSCE() &&
fSCE)
406 locOffsets =
sce->GetCalPosOffsets(loc, vhit[ii]->WireID().TPC);
407 xyz3d[0] = loc.X() - locOffsets.X();
408 xyz3d[1] = loc.Y() + locOffsets.Y();
409 xyz3d[2] = loc.Z() + locOffsets.Z();
413 0.5 * ::util::pi<>();
414 const geo::Vector_t&
dir = tracklist[trkIter]->DirectionAtPoint(vmeta[ii]->Index());
416 std::abs(std::sin(angleToVert) * dir.Y() + std::cos(angleToVert) * dir.Z());
417 if (cosgamma) { pitch = geom->
WirePitch(vhit[ii]->View()) / cosgamma; }
424 if (
sce->EnableCalSpatialSCE() &&
fSCE)
425 dirOffsets =
sce->GetCalPosOffsets(
geo::Point_t{loc.X() + pitch * dir.X(),
426 loc.Y() + pitch * dir.Y(),
427 loc.Z() + pitch * dir.Z()},
428 vhit[ii]->WireID().TPC);
429 const TVector3& dir_corr = {pitch * dir.X() - dirOffsets.X() + locOffsets.X(),
430 pitch * dir.Y() + dirOffsets.Y() - locOffsets.Y(),
431 pitch * dir.Z() + dirOffsets.Z() - locOffsets.Z()};
433 pitch = dir_corr.Mag();
441 allHits[
hits[ipl][ihit]],
451 if (fBadhit)
continue;
453 if (pitch <= 0) pitch = fTrkPitch;
454 if (!pitch)
continue;
460 spdelta.push_back(0);
463 double dx = xyz3d[0] -
xx;
464 double dy = xyz3d[1] - yy;
465 double dz = xyz3d[2] -
zz;
466 spdelta.push_back(sqrt(dx * dx + dy * dy + dz * dz));
467 Trk_Length += spdelta.back();
473 ChargeBeg.push_back(charge);
474 ChargeEnd.push(charge);
476 double MIPs = charge;
477 double dQdx = MIPs / pitch;
484 Kin_En = Kin_En + dEdx * pitch;
486 if (allHits[
hits[ipl][ihit]]->
WireID().Wire < wire0)
487 wire0 = allHits[
hits[ipl][ihit]]->WireID().Wire;
488 if (allHits[
hits[ipl][ihit]]->
WireID().Wire > wire1)
489 wire1 = allHits[
hits[ipl][ihit]]->WireID().Wire;
491 fMIPs.push_back(MIPs);
492 fdEdx.push_back(dEdx);
493 fdQdx.push_back(dQdx);
494 fwire.push_back(wire);
495 ftime.push_back(time);
499 TVector3 v(xyz3d[0], xyz3d[1], xyz3d[2]);
522 for (
int isp = 0; isp <
fnsps; ++isp) {
524 USChg += ChargeBeg[isp];
527 while (!ChargeEnd.empty()) {
528 if (countsp > 3)
break;
529 DSChg += ChargeEnd.top();
535 GoingDS = (DSChg > USChg);
540 TVector3 track_start(tracklist[trkIter]->Trajectory().
Vertex().
X(),
541 tracklist[trkIter]->Trajectory().
Vertex().
Y(),
542 tracklist[trkIter]->Trajectory().
Vertex().
Z());
543 TVector3 track_end(tracklist[trkIter]->Trajectory().End().
X(),
544 tracklist[trkIter]->Trajectory().End().
Y(),
545 tracklist[trkIter]->Trajectory().End().
Z());
547 if ((
fXYZ[0] - track_start).Mag() + (
fXYZ.back() - track_end).Mag() <
548 (
fXYZ[0] - track_end).Mag() + (
fXYZ.back() - track_start).Mag()) {
559 if (
fResRng.size() < 2 || spdelta.size() < 2) {
561 <<
"fResrng.size() = " <<
fResRng.size() <<
" spdelta.size() = " << spdelta.size();
564 fResRng[fnsps - 1] = spdelta[fnsps - 1] / 2;
565 for (
int isp = fnsps - 2; isp > -1; isp--) {
571 for (
int isp = 1; isp <
fnsps; isp++) {
576 MF_LOG_DEBUG(
"CaloPrtHit") <<
" pt wire time ResRng MIPs pitch dE/dx Ai X Y Z\n";
579 for (
int i = 0; i <
fnsps; ++i) {
580 vresRange.push_back(
fResRng[i]);
581 vdEdx.push_back(
fdEdx[i]);
582 vdQdx.push_back(
fdQdx[i]);
583 vXYZ.push_back(
fXYZ[i]);
584 if (i != 0 && i != fnsps - 1) {
592 << std::setw(4) << trkIter << std::setw(4) << ipl << std::setw(4) << i << std::setw(4)
594 << std::setiosflags(std::ios::fixed | std::ios::showpoint) << std::setprecision(2)
595 << std::setw(8) <<
fResRng[i] << std::setprecision(1) << std::setw(8) <<
fMIPs[i]
596 << std::setprecision(2) << std::setw(8) <<
fpitch[i] << std::setw(8) <<
fdEdx[i]
597 << std::setw(8) << Ai << std::setw(8) <<
fXYZ[i].x() << std::setw(8) <<
fXYZ[i].y()
598 << std::setw(8) <<
fXYZ[i].z() <<
"\n";
600 if (nPIDA > 0) { PIDA = PIDA / (double)nPIDA; }
604 MF_LOG_DEBUG(
"CaloPrtTrk") <<
"Plane # " << ipl <<
"TrkPitch= " << std::setprecision(2)
605 << fTrkPitch <<
" nhits= " << fnsps <<
"\n" 606 << std::setiosflags(std::ios::fixed | std::ios::showpoint)
607 <<
"Trk Length= " << std::setprecision(1) << Trk_Length <<
" cm," 608 <<
" KE calo= " << std::setprecision(1) << Kin_En <<
" MeV," 609 <<
" PIDA= " << PIDA <<
"\n";
612 for (
unsigned int iw = wire0; iw < wire1 + 1; ++iw) {
613 plane = allHits[
hits[ipl][0]]->WireID().Plane;
614 tpc = allHits[
hits[ipl][0]]->WireID().TPC;
615 cstat = allHits[
hits[ipl][0]]->WireID().Cryostat;
617 if (channelStatus.IsBad(channel)) {
618 MF_LOG_DEBUG(
"Calorimetry") <<
"Found dead wire at Plane = " << plane <<
" Wire =" << iw;
619 unsigned int closestwire = 0;
620 unsigned int endwire = 0;
621 unsigned int dwire = 100000;
622 double mindis = 100000;
623 double goodresrange = 0;
624 for (
size_t ihit = 0; ihit <
hits[ipl].size(); ++ihit) {
625 channel = allHits[
hits[ipl][ihit]]->Channel();
626 if (channelStatus.IsBad(channel))
continue;
628 std::vector<art::Ptr<recob::SpacePoint>> sppv = fmspts.at(
hits[ipl][ihit]);
629 if (sppv.size() < 1)
continue;
633 sppv[0]->XYZ()[0], sppv[0]->XYZ()[1], sppv[0]->XYZ()[2]};
634 double dis1 = (larEnd - xyz).Mag2();
635 if (dis1) dis1 = std::sqrt(dis1);
637 endwire = allHits[
hits[ipl][ihit]]->WireID().Wire;
641 closestwire = allHits[
hits[ipl][ihit]]->WireID().Wire;
648 deadwire.push_back(goodresrange + (
int(closestwire) -
int(iw)) * fTrkPitch);
651 deadwire.push_back(goodresrange + (
int(iw) -
int(closestwire)) * fTrkPitch);
671 evt.
put(std::move(calorimetrycol));
672 evt.
put(std::move(assn));
std::vector< double > fdEdx
std::optional< double > fNotOnTrackZcut
Reconstruction base classes.
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
The data type to uniquely identify a Plane.
bool isValid
Whether this ID points to a valid element.
constexpr auto abs(T v)
Returns the absolute value of the argument.
CryostatID_t Cryostat
Index of cryostat.
std::vector< TVector3 > fXYZ
std::vector< double > fResRng
PutHandle< PROD > put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
decltype(auto) constexpr size(T &&obj)
ADL-aware version of std::size.
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
PlaneGeo const & Plane(PlaneID const &planeid) const
Returns the specified wire.
double WireAngleToVertical(View_t view, TPCID const &tpcid) const
Returns the angle of the wires in the specified view from vertical.
View_t View() const
Which coordinate does this plane measure.
Ptr(H, T) -> Ptr< detail::not_map_vector_t< typename H::element_type >>
TPCID FindTPCAtPosition(Point_t const &point) const
Returns the ID of the TPC at specified location.
std::string fT0ModuleLabel
double dEdx_AMP(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
IDparameter< geo::WireID > WireID
Member type of validated geo::WireID parameter.
std::vector< size_t > fHitIndex
std::string fSpacePointModuleLabel
std::vector< double > ftime
std::vector< double > fetime
std::vector< Point_t > convertCollToPoint(std::vector< Point > const &coll)
The data type to uniquely identify a TPC.
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)
std::vector< double > fMIPs
void GetPitch(detinfo::DetectorPropertiesData const &det_prop, art::Ptr< recob::Hit > const &hit, std::vector< double > const &trkx, std::vector< double > const &trky, std::vector< double > const &trkz, std::vector< double > const &trkw, std::vector< double > const &trkx0, double *xyz3d, double &pitch, double TickT0)
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.
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
raw::ChannelID_t PlaneWireToChannel(WireID const &wireid) const
Returns the ID of the TPC channel connected to the specified wire.
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
constexpr auto absDiff(A const &a, B const &b)
Returns the absolute value of the difference between two values.
std::vector< double > fdQdx
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
tracking::Point_t Point_t
double TrackPitchInView(recob::Track const &track, geo::View_t view, size_t trajectory_point=0U)
Returns the projected length of track on a wire pitch step [cm].
double dEdx_AREA(detinfo::DetectorClocksData const &clock_data, detinfo::DetectorPropertiesData const &det_prop, recob::Hit const &hit, double pitch, double T0=0) const
std::string fTrackModuleLabel
unsigned int Nplanes(TPCID const &tpcid=tpc_zero) const
Returns the total number of planes in the specified TPC.
boost::graph_traits< ModuleGraph >::vertex_descriptor Vertex
constexpr double kBogusD
obviously bogus double value
std::vector< double > fstime
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
TPCID_t TPC
Index of the TPC within its cryostat.
std::vector< float > fpitch
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
recob::tracking::Plane Plane
Length_t WirePitch(PlaneID const &planeid=plane_zero) const
Returns the distance between two consecutive wires.
cet::coded_exception< error, detail::translate > exception