20 #include "art/Framework/Core/EDProducer.h"
21 #include "art/Framework/Core/ModuleMacros.h"
22 #include "art/Framework/Principal/Event.h"
23 #include "art/Framework/Services/Registry/ServiceHandle.h"
46 class CosmicPCAxisTagger;
54 void produce(art::Event&
e)
override;
70 : EDProducer{p}, fPcaAlg(
p.get<fhicl::ParameterSet>(
"PrincipalComponentsAlg"))
72 art::ServiceHandle<geo::Geometry const> geo;
74 fDetHalfHeight = geo->DetHalfHeight();
75 fDetWidth = 2. * geo->DetHalfWidth();
76 fDetLength = geo->DetLength();
78 auto const clock_data = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataForJob();
81 fPFParticleModuleLabel =
p.get<std::string>(
"PFParticleModuleLabel");
82 fPCAxisModuleLabel =
p.get<std::string>(
"PCAxisModuleLabel");
84 fTPCXBoundary =
p.get<
float>(
"TPCXBoundary", 5);
85 fTPCYBoundary =
p.get<
float>(
"TPCYBoundary", 5);
86 fTPCZBoundary =
p.get<
float>(
"TPCZBoundary", 5);
89 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataForJob(clock_data);
90 const double driftVelocity =
91 detector.DriftVelocity(detector.Efield(), detector.Temperature());
94 2 * geo->DetHalfWidth() / (driftVelocity * fSamplingRate / 1000);
96 produces<std::vector<anab::CosmicTag>>();
97 produces<art::Assns<recob::PFParticle, anab::CosmicTag>>();
98 produces<art::Assns<recob::PCAxis, anab::CosmicTag>>();
105 std::unique_ptr<std::vector<anab::CosmicTag>> cosmicTagPFParticleVector(
106 new std::vector<anab::CosmicTag>);
107 std::unique_ptr<art::Assns<recob::PCAxis, anab::CosmicTag>> assnOutCosmicTagPCAxis(
108 new art::Assns<recob::PCAxis, anab::CosmicTag>);
109 std::unique_ptr<art::Assns<recob::PFParticle, anab::CosmicTag>> assnOutCosmicTagPFParticle(
110 new art::Assns<recob::PFParticle, anab::CosmicTag>);
113 art::Handle<std::vector<recob::PFParticle>> pfParticleHandle;
114 evt.getByLabel(fPFParticleModuleLabel, pfParticleHandle);
116 if (!pfParticleHandle.isValid()) {
117 evt.put(std::move(cosmicTagPFParticleVector));
118 evt.put(std::move(assnOutCosmicTagPFParticle));
119 evt.put(std::move(assnOutCosmicTagPCAxis));
125 art::Handle<std::vector<recob::Cluster>> clusterHandle;
126 evt.getByLabel(fPFParticleModuleLabel, clusterHandle);
129 art::Handle<std::vector<recob::PCAxis>> pcaxisHandle;
130 evt.getByLabel(fPCAxisModuleLabel, pcaxisHandle);
132 if (!pcaxisHandle.isValid() || !clusterHandle.isValid()) {
133 evt.put(std::move(cosmicTagPFParticleVector));
134 evt.put(std::move(assnOutCosmicTagPFParticle));
135 evt.put(std::move(assnOutCosmicTagPCAxis));
140 art::FindManyP<recob::PCAxis> pfPartToPCAxisAssns(pfParticleHandle, evt, fPCAxisModuleLabel);
143 art::FindManyP<recob::SpacePoint> spacePointAssnVec(
144 pfParticleHandle, evt, fPFParticleModuleLabel);
148 art::FindManyP<recob::Cluster> clusterAssns(pfParticleHandle, evt, fPFParticleModuleLabel);
151 art::FindManyP<recob::Hit> clusterHitAssns(clusterHandle, evt, fPFParticleModuleLabel);
154 for (
size_t pfPartIdx = 0; pfPartIdx != pfParticleHandle->size(); pfPartIdx++) {
155 art::Ptr<recob::PFParticle> pfParticle(pfParticleHandle, pfPartIdx);
158 std::vector<art::Ptr<recob::PCAxis>> pcAxisVec = pfPartToPCAxisAssns.at(pfPartIdx);
161 if (pcAxisVec.empty())
continue;
168 if (pcAxisVec.size() > 1 && pcAxisVec.front()->getID() > pcAxisVec.back()->getID())
169 std::reverse(pcAxisVec.begin(), pcAxisVec.end());
174 const art::Ptr<recob::PCAxis>& pcAxis = pcAxisVec.front();
185 double eigenVal0 = sqrt(pcAxis->getEigenValues()[0]);
186 double maxArcLen = 3. * eigenVal0;
189 TVector3 vertexPosition(
190 pcAxis->getAvePosition()[0], pcAxis->getAvePosition()[1], pcAxis->getAvePosition()[2]);
191 TVector3 vertexDirection(pcAxis->getEigenVectors()[0][0],
192 pcAxis->getEigenVectors()[0][1],
193 pcAxis->getEigenVectors()[0][2]);
195 TVector3 pcAxisStart = vertexPosition - maxArcLen * vertexDirection;
196 TVector3 pcAxisEnd = vertexPosition + maxArcLen * vertexDirection;
199 float trackEndPt1_X = pcAxisStart[0];
200 float trackEndPt1_Y = pcAxisStart[1];
201 float trackEndPt1_Z = pcAxisStart[2];
202 float trackEndPt2_X = pcAxisEnd[0];
203 float trackEndPt2_Y = pcAxisEnd[1];
204 float trackEndPt2_Z = pcAxisEnd[2];
207 std::vector<art::Ptr<recob::Cluster>> clusterVec = clusterAssns.at(pfParticle.key());
212 for (
const auto&
cluster : clusterVec) {
214 std::vector<art::Ptr<recob::Hit>> hitVec = clusterHitAssns.at(
cluster->ID());
222 for (
const auto&
hit : hitVec) {
224 std::cout <<
"***>> Hit key: " <<
hit.key() <<
", peak - RMS: " <<
hit->PeakTimeMinusRMS()
225 <<
", peak + RMS: " <<
hit->PeakTimePlusRMS()
226 <<
", det width: " << fDetectorWidthTicks << std::endl;
228 if (
hit->PeakTimeMinusRMS() < fDetectorWidthTicks ||
229 hit->PeakTimePlusRMS() > 2. * fDetectorWidthTicks) {
238 std::vector<art::Ptr<recob::SpacePoint>> spacePointVec = spacePointAssnVec.at(pfParticle.key());
243 if (isCosmic == 0 && !spacePointVec.empty()) {
247 sqrt(std::pow(pcAxis->getEigenValues()[1], 2) + std::pow(pcAxis->getEigenValues()[1], 2));
249 if (eigenVal0 > 0. && transRMS > 0.) {
256 double arcLengthToFirstHit(9999.);
257 double arcLengthToLastHit(-9999.);
259 for (
const auto spacePoint : spacePointVec) {
260 TVector3 spacePointPos(spacePoint->XYZ()[0], spacePoint->XYZ()[1], spacePoint->XYZ()[2]);
261 TVector3 deltaPos = spacePointPos - vertexPosition;
262 double arcLenToHit = deltaPos.Dot(vertexDirection);
264 if (arcLenToHit < arcLengthToFirstHit) {
265 arcLengthToFirstHit = arcLenToHit;
266 pcAxisStart = spacePointPos;
269 if (arcLenToHit > arcLengthToLastHit) {
270 arcLengthToLastHit = arcLenToHit;
271 pcAxisEnd = spacePointPos;
276 trackEndPt1_X = pcAxisStart[0];
277 trackEndPt1_Y = pcAxisStart[1];
278 trackEndPt1_Z = pcAxisStart[2];
279 trackEndPt2_X = pcAxisEnd[0];
280 trackEndPt2_Y = pcAxisEnd[1];
281 trackEndPt2_Z = pcAxisEnd[2];
288 bool nBdX[] = {
false,
false};
289 bool nBdY[] = {
false,
false};
290 bool nBdZ[] = {
false,
false};
297 if (fDetWidth - trackEndPt1_X < fTPCXBoundary || trackEndPt1_X < fTPCXBoundary)
299 if (fDetWidth - trackEndPt2_X < fTPCXBoundary || trackEndPt2_X < fTPCXBoundary)
304 if (fDetHalfHeight - trackEndPt1_Y < fTPCYBoundary ||
305 fDetHalfHeight + trackEndPt1_Y < fTPCYBoundary)
307 if (fDetHalfHeight - trackEndPt2_Y < fTPCYBoundary ||
308 fDetHalfHeight + trackEndPt2_Y < fTPCYBoundary)
313 if (fDetLength - trackEndPt1_Z < fTPCZBoundary || trackEndPt1_Z < fTPCZBoundary)
315 if (fDetLength - trackEndPt2_Z < fTPCZBoundary || trackEndPt2_Z < fTPCZBoundary)
319 bool exitEnd1 = nBdX[0] || nBdY[0];
320 bool exitEnd2 = nBdX[1] || nBdY[1];
328 if ((exitEnd1 && exitEnd2) || exitEndZ1 || exitEndZ2) {
330 if (nBdX[0] && nBdX[1])
332 else if (nBdY[0] && nBdY[1])
334 else if ((nBdX[0] || nBdX[1]) && (nBdY[0] || nBdY[1]))
336 else if ((nBdX[0] || nBdX[1]) && (nBdZ[0] || nBdZ[1]))
342 else if (nBdZ[0] && nBdZ[1]) {
347 else if ((nBdX[0] || nBdY[0] || nBdZ[0]) != (nBdX[1] || nBdY[1] || nBdZ[1])) {
349 if (nBdX[0] || nBdX[1])
351 else if (nBdY[0] || nBdY[1])
353 else if (nBdZ[0] || nBdZ[1])
359 std::vector<float> endPt1;
360 std::vector<float> endPt2;
361 endPt1.push_back(trackEndPt1_X);
362 endPt1.push_back(trackEndPt1_Y);
363 endPt1.push_back(trackEndPt1_Z);
364 endPt2.push_back(trackEndPt2_X);
365 endPt2.push_back(trackEndPt2_Y);
366 endPt2.push_back(trackEndPt2_Z);
368 float cosmicScore = isCosmic > 0 ? 1. : 0.;
373 else if (isCosmic == 4)
377 cosmicTagPFParticleVector->emplace_back(endPt1, endPt2, cosmicScore, tag_id);
380 *
this, evt, *cosmicTagPFParticleVector, pfParticle, *assnOutCosmicTagPFParticle);
383 for (
const auto& axis : pcAxisVec) {
384 util::CreateAssn(*
this, evt, *cosmicTagPFParticleVector, axis, *assnOutCosmicTagPCAxis);
388 evt.put(std::move(cosmicTagPFParticleVector));
389 evt.put(std::move(assnOutCosmicTagPFParticle));
390 evt.put(std::move(assnOutCosmicTagPCAxis));
enum anab::cosmic_tag_id CosmicTagID_t
Declaration of signal hit object.
std::string fPFParticleModuleLabel
std::vector< reco::ClusterHit2D > Hit2DVector
CosmicPCAxisTagger(fhicl::ParameterSet const &p)
Declaration of cluster object.
void produce(art::Event &e) override
This header file defines the interface to a principal components analysis designed to be used within ...
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.
lar_cluster3d::PrincipalComponentsAlg fPcaAlg
Principal Components algorithm.
double sampling_rate(DetectorClocksData const &data)
Returns the period of the TPC readout electronics clock.
art framework interface to geometry description
BEGIN_PROLOG could also be cout
std::string fPCAxisModuleLabel