CMS 3D CMS Logo

MTDThresholdClusterizer.cc
Go to the documentation of this file.
1 // Our own includes
4 
7 
10 
11 // STL
12 #include <stack>
13 #include <vector>
14 #include <iostream>
15 #include <atomic>
16 using namespace std;
17 
18 //#define DEBUG_ENABLED
19 #ifdef DEBUG_ENABLED
20 #define DEBUG(x) do { std::cout << x << std::endl; } while (0)
21 #else
22 #define DEBUG(x)
23 #endif
24 
25 //----------------------------------------------------------------------------
27 //----------------------------------------------------------------------------
29  (edm::ParameterSet const& conf) :
30  // Get energy thresholds
31  theHitThreshold( conf.getParameter<double>("HitThreshold") ),
32  theSeedThreshold( conf.getParameter<double>("SeedThreshold") ),
33  theClusterThreshold( conf.getParameter<double>("ClusterThreshold") ),
34  theNumOfRows(0), theNumOfCols(0), theCurrentId(0),
35  theBuffer(theNumOfRows, theNumOfCols ),
36  bufferAlreadySet(false)
37 {
38 }
41 
42 
43 // Configuration descriptions
44 void
46  desc.add<double>("HitThreshold", 0.);
47  desc.add<double>("SeedThreshold", 0.);
48  desc.add<double>("ClusterThreshold", 0.);
49 }
50 
51 //----------------------------------------------------------------------------
54 //----------------------------------------------------------------------------
55 bool MTDThresholdClusterizer::setup(const MTDGeometry* geom, const MTDTopology* topo, const DetId& id)
56 {
57  theCurrentId=id;
58  //using geopraphicalId here
59  const auto& thedet = geom->idToDet(id);
60  if( thedet == nullptr ) {
61  throw cms::Exception("MTDThresholdClusterizer") << "GeographicalID: " << std::hex
62  << id.rawId()
63  << " is invalid!" << std::dec
64  << std::endl;
65  return false;
66  }
67  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(thedet->topology());
68  const RectangularMTDTopology& topol = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
69 
70  // Get the new sizes.
71  unsigned int nrows = topol.nrows(); // rows in x
72  unsigned int ncols = topol.ncolumns(); // cols in y
73 
74  theNumOfRows = nrows; // Set new sizes
75  theNumOfCols = ncols;
76 
77  DEBUG("Buffer size [" << theNumOfRows+1 << "," << theNumOfCols+1 << "]");
78 
79  if ( nrows > theBuffer.rows() ||
80  ncols > theBuffer.columns() )
81  { // change only when a larger is needed
82  // Resize the buffer
83  theBuffer.setSize(nrows+1,ncols+1); // +1 needed for MTD
84  bufferAlreadySet = true;
85  }
86 
87  return true;
88 }
89 //----------------------------------------------------------------------------
95 //----------------------------------------------------------------------------
97  const MTDGeometry* geom,
98  const MTDTopology* topo,
100 
103 
104  // Do not bother for empty detectors
105  if (begin == end)
106  {
107  edm::LogInfo("MTDThresholdClusterizer") << "No hits to clusterize";
108  return;
109  }
110 
111  DEBUG("Input collection " << input.size());
112  assert(output.empty());
113 
114  std::set<unsigned> geoIds;
115  std::multimap<unsigned, unsigned> geoIdToIdx;
116 
117  unsigned index = 0;
118  for(const auto& hit : input)
119  {
120  MTDDetId mtdId=MTDDetId(hit.detid());
121  if (mtdId.subDetector() != MTDDetId::FastTime)
122  {
123  throw cms::Exception("MTDThresholdClusterizer") << "MTDDetId: " << std::hex
124  << mtdId.rawId()
125  << " is invalid!" << std::dec
126  << std::endl;
127  }
128 
129  if ( mtdId.mtdSubDetector() == MTDDetId::BTL )
130  {
131  BTLDetId hitId(hit.detid());
132  DetId geoId = hitId.geographicalId( (BTLDetId::CrysLayout) topo->getMTDTopologyMode() ); //for BTL topology gives different layout id
133  geoIdToIdx.emplace(geoId,index);
134  geoIds.emplace(geoId);
135  ++index;
136  }
137  else if ( mtdId.mtdSubDetector() == MTDDetId::ETL )
138  {
139  ETLDetId hitId(hit.detid());
140  DetId geoId = hitId.geographicalId();
141  geoIdToIdx.emplace(geoId,index);
142  geoIds.emplace(geoId);
143  ++index;
144  }
145  else
146  {
147  throw cms::Exception("MTDThresholdClusterizer") << "MTDDetId: " << std::hex
148  << mtdId.rawId()
149  << " is invalid!" << std::dec
150  << std::endl;
151  }
152  }
153 
154  //cluster hits within geoIds (modules)
155  for(unsigned id : geoIds) {
156  // Set up the clusterization on this DetId.
157  if ( !setup(geom,topo,DetId(id)) )
158  return;
159 
160  auto range = geoIdToIdx.equal_range(id);
161  DEBUG("Matching Ids for " << std::hex << id << std::dec << " [" << range.first->second << "," << range.second->second << "]");
162 
163  // Copy MTDRecHits to the buffer array; select the seed hits
164  // on the way, and store them in theSeeds.
165  for(auto itr = range.first; itr != range.second; ++itr) {
166  const unsigned hitidx = itr->second;
167  copy_to_buffer(begin+hitidx);
168  }
169 
170  FTLClusterCollection::FastFiller clustersOnDet(output,id);
171 
172  for (unsigned int i = 0; i < theSeeds.size(); i++)
173  {
174  if ( theBuffer.energy(theSeeds[i]) > theSeedThreshold )
175  { // Is this seed still valid?
176  // Make a cluster around this seed
177  const FTLCluster & cluster = make_cluster( theSeeds[i] );
178 
179  // Check if the cluster is above threshold
180  if ( cluster.energy() > theClusterThreshold)
181  {
182  DEBUG("putting in this cluster " << i << " #hits:" << cluster.size()
183  << " E:" << cluster.energy()
184  << " T:" << cluster.time()
185  << " X:" << cluster.x()
186  << " Y:" << cluster.y());
187  clustersOnDet.push_back( cluster );
188  }
189  }
190  }
191 
192  // Erase the seeds.
193  theSeeds.clear();
194  // Need to clean unused hits from the buffer array.
195  for(auto itr = range.first; itr != range.second; ++itr) {
196  const unsigned hitidx = itr->second;
197  clear_buffer(begin+hitidx);
198  }
199  }
200 }
201 
202 //----------------------------------------------------------------------------
208 //----------------------------------------------------------------------------
210 {
211  theBuffer.clear( itr->row(), itr->column() );
212 }
213 
214 //----------------------------------------------------------------------------
216 //----------------------------------------------------------------------------
218 {
219  int row = itr->row();
220  int col = itr->column();
221  float energy = itr->energy();
222  float time = itr->time();
223  float timeError = itr->timeError();
224 
225  DEBUG("ROW " << row << " COL " << col << " ENERGY " << energy << " TIME " << time);
226  if ( energy > theHitThreshold) {
227  theBuffer.set( row, col, energy , time, timeError);
228  if ( energy > theSeedThreshold) theSeeds.push_back( FTLCluster::FTLHitPos(row,col));
229  //sort seeds?
230  }
231 }
232 
233 
234 //----------------------------------------------------------------------------
236 //----------------------------------------------------------------------------
237 FTLCluster
239 {
240 
241  //First we acquire the seeds for the clusters
242  float seed_energy= theBuffer.energy(hit.row(), hit.col());
243  float seed_time= theBuffer.time(hit.row(), hit.col());
244  float seed_time_error= theBuffer.time_error(hit.row(), hit.col());
245  theBuffer.clear(hit);
246 
247  AccretionCluster acluster;
248  acluster.add(hit, seed_energy, seed_time, seed_time_error);
249 
250  bool stopClus=false;
251  //Here we search all hits adjacent to all hits in the cluster.
252  while ( ! acluster.empty() && ! stopClus)
253  {
254  //This is the standard algorithm to find and add a hit
255  auto curInd = acluster.top(); acluster.pop();
256  for ( auto c = std::max(0,int(acluster.y[curInd]-1)); c < std::min(int(acluster.y[curInd]+2),int(theBuffer.columns())) && !stopClus; ++c) {
257  for ( auto r = std::max(0,int(acluster.x[curInd]-1)); r < std::min(int(acluster.x[curInd]+2),int(theBuffer.rows())) && !stopClus; ++r) {
258  if ( theBuffer.energy(r,c) > theHitThreshold) {
259  FTLCluster::FTLHitPos newhit(r,c);
260  if (!acluster.add( newhit, theBuffer.energy(r,c), theBuffer.time(r,c), theBuffer.time_error(r,c)))
261  {
262  stopClus=true;
263  break;
264  }
265  theBuffer.clear(newhit);
266  }
267  }
268  }
269  } // while accretion
270 
271  FTLCluster cluster( theCurrentId, acluster.isize,
272  acluster.energy.data(), acluster.time.data(), acluster.timeError.data(),
273  acluster.x.data(), acluster.y.data(),
274  acluster.xmin, acluster.ymin);
275  return cluster;
276 }
void clusterize(const FTLRecHitCollection &input, const MTDGeometry *geom, const MTDTopology *topo, FTLClusterCollection &output) override
Cluster hits. This method operates on a matrix of hits and finds the largest contiguous cluster aroun...
T getParameter(std::string const &) const
float y() const
Definition: FTLCluster.h:113
CrysLayout
Definition: BTLDetId.h:59
std::array< float, MAXSIZE > time
std::array< float, MAXSIZE > timeError
FTLRecHitCollection::const_iterator RecHitIterator
int getMTDTopologyMode() const
Definition: MTDTopology.h:74
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:50
std::vector< FTLRecHit >::const_iterator const_iterator
def setup(process, global_tag, zero_tesla=False)
Definition: GeneralSetup.py:2
float time() const
Definition: FTLCluster.h:118
int ncolumns() const override
MTDThresholdClusterizer(edm::ParameterSet const &conf)
Constructor:
bool add(FTLCluster::FTLHitPos const &p, float const ienergy, float const itime, float const itimeError)
int nrows() const override
Detector identifier base class for the MIP Timing Layer.
Definition: MTDDetId.h:21
std::array< UShort, MAXSIZE > y
static std::string const input
Definition: EdmProvDump.cc:45
static void fillDescriptions(edm::ParameterSetDescription &desc)
const MTDGeomDet * idToDet(DetId) const override
Definition: MTDGeometry.cc:184
bool setup(const MTDGeometry *geometry, const MTDTopology *topo, const DetId &id)
float x() const
Definition: FTLCluster.h:108
virtual const PixelTopology & specificTopology() const
constexpr int row() const
Definition: FTLCluster.h:61
#define end
Definition: vmac.h:39
T min(T a, T b)
Definition: MathUtil.h:58
ParameterDescriptionBase * add(U const &iLabel, T const &value)
void copy_to_buffer(RecHitIterator itr)
Copy FTLRecHit into the buffer, identify seeds.
int size() const
Definition: FTLCluster.h:129
const_iterator end() const
Definition: DetId.h:18
float energy() const
Definition: FTLCluster.h:138
std::array< float, MAXSIZE > energy
#define DEBUG(x)
SubDetector subDetector() const
Definition: MTDDetId.h:55
FTLCluster make_cluster(const FTLCluster::FTLHitPos &hit)
The actual clustering algorithm: group the neighboring hits around the seed.
Detector identifier class for the Endcap Timing Layer.
Definition: ETLDetId.h:15
#define begin
Definition: vmac.h:32
size_type size() const
Detector identifier class for the Barrel Timing Layer. The crystal count must start from 0...
Definition: BTLDetId.h:18
std::array< UShort, MAXSIZE > x
int mtdSubDetector() const
Definition: MTDDetId.h:58
col
Definition: cuy.py:1010
void clear_buffer(RecHitIterator itr)
Clear the internal buffer array.
constexpr int col() const
Definition: FTLCluster.h:62
const_iterator begin() const