88 :
IShowerTool(pset.get<fhicl::ParameterSet>(
"BaseTools"))
89 , fCalorimetryAlg(pset.get<fhicl::ParameterSet>(
"CalorimetryAlg"))
90 , fMinAngleToWire(pset.get<float>(
"MinAngleToWire"))
91 , fShapingTime(pset.get<float>(
"ShapingTime"))
92 , fMinDistCutOff(pset.get<float>(
"MinDistCutOff"))
93 , fMaxDist(pset.get<float>(
"MaxDist"))
94 , fdEdxTrackLength(pset.get<float>(
"dEdxTrackLength"))
95 , fdEdxCut(pset.get<float>(
"dEdxCut"))
96 , fUseMedian(pset.get<bool>(
"UseMedian"))
97 , fCutStartPosition(pset.get<bool>(
"CutStartPosition"))
98 , fT0Correct(pset.get<bool>(
"T0Correct"))
99 , fSCECorrectPitch(pset.get<bool>(
"SCECorrectPitch"))
100 , fSCECorrectEField(pset.get<bool>(
"SCECorrectEField"))
101 , fSCEInputCorrected(pset.get<bool>(
"SCEInputCorrected"))
102 , fSumHitSnippets(pset.get<bool>(
"SumHitSnippets"))
103 , fPFParticleLabel(pset.get<
art::InputTag>(
"PFParticleLabel"))
104 , fVerbose(pset.get<int>(
"Verbose"))
105 , fShowerStartPositionInputLabel(pset.get<std::string>(
"ShowerStartPositionInputLabel"))
106 , fInitialTrackHitsInputLabel(pset.get<std::string>(
"InitialTrackHitsInputLabel"))
107 , fInitialTrackSpacePointsInputLabel(pset.get<std::string>(
"InitialTrackSpacePointsInputLabel"))
108 , fInitialTrackInputLabel(pset.get<std::string>(
"InitialTrackInputLabel"))
109 , fShowerdEdxOutputLabel(pset.get<std::string>(
"ShowerdEdxOutputLabel"))
110 , fShowerBestPlaneOutputLabel(pset.get<std::string>(
"ShowerBestPlaneOutputLabel"))
111 , fShowerdEdxVecOutputLabel(pset.get<std::string>(
"ShowerdEdxVecOutputLabel"))
114 throw cet::exception(
"ShowerTrajPointdEdx")
115 <<
"Can only correct for SCE if input is already corrected" << std::endl;
130 mf::LogError(
"ShowerTrajPointdEdx") <<
"Start position not set, returning " << std::endl;
135 mf::LogError(
"ShowerTrajPointdEdx")
136 <<
"Initial Track Spacepoints is not set returning" << std::endl;
140 if (
fVerbose) mf::LogError(
"ShowerTrajPointdEdx") <<
"Initial Track is not set" << std::endl;
145 std::vector<art::Ptr<recob::SpacePoint>> tracksps;
148 if (tracksps.empty()) {
150 mf::LogWarning(
"ShowerTrajPointdEdx") <<
"no spacepointsin the initial track" << std::endl;
155 auto const spHandle = Event.getValidHandle<std::vector<recob::SpacePoint>>(
fPFParticleLabel);
158 const art::FindManyP<recob::Hit>& fmsp =
162 geo::Point_t ShowerStartPosition = {-999, -999, -999};
164 geo::TPCID vtxTPC =
fGeom->FindTPCAtPosition(ShowerStartPosition);
167 recob::Track InitialTrack;
172 auto const pfpHandle = Event.getValidHandle<std::vector<recob::PFParticle>>(
fPFParticleLabel);
173 const art::FindManyP<anab::T0>& fmpfpt0 =
175 std::vector<art::Ptr<anab::T0>> pfpT0Vec = fmpfpt0.at(pfparticle.key());
176 if (pfpT0Vec.size() == 1) { pfpT0Time = pfpT0Vec.front()->Time(); }
180 std::map<int, std::vector<double>> dEdx_vec;
181 std::map<int, std::vector<double>> dEdx_vecErr;
182 std::map<int, int> num_hits;
184 for (
unsigned i = 0; i !=
fGeom->MaxPlanes(); ++i) {
190 auto const clockData =
191 art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(Event);
193 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(Event, clockData);
195 std::map<art::Ptr<recob::Hit>, std::vector<art::Ptr<recob::Hit>>> hitSnippets;
197 std::vector<art::Ptr<recob::Hit>> trackHits;
204 for (
auto const& sp : tracksps) {
207 std::vector<art::Ptr<recob::Hit>> hits = fmsp.at(sp.key());
210 mf::LogWarning(
"ShowerTrajPointdEdx")
211 <<
"no hit for the spacepoint. This suggest the find many is wrong." << std::endl;
214 const art::Ptr<recob::Hit> hit = hits[0];
218 double wirepitch =
fGeom->WirePitch((geo::PlaneID)hit->WireID());
221 geo::PlaneID planeid = hit->WireID();
222 geo::TPCID TPC = planeid.asTPCID();
223 if (TPC != vtxTPC) {
continue; }
226 auto const pos = sp->position();
227 double dist_from_start = (pos - ShowerStartPosition).R();
236 unsigned int index = 999;
237 double MinDist = 999;
238 for (
unsigned int traj = 0; traj < InitialTrack.NumberTrajectoryPoints(); ++traj) {
241 auto flags = InitialTrack.FlagsAtPoint(traj);
242 if (flags.isSet(recob::TrajectoryPointFlagTraits::NoPoint)) {
continue; }
244 geo::Point_t
const TrajPosition = InitialTrack.LocationAtPoint(traj);
246 auto const dist = (pos - TrajPosition).R();
248 if (dist < MinDist && dist <
MaxDist * wirepitch) {
255 if (index == 999) {
continue; }
257 geo::Point_t
const TrajPosition = InitialTrack.LocationAtPoint(index);
258 geo::Point_t
const TrajPositionStart = InitialTrack.LocationAtPoint(0);
261 if ((TrajPosition - TrajPositionStart).R() == 0) {
continue; }
262 if ((TrajPosition - ShowerStartPosition).R() == 0) {
continue; }
264 if ((TrajPosition - TrajPositionStart).R() <
fMinDistCutOff * wirepitch) {
continue; }
267 geo::Vector_t
const TrajDirection = InitialTrack.DirectionAtPoint(index);
272 geo::Vector_t
const TrajDirectionYZ{0, TrajDirection.Y(), TrajDirection.Z()};
273 auto const PlaneDirection =
fGeom->Plane(planeid).GetIncreasingWireDirection();
275 if (std::abs((TMath::Pi() / 2 - Angle(TrajDirectionYZ, PlaneDirection))) <
fMinAngleToWire) {
276 if (
fVerbose) mf::LogWarning(
"ShowerTrajPointdEdx") <<
"remove from angle cut" << std::endl;
281 double velocity = detProp.DriftVelocity(detProp.Efield(), detProp.Temperature());
282 double distance_in_x = TrajDirection.X() * (wirepitch / TrajDirection.Dot(PlaneDirection));
283 double time_taken = std::abs(distance_in_x / velocity);
287 if (
fVerbose) mf::LogWarning(
"ShowerTrajPointdEdx") <<
"move for shaping time" << std::endl;
291 if ((TrajPosition - TrajPositionStart).R() >
dEdxTrackLength) {
continue; }
294 ++num_hits[planeid.Plane];
297 double trackpitch = (TrajDirection * (wirepitch / TrajDirection.Dot(PlaneDirection))).R();
301 trackpitch, pos, TrajDirection.Unit(), hit->WireID().TPC);
305 double dQdx = hit->Integral();
307 for (
const art::Ptr<recob::Hit> secondaryHit : hitSnippets[hit])
308 dQdx += secondaryHit->Integral();
313 double localEField = detProp.Efield();
318 clockData, detProp, dQdx, hit->PeakTime(), planeid.Plane, pfpT0Time, localEField);
321 dEdx_vec[planeid.Plane].push_back(dEdx);
326 int best_plane = -std::numeric_limits<int>::max();
327 for (
auto const& [plane, numHits] : num_hits) {
328 if (
fVerbose > 2) std::cout <<
"Plane: " << plane <<
" with size: " << numHits << std::endl;
329 if (numHits > max_hits) {
335 if (best_plane < 0) {
337 mf::LogError(
"ShowerTrajPointdEdx") <<
"No hits in any plane, returning " << std::endl;
346 std::map<int, std::vector<double>> dEdx_vec_cut;
347 for (geo::PlaneID plane_id :
fGeom->Iterate<geo::PlaneID>()) {
348 dEdx_vec_cut[plane_id.Plane] = {};
351 for (
auto& dEdx_plane : dEdx_vec) {
352 FinddEdxLength(dEdx_plane.second, dEdx_vec_cut[dEdx_plane.first]);
356 std::vector<double> dEdx_val;
357 std::vector<double> dEdx_valErr;
358 for (
auto const& dEdx_plane : dEdx_vec_cut) {
360 if ((dEdx_plane.second).empty()) {
361 dEdx_val.push_back(-999);
362 dEdx_valErr.push_back(-999);
367 dEdx_val.push_back(TMath::Median((dEdx_plane.second).size(), &(dEdx_plane.second)[0]));
371 double dEdx_mean = 0;
372 for (
auto const& dEdx : dEdx_plane.second) {
373 if (dEdx > 10 || dEdx < 0) {
continue; }
376 dEdx_val.push_back(dEdx_mean / (
float)(dEdx_plane.second).size());
381 std::cout <<
"#Best Plane: " << best_plane << std::endl;
382 for (
unsigned int plane = 0; plane < dEdx_vec.size(); plane++) {
383 std::cout <<
"#Plane: " << plane <<
" #" << std::endl;
384 std::cout <<
"#Median: " << dEdx_val[plane] <<
" #" << std::endl;
386 for (
auto const& dEdx : dEdx_vec_cut[plane]) {
387 std::cout <<
"dEdx: " << dEdx << std::endl;
401 std::vector<double>& dEdx_val)
411 if (dEdx_vec.size() < 4) {
416 bool upperbound =
false;
419 int upperbound_int = 0;
420 if (dEdx_vec[0] >
fdEdxCut) { ++upperbound_int; }
421 if (dEdx_vec[1] >
fdEdxCut) { ++upperbound_int; }
422 if (dEdx_vec[2] >
fdEdxCut) { ++upperbound_int; }
423 if (upperbound_int > 1) { upperbound =
true; }
425 dEdx_val.push_back(dEdx_vec[0]);
426 dEdx_val.push_back(dEdx_vec[1]);
427 dEdx_val.push_back(dEdx_vec[2]);
429 for (
unsigned int dEdx_iter = 2; dEdx_iter < dEdx_vec.size(); ++dEdx_iter) {
435 double dEdx = dEdx_vec[dEdx_iter];
440 dEdx_val.push_back(dEdx);
441 if (
fVerbose > 1) std::cout <<
"Adding dEdx: " << dEdx << std::endl;
446 if (dEdx_iter < dEdx_vec.size() - 1) {
447 if (dEdx_vec[dEdx_iter + 1] >
fdEdxCut) {
449 std::cout <<
"Next dEdx hit is good removing hit" << dEdx << std::endl;
454 if (dEdx_iter < dEdx_vec.size() - 2) {
455 if (dEdx_vec[dEdx_iter + 2] >
fdEdxCut) {
457 std::cout <<
"Next Next dEdx hit is good removing hit" << dEdx << std::endl;
467 dEdx_val.push_back(dEdx);
468 if (
fVerbose > 1) std::cout <<
"Adding dEdx: " << dEdx << std::endl;
473 if (dEdx_iter < dEdx_vec.size() - 1) {
474 if (dEdx_vec[dEdx_iter + 1] >
fdEdxCut) {
476 std::cout <<
"Next dEdx hit is good removing hit " << dEdx << std::endl;
481 if (dEdx_iter < dEdx_vec.size() - 2) {
482 if (dEdx_vec[dEdx_iter + 2] >
fdEdxCut) {
484 std::cout <<
"Next Next dEdx hit is good removing hit " << dEdx << std::endl;