18 #include "art/Framework/Core/EDProducer.h"
19 #include "art/Framework/Core/ModuleMacros.h"
20 #include "art/Framework/Principal/Event.h"
21 #include "art/Framework/Services/Registry/ServiceHandle.h"
36 class CosmicPFParticleTagger;
43 void produce(art::Event&
e)
override;
60 auto const* geo = lar::providerFrom<geo::Geometry>();
61 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
63 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clock_data);
65 fDetHalfHeight = geo->DetHalfHeight();
66 fDetWidth = 2. * geo->DetHalfWidth();
67 fDetLength = geo->DetLength();
71 fPFParticleModuleLabel =
p.get<std::string>(
"PFParticleModuleLabel");
72 fTrackModuleLabel =
p.get<std::string>(
"TrackModuleLabel",
"track");
73 fEndTickPadding =
p.get<
int>(
"EndTickPadding", 50);
74 fMaxOutOfTime =
p.get<
int>(
"MaxOutOfTime", 4);
76 fTPCXBoundary =
p.get<
float>(
"TPCXBoundary", 5);
77 fTPCYBoundary =
p.get<
float>(
"TPCYBoundary", 5);
78 fTPCZBoundary =
p.get<
float>(
"TPCZBoundary", 5);
80 const double driftVelocity = detp.DriftVelocity(detp.Efield(), detp.Temperature());
83 2 * geo->DetHalfWidth() / (driftVelocity * fSamplingRate / 1000);
84 fMinTickDrift = clock_data.Time2Tick(clock_data.TriggerTime());
85 fMaxTickDrift = fMinTickDrift + fDetectorWidthTicks + fEndTickPadding;
87 produces<std::vector<anab::CosmicTag>>();
88 produces<art::Assns<anab::CosmicTag, recob::Track>>();
89 produces<art::Assns<recob::PFParticle, anab::CosmicTag>>();
96 std::unique_ptr<std::vector<anab::CosmicTag>> cosmicTagTrackVector(
97 new std::vector<anab::CosmicTag>);
98 std::unique_ptr<art::Assns<anab::CosmicTag, recob::Track>> assnOutCosmicTagTrack(
99 new art::Assns<anab::CosmicTag, recob::Track>);
100 std::unique_ptr<art::Assns<recob::PFParticle, anab::CosmicTag>> assnOutCosmicTagPFParticle(
101 new art::Assns<recob::PFParticle, anab::CosmicTag>);
104 art::Handle<std::vector<recob::PFParticle>> pfParticleHandle;
105 evt.getByLabel(fPFParticleModuleLabel, pfParticleHandle);
107 if (!pfParticleHandle.isValid()) {
108 evt.put(std::move(cosmicTagTrackVector));
109 evt.put(std::move(assnOutCosmicTagTrack));
114 art::Handle<std::vector<recob::Track>> trackHandle;
115 evt.getByLabel(fTrackModuleLabel, trackHandle);
117 if (!trackHandle.isValid()) {
118 evt.put(std::move(cosmicTagTrackVector));
119 evt.put(std::move(assnOutCosmicTagTrack));
124 art::Handle<art::Assns<recob::PFParticle, recob::Track>> pfPartToTrackHandle;
125 evt.getByLabel(fTrackModuleLabel, pfPartToTrackHandle);
128 art::FindManyP<recob::Track> pfPartToTrackAssns(pfParticleHandle, evt, fTrackModuleLabel);
131 art::FindManyP<recob::Hit> hitsSpill(trackHandle, evt, fTrackModuleLabel);
134 for (
size_t pfPartIdx = 0; pfPartIdx != pfParticleHandle->size(); pfPartIdx++) {
135 art::Ptr<recob::PFParticle> pfParticle(pfParticleHandle, pfPartIdx);
138 std::vector<art::Ptr<recob::Track>> trackVec = pfPartToTrackAssns.at(pfPartIdx);
141 if (trackVec.empty()) {
143 std::vector<float> tempPt1, tempPt2;
144 tempPt1.push_back(-999);
145 tempPt1.push_back(-999);
146 tempPt1.push_back(-999);
147 tempPt2.push_back(-999);
148 tempPt2.push_back(-999);
149 tempPt2.push_back(-999);
151 util::CreateAssn(*
this, evt, *cosmicTagTrackVector, pfParticle, *assnOutCosmicTagPFParticle);
158 art::Ptr<recob::Track> track1 = trackVec.front();
160 std::vector<art::Ptr<recob::Hit>> hitVec = hitsSpill.at(track1.key());
163 auto vertexPosition = track1->Vertex();
164 auto vertexDirection = track1->VertexDirection();
165 auto endPosition = track1->End();
171 if (trackVec.size() > 1) {
172 for (
size_t trackIdx = 1; trackIdx < trackVec.size(); trackIdx++) {
173 art::Ptr<recob::Track>
track(trackVec[trackIdx]);
175 auto trackStart = track->Vertex();
176 auto trackEnd = track->End();
179 double arcLStartToStart = (trackStart - vertexPosition).Dot(vertexDirection);
180 double arcLStartToEnd = (trackEnd - vertexPosition).Dot(vertexDirection);
182 if (arcLStartToStart < 0. || arcLStartToEnd < 0.) {
183 if (arcLStartToStart < arcLStartToEnd)
184 vertexPosition = trackStart;
186 vertexPosition = trackEnd;
190 double arcLEndToStart = (trackStart - endPosition).Dot(vertexDirection);
191 double arcLEndToEnd = (trackEnd - endPosition).Dot(vertexDirection);
193 if (arcLEndToStart > 0. || arcLEndToEnd > 0.) {
194 if (arcLEndToStart > arcLEndToEnd)
195 endPosition = trackStart;
197 endPosition = trackEnd;
202 hitVec.end(), hitsSpill.at(track.key()).
begin(), hitsSpill.at(track.key()).
end());
207 float trackEndPt1_X = vertexPosition.X();
208 float trackEndPt1_Y = vertexPosition.Y();
209 float trackEndPt1_Z = vertexPosition.Z();
210 float trackEndPt2_X = endPosition.X();
211 float trackEndPt2_Y = endPosition.Y();
212 float trackEndPt2_Z = endPosition.Z();
219 for (
unsigned int p = 0;
p < hitVec.size();
p++) {
220 int peakLessRms = hitVec[
p]->PeakTimeMinusRMS();
221 int peakPlusRms = hitVec[
p]->PeakTimePlusRMS();
223 if (peakLessRms < fMinTickDrift || peakPlusRms > fMaxTickDrift) {
224 if (++nOutOfTime > fMaxOutOfTime) {
241 unsigned boundaryMask[] = {0, 0};
248 if (fDetWidth - trackEndPt1_X < fTPCXBoundary)
249 boundaryMask[0] = 0x1;
250 else if (trackEndPt1_X < fTPCXBoundary)
251 boundaryMask[0] = 0x2;
253 if (fDetWidth - trackEndPt2_X < fTPCXBoundary)
254 boundaryMask[1] = 0x1;
255 else if (trackEndPt2_X < fTPCXBoundary)
256 boundaryMask[1] = 0x2;
260 if (fDetHalfHeight - trackEndPt1_Y < fTPCYBoundary)
261 boundaryMask[0] = 0x10;
262 else if (fDetHalfHeight + trackEndPt1_Y < fTPCYBoundary)
263 boundaryMask[0] = 0x20;
265 if (fDetHalfHeight - trackEndPt2_Y < fTPCYBoundary)
266 boundaryMask[1] = 0x10;
267 else if (fDetHalfHeight + trackEndPt2_Y < fTPCYBoundary)
268 boundaryMask[1] = 0x20;
272 if (fDetLength - trackEndPt1_Z < fTPCZBoundary)
273 boundaryMask[0] = 0x100;
274 else if (trackEndPt1_Z < fTPCZBoundary)
275 boundaryMask[0] = 0x200;
277 if (fDetLength - trackEndPt2_Z < fTPCZBoundary)
278 boundaryMask[1] = 0x100;
279 else if (trackEndPt2_Z < fTPCZBoundary)
280 boundaryMask[1] = 0x200;
282 unsigned trackMask = boundaryMask[0] | boundaryMask[1];
285 for (
int idx = 0; idx < 12; idx++)
286 if (trackMask & (0x1 << idx)) nBitsSet++;
291 if ((trackMask & 0x300) != 0x300) {
293 if ((trackMask & 0x3) == 0x3)
295 else if ((trackMask & 0x30) == 0x30)
297 else if ((trackMask & 0x3) && (trackMask & 0x30))
299 else if ((trackMask & 0x3) && (trackMask & 0x300))
311 else if (nBitsSet > 0) {
315 else if (trackMask & 0x30)
317 else if (trackMask & 0x300)
322 std::vector<float> endPt1;
323 std::vector<float> endPt2;
324 endPt1.push_back(trackEndPt1_X);
325 endPt1.push_back(trackEndPt1_Y);
326 endPt1.push_back(trackEndPt1_Z);
327 endPt2.push_back(trackEndPt2_X);
328 endPt2.push_back(trackEndPt2_Y);
329 endPt2.push_back(trackEndPt2_Z);
331 float cosmicScore = isCosmic > 0 ? 1. : 0.;
336 else if (isCosmic == 4)
340 cosmicTagTrackVector->emplace_back(endPt1, endPt2, cosmicScore, tag_id);
342 util::CreateAssn(*
this, evt, *cosmicTagTrackVector, trackVec, *assnOutCosmicTagTrack);
345 util::CreateAssn(*
this, evt, *cosmicTagTrackVector, pfParticle, *assnOutCosmicTagPFParticle);
348 evt.put(std::move(cosmicTagTrackVector));
349 evt.put(std::move(assnOutCosmicTagTrack));
350 evt.put(std::move(assnOutCosmicTagPFParticle));
Utilities related to art service access.
enum anab::cosmic_tag_id CosmicTagID_t
Declaration of signal hit object.
std::string fTrackModuleLabel
process_name use argoneut_mc_hitfinder track
std::string fPFParticleModuleLabel
auto end(FixedBins< T, C > const &) noexcept
void produce(art::Event &e) override
Provides recob::Track data product.
auto begin(FixedBins< T, C > const &) noexcept
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.
CosmicPFParticleTagger(fhicl::ParameterSet const &p)
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
art framework interface to geometry description
int fMaxOutOfTime
Max hits that can be out of time before rejecting.