14 #include "art/Framework/Core/EDProducer.h"
15 #include "art/Framework/Core/ModuleMacros.h"
16 #include "art/Framework/Principal/Event.h"
17 #include "art/Framework/Principal/Handle.h"
18 #include "art/Framework/Services/Registry/ServiceHandle.h"
19 #include "canvas/Persistency/Common/Ptr.h"
20 #include "canvas/Persistency/Common/PtrVector.h"
21 #include "fhiclcpp/ParameterSet.h"
22 #include "messagefacility/MessageLogger/MessageLogger.h"
49 class BlurredClustering;
70 , fHitsModuleLabel{pset.get<std::string>(
"HitsModuleLabel")}
71 , fTrackModuleLabel{pset.get<std::string>(
"TrackModuleLabel")}
72 , fVertexModuleLabel{pset.get<std::string>(
"VertexModuleLabel")}
73 , fPFParticleModuleLabel{pset.get<std::string>(
"PFParticleModuleLabel")}
74 , fCreateDebugPDF{pset.get<
bool>(
"CreateDebugPDF")}
75 , fMergeClusters{pset.get<
bool>(
"MergeClusters")}
76 , fGlobalTPCRecon{pset.get<
bool>(
"GlobalTPCRecon")}
77 , fShowerReconOnly{pset.get<
bool>(
"ShowerReconOnly")}
78 , fBlurredClusteringAlg{pset.get<fhicl::ParameterSet>(
"BlurredClusterAlg")}
79 , fMergeClusterAlg{pset.get<fhicl::ParameterSet>(
"MergeClusterAlg")}
80 , fTrackShowerSeparationAlg{pset.get<fhicl::ParameterSet>(
"TrackShowerSeparationAlg")}
82 produces<std::vector<recob::Cluster>>();
83 produces<art::Assns<recob::Cluster, recob::Hit>>();
90 if (fCreateDebugPDF) fBlurredClusteringAlg.CreateDebugPDF(evt.run(), evt.subRun(), evt.event());
93 auto clusters = std::make_unique<std::vector<recob::Cluster>>();
94 auto associations = std::make_unique<art::Assns<recob::Cluster, recob::Hit>>();
101 art::ServiceHandle<geo::Geometry const> geom;
102 auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
104 art::ServiceHandle<detinfo::DetectorPropertiesService const>()->DataFor(evt, clockData);
106 int const readoutWindowSize =
detProp.ReadOutWindowSize();
109 art::Handle<std::vector<recob::Hit>> hitCollection;
110 std::vector<art::Ptr<recob::Hit>> hits;
111 std::vector<art::Ptr<recob::Hit>> hitsToCluster;
112 if (evt.getByLabel(fHitsModuleLabel, hitCollection)) art::fill_ptr_vector(hits, hitCollection);
114 if (fShowerReconOnly) {
117 art::Handle<std::vector<recob::Track>> trackCollection;
118 std::vector<art::Ptr<recob::Track>>
tracks;
119 if (evt.getByLabel(fTrackModuleLabel, trackCollection))
120 art::fill_ptr_vector(tracks, trackCollection);
123 art::Handle<std::vector<recob::SpacePoint>> spacePointCollection;
124 std::vector<art::Ptr<recob::SpacePoint>> spacePoints;
125 if (evt.getByLabel(fTrackModuleLabel, spacePointCollection))
126 art::fill_ptr_vector(spacePoints, spacePointCollection);
129 art::Handle<std::vector<recob::Vertex>> vertexCollection;
130 std::vector<art::Ptr<recob::Vertex>> vertices;
131 if (evt.getByLabel(fVertexModuleLabel, vertexCollection))
132 art::fill_ptr_vector(vertices, vertexCollection);
135 art::Handle<std::vector<recob::PFParticle>> pfParticleCollection;
136 std::vector<art::Ptr<recob::PFParticle>> pfParticles;
137 if (evt.getByLabel(fPFParticleModuleLabel, pfParticleCollection))
138 art::fill_ptr_vector(pfParticles, pfParticleCollection);
139 art::Handle<std::vector<recob::Cluster>> clusterCollection;
140 evt.getByLabel(fPFParticleModuleLabel, clusterCollection);
142 if (trackCollection.isValid()) {
143 art::FindManyP<recob::Hit> fmht(trackCollection, evt, fTrackModuleLabel);
144 art::FindManyP<recob::Track> fmth(hitCollection, evt, fTrackModuleLabel);
145 art::FindManyP<recob::SpacePoint> fmspt(trackCollection, evt, fTrackModuleLabel);
146 art::FindManyP<recob::Track> fmtsp(spacePointCollection, evt, fTrackModuleLabel);
147 hitsToCluster = fTrackShowerSeparationAlg.SelectShowerHits(
148 evt.event(), hits,
tracks, spacePoints, fmht, fmth, fmspt, fmtsp);
152 hitsToCluster = hits;
155 std::map<std::pair<int, int>, std::vector<art::Ptr<recob::Hit>>> planeToHits;
156 for (
auto const& hitToCluster : hitsToCluster) {
157 auto const& wireID = hitToCluster->WireID();
158 auto const planeNo = wireID.Plane;
159 auto const tpc = fGlobalTPCRecon ? wireID.TPC % 2 : wireID.TPC;
160 planeToHits[std::make_pair(planeNo, tpc)].push_back(hitToCluster);
164 for (
auto const& [plane, hits] : planeToHits) {
165 std::vector<art::PtrVector<recob::Hit>> finalClusters;
168 if (hits.size() >= fBlurredClusteringAlg.GetMinSize()) {
171 auto const image = fBlurredClusteringAlg.ConvertRecobHitsToVector(hits, readoutWindowSize);
172 auto const blurred = fBlurredClusteringAlg.GaussianBlur(image);
175 std::vector<std::vector<int>>
177 int numClusters = fBlurredClusteringAlg.FindClusters(blurred, allClusterBins);
178 mf::LogVerbatim(
"Blurred Clustering") <<
"Found " << numClusters <<
" clusters" << std::endl;
181 std::vector<art::PtrVector<recob::Hit>> planeClusters;
182 fBlurredClusteringAlg.ConvertBinsToClusters(image, allClusterBins, planeClusters);
185 if (fMergeClusters) {
186 int numMergedClusters = fMergeClusterAlg.MergeClusters(planeClusters, finalClusters);
187 mf::LogVerbatim(
"Blurred Clustering")
188 <<
"After merging, there are " << numMergedClusters <<
" clusters" << std::endl;
191 finalClusters = planeClusters;
194 if (fCreateDebugPDF) {
195 std::stringstream
name;
196 name <<
"blurred_image";
197 TH2F* imageHist = fBlurredClusteringAlg.MakeHistogram(image, TString{name.str()});
198 name <<
"_convolved";
199 TH2F* blurredHist = fBlurredClusteringAlg.MakeHistogram(blurred, TString{name.str()});
200 auto const [planeNo, tpc] = plane;
201 fBlurredClusteringAlg.SaveImage(imageHist, 1, tpc, planeNo);
202 fBlurredClusteringAlg.SaveImage(blurredHist, 2, tpc, planeNo);
203 fBlurredClusteringAlg.SaveImage(blurredHist, allClusterBins, 3, tpc, planeNo);
204 fBlurredClusteringAlg.SaveImage(imageHist, finalClusters, 4, tpc, planeNo);
206 blurredHist->Delete();
212 for (
auto const& clusterHits : finalClusters) {
213 if (clusterHits.empty())
continue;
216 unsigned int const startWire =
217 fBlurredClusteringAlg.GlobalWire(clusterHits.front()->WireID());
218 unsigned int const endWire = fBlurredClusteringAlg.GlobalWire(clusterHits.back()->WireID());
221 ClusterParamAlgo.ImportHits(gser, clusterHits);
228 clusterHits.front()->PeakTime(),
229 clusterHits.front()->SigmaPeakTime(),
232 clusterHits.back()->PeakTime(),
233 clusterHits.back()->SigmaPeakTime(),
235 clusterHits.front()->View(),
236 clusterHits.front()->WireID().planeID(),
239 clusters->emplace_back(
cluster.move());
246 evt.put(std::move(clusters));
247 evt.put(std::move(associations));
bool const fCreateDebugPDF
Class managing the creation of a new recob::Cluster object.
std::string const fPFParticleModuleLabel
ClusterModuleLabel join with tracks
bool const fShowerReconOnly
Declaration of signal hit object.
cluster::MergeClusterAlg fMergeClusterAlg
std::string const fHitsModuleLabel
static const SentryArgument_t Sentry
An instance of the sentry object.
bool const fGlobalTPCRecon
BlurredClustering(fhicl::ParameterSet const &pset)
Helper functions to create a cluster.
Wrapper for ClusterParamsAlgBase objects to accept diverse input.
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
Declaration of cluster object.
void produce(art::Event &evt) override
Provides recob::Track data product.
shower::TrackShowerSeparationAlg fTrackShowerSeparationAlg
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.
std::string const fTrackModuleLabel
cluster::BlurredClusteringAlg fBlurredClusteringAlg
Interface to class computing cluster parameters.
bool const fMergeClusters
art framework interface to geometry description
std::string const fVertexModuleLabel