16 #include "messagefacility/MessageLogger/MessageLogger.h"
29 mf::LogInfo(
"pma::PMAlgCosmicTagger")
30 <<
"Passed " << tracks.
size() <<
" tracks for tagging cosmics.";
42 mf::LogInfo(
"pma::PMAlgCosmicTagger") <<
"...tagged " << n <<
" cosmic-like tracks.";
48 mf::LogInfo(
"pma::PMAlgCosmicTagger") <<
" - tag tracks out of 1 drift window;";
51 auto const* geom = lar::providerFrom<geo::Geometry>();
53 for (
auto& t : tracks.
tracks()) {
58 bool node_out_of_drift_min =
false;
59 bool node_out_of_drift_max =
false;
60 for (
size_t nidx = 0; nidx < trk.
Nodes().size(); ++nidx) {
61 auto const& node = *(trk.
Nodes()[nidx]);
62 auto const& tpcGeo = geom->TPC(node.TPC(), node.Cryo());
64 int driftDir =
abs(tpcGeo.DetectDriftDirection());
65 p = node.Point3D()[driftDir - 1];
80 throw cet::exception(
"PMAlgCosmicTagger")
81 <<
"Drift direction unknown: " << driftDir << std::endl;
83 if (p < min - fOutOfDriftMargin) { node_out_of_drift_min =
true; }
84 if (p > max + fOutOfDriftMargin) { node_out_of_drift_max =
true; }
87 if (node_out_of_drift_min && node_out_of_drift_max) {
92 else if (node_out_of_drift_min || node_out_of_drift_max) {
99 mf::LogInfo(
"pma::PMAlgCosmicTagger") <<
" - Tagged " << n <<
" tracks out of 1 drift window.";
113 for (
auto& t : tracks.
tracks()) {
116 if (t.Track()->GetT0() != 0.0) {
117 mf::LogInfo(
"pma::PMAlgCosmicTagger") <<
" - track with T0 = " << t.Track()->GetT0();
119 if (fabs(t.Track()->GetT0() -
trigger_offset(clockData)) > fNonBeamT0Margin) {
127 mf::LogInfo(
"pma::PMAlgCosmicTagger") <<
" - Tagged " << n <<
" non-beam T0 tracks.";
137 auto const* geom = lar::providerFrom<geo::Geometry>();
139 short int hIdx = ConvertDirToInt(geom->TPC(0, 0).HeightDir());
140 short int lIdx = ConvertDirToInt(geom->TPC(0, 0).LengthDir());
143 for (
auto& t : tracks.
tracks()) {
146 auto const& node0 = *(t.Track()->Nodes()[0]);
147 auto const& node1 = *(t.Track()->Nodes()[t.Track()->Nodes().size() - 1]);
151 (node0.Point3D()[hIdx] > node1.Point3D()[hIdx]) ? node0.Point3D() : node1.Point3D();
153 (node0.Point3D()[hIdx] <= node1.Point3D()[hIdx]) ? node0.Point3D() : node1.Point3D();
156 bool top = isTopVertex(vtx, fTopFrontBackMargin, hIdx);
159 bool frontBack = isFrontBackVertex(end, fTopFrontBackMargin, lIdx);
162 if (top && frontBack) {
169 mf::LogInfo(
"pma::PMAlgCosmicTagger")
170 <<
" - Tagged " << n <<
" tracks crossing from top to front/back." << std::endl;
184 auto const* geom = lar::providerFrom<geo::Geometry>();
186 short int hIdx = ConvertDirToInt(geom->TPC(0, 0).HeightDir());
189 for (
auto& t : tracks.
tracks()) {
192 auto const& node0 = *(t.Track()->Nodes()[0]);
193 auto const& node1 = *(t.Track()->Nodes()[t.Track()->Nodes().size() - 1]);
197 (node0.Point3D()[hIdx] > node1.Point3D()[hIdx]) ? node0.Point3D() : node1.Point3D();
199 (node0.Point3D()[hIdx] <= node1.Point3D()[hIdx]) ? node0.Point3D() : node1.Point3D();
201 if (fabs(vtx[hIdx] - fDimensionsMax[hIdx]) < fApparentStopperMargin) {
203 if (fabs(end[hIdx] - fDimensionsMin[hIdx]) > 5. * fApparentStopperMargin) {
206 bool foundTrack =
false;
207 for (
auto const& tt : tracks.
tracks()) {
209 if ((&tt) == (&t))
continue;
212 TVector3 trkVtx = (tt.Track()->Nodes()[0])->
Point3D();
213 TVector3 trkEnd = (tt.Track()->Nodes()[tt.Track()->Nodes().size() - 1])->
Point3D();
215 if ((end - trkVtx).Mag() < fStopperBuffer || (end - trkEnd).Mag() < fStopperBuffer) {
226 if (!fVetoActualStopper) {
235 std::vector<float> nSigmaPerView;
238 for (
auto const view : geom->Views()) {
241 std::map<size_t, std::vector<double>> dedx;
242 t.Track()->GetRawdEdxSequence(dedx, view);
244 std::vector<double> trk_dedx;
246 for (
int h = t.Track()->NextHit(-1, view);
h != -1;
h = t.Track()->NextHit(
h, view)) {
248 if (
h > t.Track()->PrevHit(t.Track()->size(), view))
break;
250 if (dedx[
h][5] / dedx[
h][6] <= 0 || dedx[
h][5] / dedx[
h][6] > 1e6)
continue;
251 trk_dedx.push_back(dedx[
h][5] / dedx[
h][6]);
254 if (trk_dedx.size() == 0) {
255 mf::LogInfo(
"pma::PMAlgCosmicTagger")
256 <<
"View " << view <<
" has no hits." << std::endl;
261 double mean = sum /
static_cast<double>(trk_dedx.size());
264 accum += (d -
mean) * (d - mean);
266 double stdev = sqrt(accum / static_cast<double>(trk_dedx.size() - 1));
268 mf::LogInfo(
"pma::PMAlgCosmicTagger")
269 <<
" View " << view <<
" has average dedx " << mean <<
" +/- " << stdev
270 <<
" and final dedx " << trk_dedx[trk_dedx.size() - 1] << std::endl;
272 nSigmaPerView.push_back(fabs((trk_dedx[trk_dedx.size() - 1] -
mean) / stdev));
275 bool notStopper =
true;
276 short unsigned int n2Sigma = 0;
277 short unsigned int n3Sigma = 0;
278 for (
auto const nSigma : nSigmaPerView) {
279 if (nSigma >= 2.0) ++n2Sigma;
280 if (nSigma >= 3.0) ++n3Sigma;
283 if (n3Sigma > 0) notStopper =
false;
284 if (n2Sigma == nSigmaPerView.size()) notStopper =
false;
295 mf::LogInfo(
"pma::PMAlgCosmicTagger")
296 <<
" - Tagged " << n <<
" tracks stopping in the detector after starting at the top."
307 auto const* geom = lar::providerFrom<geo::Geometry>();
308 TVector3
dir = geom->TPC(0, 0).HeightDir();
310 size_t n = fullCrossingTagger(tracks, ConvertDirToInt(dir));
312 mf::LogInfo(
"pma::PMAlgCosmicTagger")
313 <<
" - Tagged " << n <<
" tracks crossing the full detector height";
322 auto const* geom = lar::providerFrom<geo::Geometry>();
323 TVector3
dir = geom->TPC(0, 0).WidthDir();
325 size_t n = fullCrossingTagger(tracks, ConvertDirToInt(dir));
327 mf::LogInfo(
"pma::PMAlgCosmicTagger")
328 <<
" - Tagged " << n <<
" tracks crossing the full detector width";
337 auto const* geom = lar::providerFrom<geo::Geometry>();
338 TVector3
dir = geom->TPC(0, 0).LengthDir();
340 size_t n = fullCrossingTagger(tracks, ConvertDirToInt(dir));
342 mf::LogInfo(
"pma::PMAlgCosmicTagger")
343 <<
" - Tagged " << n <<
" tracks crossing the full detector length";
351 if (direction == -1) {
352 mf::LogWarning(
"pma::PMAlgCosmicTagger")
353 <<
" - Could not recognise direction, not attempting to perform fullCrossingTagger.";
359 double detDim = fDimensionsMax[direction] - fDimensionsMin[direction];
370 for (
auto& t : tracks.
tracks()) {
373 auto const& node0 = *(t.Track()->Nodes()[0]);
374 auto const& node1 = *(t.Track()->Nodes()[t.Track()->Nodes().size() - 1]);
377 double trkDim = fabs(node0.Point3D()[direction] - node1.Point3D()[direction]);
379 if ((detDim - trkDim) < fFullCrossingMargin) {
382 t.Track()->SetTagFlag(dirTag);
383 mf::LogInfo(
"pma::PMAlgCosmicTagger") <<
" -- track tagged in direction " << direction
384 <<
" with " << trkDim <<
" (c.f. " << detDim <<
")";
395 return (fabs(pos[dirIndx] - fDimensionsMax[dirIndx]) < tolerance);
401 short int dirIndx)
const
404 bool front = (fabs(pos[dirIndx] - fDimensionsMin[dirIndx]) <
tolerance);
405 bool back = (fabs(pos[dirIndx] - fDimensionsMax[dirIndx]) <
tolerance);
407 return front || back;
422 auto const* geom = lar::providerFrom<geo::Geometry>();
425 for (
geo::TPCID const& tID : geom->IterateTPCIDs()) {
435 double center[3] = {0.};
439 if (center[0] - tpcDim[0] < minX) minX = center[0] - tpcDim[0];
440 if (center[0] + tpcDim[0] > maxX) maxX = center[0] + tpcDim[0];
441 if (center[1] - tpcDim[1] < minY) minY = center[1] - tpcDim[1];
442 if (center[1] + tpcDim[1] > maxY) maxY = center[1] + tpcDim[1];
443 if (center[2] - tpcDim[2] < minZ) minZ = center[2] - tpcDim[2];
444 if (center[2] + tpcDim[2] > maxZ) maxZ = center[2] + tpcDim[2];
447 fDimensionsMin.clear();
448 fDimensionsMax.clear();
449 fDimensionsMin.push_back(minX);
450 fDimensionsMin.push_back(minY);
451 fDimensionsMin.push_back(minZ);
452 fDimensionsMax.push_back(maxX);
453 fDimensionsMax.push_back(maxY);
454 fDimensionsMax.push_back(maxZ);
461 if (dir.X() > 0.99)
return 0;
462 if (dir.Y() > 0.99)
return 1;
size_t fullWidthCrossing(pma::TrkCandidateColl &tracks) const
Utilities related to art service access.
bool fTagOutOfDriftTracks
ClusterModuleLabel join with tracks
void SetTagFlag(ETag value)
Implementation of the Projection Matching Algorithm.
::fhicl::TupleAs< Point(::geo::Length_t,::geo::Length_t,::geo::Length_t)> Point3D
Atom object for reading a 3D point or vector (centimeters).
Geometry information for a single TPC.
bool fTagFullLengthTracks
std::vector< pma::Node3D * > const & Nodes() const noexcept
Implementation of the Projection Matching Algorithm.
double Length() const
Length is associated with z coordinate [cm].
size_t tagApparentStopper(pma::TrkCandidateColl &tracks) const
Access the description of detector geometry.
size_t outOfDriftWindow(pma::TrkCandidateColl &tracks) const
bool isFrontBackVertex(const TVector3 &pos, double tolerance, short int dirIndx) const
bool fTagFullHeightTracks
size_t nonBeamT0Tag(detinfo::DetectorClocksData const &clockData, pma::TrkCandidateColl &tracks) const
auto end(FixedBins< T, C > const &) noexcept
short int ConvertDirToInt(const TVector3 &dir) const
The data type to uniquely identify a TPC.
void tag(detinfo::DetectorClocksData const &clockData, pma::TrkCandidateColl &tracks)
Track finding helper for the Projection Matching Algorithm.
auto begin(FixedBins< T, C > const &) noexcept
double HalfHeight() const
Height is associated with y coordinate [cm].
double mean(const std::vector< short > &wf, size_t start, size_t nsample)
double DriftDistance() const
Contains all timing reference information for the detector.
size_t tagTopFrontBack(pma::TrkCandidateColl &tracks) const
int trigger_offset(DetectorClocksData const &data)
size_t fullHeightCrossing(pma::TrkCandidateColl &tracks) const
size_t fullCrossingTagger(pma::TrkCandidateColl &tracks, int direction) const
bool isTopVertex(const TVector3 &pos, double tolerance, short int dirIndx) const
void LocalToWorld(const double *tpc, double *world) const
Transform point from local TPC frame to world frame.
size_t fullLengthCrossing(pma::TrkCandidateColl &tracks) const
art framework interface to geometry description
double HalfWidth() const
Width is associated with x coordinate [cm].
std::vector< TrkCandidate > const & tracks() const
constexpr Point origin()
Returns a origin position with a point of the specified type.
Encapsulate the construction of a single detector plane.