LArSoft  v07_13_02
Liquid Argon Software toolkit - http://larsoft.org/
FuzzyClusterMerger_module.cc
Go to the documentation of this file.
1 // Class: FuzzyClusterMerger
3 // Module Type: producer
4 // File: FuzzyClusterMerger_module.cc
5 //
6 // Generated at Tue May 27 14:15:41 2014 by Kazuhiro Terao using artmod
7 // from cetpkgsupport v1_05_04.
9 
18 #include "fhiclcpp/ParameterSet.h"
19 
34 
41 
42 
43 
44 #include <memory>
45 
46 namespace cluster {
47 
49 
50  public:
51 
52  explicit FuzzyClusterMerger(fhicl::ParameterSet const & p);
53 
54  virtual ~FuzzyClusterMerger();
55 
56  void produce(art::Event & evt) override;
57 
58  private:
59 
62 
64  std::string fClusterModuleLabel;
65 
66 
67 
70 
72 
73  double fOOCS1MaxAngle;
74 
76  double fSDSqDistCut;
77 
79 
81 
85  double fAI2AngleCut;
86  double fAI2MinLength;
87 
92 
94 
97  double fPSD2MinDistSqd;
98 
99 
100 // TSep1UseEP: true
101 // OOCS1MaxAngle: 20. # OutOfConeSeparate 1st stage
102 //
103 // SDMinHits: 10. # CBAlgoShortestDist # SetMinHits; SetSquaredDistanceCut
104 // SDSqDistCut: 5.
105 //
106 // # 2nd stage merge
107 // #TSep2Debug: false # CBAlgoTrackSeparate // SetDebug(false); SetVerbose(false); SetUseEP(true);
108 // # TSep2Verbose: false
109 // TSep2UseEP: true
110 //
111 // # OOCS2Debug: false # CBAlgoOutOfConeSeparate // SetDebug(false); SetVerbose(false); SetMaxAngleSep(20.);
112 // # OOCS2Verbose: false
113 // OOCS2MaxAngle: 20.
114 //
115 // AI2MinHits: 50 # CBAlgoAngleIncompat // SetMinHits(50); SetAllow180Ambig(true); SetUseOpeningAngle(false);
116 // AI2Allow180Ambig: true # // SetAngleCut(10.); SetMinLength(20.); SetDebug(false);
117 // AI2UseOpeningAngle: false
118 // AI2AngleCut: 10.
119 // AI2MinLength: 20.
120 // # AI2Debug: false
121 //
122 // # COM2Debug: false # CBAlgoCenterOfMass // SetDebug(false); SetVerbose(false); UseCOMInPoly(true);
123 // # COM2Verbose: false # // UseCOMInCone(true); UseCOMNearClus(true); SetLengthReach(3.);
124 // COM2UseCOMInPoly: true
125 // COM2UseCOMInCone: true
126 // COM2UseCOMNearClus: true
127 // COM2SetLengthReach: 3.
128 //
129 // PO2MinHits: 0 # CBAlgoPolyOverlap // SetMinNumHits(0);
130 //
131 // PSD2MinHits: 30 # CCBAlgoPolyShortestDist; // SetMinNumHits(30); SetMaxNumHits(9999); SetMinDistSquared(1.); SetDebug(false);
132 // PSD2MaxHits: 9999
133 // PSD2MinDistSqd: 1
134 
135 
136 
137 
138  };
139 }
140 
141 namespace cluster {
142 
144  {
145  // Declare output data products
146  produces< std::vector<recob::Cluster> >();
147  produces< art::Assns<recob::Cluster, recob::Hit> >();
148 
149  // Fill fcl parameter
150  fClusterModuleLabel = p.get<std::string>("InputClusterLabel");
151 
152  fTSep1UseEP = p.get<bool>("TSep1UseEP");
153 
154  fOOCS1MaxAngle = p.get<double>("OOCS1MaxAngle");
155 
156  fSDMinHits = p.get<int>("SDMinHits");
157  fSDSqDistCut = p.get<double>("SDSqDistCut");
158 
159  fTSep2UseEP = p.get<bool>("TSep2UseEP");
160 
161  fOOCS2MaxAngle = p.get<double>("OOCS2MaxAngle");
162 
163  fAI2MinHits = p.get<int>("AI2MinHits");
164  fAI2Allow180Ambig = p.get<bool>("AI2Allow180Ambig");
165  fAI2UseOpeningAngle = p.get<bool>("AI2UseOpeningAngle");
166  fAI2AngleCut = p.get<double>("AI2AngleCut");
167  fAI2MinLength = p.get<double>("AI2MinLength");
168 
169 
170  fCOM2UseCOMInPoly = p.get<bool>("COM2UseCOMInPoly");
171  fCOM2UseCOMInCone = p.get<bool>("COM2UseCOMInCone");
172  fCOM2UseCOMNearClus = p.get<bool>("COM2UseCOMNearClus");
173  fCOM2SetLengthReach = p.get<double>("COM2SetLengthReach");
174 
175 
176  fPO2MinHits = p.get<int>("PO2MinHits");
177 
178  fPSD2MinHits = p.get<int>("PSD2MinHits");
179  fPSD2MaxHits = p.get<int>("PSD2MaxHits");
180  fPSD2MinDistSqd = p.get<double>("PSD2MinDistSqd");
181 
182 
183 
184  //--- Configure Merging Algorithm ---//
185 
186 
188  //fCMerge.GetManager(0).DebugMode(::cmtool::CMergeManager::kPerIteration);
189 
190  // Prohibit algorithms
191  auto prohib_algo_1_1 = new ::cmtool::CBAlgoTrackSeparate;
192  prohib_algo_1_1->SetUseEP(fTSep1UseEP);
193 
194  auto prohib_algo_1_2 = new ::cmtool::CBAlgoOutOfConeSeparate;
195  prohib_algo_1_2->SetMaxAngleSep(fOOCS1MaxAngle);
196 
197  auto prohib_algo_1 = new ::cmtool::CBAlgoArray;
198  prohib_algo_1->AddAlgo(prohib_algo_1_1,false);
199  prohib_algo_1->AddAlgo(prohib_algo_1_2,false);
200 
201  fCMerge.GetManager(0).AddSeparateAlgo( prohib_algo_1 );
202 
203  // Merge algorithms
204  auto merge_algo_1_1 = new ::cmtool::CBAlgoShortestDist;
205  merge_algo_1_1->SetMinHits(fSDMinHits);
206  merge_algo_1_1->SetSquaredDistanceCut(fSDSqDistCut);
207 
208  auto merge_algo_1_2 = new ::cmtool::CBAlgoStartTrack;
209 
210  auto merge_algo_1_3 = new ::cmtool::CBAlgoPolyContain;
211 
212  auto merge_algo_1 = new ::cmtool::CBAlgoArray;
213  merge_algo_1->AddAlgo(merge_algo_1_1,false);
214  merge_algo_1->AddAlgo(merge_algo_1_2,false);
215  merge_algo_1->AddAlgo(merge_algo_1_3,false);
216 
217  fCMerge.GetManager(0).AddMergeAlgo( merge_algo_1 );
218 
219  // Configure 2nd stage merging
220  //auto& fCMerge.GetManager(1) = GetManager(1);
222  //fCMerge.GetManager(0).DebugMode(::cmtool::CMergeManager::kPerIteration);
223 
224  // Prohibit algorithms
225  auto prohib_algo_2_1 = new ::cmtool::CBAlgoTrackSeparate;
226  // prohib_algo_2_1->SetDebug(false);
227  // prohib_algo_2_1->SetVerbose(false);
228  prohib_algo_2_1->SetUseEP(fTSep2UseEP);
229 
230  auto prohib_algo_2_2 = new ::cmtool::CBAlgoOutOfConeSeparate;
231  // prohib_algo_2_2->SetDebug(false);
232  // prohib_algo_2_2->SetVerbose(false);
233  prohib_algo_2_2->SetMaxAngleSep(fOOCS2MaxAngle);
234 
235  auto prohib_algo_2_3 = new ::cmtool::CBAlgoAngleIncompat;
236  prohib_algo_2_3->SetMinHits(fAI2MinHits);
237  prohib_algo_2_3->SetAllow180Ambig(fAI2Allow180Ambig);
238  prohib_algo_2_3->SetUseOpeningAngle(fAI2UseOpeningAngle);
239  prohib_algo_2_3->SetAngleCut(fAI2AngleCut);
240  prohib_algo_2_3->SetMinLength(fAI2MinLength);
241  // prohib_algo_2_3->SetDebug(false);
242 
243 
244 
245  auto prohib_algo_2 = new ::cmtool::CBAlgoArray;
246  prohib_algo_2->AddAlgo(prohib_algo_2_1,false);
247  prohib_algo_2->AddAlgo(prohib_algo_2_2,false);
248  prohib_algo_2->AddAlgo(prohib_algo_2_3,false);
249 
250  fCMerge.GetManager(1).AddSeparateAlgo(prohib_algo_2);
251 
252  // Merge algorithms
253  auto merge_algo_2_1 = new ::cmtool::CBAlgoCenterOfMass;
254  // merge_algo_2_1->SetDebug(false);
255  // merge_algo_2_1->SetVerbose(false);
256  merge_algo_2_1->UseCOMInPoly(fCOM2UseCOMInPoly);
257  merge_algo_2_1->UseCOMInCone(fCOM2UseCOMInCone);
258  merge_algo_2_1->UseCOMNearClus(fCOM2UseCOMNearClus);
259  merge_algo_2_1->SetLengthReach(fCOM2SetLengthReach);
260 
261 
262  auto merge_algo_2_2 = new ::cmtool::CBAlgoPolyOverlap;
263  merge_algo_2_2->SetMinNumHits(fPO2MinHits);
264 
265  auto merge_algo_2_3 = new ::cmtool::CBAlgoPolyShortestDist;
266  merge_algo_2_3->SetMinNumHits(fPSD2MinHits);
267  merge_algo_2_3->SetMaxNumHits(fPSD2MaxHits);
268  merge_algo_2_3->SetMinDistSquared(fPSD2MinDistSqd);
269  merge_algo_2_3->SetDebug(false);
270 
271  auto merge_algo_2 = new ::cmtool::CBAlgoArray;
272  merge_algo_2->AddAlgo(merge_algo_2_1,false);
273  merge_algo_2->AddAlgo(merge_algo_2_2,false);
274  merge_algo_2->AddAlgo(merge_algo_2_3,false);
275 
276  fCMerge.GetManager(1).AddMergeAlgo(merge_algo_2);
277 
278  // Prohibit algorithms
279  auto priority_algo_2 = new ::cmtool::CPAlgoIgnoreTracks;
280 
281  fCMerge.GetManager(1).AddPriorityAlgo(priority_algo_2);
282 
283  //
284  // FYI there's an algorithm to just-merge-everything if you want to do a simple test (line commented out below)
285  //
286  //fCMerge.GetManager(0).AddMergeAlgo( new CMAlgoMergeAll );
287 
288 
289  }
290 
292  {
293  // Clean up dynamic memory and other resources here.
294  }
295 
297  {
298  std::unique_ptr<std::vector<recob::Cluster> > out_clusters(new std::vector<recob::Cluster>);
299  std::unique_ptr<art::Assns<recob::Cluster, recob::Hit> > out_assn(new art::Assns<recob::Cluster, recob::Hit>);
300 
302 
303  //
304  // Preparation
305  //
306 
307  // Retrieve input clusters
309  evt.getByLabel(fClusterModuleLabel,cHandle);
310 
311  if(!cHandle.isValid())
312  throw cet::exception(__FUNCTION__) << "Invalid input cluster label!" << std::endl;
313 
314  // Cluster type conversion: recob::Hit => util::PxHit
315  std::vector<std::vector< ::util::PxHit> > local_clusters;
316  art::FindManyP<recob::Hit> hit_m(cHandle, evt, fClusterModuleLabel);
318  for(size_t i=0; i<cHandle->size(); ++i) {
319 
320  local_clusters.push_back(std::vector< ::util::PxHit>());
321 
322  const std::vector<art::Ptr<recob::Hit> >& all_hits = hit_m.at(i);
323  std::vector<art::Ptr<recob::Hit>> good_hits;
324  std::copy_if(
325  all_hits.begin(), all_hits.end(), std::back_inserter(good_hits),
326  [](auto const& pHit){ return pHit->Integral() > 0.; }
327  );
328  if (all_hits.size() > good_hits.size()) {
329  mf::LogWarning("FuzzyClusterMerger")
330  << "Dropped " << (all_hits.size() - good_hits.size()) << "/"
331  << all_hits.size()
332  << " hits which had non-positive integral in cluster #" << i;
333  }
334  if (good_hits.empty()) {
335  mf::LogError("FuzzyClusterMerger")
336  << "Cluster #" << i << " is skipped because of no good hits!";
337  continue;
338  }
339 
340  conv.GeneratePxHit(good_hits, local_clusters.back());
341  }
342 
343  //--- Process merging ---//
344  fCMerge.Process(local_clusters);
345 
346  // Store output
347  auto merged_clusters = fCMerge.GetResult().GetResult();
348 
349  auto const& cpan_v = fCMerge.GetClusters();
350  if(merged_clusters.size()!=cpan_v.size())
351 
352  throw cet::exception(__FUNCTION__) << "LOGIC ERROR: merged cluster id length != output cluster counts..." << std::endl;
353 
354 
355 
356  for(size_t out_index=0; out_index < merged_clusters.size(); ++out_index) {
357 
358  // To save typing let's just retrieve const cluster_params instance
359  const cluster_params &res = cpan_v[out_index].GetParams();
360 
361  // this "algo" is actually parroting its cluster_params
362  LazyClusterParamsAlg algo(res);
363 
364  std::vector<art::Ptr<recob::Hit> > merged_hits;
365  for(auto const& c_index : merged_clusters[out_index]) {
366  const std::vector<art::Ptr<recob::Hit> >& hits = hit_m.at(c_index);
367  merged_hits.reserve(merged_hits.size() + hits.size());
368  for(auto const& hit : hits) {
369  if (hit->Integral() > 0.) merged_hits.push_back(hit);
370  }
371  }
372 
373  // the full plane needed but not a part of cluster_params...
374  // get the one from the first hit
375  geo::PlaneID plane; // invalid by default
376  if (!merged_hits.empty()) plane = merged_hits.front()->WireID().planeID();
377 
378  // View_t needed but not a part of cluster_params, so retrieve it here
379  geo::View_t view_id = geo->Plane(plane).View();
380 
381  // Push back a new cluster data product with parameters copied from cluster_params
382  out_clusters->emplace_back(
383  res.start_point.w / fGeoU.WireToCm(), // start_wire
384  0., // sigma_start_wire
385  res.start_point.t / fGeoU.TimeToCm(), // start_tick
386  0., // sigma_start_tick
387  algo.StartCharge().value(), // start_charge
388  algo.StartAngle().value(), // start_angle
389  algo.StartOpeningAngle().value(), // start_opening
390  res.end_point.w / fGeoU.WireToCm(), // end_wire
391  0., // sigma_end_wire
392  res.end_point.t / fGeoU.TimeToCm(), // end_tick
393  0., // sigma_end_tick
394  algo.EndCharge().value(), // end_charge
395  algo.EndAngle().value(), // end_angle
396  algo.EndOpeningAngle().value(), // end_opening
397  algo.Integral().value(), // integral
398  algo.IntegralStdDev().value(), // integral_stddev
399  algo.SummedADC().value(), // summedADC
400  algo.SummedADCStdDev().value(), // summedADC_stddev
401  algo.NHits(), // n_hits
402  algo.MultipleHitDensity(), // multiple_hit_density
403  algo.Width(), // width
404  out_clusters->size(), // ID
405  view_id, // view
406  plane, // plane
407  recob::Cluster::Sentry // sentry
408  );
409 
410  util::CreateAssn(*this,
411  evt,
412  *(out_clusters.get()),
413  merged_hits,
414  *(out_assn.get())
415  );
416 
417  }
418 
419 
420 
421 
422 
423 
424 
425  /*
426  for(size_t out_index=0; out_index < merged_clusters.size(); ++out_index) {
427 
428  // To save typing let's just retrieve const cluster_params instance
429  const cluster_params &res = cpan_v[out_index].GetParams();
430 
431  // View_t needed but not a part of cluster_params, so retrieve it here
432  geo::View_t view_id = geo->Plane(cpan_v[out_index].Plane()).View();
433 
434  // Push back a new cluster data product with parameters copied from cluster_params
435  out_clusters->push_back( recob::Cluster( res.start_point.w / fGeoU.WireToCm(), 0, // start wire & error
436  res.start_point.t / fGeoU.TimeToCm(), 0, // start time & error
437  res.end_point.w / fGeoU.WireToCm(), 0, // end wire & error
438  res.end_point.t / fGeoU.TimeToCm(), 0, // end time & error
439  res.cluster_angle_2d, 0, // dT/dW (slope)
440  0, 0, // dQ/dW (what is that?)
441  res.sum_charge, // charge sum
442  view_id, // geo::View_t
443  out_clusters->size() // Cluster ID
444  )
445  );
446 
447 
448 
449  std::vector<art::Ptr<recob::Hit> > merged_hits;
450 
451  for(auto const& c_index : merged_clusters[out_index]) {
452 
453  const std::vector<art::Ptr<recob::Hit> >& hits = hit_m.at(c_index);
454 
455  merged_hits.reserve(merged_hits.size() + hits.size());
456 
457  for(auto const& ptr : hits) merged_hits.push_back(ptr);
458 
459  }
460 
461  util::CreateAssn(*this,
462  evt,
463  *(out_clusters.get()),
464  merged_hits,
465  *(out_assn.get())
466  );
467 
468  }*/
469 
470  evt.put(std::move(out_clusters));
471  evt.put(std::move(out_assn));
472  }
473 }
474 
Class def header for a class CBAlgoArray.
Class def header for a class CMergeHelper.
Algorithm class inheriting pre-computed results.
Algorithm class inheriting cluster parameters.
Class def header for a class CBAlgoShortestDistSmallCluster.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
virtual Measure_t EndAngle() override
Computes the angle of the cluster.
virtual size_t NHits() override
Returns the number of hits in the cluster.
enum geo::_plane_proj View_t
Enumerate the possible plane projections.
Declaration of signal hit object.
The data type to uniquely identify a Plane.
Definition: geo_types.h:250
std::vector< std::vector< unsigned short > > GetResult() const
Double_t TimeToCm() const
Double_t WireToCm() const
virtual Measure_t SummedADC() override
Computes the total charge of the cluster from Hit::SummedADC()
virtual Measure_t StartCharge() override
Computes the charge on the first and last wire of the track.
MaybeLogger_< ELseverityLevel::ELsev_error, false > LogError
Cluster finding and building.
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
virtual Measure_t EndOpeningAngle() override
Computes the opening angle at the start or end of the cluster.
Class def header for a class CBAlgoPolyShortestDist.
virtual Measure_t Integral() override
Computes the total charge of the cluster from Hit::Integral()
ProductID put(std::unique_ptr< PROD > &&product)
Definition: Event.h:102
bool isValid() const
Definition: Handle.h:190
Class def header for a class CBAlgoTrackSeparate.
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:171
void hits()
Definition: readHits.C:15
void GeneratePxHit(const std::vector< unsigned int > &hit_index, const std::vector< art::Ptr< recob::Hit >> hits, std::vector< util::PxHit > &pxhits) const
Generate: from 1 set of hits => 1 set of PxHits using indexes (association)
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:42
Class def header for a class CBAlgoAngleSeparate.
virtual Measure_t EndCharge() override
Computes the charge on the first and last wire of the track.
Class def header for a class CBAlgoAngleIncompat.
double t
Definition: PxUtils.h:11
T get(std::string const &key) const
Definition: ParameterSet.h:231
const std::vector< ::cluster::ClusterParamsAlg > & GetClusters() const
std::string fClusterModuleLabel
Input cluster data product producer name label.
::cmtool::CMergeHelper fCMerge
ClusterMergeHelper.
virtual Measure_t SummedADCStdDev() override
Computes the standard deviation on the charge of the cluster hits.
virtual float MultipleHitDensity() override
Fraction of wires in the cluster with more than one hit.
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.
util::PxPoint start_point
start point
Definition: ClusterParams.h:24
void AddMergeAlgo(CBoolAlgoBase *algo)
A simple method to add an algorithm for merging.
Definition: CMergeManager.h:44
const CMergeBookKeeper & GetResult() const
Definition: CMergeHelper.h:44
Declaration of cluster object.
virtual Measure_t IntegralStdDev() override
Computes the standard deviation on the charge of the cluster hits.
Detector simulation of raw signals on wires.
double w
Definition: PxUtils.h:10
::util::GeometryUtilities fGeoU
GeometryUtilities instance.
virtual float Width() override
Computes the width of the cluster.
Class def header for a class CBAlgoShortestDist.
This merge algo is looking for short tracks from the start of a shower that are overlapping a blob th...
Utility object to perform functions of association.
util::PxPoint end_point
end point
Definition: ClusterParams.h:25
virtual Measure_t StartOpeningAngle() override
Computes the opening angle at the start or end of the cluster.
virtual Measure_t StartAngle() override
Computes the angle of the cluster.
bool getByLabel(std::string const &label, std::string const &productInstanceName, Handle< PROD > &result) const
Definition: DataViewImpl.h:344
Class def header for a class CPAlgoIgnoreTracks.
MaybeLogger_< ELseverityLevel::ELsev_warning, false > LogWarning
CMergeManager & GetManager(size_t mgr_id)
Definition: CMergeHelper.cxx:8
Class def header for a class CBAlgoPolyOverlap.
Class def header for a class CBAlgoCenterOfMass.
void produce(art::Event &evt) override
TCEvent evt
Definition: DataStructs.cxx:5
void MergeTillConverge(bool doit=true)
Switch to continue merging till converges.
Definition: CMManagerBase.h:66
void AddPriorityAlgo(CPriorityAlgoBase *algo)
Setter to add an algorithm for priority determination.
Definition: CMManagerBase.h:63
void Process(const std::vector< std::vector< ::util::PxHit > > &clusters)
Namespace collecting geometry-related classes utilities.
Class def header for a class CBAlgoPolyContain.
FuzzyClusterMerger(fhicl::ParameterSet const &p)
art framework interface to geometry description
cet::coded_exception< error, detail::translate > exception
Definition: exception.h:33
void AddSeparateAlgo(CBoolAlgoBase *algo)
A simple method to add an algorithm for separation.
Definition: CMergeManager.h:47