CMS 3D CMS Logo

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Properties Friends Macros Groups Pages
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 PixelThresholdClusterizerForBricked

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
 
 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)
 Cluster pixels. This method operates on a matrix of pixels and finds the largest contiguous cluster around each seed pixel. Input and output data stored in DetSet. More...
 
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
 
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
 
const int thePixelThreshold
 
float thePixelThresholdInNoiseUnits
 Clustering-related quantities: More...
 
std::vector
< SiPixelCluster::PixelPos
theSeeds
 
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 ( 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 43 of file PixelThresholdClusterizer.cc.

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

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

Definition at line 68 of file PixelThresholdClusterizer.cc.

68 {}

Member Function Documentation

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

Definition at line 327 of file PixelThresholdClusterizer.cc.

References doMissCalibrate, doPhase2Calibration, HI_PhotonSkim_cff::electrons, SiPixelGainCalibrationServiceBase::getGain(), SiPixelGainCalibrationServiceBase::getPedestal(), SiPixelGainCalibrationServiceBase::isDead(), SiPixelGainCalibrationServiceBase::isNoisy(), EcalCondDBWriter_cfi::pedestal, funct::pow(), theConversionFactor, theConversionFactor_L1, theDetid, theElectronPerADCGain, theLayer, theOffset, theOffset_L1, thePhase2DigiBaseline, thePhase2KinkADC, thePhase2ReadoutMode, and PixelClusterizerBase::theSiPixelGainCalibrationService_.

Referenced by copy_to_buffer().

327  {
328  int electrons = 0;
329 
330  if (doPhase2Calibration) {
331  const float gain = theElectronPerADCGain;
332  int p2rm = (thePhase2ReadoutMode < -1 ? -1 : thePhase2ReadoutMode);
333 
334  if (p2rm == -1) {
335  electrons = int(adc * gain);
336  } else {
337  if (adc < thePhase2KinkADC) {
338  electrons = int((adc + 0.5) * gain);
339  } else {
340  const int dualslopeparam = (thePhase2ReadoutMode < 10 ? thePhase2ReadoutMode : 10);
341  const int dualslope = int(dualslopeparam <= 1 ? 1. : pow(2, dualslopeparam - 1));
343  adc *= dualslope;
345  electrons = int((adc + 0.5 * dualslope) * gain);
346  }
347  electrons += int(thePhase2DigiBaseline);
348  }
349 
350  return electrons;
351  }
352 
353  if (doMissCalibrate) {
354  // do not perform calibration if pixel is dead!
355 
358  // Linear approximation of the TANH response
359  // Pixel(0,0,0)
360  //const float gain = 2.95; // 1 ADC = 2.95 VCALs (1/0.339)
361  //const float pedestal = -83.; // -28/0.339
362  // Roc-0 average
363  //const float gain = 1./0.357; // 1 ADC = 2.80 VCALs
364  //const float pedestal = -28.2 * gain; // -79.
365 
366  float DBgain = theSiPixelGainCalibrationService_->getGain(theDetid, col, row);
368  float DBpedestal = pedestal * DBgain;
369 
370  // Roc-6 average
371  //const float gain = 1./0.313; // 1 ADC = 3.19 VCALs
372  //const float pedestal = -6.2 * gain; // -19.8
373  //
374  float vcal = adc * DBgain - DBpedestal;
375 
376  // atanh calibration
377  // Roc-6 average
378  //const float p0 = 0.00492;
379  //const float p1 = 1.998;
380  //const float p2 = 90.6;
381  //const float p3 = 134.1;
382  // Roc-6 average
383  //const float p0 = 0.00382;
384  //const float p1 = 0.886;
385  //const float p2 = 112.7;
386  //const float p3 = 113.0;
387  //float vcal = ( atanh( (adc-p3)/p2) + p1)/p0;
388 
389  if (theLayer == 1) {
390  electrons = int(vcal * theConversionFactor_L1 + theOffset_L1);
391  } else {
392  electrons = int(vcal * theConversionFactor + theOffset);
393  }
394  }
395  } else { // No misscalibration in the digitizer
396  // Simple (default) linear gain
397  const float gain = theElectronPerADCGain; // default: 1 ADC = 135 electrons
398  const float pedestal = 0.; //
399  electrons = int(adc * gain + pedestal);
400  }
401 
402  return electrons;
403 }
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_
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
int col
Definition: cuy.py:1009
Power< A, B >::type pow(const A &a, const B &b)
Definition: Power.h:29
uint16_t *__restrict__ uint16_t const *__restrict__ adc
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 199 of file PixelThresholdClusterizer.cc.

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

