CMS 3D CMS Logo

List of all members | Public Member Functions | Static Public Member Functions | Protected Member Functions | Protected Attributes
PixelThresholdClusterizer Class Reference

A specific threshold-based pixel clustering algorithm. More...

#include <PixelThresholdClusterizer.h>

Inheritance diagram for PixelThresholdClusterizer:
PixelClusterizerBase

Public Member Functions

void clusterizeDetUnit (const edm::DetSet< PixelDigi > &input, const PixelGeomDetUnit *pixDet, const TrackerTopology *tTopo, const std::vector< short > &badChannels, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output) override
 
void clusterizeDetUnit (const edmNew::DetSet< SiPixelCluster > &input, const PixelGeomDetUnit *pixDet, const TrackerTopology *tTopo, const std::vector< short > &badChannels, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output) override
 
bool isCalibrated ()
 
 PixelThresholdClusterizer (edm::ParameterSet const &conf)
 
 ~PixelThresholdClusterizer () override
 
- Public Member Functions inherited from PixelClusterizerBase
void setSiPixelGainCalibrationService (SiPixelGainCalibrationServiceBase *in)
 
virtual ~PixelClusterizerBase ()
 

Static Public Member Functions

static void fillPSetDescription (edm::ParameterSetDescription &desc)
 

Protected Member Functions

int calibrate (int adc, int col, int row)
 
void clear_buffer (DigiIterator begin, DigiIterator end)
 Clear the internal buffer array. More...
 
void clear_buffer (ClusterIterator begin, ClusterIterator end)
 
