10 #include "art/Framework/Core/EDProducer.h"
11 #include "art/Framework/Core/ModuleMacros.h"
12 #include "art/Framework/Principal/Event.h"
13 #include "art/Framework/Principal/Handle.h"
14 #include "art/Framework/Principal/Run.h"
15 #include "art/Framework/Principal/SubRun.h"
16 #include "art/Framework/Services/Registry/ServiceHandle.h"
17 #include "canvas/Persistency/Common/FindManyP.h"
18 #include "canvas/Utilities/InputTag.h"
19 #include "fhiclcpp/ParameterSet.h"
20 #include "messagefacility/MessageLogger/MessageLogger.h"
74 const art::Event& evt,
75 const std::vector<art::Ptr<recob::PFParticle>>& slicePFPs,
76 const art::Handle<std::vector<recob::PFParticle>>& pfpHandle,
77 const art::Handle<std::vector<recob::Track>>& trackHandle,
78 const art::FindManyP<recob::Track>& fmPFPTrack)
const;
81 const std::map<art::Ptr<anab::T0>,
bool>& sliceT0CorrectMap)
const;
86 ,
fGeom(lar::providerFrom<geo::Geometry>())
87 , fSCE(lar::providerFrom<spacecharge::SpaceChargeService>())
88 , fCorrectNoT0Tag(
p.get<
bool>(
"CorrectNoT0Tag"))
89 , fCorrectSCE(
p.get<
bool>(
"CorrectSCE"))
90 , fSCEXCorrFlip(
p.get<
bool>(
"SCEXCorrFlip"))
91 , fPFPLabel(
p.get<std::string>(
"PFPLabel"))
92 , fTrackLabel(
p.get<std::string>(
"TrackLabel"))
93 , fT0Labels(
p.get<std::vector<std::string>>(
"T0Labels"))
94 , fT0LabelsCorrectT0(
p.get<std::vector<bool>>(
"T0LabelsCorrectT0"))
97 produces<std::vector<anab::T0>>();
98 produces<std::vector<recob::Slice>>();
99 produces<std::vector<recob::PFParticle>>();
100 produces<std::vector<recob::SpacePoint>>();
101 produces<std::vector<recob::Cluster>>();
102 produces<std::vector<recob::Vertex>>();
103 produces<std::vector<larpandoraobj::PFParticleMetadata>>();
106 produces<art::Assns<anab::T0, recob::PFParticle>>();
107 produces<art::Assns<recob::Slice, recob::Hit>>();
109 produces<art::Assns<recob::PFParticle, recob::Slice>>();
110 produces<art::Assns<recob::PFParticle, recob::SpacePoint>>();
111 produces<art::Assns<recob::PFParticle, recob::Vertex>>();
112 produces<art::Assns<recob::PFParticle, recob::Cluster>>();
113 produces<art::Assns<recob::PFParticle, larpandoraobj::PFParticleMetadata>>();
114 produces<art::Assns<recob::SpacePoint, recob::Hit>>();
115 produces<art::Assns<recob::Cluster, recob::Hit>>();
122 auto t0Collection = std::make_unique<std::vector<anab::T0>>();
123 auto pfpCollection = std::make_unique<std::vector<recob::PFParticle>>();
124 auto clusterCollection = std::make_unique<std::vector<recob::Cluster>>();
125 auto spCollection = std::make_unique<std::vector<recob::SpacePoint>>();
126 auto vtxCollection = std::make_unique<std::vector<recob::Vertex>>();
127 auto sliceCollection = std::make_unique<std::vector<recob::Slice>>();
128 auto pfpMetaCollection = std::make_unique<std::vector<larpandoraobj::PFParticleMetadata>>();
131 auto t0PFPAssn = std::make_unique<art::Assns<anab::T0, recob::PFParticle>>();
132 auto sliceHitAssn = std::make_unique<art::Assns<recob::Slice, recob::Hit>>();
133 auto pfpSliceAssn = std::make_unique<art::Assns<recob::PFParticle, recob::Slice>>();
134 auto pfpVtxAssn = std::make_unique<art::Assns<recob::PFParticle, recob::Vertex>>();
135 auto pfpSPAssn = std::make_unique<art::Assns<recob::PFParticle, recob::SpacePoint>>();
136 auto pfpClusterAssn = std::make_unique<art::Assns<recob::PFParticle, recob::Cluster>>();
137 auto pfpMetaAssn = std::make_unique<art::Assns<recob::PFParticle, larpandoraobj::PFParticleMetadata>>();
138 auto spHitAssn = std::make_unique<art::Assns<recob::SpacePoint, recob::Hit>>();
139 auto clusterHitAssn = std::make_unique<art::Assns<recob::Cluster, recob::Hit>>();
141 art::PtrMaker<anab::T0> t0PtrMaker { evt };
142 art::PtrMaker<recob::PFParticle> pfpPtrMaker { evt };
143 art::PtrMaker<recob::Cluster> clusterPtrMaker { evt };
144 art::PtrMaker<recob::Vertex> vtxPtrMaker { evt };
145 art::PtrMaker<recob::Slice> slicePtrMaker { evt };
146 art::PtrMaker<recob::SpacePoint> spPtrMaker { evt };
147 art::PtrMaker<larpandoraobj::PFParticleMetadata> pfpMetaPtrMaker { evt };
150 art::Handle<std::vector<recob::Slice>> sliceHandle;
151 std::vector<art::Ptr<recob::Slice>> allSlices;
152 if (evt.getByLabel(fPFPLabel, sliceHandle))
153 art::fill_ptr_vector(allSlices, sliceHandle);
156 art::Handle<std::vector<recob::Cluster>> clusterHandle;
157 std::vector<art::Ptr<recob::Cluster>> allClusters;
158 if (evt.getByLabel(fPFPLabel, clusterHandle))
159 art::fill_ptr_vector(allClusters, clusterHandle);
162 art::Handle<std::vector<recob::SpacePoint>> spHandle;
163 std::vector<art::Ptr<recob::SpacePoint>> allSpacePoints;
164 if (evt.getByLabel(fPFPLabel, spHandle))
165 art::fill_ptr_vector(allSpacePoints, spHandle);
168 art::Handle<std::vector<recob::PFParticle>> pfpHandle;
169 std::vector<art::Ptr<recob::PFParticle>> allPFParticles;
170 if (evt.getByLabel(fPFPLabel, pfpHandle))
171 art::fill_ptr_vector(allPFParticles, pfpHandle);
174 art::Handle<std::vector<recob::Track>> trackHandle;
175 std::vector<art::Ptr<recob::Track>> allTracks;
176 if (evt.getByLabel(fTrackLabel, trackHandle))
177 art::fill_ptr_vector(allTracks, trackHandle);
179 art::FindManyP<recob::PFParticle> fmSlicePFP(sliceHandle, evt, fPFPLabel);
180 art::FindManyP<recob::Track> fmPFPTrack(pfpHandle, evt, fTrackLabel);
181 art::FindManyP<recob::SpacePoint> fmPFPSP(pfpHandle, evt, fPFPLabel);
182 art::FindManyP<recob::Cluster> fmPFPCluster(pfpHandle, evt, fPFPLabel);
183 art::FindManyP<recob::Vertex> fmPFPVertex(pfpHandle, evt, fPFPLabel);
184 art::FindManyP<recob::Hit> fmClusterHit(clusterHandle, evt, fPFPLabel);
185 art::FindManyP<recob::Hit> fmSPHit(spHandle, evt, fPFPLabel);
186 art::FindManyP<recob::Hit> fmSliceHit(sliceHandle, evt, fPFPLabel);
187 art::FindManyP<larpandoraobj::PFParticleMetadata> fmPFPMeta(pfpHandle, evt, fPFPLabel);
191 if (!fmSlicePFP.isValid()) {
192 throw cet::exception(
"SCECorrection") <<
"FindMany Slice-PFP is not Valid" << std::endl;
194 if (!fmPFPSP.isValid()) {
195 throw cet::exception(
"SCECorrection") <<
"FindMany PFP-SpacePoint is not Valid" << std::endl;
197 if (!fmSPHit.isValid()) {
198 throw cet::exception(
"SCECorrection") <<
"FindMany SpacePoint-Hit is not Valid" << std::endl;
203 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
204 auto const detProp = art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
206 for (
auto const& slice : allSlices) {
210 sliceCollection->push_back(newSlice);
211 art::Ptr<recob::Slice> newSlicePtr = slicePtrMaker(sliceCollection->size() - 1);
214 const std::vector<art::Ptr<recob::PFParticle>> slicePFPs = fmSlicePFP.at(slice.key());
216 const std::map<art::Ptr<anab::T0>,
bool> sliceT0CorrectMap = getSliceT0s(
217 evt, slicePFPs, pfpHandle, trackHandle, fmPFPTrack);
219 const std::pair<art::Ptr<anab::T0>,
bool> sliceT0CorrectPair = getSliceBestT0(sliceT0CorrectMap);
221 if (sliceT0CorrectPair.first.isNull() && !fCorrectNoT0Tag) {
225 art::Ptr<anab::T0> newT0Ptr;
227 if (!sliceT0CorrectPair.first.isNull()) {
229 t0Offset =
detProp.DriftVelocity() * sliceT0CorrectPair.first->Time() / 1e3;
231 t0Collection->push_back(*sliceT0CorrectPair.first);
232 newT0Ptr = t0PtrMaker(t0Collection->size() - 1);
237 if (fmSliceHit.isValid()) {
238 const std::vector<art::Ptr<recob::Hit>> sliceHits = fmSliceHit.at(slice.key());
239 for (
const art::Ptr<recob::Hit>& hitPtr : sliceHits) {
240 sliceHitAssn->addSingle(newSlicePtr, hitPtr);
245 for (
auto const& pfp : slicePFPs) {
249 pfpCollection->push_back(newPFP);
250 art::Ptr<recob::PFParticle> newPFPPtr = pfpPtrMaker(pfpCollection->size() - 1);
251 pfpSliceAssn->addSingle(newPFPPtr, newSlicePtr);
253 if (!newT0Ptr.isNull()) {
254 t0PFPAssn->addSingle(newT0Ptr, newPFPPtr);
257 std::vector<art::Ptr<recob::SpacePoint>> pfpSPs = fmPFPSP.at(pfp.key());
259 if (fmPFPVertex.isValid()) {
260 std::vector<art::Ptr<recob::Vertex>> pfpVertices = fmPFPVertex.at(pfp.key());
261 for (
auto const& pfpVertex : pfpVertices) {
266 std::vector<art::Ptr<recob::SpacePoint>> vtxSPs = pfpSPs.size() ? pfpSPs : allSpacePoints;
268 double minVtxSPDist = std::numeric_limits<double>::max();
269 art::Ptr<recob::SpacePoint> spPtr;
270 for (
auto const& sp : vtxSPs) {
271 geo::Point_t spPos(sp->XYZ()[0], sp->XYZ()[1], sp->XYZ()[2]);
273 if (vtxSPDiff.Mag2() < minVtxSPDist) {
275 minVtxSPDist = vtxSPDiff.Mag2();
283 art::Ptr<recob::Hit> spHitPtr = fmSPHit.at(spPtr.key()).
front();
286 if (!sliceT0CorrectPair.first.isNull() && sliceT0CorrectPair.second) {
291 if (fCorrectSCE && fSCE->EnableCalSpatialSCE()) {
294 posOffset.SetX(-posOffset.X());
300 recob::Vertex newVtx(vtxPos, pfpVertex->covariance(), pfpVertex->chi2(),
301 pfpVertex->ndof(), pfpVertex->ID());
302 vtxCollection->push_back(newVtx);
303 art::Ptr<recob::Vertex> newVtxPtr = vtxPtrMaker(vtxCollection->size() - 1);
304 pfpVtxAssn->addSingle(newPFPPtr, newVtxPtr);
308 for (
auto const& sp : pfpSPs) {
311 geo::Point_t spPos(sp->XYZ()[0], sp->XYZ()[1], sp->XYZ()[2]);
316 art::Ptr<recob::Hit> spHitPtr = fmSPHit.at(sp.key()).
front();
319 if (!sliceT0CorrectPair.first.isNull() && sliceT0CorrectPair.second) {
324 if (fCorrectSCE && fSCE->EnableCalSpatialSCE()) {
327 posOffset.SetX(-posOffset.X());
333 Double32_t spXYZ[3] = { spPos.X(), spPos.Y(), spPos.Z() };
336 spCollection->push_back(correctedSP);
337 art::Ptr<recob::SpacePoint> spPtr = spPtrMaker(spCollection->size() - 1);
338 pfpSPAssn->addSingle(newPFPPtr, spPtr);
339 spHitAssn->addSingle(spPtr, spHitPtr);
343 if (fmPFPCluster.isValid() && fmClusterHit.isValid()) {
344 std::vector<art::Ptr<recob::Cluster>> pfpClusters = fmPFPCluster.at(pfp.key());
345 for (
auto const& pfpCluster : pfpClusters) {
347 clusterCollection->push_back(newCluster);
348 art::Ptr<recob::Cluster> newClusterPtr = clusterPtrMaker(clusterCollection->size() - 1);
350 std::vector<art::Ptr<recob::Hit>> clusterHits = fmClusterHit.at(pfpCluster.key());
351 pfpClusterAssn->addSingle(newPFPPtr, newClusterPtr);
352 for (
auto const& clusterHit : clusterHits) {
353 clusterHitAssn->addSingle(newClusterPtr, clusterHit);
359 if (fmPFPMeta.isValid()) {
360 const std::vector<art::Ptr<larpandoraobj::PFParticleMetadata>> pfpMetas = fmPFPMeta.at(pfp.key());
361 for (
const art::Ptr<larpandoraobj::PFParticleMetadata>& pfpMeta : pfpMetas) {
363 pfpMetaCollection->push_back(newPFPMeta);
364 art::Ptr<larpandoraobj::PFParticleMetadata> newPFPMetaPtr = pfpMetaPtrMaker(pfpMetaCollection->size() - 1);
365 pfpMetaAssn->addSingle(newPFPPtr, newPFPMetaPtr);
374 evt.put(std::move(t0Collection));
375 evt.put(std::move(sliceCollection));
376 evt.put(std::move(clusterCollection));
377 evt.put(std::move(pfpCollection));
378 evt.put(std::move(spCollection));
379 evt.put(std::move(vtxCollection));
380 evt.put(std::move(pfpMetaCollection));
382 evt.put(std::move(t0PFPAssn));
384 evt.put(std::move(sliceHitAssn));
385 evt.put(std::move(pfpSPAssn));
386 evt.put(std::move(spHitAssn));
387 evt.put(std::move(pfpVtxAssn));
388 evt.put(std::move(pfpSliceAssn));
389 evt.put(std::move(pfpClusterAssn));
390 evt.put(std::move(clusterHitAssn));
391 evt.put(std::move(pfpMetaAssn));
408 throw cet::exception(
"SCECorrection") <<
"Drift direction unknown: " << driftDirection
414 const art::Event&
evt,
415 const std::vector<art::Ptr<recob::PFParticle>>& slicePFPs,
416 const art::Handle<std::vector<recob::PFParticle>>& pfpHandle,
417 const art::Handle<std::vector<recob::Track>>& trackHandle,
418 const art::FindManyP<recob::Track>& fmPFPTrack)
const
421 std::map<art::Ptr<anab::T0>,
bool> pfpT0CorrectMap;
423 for (
auto const& pfp : slicePFPs) {
427 for (
unsigned int i = 0; i < fT0Labels.size(); i++) {
428 std::string t0Label = fT0Labels.at(i);
431 art::FindManyP<anab::T0> fmPFPT0(pfpHandle, evt, t0Label);
432 if (fmPFPT0.isValid()) {
433 std::vector<art::Ptr<anab::T0>> pfpT0s = fmPFPT0.at(pfp.key());
434 if (pfpT0s.size() == 1) {
435 pfpT0CorrectMap[pfpT0s.front()] = fT0LabelsCorrectT0.at(i);
440 if (!fmPFPTrack.isValid())
442 std::vector<art::Ptr<recob::Track>> pfpTracks = fmPFPTrack.at(pfp.key());
443 if (pfpTracks.size() != 1) {
446 art::Ptr<recob::Track> pfpTrack = pfpTracks.front();
449 art::FindManyP<anab::T0> fmTrackT0(trackHandle, evt, t0Label);
450 if (fmTrackT0.isValid()) {
451 std::vector<art::Ptr<anab::T0>> trackT0s = fmTrackT0.at(pfpTrack.key());
452 if (trackT0s.size() == 1) {
453 pfpT0CorrectMap[trackT0s.front()] = fT0LabelsCorrectT0.at(i);
459 return pfpT0CorrectMap;
463 const std::map<art::Ptr<anab::T0>,
bool>& sliceT0CorrectMap)
const
466 if (!sliceT0CorrectMap.size()) {
467 return std::pair<art::Ptr<anab::T0>,
bool>();
470 double minT0 = std::numeric_limits<double>::max();
471 std::pair<art::Ptr<anab::T0>,
bool> sliceT0CorrectPair;
472 for (
auto const& sliceT0CorrectIter : sliceT0CorrectMap) {
473 double t0Time =
abs(sliceT0CorrectIter.first->Time());
474 if (t0Time < minT0) {
476 sliceT0CorrectPair = sliceT0CorrectIter;
479 return sliceT0CorrectPair;
ROOT::Math::DisplacementVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Vector_t
Type for representation of momenta in 3D space.
SCECorrection(fhicl::ParameterSet const &p)
geo::GeometryCore const * fGeom
Utilities related to art service access.
Declaration of signal hit object.
geo::Vector_t applyT0Shift(const double &t0, const geo::TPCID &tpcId) const
Geometry information for a single TPC.
Set of hits with a 2D structure.
Definition of vertex object for LArSoft.
void produce(art::Event &evt) override
spacecharge::SpaceCharge const * fSCE
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Access the description of detector geometry.
std::map< art::Ptr< anab::T0 >, bool > getSliceT0s(const art::Event &evt, const std::vector< art::Ptr< recob::PFParticle >> &slicePFPs, const art::Handle< std::vector< recob::PFParticle >> &pfpHandle, const art::Handle< std::vector< recob::Track >> &trackHandle, const art::FindManyP< recob::Track > &fmPFPTrack) const
Metadata associated to PFParticles.
const std::string fPFPLabel
const std::vector< bool > fT0LabelsCorrectT0
std::pair< art::Ptr< anab::T0 >, bool > getSliceBestT0(const std::map< art::Ptr< anab::T0 >, bool > &sliceT0CorrectMap) const
The data type to uniquely identify a TPC.
Description of geometry of one entire detector.
Declaration of cluster object.
Provides recob::Track data product.
constexpr TPCID const & asTPCID() const
Conversion to TPCID (for convenience of notation).
const std::string fTrackLabel
Hierarchical representation of particle flow.
short int DetectDriftDirection() const
Returns the expected drift direction based on geometry.
TPCID_t TPC
Index of the TPC within its cryostat.
const bool fCorrectNoT0Tag
ROOT::Math::PositionVector3D< ROOT::Math::Cartesian3D< double >, ROOT::Math::GlobalCoordinateSystemTag > Point_t
Type for representation of position in physical 3D space.
art framework interface to geometry description
const std::vector< std::string > fT0Labels
SCECorrection & operator=(SCECorrection const &)=delete