Referenced by PixelThresholdClusterizerForBricked::clusterizeDetUnitT(), and clusterizeDetUnitT().

199  {
200  for (DigiIterator di = begin; di != end; ++di) {
201  theBuffer.set_adc(di->row(), di->column(), 0); // reset pixel adc to 0
202  }
203 }
SiPixelArrayBuffer theBuffer
Data storage.
void set_adc(int row, int col, int adc)
edm::DetSet< PixelDigi >::const_iterator DigiIterator
string end
Definition: dataset.py:937
void PixelThresholdClusterizer::clear_buffer ( ClusterIterator  begin,
ClusterIterator  end 
)
protected

Definition at line 205 of file PixelThresholdClusterizer.cc.

References dataset::end, mps_fire::i, digitizers_cfi::pixel, SiPixelArrayBuffer::set_adc(), theBuffer, SiPixelCluster::Pixel::x, and SiPixelCluster::Pixel::y.

205  {
206  for (ClusterIterator ci = begin; ci != end; ++ci) {
207  for (int i = 0; i < ci->size(); ++i) {
208  const SiPixelCluster::Pixel pixel = ci->pixel(i);
209 
210  theBuffer.set_adc(pixel.x, pixel.y, 0); // reset pixel adc to 0
211  }
212  }
213 }
SiPixelArrayBuffer theBuffer
Data storage.
void set_adc(int row, int col, int adc)
edmNew::DetSet< SiPixelCluster >::const_iterator ClusterIterator
string end
Definition: dataset.py:937
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.

Reimplemented in PixelThresholdClusterizerForBricked.

Definition at line 63 of file PixelThresholdClusterizer.h.

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)
Cluster pixels. This method operates on a matrix of pixels and finds the largest contiguous cluster a...
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.

Reimplemented in PixelThresholdClusterizerForBricked.

Definition at line 70 of file PixelThresholdClusterizer.h.

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)
Cluster pixels. This method operates on a matrix of pixels and finds the largest contiguous cluster a...
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

Cluster pixels. This method operates on a matrix of pixels and finds the largest contiguous cluster around each seed pixel. Input and output data stored in DetSet.

Definition at line 125 of file PixelThresholdClusterizer.cc.

References cms::cuda::assert(), SplitLinear::begin, edmNew::DetSetVector< T >::FastFiller::begin(), SiPixelCluster::charge(), GetRecoTauVFromDQM_MC_cff::cl2, clear_buffer(), copy_to_buffer(), edmNew::DetSetVector< T >::FastFiller::empty(), edmNew::DetSetVector< T >::FastFiller::end(), dataset::end, mps_fire::i, make_cluster(), SiPixelCluster::minPixelRow(), eostools::move(), edmNew::DetSetVector< T >::FastFiller::push_back(), TrackerTopology::pxbLayer(), setup(), DetId::subdetId(), theBuffer, theClusterThreshold, theClusterThreshold_L1, theDetid, theFakePixels, theLayer, theSeeds, and theSeedThreshold.

Referenced by PixelThresholdClusterizerForBricked::clusterizeDetUnit().

