CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
MTDThresholdClusterizer.cc
Go to the documentation of this file.
1 // Our own includes
5 
8 
12 
13 // STL
14 #include <stack>
15 #include <vector>
16 #include <iostream>
17 #include <atomic>
18 #include <cmath>
19 using namespace std;
20 
21 //#define DEBUG_ENABLED
22 #ifdef DEBUG_ENABLED
23 #define DEBUG(x) \
24  do { \
25  std::cout << x << std::endl; \
26  } while (0)
27 #else
28 #define DEBUG(x)
29 #endif
30 
31 //----------------------------------------------------------------------------
33 //----------------------------------------------------------------------------
35  : // Get energy thresholds
36  theHitThreshold(conf.getParameter<double>("HitThreshold")),
37  theSeedThreshold(conf.getParameter<double>("SeedThreshold")),
38  theClusterThreshold(conf.getParameter<double>("ClusterThreshold")),
39  theTimeThreshold(conf.getParameter<double>("TimeThreshold")),
40  thePositionThreshold(conf.getParameter<double>("PositionThreshold")),
41  theNumOfRows(0),
42  theNumOfCols(0),
43  theCurrentId(0),
44  theBuffer(theNumOfRows, theNumOfCols),
45  bufferAlreadySet(false) {}
48 
49 // Configuration descriptions
51  desc.add<double>("HitThreshold", 0.);
52  desc.add<double>("SeedThreshold", 0.);
53  desc.add<double>("ClusterThreshold", 0.);
54  desc.add<double>("TimeThreshold", 10.);
55  desc.add<double>("PositionThreshold", -1.0);
56 }
57 
58 //----------------------------------------------------------------------------
61 //----------------------------------------------------------------------------
62 bool MTDThresholdClusterizer::setup(const MTDGeometry* geom, const MTDTopology* topo, const DetId& id) {
63  theCurrentId = id;
64  //using geopraphicalId here
65  const auto& thedet = geom->idToDet(id);
66  if (thedet == nullptr) {
67  throw cms::Exception("MTDThresholdClusterizer")
68  << "GeographicalID: " << std::hex << id.rawId() << " is invalid!" << std::dec << std::endl;
69  return false;
70  }
71  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(thedet->topology());
72  const RectangularMTDTopology& topol = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
73 
74  // Get the new sizes.
75  unsigned int nrows = topol.nrows(); // rows in x
76  unsigned int ncols = topol.ncolumns(); // cols in y
77 
78  theNumOfRows = nrows; // Set new sizes
79  theNumOfCols = ncols;
80 
81  DEBUG("Buffer size [" << theNumOfRows + 1 << "," << theNumOfCols + 1 << "]");
82 
83  if (nrows > theBuffer.rows() || ncols > theBuffer.columns()) { // change only when a larger is needed
84  // Resize the buffer
85  theBuffer.setSize(nrows + 1, ncols + 1); // +1 needed for MTD
86  bufferAlreadySet = true;
87  }
88 
89  return true;
90 }
91 //----------------------------------------------------------------------------
97 //----------------------------------------------------------------------------
99  const MTDGeometry* geom,
100  const MTDTopology* topo,
104 
105  // Do not bother for empty detectors
106  if (begin == end) {
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  MTDDetId mtdId = MTDDetId(hit.detid());
120  if (mtdId.subDetector() != MTDDetId::FastTime) {
121  throw cms::Exception("MTDThresholdClusterizer")
122  << "MTDDetId: " << std::hex << mtdId.rawId() << " is invalid!" << std::dec << std::endl;
123  }
124 
125  if (mtdId.mtdSubDetector() == MTDDetId::BTL) {
126  BTLDetId hitId(hit.detid());
127  //for BTL topology gives different layout id
128  DetId geoId = hitId.geographicalId(MTDTopologyMode::crysLayoutFromTopoMode(topo->getMTDTopologyMode()));
129  geoIdToIdx.emplace(geoId, index);
130  geoIds.emplace(geoId);
131  ++index;
132  } else if (mtdId.mtdSubDetector() == MTDDetId::ETL) {
133  ETLDetId hitId(hit.detid());
134  DetId geoId = hitId.geographicalId();
135  geoIdToIdx.emplace(geoId, index);
136  geoIds.emplace(geoId);
137  ++index;
138  } else {
139  throw cms::Exception("MTDThresholdClusterizer")
140  << "MTDDetId: " << std::hex << mtdId.rawId() << " is invalid!" << std::dec << std::endl;
141  }
142  }
143 
144  //cluster hits within geoIds (modules)
145  for (unsigned id : geoIds) {
146  // Set up the clusterization on this DetId.
147  if (!setup(geom, topo, DetId(id)))
148  return;
149 
150  auto range = geoIdToIdx.equal_range(id);
151  DEBUG("Matching Ids for " << std::hex << id << std::dec << " [" << range.first->second << ","
152  << range.second->second << "]");
153 
154  // Copy MTDRecHits to the buffer array; select the seed hits
155  // on the way, and store them in theSeeds.
156  for (auto itr = range.first; itr != range.second; ++itr) {
157  const unsigned hitidx = itr->second;
158  copy_to_buffer(begin + hitidx, geom, topo);
159  }
160 
161  FTLClusterCollection::FastFiller clustersOnDet(output, id);
162 
163  for (unsigned int i = 0; i < theSeeds.size(); i++) {
164  if (theBuffer.energy(theSeeds[i]) > theSeedThreshold) { // Is this seed still valid?
165  // Make a cluster around this seed
166  const FTLCluster& cluster = make_cluster(theSeeds[i]);
167 
168  // Check if the cluster is above threshold
169  if (cluster.energy() > theClusterThreshold) {
170  DEBUG("putting in this cluster " << i << " #hits:" << cluster.size() << " E:" << cluster.energy()
171  << " T:" << cluster.time() << " X:" << cluster.x() << " Y:" << cluster.y());
172  clustersOnDet.push_back(cluster);
173  }
174  }
175  }
176 
177  // Erase the seeds.
178  theSeeds.clear();
179  // Need to clean unused hits from the buffer array.
180  for (auto itr = range.first; itr != range.second; ++itr) {
181  const unsigned hitidx = itr->second;
182  clear_buffer(begin + hitidx);
183  }
184  }
185 }
186 
187 //----------------------------------------------------------------------------
193 //----------------------------------------------------------------------------
194 void MTDThresholdClusterizer::clear_buffer(RecHitIterator itr) { theBuffer.clear(itr->row(), itr->column()); }
195 
196 //----------------------------------------------------------------------------
198 //----------------------------------------------------------------------------
200  MTDDetId mtdId = MTDDetId(itr->detid());
201  int row = itr->row();
202  int col = itr->column();
204  float energy = itr->energy();
205  float time = itr->time();
206  float timeError = itr->timeError();
207  float position = itr->position();
208  // position is the longitudinal offset that should be added into local x for bars in phi geometry
209  LocalError local_error(0, 0, 0);
210  GlobalPoint global_point(0, 0, 0);
211  if (mtdId.mtdSubDetector() == MTDDetId::BTL) {
213  BTLDetId id = itr->id();
214  DetId geoId = id.geographicalId(MTDTopologyMode::crysLayoutFromTopoMode(topo->getMTDTopologyMode()));
215  const auto& det = geom->idToDet(geoId);
216  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(det->topology());
217  const RectangularMTDTopology& topol = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
218  MeasurementPoint mp(row, col);
219  LocalPoint lp_ctr = topol.localPosition(mp);
220  LocalPoint lp(lp_ctr.x() + position + topol.pitch().first * 0.5f, lp_ctr.y(), lp_ctr.z());
221  // local coordinates of BTL module locates RecHits on the left edge of the bar (-9.2, -3.067, 3.067)
222  // (position + topol.pitch().first/2.0) is the distance from the left edge to the Hit point
223  global_point = det->toGlobal(lp);
224  BTLRecHitsErrorEstimatorIM btlError(det, lp);
225  local_error = btlError.localError();
226  } else if (mtdId.mtdSubDetector() == MTDDetId::ETL) {
228  ETLDetId id = itr->id();
229  DetId geoId = id.geographicalId();
230  const auto& det = geom->idToDet(geoId);
231  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(det->topology());
232  const RectangularMTDTopology& topol = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
233 
234  MeasurementPoint mp(row, col);
235  LocalPoint lp = topol.localPosition(mp);
236  global_point = det->toGlobal(lp);
237  }
238 
239  DEBUG("ROW " << row << " COL " << col << " ENERGY " << energy << " TIME " << time);
240  if (energy > theHitThreshold) {
241  theBuffer.set(row, col, subDet, energy, time, timeError, local_error, global_point);
242  if (energy > theSeedThreshold)
243  theSeeds.push_back(FTLCluster::FTLHitPos(row, col));
244  //sort seeds?
245  }
246 }
247 
248 //----------------------------------------------------------------------------
250 //----------------------------------------------------------------------------
252  //First we acquire the seeds for the clusters
253 
254  GeomDetEnumerators::Location seed_subdet = theBuffer.subDet(hit.row(), hit.col());
255  float seed_energy = theBuffer.energy(hit.row(), hit.col());
256  float seed_time = theBuffer.time(hit.row(), hit.col());
257  float seed_time_error = theBuffer.time_error(hit.row(), hit.col());
258  auto const seedPoint = theBuffer.global_point(hit.row(), hit.col());
259  double seed_error_xx = theBuffer.local_error(hit.row(), hit.col()).xx();
260  double seed_error_yy = theBuffer.local_error(hit.row(), hit.col()).yy();
261  theBuffer.clear(hit);
262 
263  AccretionCluster acluster;
264  acluster.add(hit, seed_energy, seed_time, seed_time_error);
265 
266  bool stopClus = false;
267  //Here we search all hits adjacent to all hits in the cluster.
268  while (!acluster.empty() && !stopClus) {
269  //This is the standard algorithm to find and add a hit
270  auto curInd = acluster.top();
271  acluster.pop();
272  for (auto c = std::max(0, int(acluster.y[curInd] - 1));
273  c < std::min(int(acluster.y[curInd] + 2), int(theBuffer.columns())) && !stopClus;
274  ++c) {
275  for (auto r = std::max(0, int(acluster.x[curInd] - 1));
276  r < std::min(int(acluster.x[curInd] + 2), int(theBuffer.rows())) && !stopClus;
277  ++r) {
278  if (theBuffer.energy(r, c) > theHitThreshold) {
279  if (std::abs(theBuffer.time(r, c) - seed_time) >
281  sqrt(theBuffer.time_error(r, c) * theBuffer.time_error(r, c) + seed_time_error * seed_time_error))
282  continue;
283  if ((seed_subdet == GeomDetEnumerators::barrel) && (theBuffer.subDet(r, c) == GeomDetEnumerators::barrel)) {
284  double hit_error_xx = theBuffer.local_error(r, c).xx();
285  double hit_error_yy = theBuffer.local_error(r, c).yy();
286  if (thePositionThreshold > 0) {
287  if (((theBuffer.global_point(r, c) - seedPoint).mag2()) >
289  (hit_error_xx + seed_error_xx + hit_error_yy + seed_error_yy))
290  continue;
291  }
292  }
293  FTLCluster::FTLHitPos newhit(r, c);
294  if (!acluster.add(newhit, theBuffer.energy(r, c), theBuffer.time(r, c), theBuffer.time_error(r, c))) {
295  stopClus = true;
296  break;
297  }
298  theBuffer.clear(newhit);
299  }
300  }
301  }
302  } // while accretion
303 
304  FTLCluster cluster(theCurrentId,
305  acluster.isize,
306  acluster.energy.data(),
307  acluster.time.data(),
308  acluster.timeError.data(),
309  acluster.x.data(),
310  acluster.y.data(),
311  acluster.xmin,
312  acluster.ymin);
313  return cluster;
314 }
float time_error(uint row, uint col) const
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...
GeomDetEnumerators::Location subDet(uint row, uint col) const
Use subDet to identify whether the Hit is in BTL or ETL.
void push_back(data_type const &d)
float xx() const
Definition: LocalError.h:22
uint rows() const
const edm::EventSetup & c
float y() const
Definition: FTLCluster.h:125
uint16_t *__restrict__ id
static void fillPSetDescription(edm::ParameterSetDescription &desc)
FTLRecHitCollection::const_iterator RecHitIterator
uint columns() const
int getMTDTopologyMode() const
Definition: MTDTopology.h:27
constexpr uint32_t rawId() const
get the raw id
Definition: DetId.h:57
std::vector< T >::const_iterator const_iterator
T y() const
Definition: PV3DBase.h:60
float time() const
Definition: FTLCluster.h:130
const float theHitThreshold
Clustering-related quantities:
int theNumOfRows
Geometry-related information.
MTDThresholdClusterizer(edm::ParameterSet const &conf)
Constructor:
bool add(FTLCluster::FTLHitPos const &p, float const ienergy, float const itime, float const itimeError)
assert(be >=bs)
LocalError local_error(uint row, uint col) const
Detector identifier base class for the MIP Timing Layer.
Definition: MTDDetId.h:21
static std::string const input
Definition: EdmProvDump.cc:47
const uint16_t range(const Frame &aFrame)
void copy_to_buffer(RecHitIterator itr, const MTDGeometry *geom, const MTDTopology *topo)
Copy FTLRecHit into the buffer, identify seeds.
float time(uint row, uint col) const
bool setup(const MTDGeometry *geometry, const MTDTopology *topo, const DetId &id)
std::array< float, MAXSIZE > timeError
float x() const
Definition: FTLCluster.h:120
int ncolumns() const override
float yy() const
Definition: LocalError.h:24
T sqrt(T t)
Definition: SSEVec.h:19
T z() const
Definition: PV3DBase.h:61
T mag2() const
The vector magnitude squared. Equivalent to vec.dot(vec)
virtual const PixelTopology & specificTopology() const
constexpr int row() const
Definition: FTLCluster.h:61
float energy(uint row, uint col) const
const MTDGeomDet * idToDet(DetId) const override
Definition: MTDGeometry.cc:171
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
int nrows() const override
T min(T a, T b)
Definition: MathUtil.h:58
std::vector< FTLCluster::FTLHitPos > theSeeds
ParameterDescriptionBase * add(U const &iLabel, T const &value)
GlobalPoint global_point(uint row, uint col) const
int size() const
Definition: FTLCluster.h:141
std::array< UShort, MAXSIZE > x
std::array< float, MAXSIZE > time
const_iterator end() const
Log< level::Info, false > LogInfo
Definition: DetId.h:17
float energy() const
Definition: FTLCluster.h:149
#define DEBUG(x)
std::pair< float, float > pitch() const override
MTDArrayBuffer theBuffer
Data storage.
SubDetector subDetector() const
Definition: MTDDetId.h:53
FTLCluster make_cluster(const FTLCluster::FTLHitPos &hit)
The actual clustering algorithm: group the neighboring hits around the seed.
void set(uint row, uint col, GeomDetEnumerators::Location subDet, float energy, float time, float time_error, const LocalError &local_error, const GlobalPoint &global_point)
Detector identifier class for the Endcap Timing Layer.
Definition: ETLDetId.h:15
size_type size() const
static int position[264][3]
Definition: ReadPGInfo.cc:289
Detector identifier class for the Barrel Timing Layer. The crystal count must start from 0...
Definition: BTLDetId.h:18
int mtdSubDetector() const
Definition: MTDDetId.h:56
string end
Definition: dataset.py:937
void clear_buffer(RecHitIterator itr)
Clear the internal buffer array.
BTLDetId::CrysLayout crysLayoutFromTopoMode(const int &topoMode)
std::array< UShort, MAXSIZE > y
constexpr int col() const
Definition: FTLCluster.h:62
int col
Definition: cuy.py:1009
LocalPoint localPosition(const MeasurementPoint &mp) const override
void clear(uint row, uint col)
T x() const
Definition: PV3DBase.h:59
std::array< float, MAXSIZE > energy
void setSize(uint rows, uint cols)
const_iterator begin() const