LArSoft  v06_85_00
Liquid Argon Software toolkit - http://larsoft.org/
BlurredClustering_module.cc
Go to the documentation of this file.
1 // Class: BlurredClustering
3 // Module Type: producer
4 // File: BlurredClustering_module.cc
5 // Author: Mike Wallbank (m.wallbank@sheffield.ac.uk), May 2015
6 //
7 // Reconstructs showers by blurring the hit map image to introduce fake
8 // hits before clustering to make fuller and more complete clusters.
9 //
10 // See DUNE-DocDB 54 (public) for details.
12 
13 // Framework includes:
16 #include "fhiclcpp/ParameterSet.h"
25 
26 // LArSoft includes
44 
45 // ROOT & C++ includes
46 #include <string>
47 #include <vector>
48 #include <map>
49 
50 namespace cluster {
51  class BlurredClustering;
52 }
53 
55 public:
56 
57  explicit BlurredClustering(fhicl::ParameterSet const& pset);
58  virtual ~BlurredClustering();
59 
60  void produce(art::Event &evt);
61  void reconfigure(fhicl::ParameterSet const &p);
62 
63 private:
64 
68 
69  // Create instances of algorithm classes to perform the clustering
73 
74  // Output containers to place in event
75  std::unique_ptr<std::vector<recob::Cluster> > clusters;
76  std::unique_ptr<art::Assns<recob::Cluster,recob::Hit> > associations;
77 
78 };
79 
80 cluster::BlurredClustering::BlurredClustering(fhicl::ParameterSet const &pset) : fBlurredClusteringAlg(pset.get<fhicl::ParameterSet>("BlurredClusterAlg")),
81  fMergeClusterAlg(pset.get<fhicl::ParameterSet>("MergeClusterAlg")),
82  fTrackShowerSeparationAlg(pset.get<fhicl::ParameterSet>("TrackShowerSeparationAlg")) {
83  this->reconfigure(pset);
84  produces<std::vector<recob::Cluster> >();
85  produces<art::Assns<recob::Cluster,recob::Hit> >();
86 }
87 
89 
91  fHitsModuleLabel = p.get<std::string>("HitsModuleLabel");
92  fTrackModuleLabel = p.get<std::string>("TrackModuleLabel");
93  fVertexModuleLabel = p.get<std::string>("VertexModuleLabel");
94  fPFParticleModuleLabel = p.get<std::string>("PFParticleModuleLabel");
95  fCreateDebugPDF = p.get<bool> ("CreateDebugPDF");
96  fMergeClusters = p.get<bool> ("MergeClusters");
97  fGlobalTPCRecon = p.get<bool> ("GlobalTPCRecon");
98  fShowerReconOnly = p.get<bool> ("ShowerReconOnly");
100  fMergeClusterAlg.reconfigure(p.get<fhicl::ParameterSet>("MergeClusterAlg"));
101  fTrackShowerSeparationAlg.reconfigure(p.get<fhicl::ParameterSet>("TrackShowerSeparationAlg"));
102 }
103 
105 
106  fEvent = evt.event();
107  fRun = evt.run();
108  fSubrun = evt.subRun();
109 
110  // Create debug pdf to illustrate the blurring process
111  if (fCreateDebugPDF)
113 
114  // Output containers -- collection of clusters and associations
115  clusters.reset(new std::vector<recob::Cluster>);
117 
118  // Compute the cluster characteristics
119  // Just use default for now, but configuration will go here
121 
122  // Create geometry handle
124 
125  // Get the hits from the event
126  art::Handle<std::vector<recob::Hit> > hitCollection;
127  std::vector<art::Ptr<recob::Hit> > hits;
128  std::vector<art::Ptr<recob::Hit> > hitsToCluster;
129  if (evt.getByLabel(fHitsModuleLabel,hitCollection))
130  art::fill_ptr_vector(hits, hitCollection);
131 
132  if (fShowerReconOnly) {
133 
134  // Get the tracks from the event
135  art::Handle<std::vector<recob::Track> > trackCollection;
136  std::vector<art::Ptr<recob::Track> > tracks;
137  if (evt.getByLabel(fTrackModuleLabel,trackCollection))
138  art::fill_ptr_vector(tracks, trackCollection);
139 
140  // Get the space points from the event
141  art::Handle<std::vector<recob::SpacePoint> > spacePointCollection;
142  std::vector<art::Ptr<recob::SpacePoint> > spacePoints;
143  if (evt.getByLabel(fTrackModuleLabel,spacePointCollection))
144  art::fill_ptr_vector(spacePoints, spacePointCollection);
145 
146  // Get vertices from the event
147  art::Handle<std::vector<recob::Vertex> > vertexCollection;
148  std::vector<art::Ptr<recob::Vertex> > vertices;
149  if (evt.getByLabel(fVertexModuleLabel, vertexCollection))
150  art::fill_ptr_vector(vertices, vertexCollection);
151 
152  // Get pandora pfparticles and clusters from the event
153  art::Handle<std::vector<recob::PFParticle> > pfParticleCollection;
154  std::vector<art::Ptr<recob::PFParticle> > pfParticles;
155  if (evt.getByLabel(fPFParticleModuleLabel, pfParticleCollection))
156  art::fill_ptr_vector(pfParticles, pfParticleCollection);
157  art::Handle<std::vector<recob::Cluster> > clusterCollection;
158  evt.getByLabel(fPFParticleModuleLabel, clusterCollection);
159 
160  if (trackCollection.isValid()) {
161  art::FindManyP<recob::Hit> fmht(trackCollection, evt, fTrackModuleLabel);
162  art::FindManyP<recob::Track> fmth(hitCollection, evt, fTrackModuleLabel);
163  art::FindManyP<recob::SpacePoint> fmspt(trackCollection, evt, fTrackModuleLabel);
164  art::FindManyP<recob::Track> fmtsp(spacePointCollection, evt, fTrackModuleLabel);
165  hitsToCluster = fTrackShowerSeparationAlg.SelectShowerHits(evt.event(), hits, tracks, spacePoints, fmht, fmth, fmspt, fmtsp);
166  }
167 
168  // // Remove hits from tracks before performing any clustering
169  // if (pfParticleCollection.isValid() and clusterCollection.isValid()) {
170  // mf::LogInfo("BlurredCluster") << "Removing track-like hits before clustering: will use information from PFParticles." << std::endl;
171  // art::FindManyP<recob::Cluster> fmcpfp(pfParticleCollection, evt, fPFParticleModuleLabel);
172  // art::FindManyP<recob::Hit> fmhpfp(clusterCollection, evt, fPFParticleModuleLabel);
173  // hitsToCluster = fTrackShowerSeparationAlg.RemoveTrackHits(hits, pfParticles, fmcpfp, fmhpfp);
174  // }
175  // else if (trackCollection.isValid() and trackCollection.isValid() and spacePointCollection.isValid()) {
176  // mf::LogInfo("BlurredCluster") << "Removing track-like hits before clustering: no PFParticle information available so will use tracks and vertices." << std::endl;
177  // art::FindManyP<recob::Track> fmth(hitCollection, evt, fTrackModuleLabel);
178  // art::FindManyP<recob::Track> fmtsp(spacePointCollection, evt, fTrackModuleLabel);
179  // art::FindManyP<recob::Hit> fmh(trackCollection, evt, fTrackModuleLabel);
180  // hitsToCluster = fTrackShowerSeparationAlg.RemoveTrackHits(hits, tracks, spacePoints, vertices, fmth, fmtsp, fmh, evt.event(), evt.run());
181  // }
182  // else
183  // throw art::Exception(art::errors::Configuration) << "Error: configuration is set to remove track-like hits before clustering but no prior reconstruction is provided... "
184  // << std::endl
185  // << "Require either a) Pandora or b) track, vertices and space points to have already been found." << std::endl;
186 
187  }
188 
189  else
190  hitsToCluster = hits;
191 
192  // Make a map between the planes and the hits on each
193  std::map<std::pair<int,int>,std::vector<art::Ptr<recob::Hit> > > planeToHits;
194  for (std::vector<art::Ptr<recob::Hit> >::iterator hitToCluster = hitsToCluster.begin(); hitToCluster != hitsToCluster.end(); ++hitToCluster) {
195  if (fGlobalTPCRecon)
196  planeToHits[std::make_pair((*hitToCluster)->WireID().Plane,(*hitToCluster)->WireID().TPC%2)].push_back(*hitToCluster);
197  else
198  planeToHits[std::make_pair((*hitToCluster)->WireID().Plane,(*hitToCluster)->WireID().TPC)].push_back(*hitToCluster);
199  }
200 
201  // Loop over views
202  for (std::map<std::pair<int,int>,std::vector<art::Ptr<recob::Hit> > >::iterator planeIt = planeToHits.begin(); planeIt != planeToHits.end(); ++planeIt) {
203 
204  //std::cout << "Clustering in plane " << planeIt->first.first << " in global TPC " << planeIt->first.second << std::endl;
205  // if (!(planeIt->first.first == 1 and planeIt->first.second == 1))
206  // continue;
207 
208  std::vector<art::PtrVector<recob::Hit> > finalClusters;
209 
210  // Implement the algorithm
211  if (planeIt->second.size() >= fBlurredClusteringAlg.GetMinSize()) {
212 
213  // Convert hit map to TH2 histogram and blur it
214  std::vector<std::vector<double> > image = fBlurredClusteringAlg.ConvertRecobHitsToVector(planeIt->second);
215  std::vector<std::vector<double> > blurred = fBlurredClusteringAlg.GaussianBlur(image);
216 
217  // Find clusters in histogram
218  std::vector<std::vector<int> > allClusterBins; // Vector of clusters (clusters are vectors of hits)
219  int numClusters = fBlurredClusteringAlg.FindClusters(blurred, allClusterBins);
220  mf::LogVerbatim("Blurred Clustering") << "Found " << numClusters << " clusters" << std::endl;
221 
222  // Create output clusters from the vector of clusters made in FindClusters
223  std::vector<art::PtrVector<recob::Hit> > planeClusters;
224  fBlurredClusteringAlg.ConvertBinsToClusters(image, allClusterBins, planeClusters);
225 
226  // Use the cluster merging algorithm
227  if (fMergeClusters) {
228  int numMergedClusters = fMergeClusterAlg.MergeClusters(planeClusters, finalClusters);
229  mf::LogVerbatim("Blurred Clustering") << "After merging, there are " << numMergedClusters << " clusters" << std::endl;
230  }
231  else finalClusters = planeClusters;
232 
233  // Make the debug PDF
234  if (fCreateDebugPDF) {
235  std::stringstream name;
236  name << "blurred_image";
237  TH2F* imageHist = fBlurredClusteringAlg.MakeHistogram(image, TString(name.str()));
238  name << "_convolved";
239  TH2F* blurredHist = fBlurredClusteringAlg.MakeHistogram(blurred, TString(name.str()));
240  fBlurredClusteringAlg.SaveImage(imageHist, 1, planeIt->first.second, planeIt->first.first);
241  fBlurredClusteringAlg.SaveImage(blurredHist, 2, planeIt->first.second, planeIt->first.first);
242  fBlurredClusteringAlg.SaveImage(blurredHist, allClusterBins, 3, planeIt->first.second, planeIt->first.first);
243  fBlurredClusteringAlg.SaveImage(imageHist, finalClusters, 4, planeIt->first.second, planeIt->first.first);
244  imageHist->Delete();
245  blurredHist->Delete();
246  }
247 
248  } // End min hits check
249 
250  //fBlurredClusteringAlg.fHitMap.clear();
251 
252  // Make the output cluster objects
253  for (std::vector<art::PtrVector<recob::Hit> >::iterator clusIt = finalClusters.begin(); clusIt != finalClusters.end(); ++clusIt) {
254 
255  art::PtrVector<recob::Hit> clusterHits = *clusIt;
256  if (clusterHits.size() > 0) {
257 
258  // Get the start and end wires of the cluster
259  unsigned int startWire = fBlurredClusteringAlg.GlobalWire(clusterHits.front()->WireID());
260  unsigned int endWire = fBlurredClusteringAlg.GlobalWire(clusterHits.back()->WireID());
261 
262  // Put cluster hits in the algorithm
263  ClusterParamAlgo.ImportHits(clusterHits);
264 
265  // Create the recob::Cluster and place in the vector of clusters
267  ClusterParamAlgo, // algo
268  float(startWire), // start_wire
269  0., // sigma_start_wire
270  clusterHits.front()->PeakTime(), // start_tick
271  clusterHits.front()->SigmaPeakTime(), // sigma_start_tick
272  float(endWire), // end_wire
273  0., // sigma_end_wire,
274  clusterHits.back()->PeakTime(), // end_tick
275  clusterHits.back()->SigmaPeakTime(), // sigma_end_tick
276  clusters->size(), // ID
277  clusterHits.front()->View(), // view
278  clusterHits.front()->WireID().planeID(), // plane
279  recob::Cluster::Sentry // sentry
280  );
281 
282  clusters->emplace_back(cluster.move());
283 
284  // Associate the hits to this cluster
285  util::CreateAssn(*this, evt, *(clusters.get()), clusterHits, *(associations.get()));
286 
287  } // End this cluster
288 
289  } // End loop over all clusters
290 
291  }
292 
293  evt.put(std::move(clusters));
294  evt.put(std::move(associations));
295 
296  return;
297 
298 }
299 
void SaveImage(TH2F *image, std::vector< art::PtrVector< recob::Hit > > const &allClusters, int pad, int tpc, int plane)
MaybeLogger_< ELseverityLevel::ELsev_info, true > LogVerbatim
SubRunNumber_t subRun() const
Definition: Event.h:72
int FindClusters(std::vector< std::vector< double > > const &image, std::vector< std::vector< int > > &allcluster)
Find clusters in the histogram.
Class managing the creation of a new recob::Cluster object.
std::vector< std::vector< double > > GaussianBlur(std::vector< std::vector< double > > const &image)
Applies Gaussian blur to image.
void reconfigure(fhicl::ParameterSet const &pset)
Read in configurable parameters from provided parameter set.
Encapsulate the construction of a single cyostat.
void reconfigure(fhicl::ParameterSet const &p)
Declaration of signal hit object.
int MergeClusters(std::vector< art::PtrVector< recob::Hit > > const &planeClusters, std::vector< art::PtrVector< recob::Hit > > &clusters)
cluster::MergeClusterAlg fMergeClusterAlg
std::vector< art::Ptr< recob::Hit > > SelectShowerHits(int event, const std::vector< art::Ptr< recob::Hit > > &hits, const std::vector< art::Ptr< recob::Track > > &tracks, const std::vector< art::Ptr< recob::SpacePoint > > &spacePoints, const art::FindManyP< recob::Hit > &fmht, const art::FindManyP< recob::Track > &fmth, const art::FindManyP< recob::SpacePoint > &fmspt, const art::FindManyP< recob::Track > &fmtsp)
Cluster finding and building.
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
void reconfigure(fhicl::ParameterSet const &p)
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
bool isValid() const
Definition: Handle.h:190
auto vector(Vector const &v)
Returns a manipulator which will print the specified array.
Definition: DumpUtils.h:265
reference back()
Definition: PtrVector.h:393
void CreateDebugPDF(int run, int subrun, int event)
Create the PDF to save debug images.
void hits()
Definition: readHits.C:15
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
BlurredClustering(fhicl::ParameterSet const &pset)
void reconfigure(fhicl::ParameterSet const &p)
std::unique_ptr< std::vector< recob::Cluster > > clusters
parameter set interface
Helper functions to create a cluster.
Wrapper for ClusterParamsAlgBase objects to accept diverse input.
T get(std::string const &key) const
Definition: ParameterSet.h:231
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
bool CreateAssn(PRODUCER const &prod, art::Event &evt, std::vector< T > const &a, art::Ptr< U > const &b, art::Assns< U, T > &assn, std::string a_instance, size_t indx=UINT_MAX)
Creates a single one-to-one association.
EventNumber_t event() const
Definition: Event.h:67
Declaration of cluster object.
Provides recob::Track data product.
size_type size() const
Definition: PtrVector.h:308
shower::TrackShowerSeparationAlg fTrackShowerSeparationAlg
reference front()
Definition: PtrVector.h:379
TH2F * MakeHistogram(std::vector< std::vector< double > > const &image, TString name)
Converts a 2D vector in a histogram for the debug pdf.
Utility object to perform functions of association.
cluster::BlurredClusteringAlg fBlurredClusteringAlg
Encapsulate the construction of a single detector plane.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
void ImportHits(Iter begin, Iter end)
Calls SetHits() with the hits in the sequence.
std::vector< std::vector< double > > ConvertRecobHitsToVector(std::vector< art::Ptr< recob::Hit > > const &hits)
Takes hit map and returns a 2D vector representing wire and tick, filled with the charge...
Interface to class computing cluster parameters.
void fill_ptr_vector(std::vector< Ptr< T >> &ptrs, H const &h)
Definition: Ptr.h:464
std::unique_ptr< art::Assns< recob::Cluster, recob::Hit > > associations
RunNumber_t run() const
Definition: Event.h:77
void ConvertBinsToClusters(std::vector< std::vector< double > > const &image, std::vector< std::vector< int > > const &allClusterBins, std::vector< art::PtrVector< recob::Hit > > &clusters)
Takes a vector of clusters (itself a vector of hits) and turns them into clusters using the initial h...
unsigned int GetMinSize()
Minimum size of cluster to save.
art framework interface to geometry description
Encapsulate the construction of a single detector plane.
int GlobalWire(geo::WireID const &wireID)
Find the global wire position.