template<typename T >
void clusterizeDetUnitT (const T &input, const PixelGeomDetUnit *pixDet, const TrackerTopology *tTopo, const std::vector< short > &badChannels, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
 
void copy_to_buffer (DigiIterator begin, DigiIterator end)
 Copy adc counts from PixelDigis into the buffer, identify seeds. More...
 
void copy_to_buffer (ClusterIterator begin, ClusterIterator end)
 
SiPixelCluster make_cluster (const SiPixelCluster::PixelPos &pix, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
 The actual clustering algorithm: group the neighboring pixels around the seed. More...
 
bool setup (const PixelGeomDetUnit *pixDet)
 Private helper methods: More...
 

Protected Attributes

const bool doMissCalibrate
 
const bool doPhase2Calibration
 
const bool doSplitClusters
 
const bool dropDuplicates
 
SiPixelArrayBuffer theBuffer
 Data storage. More...
 
std::vector< SiPixelClustertheClusters
 
const int theClusterThreshold
 
const int theClusterThreshold_L1
 
float theClusterThresholdInNoiseUnits
 
const int theConversionFactor
 
const int theConversionFactor_L1
 
uint32_t theDetid
 
const double theElectronPerADCGain
 
std::vector< bool > theFakePixels
 
int theLayer
 
int theNumOfCols
 
int theNumOfRows
 Geometry-related information. More...
 
const int theOffset
 
const int theOffset_L1
 
const double thePhase2DigiBaseline
 
const int thePhase2KinkADC
 
const int thePhase2ReadoutMode
 
std::vector< uint8_t > thePixelOccurrence
 
const int thePixelThreshold
 
float thePixelThresholdInNoiseUnits
 Clustering-related quantities: More...
 
std::vector< SiPixelCluster::PixelPostheSeeds
 
const int theSeedThreshold
 
float theSeedThresholdInNoiseUnits
 
- Protected Attributes inherited from PixelClusterizerBase
SiPixelGainCalibrationServiceBasetheSiPixelGainCalibrationService_
 

Additional Inherited Members

- Public Types inherited from PixelClusterizerBase
typedef edmNew::DetSet< SiPixelCluster >::const_iterator ClusterIterator
 
typedef edm::DetSet< PixelDigi >::const_iterator DigiIterator
 

Detailed Description

A specific threshold-based pixel clustering algorithm.

An explicit threshold-based clustering algorithm.

General logic of PixelThresholdClusterizer:

The clusterization is performed on a matrix with size equal to the size of the pixel detector, each cell containing the ADC count of the corresponding pixel. The matrix is reset after each clusterization.

The search starts from seed pixels, i.e. pixels with sufficiently large amplitudes, found at the time of filling of the matrix and stored in a SiPixelArrayBuffer.

Translate the pixel charge to electrons, we are suppose to do the calibrations ADC->electrons here. Modify the thresholds to be in electrons, convert adc to electrons. d.k. 20/3/06 Get rid of the noiseVector. d.k. 28/3/06

A threshold-based clustering algorithm which clusters SiPixelDigis into SiPixelClusters for each DetUnit. The algorithm is straightforward and purely topological: the clustering process starts with seed pixels and continues by adding adjacent pixels above the pixel threshold. Once the cluster is made, it has to be above the cluster threshold as well.

The clusterization is performed on a matrix with size equal to the size of the pixel detector, each cell containing the ADC count of the corresponding pixel. The matrix is reset after each clusterization.

The search starts from seed pixels, i.e. pixels with sufficiently large amplitudes, found at the time of filling of the matrix and stored in a

At this point the noise and dead channels are ignored, but soon they won't be.

SiPixelCluster contains a barrycenter, but it should be noted that that information is largely useless. One must use a PositionEstimator class to compute the RecHit position and its error for every given cluster.

Author
Largely copied from NewPixelClusterizer in ORCA written by Danek Kotlinski (PSI). Ported to CMSSW by Petar Maksimovic (JHU). DetSetVector data container implemented by V.Chiochia (Uni Zurich)

Sets the PixelArrayBuffer dimensions and pixel thresholds. Makes clusters and stores them in theCache if the option useCache has been set.

Definition at line 57 of file PixelThresholdClusterizer.h.

Constructor & Destructor Documentation

◆ PixelThresholdClusterizer()

PixelThresholdClusterizer::PixelThresholdClusterizer ( edm::ParameterSet const &  conf)

Constructor: Initilize the buffer to hold pixels from a detector module. This is a vector of 44k ints, stays valid all the time.

Definition at line 44 of file PixelThresholdClusterizer.cc.

References SiPixelArrayBuffer::setSize(), theBuffer, theFakePixels, theNumOfCols, theNumOfRows, and thePixelOccurrence.

45  : // Get thresholds in electrons
46  thePixelThreshold(conf.getParameter<int>("ChannelThreshold")),
47  theSeedThreshold(conf.getParameter<int>("SeedThreshold")),
48  theClusterThreshold(conf.getParameter<int>("ClusterThreshold")),
49  theClusterThreshold_L1(conf.getParameter<int>("ClusterThreshold_L1")),
50  theConversionFactor(conf.getParameter<int>("VCaltoElectronGain")),
51  theConversionFactor_L1(conf.getParameter<int>("VCaltoElectronGain_L1")),
52  theOffset(conf.getParameter<int>("VCaltoElectronOffset")),
53  theOffset_L1(conf.getParameter<int>("VCaltoElectronOffset_L1")),
54  theElectronPerADCGain(conf.getParameter<double>("ElectronPerADCGain")),
55  doPhase2Calibration(conf.getParameter<bool>("Phase2Calibration")),
56  dropDuplicates(conf.getParameter<bool>("DropDuplicates")),
57  thePhase2ReadoutMode(conf.getParameter<int>("Phase2ReadoutMode")),
58  thePhase2DigiBaseline(conf.getParameter<double>("Phase2DigiBaseline")),
59  thePhase2KinkADC(conf.getParameter<int>("Phase2KinkADC")),
60  theNumOfRows(0),
61  theNumOfCols(0),
62  theDetid(0),
63  // Get the constants for the miss-calibration studies
64  doMissCalibrate(conf.getParameter<bool>("MissCalibrate")),
65  doSplitClusters(conf.getParameter<bool>("SplitClusters")) {
67  theFakePixels.clear();
68  thePixelOccurrence.clear();
69 }
SiPixelArrayBuffer theBuffer
Data storage.
int theNumOfRows
Geometry-related information.
std::vector< uint8_t > thePixelOccurrence
void setSize(int rows, int cols)

◆ ~PixelThresholdClusterizer()

PixelThresholdClusterizer::~PixelThresholdClusterizer ( )
override

Definition at line 71 of file PixelThresholdClusterizer.cc.

71 {}

Member Function Documentation

◆ calibrate()

int PixelThresholdClusterizer::calibrate ( int  adc,
int  col,
int  row 
)
protected

Definition at line 280 of file PixelThresholdClusterizer.cc.

References gpuClustering::adc, cuy::col, doMissCalibrate, doPhase2Calibration, pwdgSkimBPark_cfi::electrons, PedestalClient_cfi::gain, SiPixelGainCalibrationServiceBase::getGain(), SiPixelGainCalibrationServiceBase::getPedestal(), createfilelist::int, SiPixelGainCalibrationServiceBase::isDead(), SiPixelGainCalibrationServiceBase::isNoisy(), EcalCondDBWriter_cfi::pedestal, conifer::pow(), theConversionFactor, theConversionFactor_L1, theDetid, theElectronPerADCGain, theLayer, theOffset, theOffset_L1, thePhase2DigiBaseline, thePhase2KinkADC, thePhase2ReadoutMode, and PixelClusterizerBase::theSiPixelGainCalibrationService_.

Referenced by copy_to_buffer().

280  {
281  int electrons = 0;
282 
283  if (doPhase2Calibration) {
284  const float gain = theElectronPerADCGain;
285  int p2rm = (thePhase2ReadoutMode < -1 ? -1 : thePhase2ReadoutMode);
286 
287  if (p2rm == -1) {
288  electrons = int(adc * gain);
289  } else {
290  if (adc < thePhase2KinkADC) {
291  electrons = int((adc + 0.5) * gain);
292  } else {
293  const int dualslopeparam = (thePhase2ReadoutMode < 10 ? thePhase2ReadoutMode : 10);
294  const int dualslope = int(dualslopeparam <= 1 ? 1. : pow(2, dualslopeparam - 1));
296  adc *= dualslope;
298  electrons = int((adc + 0.5 * dualslope) * gain);
299  }
301  }
302 
303  return electrons;
304  }
305 
306  if (doMissCalibrate) {
307  // do not perform calibration if pixel is dead!
308 
311  // Linear approximation of the TANH response
312  // Pixel(0,0,0)
313  //const float gain = 2.95; // 1 ADC = 2.95 VCALs (1/0.339)
314  //const float pedestal = -83.; // -28/0.339
315  // Roc-0 average
316  //const float gain = 1./0.357; // 1 ADC = 2.80 VCALs
317  //const float pedestal = -28.2 * gain; // -79.
318 
319  float DBgain = theSiPixelGainCalibrationService_->getGain(theDetid, col, row);
321  float DBpedestal = pedestal * DBgain;
322 
323  // Roc-6 average
324  //const float gain = 1./0.313; // 1 ADC = 3.19 VCALs
325  //const float pedestal = -6.2 * gain; // -19.8
326  //
327  float vcal = adc * DBgain - DBpedestal;
328 
329  // atanh calibration
330  // Roc-6 average
331  //const float p0 = 0.00492;
332  //const float p1 = 1.998;
333  //const float p2 = 90.6;
334  //const float p3 = 134.1;
335  // Roc-6 average
336  //const float p0 = 0.00382;
337  //const float p1 = 0.886;
338  //const float p2 = 112.7;
339  //const float p3 = 113.0;
340  //float vcal = ( atanh( (adc-p3)/p2) + p1)/p0;
341 
342  if (theLayer == 1) {
344  } else {
346  }
347  }
348  } else { // No misscalibration in the digitizer
349  // Simple (default) linear gain
350  const float gain = theElectronPerADCGain; // default: 1 ADC = 135 electrons
351  const float pedestal = 0.; //
352  electrons = int(adc * gain + pedestal);
353  }
354 
355  return electrons;
356 }
constexpr int pow(int x)
Definition: conifer.h:24
virtual bool isDead(const uint32_t &detID, const int &col, const int &row)=0
virtual float getPedestal(const uint32_t &detID, const int &col, const int &row)=0
SiPixelGainCalibrationServiceBase * theSiPixelGainCalibrationService_
col
Definition: cuy.py:1009
virtual float getGain(const uint32_t &detID, const int &col, const int &row)=0
virtual bool isNoisy(const uint32_t &detID, const int &col, const int &row)=0
uint16_t *__restrict__ uint16_t const *__restrict__ adc

◆ clear_buffer() [1/2]

void PixelThresholdClusterizer::clear_buffer ( DigiIterator  begin,
DigiIterator  end 
)
protected

Clear the internal buffer array.

Pixels which are not part of recognized clusters are NOT ERASED during the cluster finding. Erase them now.

TO DO: ask Danek... wouldn't it be faster to simply memcopy() zeros into the whole buffer array?

Definition at line 135 of file PixelThresholdClusterizer.cc.

References mps_fire::end, SiPixelArrayBuffer::set_adc(), and theBuffer.

135  {
136  for (DigiIterator di = begin; di != end; ++di) {
137  theBuffer.set_adc(di->row(), di->column(), 0); // reset pixel adc to 0
138  }
139 }
SiPixelArrayBuffer theBuffer
Data storage.
void set_adc(int row, int col, int adc)
edm::DetSet< PixelDigi >::const_iterator DigiIterator

◆ clear_buffer() [2/2]

void PixelThresholdClusterizer::clear_buffer ( ClusterIterator  begin,
ClusterIterator  end 
)
protected

Definition at line 141 of file PixelThresholdClusterizer.cc.

References mps_fire::end, mps_fire::i, muonClassificationByHits_cfi::pixel, SiPixelArrayBuffer::set_adc(), and theBuffer.

141  {
142  for (ClusterIterator ci = begin; ci != end; ++ci) {
143  for (int i = 0; i < ci->size(); ++i) {
144  const SiPixelCluster::Pixel pixel = ci->pixel(i);
145 
146  theBuffer.set_adc(pixel.x, pixel.y, 0); // reset pixel adc to 0
147  }
148  }
149 }
SiPixelArrayBuffer theBuffer
Data storage.
void set_adc(int row, int col, int adc)
edmNew::DetSet< SiPixelCluster >::const_iterator ClusterIterator

◆ clusterizeDetUnit() [1/2]

void PixelThresholdClusterizer::clusterizeDetUnit ( const edm::DetSet< PixelDigi > &  input,
const PixelGeomDetUnit pixDet,
const TrackerTopology tTopo,
const std::vector< short > &  badChannels,
edmNew::DetSetVector< SiPixelCluster >::FastFiller &  output 
)
inlineoverridevirtual

Implements PixelClusterizerBase.

Definition at line 63 of file PixelThresholdClusterizer.h.

References input.

67  {
68  clusterizeDetUnitT(input, pixDet, tTopo, badChannels, output);
69  }
void clusterizeDetUnitT(const T &input, const PixelGeomDetUnit *pixDet, const TrackerTopology *tTopo, const std::vector< short > &badChannels, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
static std::string const input
Definition: EdmProvDump.cc:50
Definition: output.py:1

◆ clusterizeDetUnit() [2/2]

void PixelThresholdClusterizer::clusterizeDetUnit ( const edmNew::DetSet< SiPixelCluster > &  input,
const PixelGeomDetUnit pixDet,
const TrackerTopology tTopo,
const std::vector< short > &  badChannels,
edmNew::DetSetVector< SiPixelCluster >::FastFiller &  output 
)
inlineoverridevirtual

Implements PixelClusterizerBase.

Definition at line 70 of file PixelThresholdClusterizer.h.

References input.

74  {
75  clusterizeDetUnitT(input, pixDet, tTopo, badChannels, output);
76  }
void clusterizeDetUnitT(const T &input, const PixelGeomDetUnit *pixDet, const TrackerTopology *tTopo, const std::vector< short > &badChannels, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
static std::string const input
Definition: EdmProvDump.cc:50
Definition: output.py:1

◆ clusterizeDetUnitT()

template<typename T >
void PixelThresholdClusterizer::clusterizeDetUnitT ( const T input,
const PixelGeomDetUnit pixDet,
const TrackerTopology tTopo,
const std::vector< short > &  badChannels,
edmNew::DetSetVector< SiPixelCluster >::FastFiller &  output 
)
protected

◆ copy_to_buffer() [1/2]

void PixelThresholdClusterizer::copy_to_buffer ( DigiIterator  begin,
DigiIterator  end 
)
protected

Copy adc counts from PixelDigis into the buffer, identify seeds.

Definition at line 154 of file PixelThresholdClusterizer.cc.

References gpuClustering::adc, cms::cuda::assert(), calibrate(), cuy::col, gather_cfg::cout, doMissCalibrate, doPhase2Calibration, dropDuplicates, HPSPFTauProducerPuppi_cfi::electron, mps_fire::end, PedestalClient_cfi::gain, mps_fire::i, recoMuon::in, SiPixelArrayBuffer::index(), createfilelist::int, EcalCondDBWriter_cfi::pedestal, MatrixUtil::remove(), SiPixelArrayBuffer::set_adc(), theBuffer, theConversionFactor, theConversionFactor_L1, theDetid, theElectronPerADCGain, theFakePixels, theLayer, theNumOfCols, theOffset, theOffset_L1, thePixelOccurrence, thePixelThreshold, theSeeds, and theSeedThreshold.

154  {
155 #ifdef PIXELREGRESSION
156  static std::atomic<int> s_ic = 0;
157  in ic = ++s_ic;
158  if (ic == 1) {
159  // std::cout << (doMissCalibrate ? "VI from db" : "VI linear") << std::endl;
160  }
161 #endif
162 
163  //If called with empty/invalid DetSet, warn the user
164  if (end <= begin) {
165  edm::LogWarning("PixelThresholdClusterizer") << " copy_to_buffer called with empty or invalid range" << std::endl;
166  return;
167  }
168 
169  int electron[end - begin]; // pixel charge in electrons
170  memset(electron, 0, (end - begin) * sizeof(int));
171 
172  if (doPhase2Calibration) {
173  int i = 0;
174  for (DigiIterator di = begin; di != end; ++di) {
175  electron[i] = calibrate(di->adc(), di->column(), di->row());
176  i++;
177  }
178  assert(i == (end - begin));
179  }
180 
181  else {
182  if (doMissCalibrate) {
183  if (theLayer == 1) {
184  (*theSiPixelGainCalibrationService_)
186  } else {
187  (*theSiPixelGainCalibrationService_).calibrate(theDetid, begin, end, theConversionFactor, theOffset, electron);
188  }
189  } else {
190  int i = 0;
191  const float gain = theElectronPerADCGain; // default: 1 ADC = 135 electrons
192  for (DigiIterator di = begin; di != end; ++di) {
193  auto adc = di->adc();
194  const float pedestal = 0.; //
195  electron[i] = int(adc * gain + pedestal);
196  ++i;
197  }
198  assert(i == (end - begin));
199  }
200  }
201 
202  int i = 0;
203 #ifdef PIXELREGRESSION
204  static std::atomic<int> eqD = 0;
205 #endif
206  for (DigiIterator di = begin; di != end; ++di) {
207  int row = di->row();
208  int col = di->column();
209  // VV: do not calibrate a fake pixel, it already has a unit of 10e-:
210  int adc = (di->flag() != 0) ? di->adc() * 10 : electron[i]; // this is in electrons
211  i++;
212 
213 #ifdef PIXELREGRESSION
214  int adcOld = calibrate(di->adc(), col, row);
215  //assert(adc==adcOld);
216  if (adc != adcOld)
217  std::cout << "VI " << eqD << ' ' << ic << ' ' << end - begin << ' ' << i << ' ' << di->adc() << ' ' << adc << ' '
218  << adcOld << std::endl;
219  else
220  ++eqD;
221 #endif
222 
223  if (adc < 100)
224  adc = 100; // put all negative pixel charges into the 100 elec bin
225  /* This is semi-random good number. The exact number (in place of 100) is irrelevant from the point
226  of view of the final cluster charge since these are typically >= 20000.
227  */
228 
229  thePixelOccurrence[theBuffer.index(row, col)]++; // increment the occurrence counter
230  uint8_t occurrence =
231  (!dropDuplicates) ? 1 : thePixelOccurrence[theBuffer.index(row, col)]; // get the occurrence counter
232 
233  switch (occurrence) {
234  // the 1st occurrence (standard treatment)
235  case 1:
236  if (adc >= thePixelThreshold) {
237  theBuffer.set_adc(row, col, adc);
238  // VV: add pixel to the fake list. Only when running on digi collection
239  if (di->flag() != 0)
240  theFakePixels[row * theNumOfCols + col] = true;
241  if (adc >= theSeedThreshold)
242  theSeeds.push_back(SiPixelCluster::PixelPos(row, col));
243  }
244  break;
245 
246  // the 2nd occurrence (duplicate pixel: reset the buffer to 0 and remove from the list of seed pixels)
247  case 2:
248  theBuffer.set_adc(row, col, 0);
250  break;
251 
252  // in case a pixel appears more than twice, nothing needs to be done because it was already removed at the 2nd occurrence
253  }
254  }
255  assert(i == (end - begin));
256 }
SiPixelArrayBuffer theBuffer
Data storage.
assert(be >=bs)
void set_adc(int row, int col, int adc)
int index(int row, int col) const
Definition of indexing within the buffer.
edm::DetSet< PixelDigi >::const_iterator DigiIterator
std::vector< uint8_t > thePixelOccurrence
def remove(d, key, TELL=False)
Definition: MatrixUtil.py:223
col
Definition: cuy.py:1009
int calibrate(int adc, int col, int row)
Log< level::Warning, false > LogWarning
std::vector< SiPixelCluster::PixelPos > theSeeds
uint16_t *__restrict__ uint16_t const *__restrict__ adc

◆ copy_to_buffer() [2/2]

void PixelThresholdClusterizer::copy_to_buffer ( ClusterIterator  begin,
ClusterIterator  end 
)
protected

Definition at line 258 of file PixelThresholdClusterizer.cc.

References gpuClustering::adc, SiPixelArrayBuffer::add_adc(), cuy::col, mps_fire::end, mps_fire::i, muonClassificationByHits_cfi::pixel, theBuffer, thePixelThreshold, theSeeds, and theSeedThreshold.

258  {
259  // loop over clusters
260  for (ClusterIterator ci = begin; ci != end; ++ci) {
261  // loop over pixels
262  for (int i = 0; i < ci->size(); ++i) {
263  const SiPixelCluster::Pixel pixel = ci->pixel(i);
264 
265  int row = pixel.x;
266  int col = pixel.y;
267  int adc = pixel.adc;
268  if (adc >= thePixelThreshold) {
269  theBuffer.add_adc(row, col, adc);
270  if (adc >= theSeedThreshold)
271  theSeeds.push_back(SiPixelCluster::PixelPos(row, col));
272  }
273  }
274  }
275 }
SiPixelArrayBuffer theBuffer
Data storage.
void add_adc(int row, int col, int adc)
edmNew::DetSet< SiPixelCluster >::const_iterator ClusterIterator
col
Definition: cuy.py:1009
std::vector< SiPixelCluster::PixelPos > theSeeds
uint16_t *__restrict__ uint16_t const *__restrict__ adc

◆ fillPSetDescription()

void PixelThresholdClusterizer::fillPSetDescription ( edm::ParameterSetDescription desc)
static

Definition at line 74 of file PixelThresholdClusterizer.cc.

References submitPVResolutionJobs::desc.

Referenced by SiPixelClusterProducer::fillDescriptions().

74  {
75  desc.add<int>("ChannelThreshold", 1000);
76  desc.add<bool>("MissCalibrate", true);
77  desc.add<bool>("SplitClusters", false);
78  desc.add<int>("VCaltoElectronGain", 65);
79  desc.add<int>("VCaltoElectronGain_L1", 65);
80  desc.add<int>("VCaltoElectronOffset", -414);
81  desc.add<int>("VCaltoElectronOffset_L1", -414);
82  desc.add<int>("SeedThreshold", 1000);
83  desc.add<int>("ClusterThreshold_L1", 4000);
84  desc.add<int>("ClusterThreshold", 4000);
85  desc.add<double>("ElectronPerADCGain", 135.);
86  desc.add<bool>("DropDuplicates", true);
87  desc.add<bool>("Phase2Calibration", false);
88  desc.add<int>("Phase2ReadoutMode", -1);
89  desc.add<double>("Phase2DigiBaseline", 1200.);
90  desc.add<int>("Phase2KinkADC", 8);
91 }

◆ isCalibrated()

bool PixelThresholdClusterizer::isCalibrated ( )
inline

Definition at line 80 of file PixelThresholdClusterizer.h.

◆ make_cluster()

SiPixelCluster PixelThresholdClusterizer::make_cluster ( const SiPixelCluster::PixelPos pix,
edmNew::DetSetVector< SiPixelCluster >::FastFiller &  output 
)
protected

The actual clustering algorithm: group the neighboring pixels around the seed.

Definition at line 361 of file PixelThresholdClusterizer.cc.

References PixelClusterizerBase::AccretionCluster::adc, PixelClusterizerBase::AccretionCluster::add(), SiPixelCluster::add(), HltBtagPostValidation_cff::c, SiPixelCluster::charge(), GetRecoTauVFromDQM_MC_cff::cl2, EMEnrichingFilter_cfi::clusterThreshold, SiPixelCluster::PixelPos::col(), SiPixelArrayBuffer::columns(), doSplitClusters, PixelClusterizerBase::AccretionCluster::empty(), mps_fire::i, PixelClusterizerBase::AccretionCluster::isize, SiStripPI::max, SiStripPI::min, SiPixelCluster::minPixelRow(), SiPixelCluster::pixels(), PixelClusterizerBase::AccretionCluster::pop(), alignCSCRings::r, SiPixelCluster::PixelPos::row(), SiPixelArrayBuffer::rows(), SiPixelArrayBuffer::set_adc(), theBuffer, theClusterThreshold, theClusterThreshold_L1, theFakePixels, theLayer, theNumOfCols, thePixelThreshold, PixelClusterizerBase::AccretionCluster::top(), PixelClusterizerBase::AccretionCluster::x, PixelClusterizerBase::AccretionCluster::xmin, PixelClusterizerBase::AccretionCluster::y, and PixelClusterizerBase::AccretionCluster::ymin.

362  {
363  //First we acquire the seeds for the clusters
364  uint16_t seed_adc;
365  std::stack<SiPixelCluster::PixelPos, std::vector<SiPixelCluster::PixelPos> > dead_pixel_stack;
366 
367  //The individual modules have been loaded into a buffer.
368  //After each pixel has been considered by the clusterizer, we set the adc count to 1
369  //to mark that we have already considered it.
370  //The only difference between dead/noisy pixels and standard ones is that for dead/noisy pixels,
371  //We consider the charge of the pixel to always be zero.
372 
373  /* this is not possible as dead and noisy pixel cannot make it into a seed...
374  if ( doMissCalibrate &&
375  (theSiPixelGainCalibrationService_->isDead(theDetid,pix.col(),pix.row()) ||
376  theSiPixelGainCalibrationService_->isNoisy(theDetid,pix.col(),pix.row())) )
377  {
378  std::cout << "IMPOSSIBLE" << std::endl;
379  seed_adc = 0;
380  theBuffer.set_adc(pix, 1);
381  }
382  else {
383  */
384  // Note: each ADC value is limited here to 65535 (std::numeric_limits<uint16_t>::max),
385  // as it is later stored as uint16_t in SiPixelCluster and PixelClusterizerBase/AccretionCluster
386  // (reminder: ADC values here may be expressed in number of electrons)
387  seed_adc = std::min(theBuffer(pix.row(), pix.col()), int(std::numeric_limits<uint16_t>::max()));
388  theBuffer.set_adc(pix, 1);
389  // }
390 
391  AccretionCluster acluster, cldata;
392  acluster.add(pix, seed_adc);
393  cldata.add(pix, seed_adc);
394 
395  //Here we search all pixels adjacent to all pixels in the cluster.
396  bool dead_flag = false;
397  while (!acluster.empty()) {
398  //This is the standard algorithm to find and add a pixel
399  auto curInd = acluster.top();
400  acluster.pop();
401  for (auto c = std::max(0, int(acluster.y[curInd]) - 1);
402  c < std::min(int(acluster.y[curInd]) + 2, theBuffer.columns());
403  ++c) {
404  for (auto r = std::max(0, int(acluster.x[curInd]) - 1);
405  r < std::min(int(acluster.x[curInd]) + 2, theBuffer.rows());
406  ++r) {
407  if (theBuffer(r, c) >= thePixelThreshold) {
408  SiPixelCluster::PixelPos newpix(r, c);
409  auto const newpix_adc = std::min(theBuffer(r, c), int(std::numeric_limits<uint16_t>::max()));
410  if (!acluster.add(newpix, newpix_adc))
411  goto endClus;
412  // VV: no fake pixels in cluster, leads to non-contiguous clusters
413  if (!theFakePixels[r * theNumOfCols + c]) {
414  cldata.add(newpix, newpix_adc);
415  }
416  theBuffer.set_adc(newpix, 1);
417  }
418 
419  /* //Commenting out the addition of dead pixels to the cluster until further testing -- dfehling 06/09
420  //Check on the bounds of the module; this is to keep the isDead and isNoisy modules from returning errors
421  else if(r>= 0 && c >= 0 && (r <= (theNumOfRows-1.)) && (c <= (theNumOfCols-1.))){
422  //Check for dead/noisy pixels check that the buffer is not -1 (already considered). Check whether we want to split clusters separated by dead pixels or not.
423  if((theSiPixelGainCalibrationService_->isDead(theDetid,c,r) || theSiPixelGainCalibrationService_->isNoisy(theDetid,c,r)) && theBuffer(r,c) != 1){
424 
425  //If a pixel is dead or noisy, check to see if we want to split the clusters or not.
426  //Push it into a dead pixel stack in case we want to split the clusters. Otherwise add it to the cluster.
427  //If we are splitting the clusters, we will iterate over the dead pixel stack later.
428 
429  SiPixelCluster::PixelPos newpix(r,c);
430  if(!doSplitClusters){
431 
432  cluster.add(newpix, std::min(theBuffer(r, c), int(std::numeric_limits<uint16_t>::max())));}
433  else if(doSplitClusters){
434  dead_pixel_stack.push(newpix);
435  dead_flag = true;}
436 
437  theBuffer.set_adc(newpix, 1);
438  }
439 
440  }
441  */
442  }
443  }
444 
445  } // while accretion
446 endClus:
447  SiPixelCluster cluster(cldata.isize, cldata.adc, cldata.x, cldata.y, cldata.xmin, cldata.ymin);
448  //Here we split the cluster, if the flag to do so is set and we have found a dead or noisy pixel.
449 
450  if (dead_flag && doSplitClusters) {
451  // Set separate cluster threshold for L1 (needed for phase1)
453  if (theLayer == 1)
455 
456  //Set the first cluster equal to the existing cluster.
457  SiPixelCluster first_cluster = cluster;
458  bool have_second_cluster = false;
459  while (!dead_pixel_stack.empty()) {
460  //consider each found dead pixel
461  SiPixelCluster::PixelPos deadpix = dead_pixel_stack.top();
462  dead_pixel_stack.pop();
463  theBuffer.set_adc(deadpix, 1);
464 
465  //Clusterize the split cluster using the dead pixel as a seed
466  SiPixelCluster second_cluster = make_cluster(deadpix, output);
467 
468  //If both clusters would normally have been found by the clusterizer, put them into output
469  if (second_cluster.charge() >= clusterThreshold && first_cluster.charge() >= clusterThreshold) {
470  output.push_back(second_cluster);
471  have_second_cluster = true;
472  }
473 
474  //We also want to keep the merged cluster in data and let the RecHit algorithm decide which set to keep
475  //This loop adds the second cluster to the first.
476  const std::vector<SiPixelCluster::Pixel>& branch_pixels = second_cluster.pixels();
477  for (unsigned int i = 0; i < branch_pixels.size(); i++) {
478  auto const temp_x = branch_pixels[i].x;
479  auto const temp_y = branch_pixels[i].y;
480  auto const temp_adc = branch_pixels[i].adc;
481  SiPixelCluster::PixelPos newpix(temp_x, temp_y);
482  cluster.add(newpix, temp_adc);
483  }
484  }
485 
486  //Remember to also add the first cluster if we added the second one.
487  if (first_cluster.charge() >= clusterThreshold && have_second_cluster) {
488  output.push_back(first_cluster);
489  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
490  return cl1.minPixelRow() < cl2.minPixelRow();
491  });
492  }
493  }
494 
495  return cluster;
496 }
SiPixelArrayBuffer theBuffer
Data storage.
SiPixelCluster make_cluster(const SiPixelCluster::PixelPos &pix, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
The actual clustering algorithm: group the neighboring pixels around the seed.
void set_adc(int row, int col, int adc)
int minPixelRow() const
int charge() const
const std::vector< Pixel > pixels() const
Pixel cluster – collection of neighboring pixels above threshold.
constexpr int row() const
constexpr int col() const
Definition: output.py:1

◆ setup()

bool PixelThresholdClusterizer::setup ( const PixelGeomDetUnit pixDet)
protected

Private helper methods:

Prepare the Clusterizer to work on a particular DetUnit. Re-init the size of the panel/plaquette (so update nrows and ncols),

Definition at line 97 of file PixelThresholdClusterizer.cc.

References SiPixelArrayBuffer::columns(), hgcalPlots::ncols, PixelTopology::ncolumns(), PixelTopology::nrows(), SiPixelArrayBuffer::rows(), SiPixelArrayBuffer::setSize(), PixelGeomDetUnit::specificTopology(), theBuffer, theFakePixels, theNumOfCols, theNumOfRows, and thePixelOccurrence.

97  {
98  // Cache the topology.
99  const PixelTopology& topol = pixDet->specificTopology();
100 
101  // Get the new sizes.
102  int nrows = topol.nrows(); // rows in x
103  int ncols = topol.ncolumns(); // cols in y
104 
105  theNumOfRows = nrows; // Set new sizes
107 
108  if (nrows > theBuffer.rows() || ncols > theBuffer.columns()) { // change only when a larger is needed
109  if (nrows != theNumOfRows || ncols != theNumOfCols)
110  edm::LogWarning("setup()") << "pixel buffer redefined to" << nrows << " * " << ncols;
111  //theNumOfRows = nrows; // Set new sizes
112  //theNumOfCols = ncols;
113  // Resize the buffer
114  theBuffer.setSize(nrows, ncols); // Modify
115  }
116 
117  theFakePixels.resize(nrows * ncols, false);
118 
119  thePixelOccurrence.resize(nrows * ncols, 0);
120 
121  return true;
122 }
SiPixelArrayBuffer theBuffer
Data storage.
virtual int ncolumns() const =0
virtual int nrows() const =0
int theNumOfRows
Geometry-related information.
std::vector< uint8_t > thePixelOccurrence
void setSize(int rows, int cols)
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
Log< level::Warning, false > LogWarning

Member Data Documentation

◆ doMissCalibrate

const bool PixelThresholdClusterizer::doMissCalibrate
protected

Definition at line 128 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ doPhase2Calibration

const bool PixelThresholdClusterizer::doPhase2Calibration
protected

Definition at line 115 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ doSplitClusters

const bool PixelThresholdClusterizer::doSplitClusters
protected

Definition at line 129 of file PixelThresholdClusterizer.h.

Referenced by make_cluster().

◆ dropDuplicates

const bool PixelThresholdClusterizer::dropDuplicates
protected

Definition at line 117 of file PixelThresholdClusterizer.h.

Referenced by copy_to_buffer().

◆ theBuffer

SiPixelArrayBuffer PixelThresholdClusterizer::theBuffer
protected

Data storage.

Definition at line 91 of file PixelThresholdClusterizer.h.

Referenced by clear_buffer(), copy_to_buffer(), make_cluster(), PixelThresholdClusterizer(), and setup().

◆ theClusters

std::vector<SiPixelCluster> PixelThresholdClusterizer::theClusters
protected

Definition at line 93 of file PixelThresholdClusterizer.h.

◆ theClusterThreshold

const int PixelThresholdClusterizer::theClusterThreshold
protected

Definition at line 106 of file PixelThresholdClusterizer.h.

Referenced by make_cluster().

◆ theClusterThreshold_L1

const int PixelThresholdClusterizer::theClusterThreshold_L1
protected

Definition at line 107 of file PixelThresholdClusterizer.h.

Referenced by make_cluster().

◆ theClusterThresholdInNoiseUnits

float PixelThresholdClusterizer::theClusterThresholdInNoiseUnits
protected

Definition at line 102 of file PixelThresholdClusterizer.h.

◆ theConversionFactor

const int PixelThresholdClusterizer::theConversionFactor
protected

Definition at line 108 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ theConversionFactor_L1

const int PixelThresholdClusterizer::theConversionFactor_L1
protected

Definition at line 109 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ theDetid

uint32_t PixelThresholdClusterizer::theDetid
protected

Definition at line 126 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ theElectronPerADCGain

const double PixelThresholdClusterizer::theElectronPerADCGain
protected

Definition at line 113 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ theFakePixels

std::vector<bool> PixelThresholdClusterizer::theFakePixels
protected

◆ theLayer

int PixelThresholdClusterizer::theLayer
protected

Definition at line 127 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), copy_to_buffer(), and make_cluster().

◆ theNumOfCols

int PixelThresholdClusterizer::theNumOfCols
protected

◆ theNumOfRows

int PixelThresholdClusterizer::theNumOfRows
protected

Geometry-related information.

Definition at line 124 of file PixelThresholdClusterizer.h.

Referenced by PixelThresholdClusterizer(), and setup().

◆ theOffset

const int PixelThresholdClusterizer::theOffset
protected

Definition at line 110 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ theOffset_L1

const int PixelThresholdClusterizer::theOffset_L1
protected

Definition at line 111 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

◆ thePhase2DigiBaseline

const double PixelThresholdClusterizer::thePhase2DigiBaseline
protected

Definition at line 120 of file PixelThresholdClusterizer.h.

Referenced by calibrate().

◆ thePhase2KinkADC

const int PixelThresholdClusterizer::thePhase2KinkADC
protected

Definition at line 121 of file PixelThresholdClusterizer.h.

Referenced by calibrate().

◆ thePhase2ReadoutMode

const int PixelThresholdClusterizer::thePhase2ReadoutMode
protected

Definition at line 119 of file PixelThresholdClusterizer.h.

Referenced by calibrate().

◆ thePixelOccurrence

std::vector<uint8_t> PixelThresholdClusterizer::thePixelOccurrence
protected

Definition at line 97 of file PixelThresholdClusterizer.h.

Referenced by copy_to_buffer(), PixelThresholdClusterizer(), and setup().

◆ thePixelThreshold

const int PixelThresholdClusterizer::thePixelThreshold
protected

Definition at line 104 of file PixelThresholdClusterizer.h.

Referenced by copy_to_buffer(), and make_cluster().

◆ thePixelThresholdInNoiseUnits

float PixelThresholdClusterizer::thePixelThresholdInNoiseUnits
protected

Clustering-related quantities:

Definition at line 100 of file PixelThresholdClusterizer.h.

◆ theSeeds

std::vector<SiPixelCluster::PixelPos> PixelThresholdClusterizer::theSeeds
protected

Definition at line 92 of file PixelThresholdClusterizer.h.

Referenced by copy_to_buffer().

◆ theSeedThreshold

const int PixelThresholdClusterizer::theSeedThreshold
protected

Definition at line 105 of file PixelThresholdClusterizer.h.

Referenced by copy_to_buffer().

◆ theSeedThresholdInNoiseUnits

float PixelThresholdClusterizer::theSeedThresholdInNoiseUnits
protected

Definition at line 101 of file PixelThresholdClusterizer.h.