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  theTimeThreshold( conf.getParameter<double>("TimeThreshold") ),
35  theNumOfRows(0), theNumOfCols(0), theCurrentId(0),
36  theBuffer(theNumOfRows, theNumOfCols ),
37  bufferAlreadySet(false)
38 {
39 }
42 
43 
44 // Configuration descriptions
45 void
47  desc.add<double>("HitThreshold", 0.);
48  desc.add<double>("SeedThreshold", 0.);
49  desc.add<double>("ClusterThreshold", 0.);
50  desc.add<double>("TimeThreshold", 10.);
51 }
52 
53 //----------------------------------------------------------------------------
56 //----------------------------------------------------------------------------
57 bool MTDThresholdClusterizer::setup(const MTDGeometry* geom, const MTDTopology* topo, const DetId& id)
58 {
59  theCurrentId=id;
60  //using geopraphicalId here
61  const auto& thedet = geom->idToDet(id);
62  if( thedet == nullptr ) {
63  throw cms::Exception("MTDThresholdClusterizer") << "GeographicalID: " << std::hex
64  << id.rawId()
65  << " is invalid!" << std::dec
66  << std::endl;
67  return false;
68  }
69  const ProxyMTDTopology& topoproxy = static_cast<const ProxyMTDTopology&>(thedet->topology());
70  const RectangularMTDTopology& topol = static_cast<const RectangularMTDTopology&>(topoproxy.specificTopology());
71 
72  // Get the new sizes.
73  unsigned int nrows = topol.nrows(); // rows in x
74  unsigned int ncols = topol.ncolumns(); // cols in y
75 
76  theNumOfRows = nrows; // Set new sizes
77  theNumOfCols = ncols;
78 
79  DEBUG("Buffer size [" << theNumOfRows+1 << "," << theNumOfCols+1 << "]");
80 
81  if ( nrows > theBuffer.rows() ||
82  ncols > theBuffer.columns() )
83  { // 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,
102 
105 
106  // Do not bother for empty detectors
107  if (begin == end)
108  {
109  edm::LogInfo("MTDThresholdClusterizer") << "No hits to clusterize";
110  return;
111  }
112 
113  DEBUG("Input collection " << input.size());
114  assert(output.empty());
115 
116  std::set<unsigned> geoIds;
117  std::multimap<unsigned, unsigned> geoIdToIdx;
118 
119  unsigned index = 0;
120  for(const auto& hit : input)
121  {
122  MTDDetId mtdId=MTDDetId(hit.detid());
123  if (mtdId.subDetector() != MTDDetId::FastTime)
124  {
125  throw cms::Exception("MTDThresholdClusterizer") << "MTDDetId: " << std::hex
126  << mtdId.rawId()
127  << " is invalid!" << std::dec
128  << std::endl;
129  }
130 
131  if ( mtdId.mtdSubDetector() == MTDDetId::BTL )
132  {
133  BTLDetId hitId(hit.detid());
134  DetId geoId = hitId.geographicalId( (BTLDetId::CrysLayout) topo->getMTDTopologyMode() ); //for BTL topology gives different layout id
135  geoIdToIdx.emplace(geoId,index);
136  geoIds.emplace(geoId);
137  ++index;
138  }
139  else if ( mtdId.mtdSubDetector() == MTDDetId::ETL )
140  {
141  ETLDetId hitId(hit.detid());
142  DetId geoId = hitId.geographicalId();
143  geoIdToIdx.emplace(geoId,index);
144  geoIds.emplace(geoId);
145  ++index;
146  }
147  else
148  {
149  throw cms::Exception("MTDThresholdClusterizer") << "MTDDetId: " << std::hex
150  << mtdId.rawId()
151  << " is invalid!" << std::dec
152  << std::endl;
153  }
154  }
155 
156  //cluster hits within geoIds (modules)
157  for(unsigned id : geoIds) {
158  // Set up the clusterization on this DetId.
159  if ( !setup(geom,topo,DetId(id)) )
160  return;
161 
162  auto range = geoIdToIdx.equal_range(id);
163  DEBUG("Matching Ids for " << std::hex << id << std::dec << " [" << range.first->second << "," << range.second->second << "]");
164 
165  // Copy MTDRecHits to the buffer array; select the seed hits
166  // on the way, and store them in theSeeds.
167  for(auto itr = range.first; itr != range.second; ++itr) {
168  const unsigned hitidx = itr->second;
169  copy_to_buffer(begin+hitidx);
170  }
171 
172  FTLClusterCollection::FastFiller clustersOnDet(output,id);
173 
174  for (unsigned int i = 0; i < theSeeds.size(); i++)
175  {
176  if ( theBuffer.energy(theSeeds[i]) > theSeedThreshold )
177  { // Is this seed still valid?
178  // Make a cluster around this seed
179  const FTLCluster & cluster = make_cluster( theSeeds[i] );
180 
181  // Check if the cluster is above threshold
182  if ( cluster.energy() > theClusterThreshold)
183  {
184  DEBUG("putting in this cluster " << i << " #hits:" << cluster.size()
185  << " E:" << cluster.energy()
186  << " T:" << cluster.time()
187  << " X:" << cluster.x()
188  << " Y:" << cluster.y());
189  clustersOnDet.push_back( cluster );
190  }
191  }
192  }
193 
194  // Erase the seeds.
195  theSeeds.clear();
196  // Need to clean unused hits from the buffer array.
197  for(auto itr = range.first; itr != range.second; ++itr) {
198  const unsigned hitidx = itr->second;
199  clear_buffer(begin+hitidx);
200  }
201  }
202 }
203 
204 //----------------------------------------------------------------------------
210 //----------------------------------------------------------------------------
212 {
213  theBuffer.clear( itr->row(), itr->column() );
214 }
215 
216 //----------------------------------------------------------------------------
218 //----------------------------------------------------------------------------
220 {
221  int row = itr->row();
222  int col = itr->column();
223  float energy = itr->energy();
224  float time = itr->time();
225  float timeError = itr->timeError();
226 
227  DEBUG("ROW " << row << " COL " << col << " ENERGY " << energy << " TIME " << time);
228  if ( energy > theHitThreshold) {
229  theBuffer.set( row, col, energy , time, timeError);
230  if ( energy > theSeedThreshold) theSeeds.push_back( FTLCluster::FTLHitPos(row,col));
231  //sort seeds?
232  }
233 }
234 
235 
236 //----------------------------------------------------------------------------
238 //----------------------------------------------------------------------------
239 FTLCluster
241 {
242 
243  //First we acquire the seeds for the clusters
244  float seed_energy= theBuffer.energy(hit.row(), hit.col());
245  float seed_time= theBuffer.time(hit.row(), hit.col());
246  float seed_time_error= theBuffer.time_error(hit.row(), hit.col());
247  theBuffer.clear(hit);
248 
249  AccretionCluster acluster;
250  acluster.add(hit, seed_energy, seed_time, seed_time_error);
251 
252  bool stopClus=false;
253  //Here we search all hits adjacent to all hits in the cluster.
254  while ( ! acluster.empty() && ! stopClus)
255  {
256  //This is the standard algorithm to find and add a hit
257  auto curInd = acluster.top(); acluster.pop();
258  for ( auto c = std::max(0,int(acluster.y[curInd]-1)); c < std::min(int(acluster.y[curInd]+2),int(theBuffer.columns())) && !stopClus; ++c) {
259  for ( auto r = std::max(0,int(acluster.x[curInd]-1)); r < std::min(int(acluster.x[curInd]+2),int(theBuffer.rows())) && !stopClus; ++r) {
260  if ( theBuffer.energy(r,c) > theHitThreshold) {
261  if (std::abs(theBuffer.time(r,c) - seed_time) > theTimeThreshold*sqrt( theBuffer.time_error(r,c)*theBuffer.time_error(r,c) + seed_time_error*seed_time_error))
262  continue;
263  FTLCluster::FTLHitPos newhit(r,c);
264  if (!acluster.add( newhit, theBuffer.energy(r,c), theBuffer.time(r,c), theBuffer.time_error(r,c)))
265  {
266  stopClus=true;
267  break;
268  }
269  theBuffer.clear(newhit);
270  }
271  }
272  }
273  } // while accretion
274 
275  FTLCluster cluster( theCurrentId, acluster.isize,
276  acluster.energy.data(), acluster.time.data(), acluster.timeError.data(),
277  acluster.x.data(), acluster.y.data(),
278  acluster.xmin, acluster.ymin);
279  return cluster;
280 }
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
void push_back(data_type const &d)
float y() const
Definition: FTLCluster.h:113
CrysLayout
Definition: BTLDetId.h:66
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< T >::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:48
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
T sqrt(T t)
Definition: SSEVec.h:18
virtual const PixelTopology & specificTopology() const
constexpr int row() const
Definition: FTLCluster.h:61
Abs< T >::type abs(const T &t)
Definition: Abs.h:22
#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