SmallClusterFinder_module.cc
Go to the documentation of this file.
1 ////////////////////////////////////////////////////////////////////////
2 //
3 // \file SmallClusterFinder.cxx
4 //
5 // \author corey.adams@yale.edu
6 //
7 // This algorithm is designed to find small clusters that could correspond to gammas
8 // or low energy electrons.
9 //
10 /* There are two parameters that matter from the fcl file:
11  fNHitsInClust is the number of hits that should be in these small clusters
12  ^-- Gamma events seem to rarely have more than 4 hits in the cluster
13  ^-- SN events are unclear. Should this even be used for SN?
14  fRadiusSizePar is the distance (in cm) between the small clusters and any other hits.
15 
16  This algorithm sorts the hits by plane, and then looks at each hit individually. If
17  there is a hit within RadiusSizePar, it gets added to a local list. All other hits
18  are ignored. Then, if the number of hits that got added to the local list is greater
19  then NHitsInClust, the original hit is ignored. If it's less, the original hit is
20  presumed to be part of a very small (or single hit) cluster. So its added to the list
21  of hits in the small cluster.
22 
23  All of the small clusters are then split apart into groups in the way you would expect.
24  Each cluster is assigned an ID number to distinguish it, and the hits that aren't
25  identified as small clusters all end up in the "leftover" cluster. The numbering scheme
26  is ID = 100*iPlane + Cluster on that plane, and the leftover hits are the first (0th)
27  cluster written out.
28 
29  All of the heavy lifting is done is the SmallClusterFinderAlg.
30  This module remains responsible for interacting with the framework, getting hits,
31  writing clusters, etc.
32 
33  Thanks to Andrzej for the basic alg.
34 
35  -Corey
36 */
37 //
38 ///////////////////////////////////////////////////////////////////////
39 
40 #include <iostream>
41 
42 // include the proper bit of the framework
46 
47 //All the larsoft goodies:
59 
60 namespace cluster {
61 
63  public:
64  explicit SmallClusterFinder(fhicl::ParameterSet const& pset);
65 
66  private:
67  void beginJob() override;
68  void produce(art::Event& evt) override; /**Routine that finds the cluster and sets
69  the dTdW of the 2D shower*/
70 
72 
73  //input parameters
75  bool verbose;
76  // double fRadiusSizePar; //Determines the max radius of the cluster, must be separated
77  // double fNHitsInClust; //Forces cluster to have a max number of hits
78  // Remember, this is the *small* cluster finder
79 
80  SmallClusterFinderAlg fSmallClusterFinderAlg; //object that actually finds and sorts gammas
81 
82  unsigned int fNPlanes; // number of planes
83 
85  unsigned int& p,
86  unsigned int& cs,
87  unsigned int& t,
88  unsigned int& w);
89 
90  }; // class SmallAngleFinder
91 
92 }
93 namespace cluster {
95  : EDProducer{pset}, fSmallClusterFinderAlg(pset.get<fhicl::ParameterSet>("smallClustAlg"))
96  {
97  fHitFinderModuleLabel = pset.get<std::string>("HitFinderModuleLabel");
98  verbose = pset.get<bool>("Verbose");
99 
100  produces<std::vector<recob::Cluster>>(); //This code makes clusters
101  produces<art::Assns<recob::Cluster, recob::Hit>>(); //Matches clusters with hits
102  }
103 
104  // ***************** //
105  void
107  {
108  // this will not change on a run per run basis.
109  fNPlanes = geom->Nplanes(); //get the number of planes in the TPC
110  }
111 
112  // ***************** //
113  // This method actually makes the clusters.
114  void
116  {
117  /**Get Clusters*/
118 
119  //Get the hits for this event:
121  evt.getByLabel(fHitFinderModuleLabel, HitListHandle);
122 
123  //A vector to hold hits, not yet filled:
124  std::vector<art::Ptr<recob::Hit>> hitlist;
125 
126  //How many hits in this event? Tell user:
127  if (verbose)
128  std::cout << " ++++ Hitsreceived received " << HitListHandle->size() << " +++++ "
129  << std::endl;
130  //Catch the case were there are no hits in the event:
131  if (HitListHandle->size() == 0) {
132  if (verbose) std::cout << "No hits received! Exiting." << std::endl;
133  return;
134  }
135  hitlist.resize(HitListHandle->size());
136 
137  //wrap the hits in art::Ptrs to pass to the Alg
138  for (unsigned int iHit = 0; iHit < hitlist.size(); iHit++) {
139  hitlist[iHit] = art::Ptr<recob::Hit>(HitListHandle, iHit);
140  }
141 
142  //std::cout << "Passing " << hitlist.size() << " hits to the alg." << std::endl;
143 
144  // Now run the alg to find the gammas:
145  auto const clockData = art::ServiceHandle<detinfo::DetectorClocksService const>()->DataFor(evt);
146  auto const detProp =
148  util::GeometryUtilities const gser{*geom, clockData, detProp};
149  fSmallClusterFinderAlg.FindSmallClusters(gser, clockData, detProp, hitlist);
150 
151  // make an art::PtrVector of the clusters
152  auto SmallClusterFinder = std::make_unique<std::vector<recob::Cluster>>();
153  auto assn = std::make_unique<art::Assns<recob::Cluster, recob::Hit>>();
154 
155  // prepare the algorithm to compute the cluster characteristics;
156  // we use the "standard" one here; configuration would happen here,
157  // but we are using the default configuration for that algorithm
159 
160  for (unsigned int iplane = 0; iplane < fNPlanes; iplane++) {
161 
162  auto const leftoverHits = fSmallClusterFinderAlg.GetLeftoversByPlane(iplane);
163 
164  //write the leftover hits as a cluster:
165  if (leftoverHits.size() != 0) {
166  // pick some information from the first hit
167  geo::PlaneID planeID = leftoverHits.front()->WireID().planeID();
168  if (verbose)
169  std::cout << "Writing leftover hits to cluster ID: " << iplane * 100 << std::endl;
170 
171  ClusterParamAlgo.ImportHits(gser, leftoverHits);
172 
173  // create the recob::Cluster directly in the vector
174  ClusterCreator leftover(gser,
175  ClusterParamAlgo, // algo
176  0., // start_wire
177  0., // sigma_start_wire
178  0., // start_tick
179  0., // sigma_start_tick
180  0., // end_wire
181  0., // sigma_end_wire,
182  0., // end_tick
183  0., // sigma_end_tick
184  iplane * 100, // ID
185  geom->Plane(iplane, planeID.TPC, planeID.Cryostat).View(),
186  planeID, // plane
187  recob::Cluster::Sentry // sentry
188  );
189 
190  SmallClusterFinder->emplace_back(leftover.move());
191 
192  util::CreateAssn(evt, *SmallClusterFinder, leftoverHits, *assn);
193  } //leftovers are written for this plane, if they exist.
194 
195  auto const smallClusters = fSmallClusterFinderAlg.GetSmallClustersByPlane(iplane);
196  for (unsigned int i = 0; i < smallClusters.size(); i++) {
197  // pick some information from the first hit
198  geo::PlaneID planeID; // invalid by default
199  if (!smallClusters.empty()) planeID = smallClusters[i].front()->WireID().planeID();
200 
201  ClusterParamAlgo.ImportHits(gser, smallClusters[i]);
202 
203  // create the recob::Cluster directly in the vector
204  ClusterCreator clust(gser,
205  ClusterParamAlgo, // algo
206  0., // start_wire
207  0., // sigma_start_wire
208  0., // start_tick
209  0., // sigma_start_tick
210  0., // end_wire
211  0., // sigma_end_wire,
212  0., // end_tick
213  0., // sigma_end_tick
214  iplane * 100 + i + 1, // ID
215  geom->Plane(iplane, planeID.TPC, planeID.Cryostat).View(),
216  planeID, // plane
217  recob::Cluster::Sentry // sentry
218  );
219 
220  SmallClusterFinder->emplace_back(clust.move());
221  // associate the hits to this cluster
222  util::CreateAssn(evt, *SmallClusterFinder, smallClusters[i], *assn);
223  }
224  }
225 
227  evt.put(std::move(assn));
228  } //end produce
229 
231 }
Class managing the creation of a new recob::Cluster object.
PlaneGeo const & Plane(unsigned int const p, unsigned int const tpc=0, unsigned int const cstat=0) const
Returns the specified wire.
void produce(art::Event &evt) override
std::string string
Definition: nybbler.cc:12
SmallClusterFinderAlg fSmallClusterFinderAlg
EDProducer(fhicl::ParameterSet const &pset)
Definition: EDProducer.h:20
The data type to uniquely identify a Plane.
Definition: geo_types.h:472
SmallClusterFinder(fhicl::ParameterSet const &pset)
CryostatID_t Cryostat
Index of cryostat.
Definition: geo_types.h:212
void FindSmallClusters(util::GeometryUtilities const &gser, detinfo::DetectorClocksData const &dataClocks, detinfo::DetectorPropertiesData const &detProp, std::vector< art::Ptr< recob::Hit >> allHits)
Cluster finding and building.
static const SentryArgument_t Sentry
An instance of the sentry object.
Definition: Cluster.h:182
View_t View() const
Which coordinate does this plane measure.
Definition: PlaneGeo.h:184
bool getByLabel(std::string const &label, std::string const &instance, Handle< PROD > &result) const
Definition: DataViewImpl.h:633
unsigned int Nplanes(unsigned int tpc=0, unsigned int cstat=0) const
Returns the total number of wire planes in the specified TPC.
#define DEFINE_ART_MODULE(klass)
Definition: ModuleMacros.h:67
const double a
def move(depos, offset)
Definition: depos.py:107
Helper functions to create a cluster.
Wrapper for ClusterParamsAlgBase objects to accept diverse input.
std::vector< art::Ptr< recob::Hit > > GetLeftoversByPlane(unsigned int iPlane)
p
Definition: test.py:223
Wrapper for ClusterParamsAlgBase objects to accept arbitrary input.
ProductID put(std::unique_ptr< PROD > &&edp, std::string const &instance={})
Definition: DataViewImpl.h:686
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.
int GetPlaneAndTPC(art::Ptr< recob::Hit > a, unsigned int &p, unsigned int &cs, unsigned int &t, unsigned int &w)
Declaration of signal hit object.
Encapsulate the construction of a single detector plane.
std::vector< std::vector< art::Ptr< recob::Hit > > > GetSmallClustersByPlane(unsigned int iPlane)
art::ServiceHandle< geo::Geometry const > geom
Interface to class computing cluster parameters.
TCEvent evt
Definition: DataStructs.cxx:7
const char * cs
TPCID_t TPC
Index of the TPC within its cryostat.
Definition: geo_types.h:406
QTextStream & endl(QTextStream &s)