129  {
130  typename T::const_iterator begin = input.begin();
131  typename T::const_iterator end = input.end();
132 
133  // this should never happen and the raw2digi does not create empty detsets
134  if (begin == end) {
135  edm::LogError("PixelThresholdClusterizer") << "@SUB=PixelThresholdClusterizer::clusterizeDetUnitT()"
136  << " No digis to clusterize";
137  }
138 
139  // Set up the clusterization on this DetId.
140  if (!setup(pixDet))
141  return;
142 
143  theDetid = input.detId();
144 
145  // Set separate cluster threshold for L1 (needed for phase1)
146  auto clusterThreshold = theClusterThreshold;
147  theLayer = (DetId(theDetid).subdetId() == 1) ? tTopo->pxbLayer(theDetid) : 0;
148  if (theLayer == 1)
149  clusterThreshold = theClusterThreshold_L1;
150 
151  // Copy PixelDigis to the buffer array; select the seed pixels
152  // on the way, and store them in theSeeds.
153  if (end > begin)
154  copy_to_buffer(begin, end);
155 
156  assert(output.empty());
157  // Loop over all seeds. TO DO: wouldn't using iterators be faster?
158  for (unsigned int i = 0; i < theSeeds.size(); i++) {
159  // Gavril : The charge of seeds that were already inlcuded in clusters is set to 1 electron
160  // so we don't want to call "make_cluster" for these cases
161  if (theBuffer(theSeeds[i]) >= theSeedThreshold) { // Is this seed still valid?
162  // Make a cluster around this seed
163  SiPixelCluster&& cluster = make_cluster(theSeeds[i], output);
164 
165  // Check if the cluster is above threshold
166  // (TO DO: one is signed, other unsigned, gcc warns...)
167  if (cluster.charge() >= clusterThreshold) {
168  // sort by row (x)
169  output.push_back(std::move(cluster));
170  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
171  return cl1.minPixelRow() < cl2.minPixelRow();
172  });
173  }
174  }
175  }
176  // sort by row (x) maybe sorting the seed would suffice....
177  std::sort_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
178  return cl1.minPixelRow() < cl2.minPixelRow();
179  });
180 
181  // Erase the seeds.
182  theSeeds.clear();
183 
184  // Need to clean unused pixels from the buffer array.
185  clear_buffer(begin, end);
186 
187  theFakePixels.clear();
188 }
void push_back(data_type const &d)
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.
int charge() const
Log< level::Error, false > LogError
assert(be >=bs)
static std::string const input
Definition: EdmProvDump.cc:47
int minPixelRow() const
def move
Definition: eostools.py:511
constexpr int subdetId() const
get the contents of the subdetector field (not cast into any detector&#39;s numbering enum) ...
Definition: DetId.h:48
unsigned int pxbLayer(const DetId &id) const
Definition: DetId.h:17
void clear_buffer(DigiIterator begin, DigiIterator end)
Clear the internal buffer array.
Pixel cluster – collection of neighboring pixels above threshold.
string end
Definition: dataset.py:937
bool setup(const PixelGeomDetUnit *pixDet)
Private helper methods:
std::vector< SiPixelCluster::PixelPos > theSeeds
void copy_to_buffer(DigiIterator begin, DigiIterator end)
Copy adc counts from PixelDigis into the buffer, identify seeds.
void PixelThresholdClusterizer::copy_to_buffer ( DigiIterator  begin,
DigiIterator  end 
)
protected

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

Definition at line 218 of file PixelThresholdClusterizer.cc.

References gpuClustering::adc, cms::cuda::assert(), SplitLinear::begin, calibrate(), cuy::col, gather_cfg::cout, doMissCalibrate, doPhase2Calibration, metsig::electron, dataset::end, mps_fire::i, recoMuon::in, EcalCondDBWriter_cfi::pedestal, SiPixelArrayBuffer::set_adc(), theBuffer, theConversionFactor, theConversionFactor_L1, theDetid, theElectronPerADCGain, theFakePixels, theLayer, theNumOfCols, theOffset, theOffset_L1, thePixelThreshold, theSeeds, and theSeedThreshold.

Referenced by PixelThresholdClusterizerForBricked::clusterizeDetUnitT(), and clusterizeDetUnitT().

218  {
219 #ifdef PIXELREGRESSION
220  static std::atomic<int> s_ic = 0;
221  in ic = ++s_ic;
222  if (ic == 1) {
223  // std::cout << (doMissCalibrate ? "VI from db" : "VI linear") << std::endl;
224  }
225 #endif
226 
227  //If called with empty/invalid DetSet, warn the user
228  if (end <= begin) {
229  edm::LogWarning("PixelThresholdClusterizer") << " copy_to_buffer called with empty or invalid range" << std::endl;
230  return;
231  }
232 
233  int electron[end - begin]; // pixel charge in electrons
234  memset(electron, 0, (end - begin) * sizeof(int));
235 
236  if (doPhase2Calibration) {
237  int i = 0;
238  for (DigiIterator di = begin; di != end; ++di) {
239  electron[i] = calibrate(di->adc(), di->column(), di->row());
240  i++;
241  }
242  assert(i == (end - begin));
243  }
244 
245  else {
246  if (doMissCalibrate) {
247  if (theLayer == 1) {
248  (*theSiPixelGainCalibrationService_)
249  .calibrate(theDetid, begin, end, theConversionFactor_L1, theOffset_L1, electron);
250  } else {
251  (*theSiPixelGainCalibrationService_).calibrate(theDetid, begin, end, theConversionFactor, theOffset, electron);
252  }
253  } else {
254  int i = 0;
255  const float gain = theElectronPerADCGain; // default: 1 ADC = 135 electrons
256  for (DigiIterator di = begin; di != end; ++di) {
257  auto adc = di->adc();
258  const float pedestal = 0.; //
259  electron[i] = int(adc * gain + pedestal);
260  ++i;
261  }
262  assert(i == (end - begin));
263  }
264  }
265 
266  int i = 0;
267 #ifdef PIXELREGRESSION
268  static std::atomic<int> eqD = 0;
269 #endif
270  for (DigiIterator di = begin; di != end; ++di) {
271  int row = di->row();
272  int col = di->column();
273  // VV: do not calibrate a fake pixel, it already has a unit of 10e-:
274  int adc = (di->flag() != 0) ? di->adc() * 10 : electron[i]; // this is in electrons
275  i++;
276 
277 #ifdef PIXELREGRESSION
278  int adcOld = calibrate(di->adc(), col, row);
279  //assert(adc==adcOld);
280  if (adc != adcOld)
281  std::cout << "VI " << eqD << ' ' << ic << ' ' << end - begin << ' ' << i << ' ' << di->adc() << ' ' << adc << ' '
282  << adcOld << std::endl;
283  else
284  ++eqD;
285 #endif
286 
287  if (adc < 100)
288  adc = 100; // put all negative pixel charges into the 100 elec bin
289  /* This is semi-random good number. The exact number (in place of 100) is irrelevant from the point
290  of view of the final cluster charge since these are typically >= 20000.
291  */
292 
293  if (adc >= thePixelThreshold) {
294  theBuffer.set_adc(row, col, adc);
295  // VV: add pixel to the fake list. Only when running on digi collection
296  if (di->flag() != 0)
297  theFakePixels[row * theNumOfCols + col] = true;
298  if (adc >= theSeedThreshold)
299  theSeeds.push_back(SiPixelCluster::PixelPos(row, col));
300  }
301  }
302  assert(i == (end - begin));
303 }
SiPixelArrayBuffer theBuffer
Data storage.
assert(be >=bs)
void set_adc(int row, int col, int adc)
edm::DetSet< PixelDigi >::const_iterator DigiIterator
string end
Definition: dataset.py:937
tuple cout
Definition: gather_cfg.py:144
int calibrate(int adc, int col, int row)
Log< level::Warning, false > LogWarning
int col
Definition: cuy.py:1009
std::vector< SiPixelCluster::PixelPos > theSeeds
uint16_t *__restrict__ uint16_t const *__restrict__ adc
void PixelThresholdClusterizer::copy_to_buffer ( ClusterIterator  begin,
ClusterIterator  end 
)
protected

Definition at line 305 of file PixelThresholdClusterizer.cc.

References gpuClustering::adc, SiPixelCluster::Pixel::adc, SiPixelArrayBuffer::add_adc(), cuy::col, dataset::end, mps_fire::i, digitizers_cfi::pixel, theBuffer, thePixelThreshold, theSeeds, theSeedThreshold, SiPixelCluster::Pixel::x, and SiPixelCluster::Pixel::y.

305  {
306  // loop over clusters
307  for (ClusterIterator ci = begin; ci != end; ++ci) {
308  // loop over pixels
309  for (int i = 0; i < ci->size(); ++i) {
310  const SiPixelCluster::Pixel pixel = ci->pixel(i);
311 
312  int row = pixel.x;
313  int col = pixel.y;
314  int adc = pixel.adc;
315  if (adc >= thePixelThreshold) {
316  theBuffer.add_adc(row, col, adc);
317  if (adc >= theSeedThreshold)
318  theSeeds.push_back(SiPixelCluster::PixelPos(row, col));
319  }
320  }
321  }
322 }
SiPixelArrayBuffer theBuffer
Data storage.
void add_adc(int row, int col, int adc)
edmNew::DetSet< SiPixelCluster >::const_iterator ClusterIterator
string end
Definition: dataset.py:937
int col
Definition: cuy.py:1009
std::vector< SiPixelCluster::PixelPos > theSeeds
uint16_t *__restrict__ uint16_t const *__restrict__ adc
void PixelThresholdClusterizer::fillPSetDescription ( edm::ParameterSetDescription desc)
static

Definition at line 71 of file PixelThresholdClusterizer.cc.

References edm::ParameterSetDescription::add().

Referenced by SiPixelClusterProducer::fillDescriptions().

71  {
72  desc.add<int>("ChannelThreshold", 1000);
73  desc.add<bool>("MissCalibrate", true);
74  desc.add<bool>("SplitClusters", false);
75  desc.add<int>("VCaltoElectronGain", 65);
76  desc.add<int>("VCaltoElectronGain_L1", 65);
77  desc.add<int>("VCaltoElectronOffset", -414);
78  desc.add<int>("VCaltoElectronOffset_L1", -414);
79  desc.add<int>("SeedThreshold", 1000);
80  desc.add<int>("ClusterThreshold_L1", 4000);
81  desc.add<int>("ClusterThreshold", 4000);
82  desc.add<double>("ElectronPerADCGain", 135.);
83  desc.add<bool>("Phase2Calibration", false);
84  desc.add<int>("Phase2ReadoutMode", -1);
85  desc.add<double>("Phase2DigiBaseline", 1200.);
86  desc.add<int>("Phase2KinkADC", 8);
87 }
ParameterDescriptionBase * add(U const &iLabel, T const &value)
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 408 of file PixelThresholdClusterizer.cc.

References PixelClusterizerBase::AccretionCluster::adc, PixelClusterizerBase::AccretionCluster::add(), SiPixelCluster::add(), edmNew::DetSetVector< T >::FastFiller::begin(), c, SiPixelCluster::charge(), GetRecoTauVFromDQM_MC_cff::cl2, SiPixelCluster::PixelPos::col(), SiPixelArrayBuffer::columns(), doSplitClusters, PixelClusterizerBase::AccretionCluster::empty(), edmNew::DetSetVector< T >::FastFiller::end(), mps_fire::i, PixelClusterizerBase::AccretionCluster::isize, SiStripPI::max, SiStripPI::min, SiPixelCluster::minPixelRow(), SiPixelCluster::pixels(), PixelClusterizerBase::AccretionCluster::pop(), edmNew::DetSetVector< T >::FastFiller::push_back(), 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.

Referenced by PixelThresholdClusterizerForBricked::clusterizeDetUnitT(), and clusterizeDetUnitT().

409  {
410  //First we acquire the seeds for the clusters
411  int seed_adc;
412  stack<SiPixelCluster::PixelPos, vector<SiPixelCluster::PixelPos> > dead_pixel_stack;
413 
414  //The individual modules have been loaded into a buffer.
415  //After each pixel has been considered by the clusterizer, we set the adc count to 1
416  //to mark that we have already considered it.
417  //The only difference between dead/noisy pixels and standard ones is that for dead/noisy pixels,
418  //We consider the charge of the pixel to always be zero.
419 
420  /* this is not possible as dead and noisy pixel cannot make it into a seed...
421  if ( doMissCalibrate &&
422  (theSiPixelGainCalibrationService_->isDead(theDetid,pix.col(),pix.row()) ||
423  theSiPixelGainCalibrationService_->isNoisy(theDetid,pix.col(),pix.row())) )
424  {
425  std::cout << "IMPOSSIBLE" << std::endl;
426  seed_adc = 0;
427  theBuffer.set_adc(pix, 1);
428  }
429  else {
430  */
431  seed_adc = theBuffer(pix.row(), pix.col());
432  theBuffer.set_adc(pix, 1);
433  // }
434 
435  AccretionCluster acluster, cldata;
436  acluster.add(pix, seed_adc);
437  cldata.add(pix, seed_adc);
438 
439  //Here we search all pixels adjacent to all pixels in the cluster.
440  bool dead_flag = false;
441  while (!acluster.empty()) {
442  //This is the standard algorithm to find and add a pixel
443  auto curInd = acluster.top();
444  acluster.pop();
445  for (auto c = std::max(0, int(acluster.y[curInd]) - 1);
446  c < std::min(int(acluster.y[curInd]) + 2, theBuffer.columns());
447  ++c) {
448  for (auto r = std::max(0, int(acluster.x[curInd]) - 1);
449  r < std::min(int(acluster.x[curInd]) + 2, theBuffer.rows());
450  ++r) {
451  if (theBuffer(r, c) >= thePixelThreshold) {
452  SiPixelCluster::PixelPos newpix(r, c);
453  if (!acluster.add(newpix, theBuffer(r, c)))
454  goto endClus;
455  // VV: no fake pixels in cluster, leads to non-contiguous clusters
456  if (!theFakePixels[r * theNumOfCols + c]) {
457  cldata.add(newpix, theBuffer(r, c));
458  }
459  theBuffer.set_adc(newpix, 1);
460  }
461 
462  /* //Commenting out the addition of dead pixels to the cluster until further testing -- dfehling 06/09
463  //Check on the bounds of the module; this is to keep the isDead and isNoisy modules from returning errors
464  else if(r>= 0 && c >= 0 && (r <= (theNumOfRows-1.)) && (c <= (theNumOfCols-1.))){
465  //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.
466  if((theSiPixelGainCalibrationService_->isDead(theDetid,c,r) || theSiPixelGainCalibrationService_->isNoisy(theDetid,c,r)) && theBuffer(r,c) != 1){
467 
468  //If a pixel is dead or noisy, check to see if we want to split the clusters or not.
469  //Push it into a dead pixel stack in case we want to split the clusters. Otherwise add it to the cluster.
470  //If we are splitting the clusters, we will iterate over the dead pixel stack later.
471 
472  SiPixelCluster::PixelPos newpix(r,c);
473  if(!doSplitClusters){
474 
475  cluster.add(newpix, theBuffer(r,c));}
476  else if(doSplitClusters){
477  dead_pixel_stack.push(newpix);
478  dead_flag = true;}
479 
480  theBuffer.set_adc(newpix, 1);
481  }
482 
483  }
484  */
485  }
486  }
487 
488  } // while accretion
489 endClus:
490  SiPixelCluster cluster(cldata.isize, cldata.adc, cldata.x, cldata.y, cldata.xmin, cldata.ymin);
491  //Here we split the cluster, if the flag to do so is set and we have found a dead or noisy pixel.
492 
493  if (dead_flag && doSplitClusters) {
494  // Set separate cluster threshold for L1 (needed for phase1)
495  auto clusterThreshold = theClusterThreshold;
496  if (theLayer == 1)
497  clusterThreshold = theClusterThreshold_L1;
498 
499  //Set the first cluster equal to the existing cluster.
500  SiPixelCluster first_cluster = cluster;
501  bool have_second_cluster = false;
502  while (!dead_pixel_stack.empty()) {
503  //consider each found dead pixel
504  SiPixelCluster::PixelPos deadpix = dead_pixel_stack.top();
505  dead_pixel_stack.pop();
506  theBuffer.set_adc(deadpix, 1);
507 
508  //Clusterize the split cluster using the dead pixel as a seed
509  SiPixelCluster second_cluster = make_cluster(deadpix, output);
510 
511  //If both clusters would normally have been found by the clusterizer, put them into output
512  if (second_cluster.charge() >= clusterThreshold && first_cluster.charge() >= clusterThreshold) {
513  output.push_back(second_cluster);
514  have_second_cluster = true;
515  }
516 
517  //We also want to keep the merged cluster in data and let the RecHit algorithm decide which set to keep
518  //This loop adds the second cluster to the first.
519  const std::vector<SiPixelCluster::Pixel>& branch_pixels = second_cluster.pixels();
520  for (unsigned int i = 0; i < branch_pixels.size(); i++) {
521  int temp_x = branch_pixels[i].x;
522  int temp_y = branch_pixels[i].y;
523  int temp_adc = branch_pixels[i].adc;
524  SiPixelCluster::PixelPos newpix(temp_x, temp_y);
525  cluster.add(newpix, temp_adc);
526  }
527  }
528 
529  //Remember to also add the first cluster if we added the second one.
530  if (first_cluster.charge() >= clusterThreshold && have_second_cluster) {
531  output.push_back(first_cluster);
532  std::push_heap(output.begin(), output.end(), [](SiPixelCluster const& cl1, SiPixelCluster const& cl2) {
533  return cl1.minPixelRow() < cl2.minPixelRow();
534  });
535  }
536  }
537 
538  return cluster;
539 }
void push_back(data_type const &d)
SiPixelArrayBuffer theBuffer
Data storage.
const edm::EventSetup & c
SiPixelCluster make_cluster(const SiPixelCluster::PixelPos &pix, edmNew::DetSetVector< SiPixelCluster >::FastFiller &output)
The actual clustering algorithm: group the neighboring pixels around the seed.
int charge() const
void set_adc(int row, int col, int adc)
int minPixelRow() const
constexpr int col() const
Pixel cluster – collection of neighboring pixels above threshold.
constexpr int row() const
const std::vector< Pixel > pixels() const
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 93 of file PixelThresholdClusterizer.cc.

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

Referenced by PixelThresholdClusterizerForBricked::clusterizeDetUnitT(), and clusterizeDetUnitT().

93  {
94  // Cache the topology.
95  const PixelTopology& topol = pixDet->specificTopology();
96 
97  // Get the new sizes.
98  int nrows = topol.nrows(); // rows in x
99  int ncols = topol.ncolumns(); // cols in y
100 
101  theNumOfRows = nrows; // Set new sizes
102  theNumOfCols = ncols;
103 
104  if (nrows > theBuffer.rows() || ncols > theBuffer.columns()) { // change only when a larger is needed
105  if (nrows != theNumOfRows || ncols != theNumOfCols)
106  edm::LogWarning("setup()") << "pixel buffer redefined to" << nrows << " * " << ncols;
107  //theNumOfRows = nrows; // Set new sizes
108  //theNumOfCols = ncols;
109  // Resize the buffer
110  theBuffer.setSize(nrows, ncols); // Modify
111  }
112 
113  theFakePixels.resize(nrows * ncols, false);
114 
115  return true;
116 }
SiPixelArrayBuffer theBuffer
Data storage.
virtual int ncolumns() const =0
virtual int nrows() const =0
int theNumOfRows
Geometry-related information.
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

const bool PixelThresholdClusterizer::doMissCalibrate
protected

Definition at line 121 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

const bool PixelThresholdClusterizer::doPhase2Calibration
protected

Definition at line 111 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

const bool PixelThresholdClusterizer::doSplitClusters
protected
SiPixelArrayBuffer PixelThresholdClusterizer::theBuffer
protected
std::vector<SiPixelCluster> PixelThresholdClusterizer::theClusters
protected

Definition at line 91 of file PixelThresholdClusterizer.h.

const int PixelThresholdClusterizer::theClusterThreshold
protected
const int PixelThresholdClusterizer::theClusterThreshold_L1
protected
float PixelThresholdClusterizer::theClusterThresholdInNoiseUnits
protected

Definition at line 98 of file PixelThresholdClusterizer.h.

const int PixelThresholdClusterizer::theConversionFactor
protected

Definition at line 104 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

const int PixelThresholdClusterizer::theConversionFactor_L1
protected

Definition at line 105 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

uint32_t PixelThresholdClusterizer::theDetid
protected
const double PixelThresholdClusterizer::theElectronPerADCGain
protected

Definition at line 109 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

std::vector<bool> PixelThresholdClusterizer::theFakePixels
protected
int PixelThresholdClusterizer::theLayer
protected
int PixelThresholdClusterizer::theNumOfCols
protected
int PixelThresholdClusterizer::theNumOfRows
protected

Geometry-related information.

Definition at line 117 of file PixelThresholdClusterizer.h.

Referenced by PixelThresholdClusterizer(), and setup().

const int PixelThresholdClusterizer::theOffset
protected

Definition at line 106 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

const int PixelThresholdClusterizer::theOffset_L1
protected

Definition at line 107 of file PixelThresholdClusterizer.h.

Referenced by calibrate(), and copy_to_buffer().

const double PixelThresholdClusterizer::thePhase2DigiBaseline
protected

Definition at line 113 of file PixelThresholdClusterizer.h.

Referenced by calibrate().

const int PixelThresholdClusterizer::thePhase2KinkADC
protected

Definition at line 114 of file PixelThresholdClusterizer.h.

Referenced by calibrate().

const int PixelThresholdClusterizer::thePhase2ReadoutMode
protected

Definition at line 112 of file PixelThresholdClusterizer.h.

Referenced by calibrate().

const int PixelThresholdClusterizer::thePixelThreshold
protected
float PixelThresholdClusterizer::thePixelThresholdInNoiseUnits
protected

Clustering-related quantities:

Definition at line 96 of file PixelThresholdClusterizer.h.

std::vector<SiPixelCluster::PixelPos> PixelThresholdClusterizer::theSeeds
protected
const int PixelThresholdClusterizer::theSeedThreshold
protected
float PixelThresholdClusterizer::theSeedThresholdInNoiseUnits
protected

Definition at line 97 of file PixelThresholdClusterizer.h.