46 conf_(conf), bufferAlreadySet(
false), theNumOfRows(0), theNumOfCols(0), detid_(0)
50 conf_.getParameter<
int>(
"ChannelThreshold");
52 conf_.getParameter<
int>(
"SeedThreshold");
54 conf_.getParameter<
double>(
"ClusterThreshold");
56 conf_.getParameter<
int>(
"VCaltoElectronGain");
58 conf_.getParameter<
int>(
"VCaltoElectronOffset");
59 if ( conf_.exists(
"AdcFullScaleStack") ) theStackADC_=conf_.getParameter<
int>(
"AdcFullScaleStack");
62 if ( conf_.exists(
"FirstStackLayer") ) theFirstStack_=conf_.getParameter<
int>(
"FirstStackLayer");
67 doMissCalibrate=conf_.getUntrackedParameter<
bool>(
"MissCalibrate",
true);
68 doSplitClusters = conf.
getParameter<
bool>(
"SplitClusters");
69 theBuffer.setSize( theNumOfRows, theNumOfCols );
84 int nrows = topol.
nrows();
90 if ( nrows > theBuffer.rows() ||
91 ncols > theBuffer.columns() )
99 theBuffer.setSize(nrows,ncols);
100 bufferAlreadySet =
true;
114 const std::vector<short>& badChannels,
124 if ( !
setup(pixDet) )
127 detid_ = input.
detId();
131 copy_to_buffer(begin, end);
135 for (
unsigned int i = 0;
i < theSeeds.size();
i++)
140 if ( theBuffer(theSeeds[
i]) >= theSeedThreshold )
147 if ( cluster.
charge() >= theClusterThreshold)
159 clear_buffer(begin, end);
176 theBuffer.set_adc( di->row(), di->column(), 0 );
185 #ifdef PIXELREGRESSION 186 static std::atomic<int> s_ic=0;
193 if ( doMissCalibrate ) {
194 (*theSiPixelGainCalibrationService_).calibrate(detid_,begin,end,theConversionFactor, theOffset,electron);
199 auto adc = di->adc();
200 const float gain = 135.;
202 electron[
i] =
int(
adc * gain + pedestal);
203 if (layer>=theFirstStack_) {
204 if (theStackADC_==1&&
adc==1) {
205 electron[
i] =
int(255*135);
207 if (theStackADC_>1&&theStackADC_!=255&&
adc>=1){
208 const float gain = 135.;
209 electron[
i] =
int((
adc-1) * gain * 255/
float(theStackADC_-1));
214 assert(i==(end-begin));
218 #ifdef PIXELREGRESSION 219 static std::atomic<int> eqD=0;
223 int col = di->column();
224 int adc = electron[i++];
225 #ifdef PIXELREGRESSION 226 int adcOld = calibrate(di->adc(),
col,row);
229 LogWarning(
"Phase2ITPixelThresholdClusterizer") << eqD <<
' '<< ic <<
' '<< end-begin <<
' '<< i <<
' '<< di->adc() <<
' ' << adc <<
' '<< adcOld;
235 if ( adc >= thePixelThreshold) {
236 theBuffer.set_adc( row, col, adc);
240 assert(i==(end-begin));
253 if ( doMissCalibrate )
257 if ( !theSiPixelGainCalibrationService_->isDead(detid_,col,row) &&
258 !theSiPixelGainCalibrationService_->isNoisy(detid_,col,row) )
269 float DBgain = theSiPixelGainCalibrationService_->getGain(detid_, col, row);
270 float DBpedestal = theSiPixelGainCalibrationService_->getPedestal(detid_, col, row) * DBgain;
277 float vcal = adc * DBgain - DBpedestal;
292 electrons =
int( vcal * theConversionFactor + theOffset);
298 const float gain = 135.;
300 electrons =
int(adc * gain + pedestal);
301 if (layer>=theFirstStack_) {
302 if (theStackADC_==1&&adc==1)
304 electrons =
int(255*135);
306 if (theStackADC_>1&&theStackADC_!=255&&adc>=1)
308 const float gain = 135.;
309 electrons =
int((adc-1) * gain * 255/
float(theStackADC_-1));
320 struct AccretionCluster {
321 typedef uint32_t UShort;
328 unsigned int isize=0;
332 UShort top()
const {
return curr;}
333 void pop() { ++curr;}
334 bool empty() {
return curr==isize;}
337 if (isize==MAXSIZE)
return false;
359 stack<Phase2ITPixelCluster::PixelPos, vector<Phase2ITPixelCluster::PixelPos> > dead_pixel_stack;
367 seed_adc = theBuffer(pix.
row(), pix.
col());
368 theBuffer.set_adc( pix, 1);
370 AccretionCluster acluster;
371 acluster.add(pix, seed_adc);
374 bool dead_flag =
false;
375 while ( ! acluster.empty())
378 auto curInd = acluster.top(); acluster.pop();
379 for (
auto c =
std::max(0,
int(acluster.y[curInd])-1);
c <
std::min(
int(acluster.y[curInd])+2,theBuffer.columns()) ; ++
c) {
380 for (
auto r =
std::max(0,
int(acluster.x[curInd])-1);
r <
std::min(
int(acluster.x[curInd])+2,theBuffer.rows()); ++
r) {
381 if ( theBuffer(
r,
c) >= thePixelThreshold) {
383 if (!acluster.add( newpix, theBuffer(
r,
c)))
goto endClus;
384 theBuffer.set_adc( newpix, 1);
419 Phase2ITPixelCluster cluster(acluster.isize,acluster.adc, acluster.x,acluster.y, acluster.xmin,acluster.ymin);
422 if (dead_flag && doSplitClusters)
426 bool have_second_cluster =
false;
427 while ( !dead_pixel_stack.empty() )
431 theBuffer.set_adc(deadpix, 1);
437 if ( second_cluster.
charge() >= theClusterThreshold &&
438 first_cluster.
charge() >= theClusterThreshold )
441 have_second_cluster =
true;
446 const std::vector<Phase2ITPixelCluster::Pixel>& branch_pixels = second_cluster.
pixels();
447 for (
unsigned int i = 0;
i<branch_pixels.size();
i++)
449 int temp_x = branch_pixels[
i].x;
450 int temp_y = branch_pixels[
i].y;
451 int temp_adc = branch_pixels[
i].adc;
453 cluster.
add(newpix, temp_adc);}
457 if ( first_cluster.
charge() >= theClusterThreshold && have_second_cluster)
int adc(sample_type sample)
get the ADC sample (12 bits)
T getParameter(std::string const &) const
void push_back(data_type const &d)
virtual int nrows() const =0
Phase2ITPixelThresholdClusterizer(edm::ParameterSet const &conf)
void clusterizeDetUnit(const edm::DetSet< PixelDigi > &input, const PixelGeomDetUnit *pixDet, const std::vector< short > &badChannels, edmNew::DetSetVector< Phase2ITPixelCluster >::FastFiller &output)
Cluster pixels. This method operates on a matrix of pixels and finds the largest contiguous cluster a...
det_id_type detId() const
def setup(process, global_tag, zero_tesla=False)
void add(const std::vector< const T * > &source, std::vector< const T * > &dest)
static void pop(std::vector< T > &vec, unsigned int index)
unsigned int layer() const
layer id
static std::string const input
T x() const
Cartesian x coordinate.
void add(const PixelPos &pix, uint32_t adc)
Phase2ITPixelCluster make_cluster(const Phase2ITPixelCluster::PixelPos &pix, edmNew::DetSetVector< Phase2ITPixelCluster >::FastFiller &output)
The actual clustering algorithm: group the neighboring pixels around the seed.
~Phase2ITPixelThresholdClusterizer()
int calibrate(int adc, int col, int row)
const std::vector< Pixel > pixels() const
int subdetId() const
get the contents of the subdetector field (not cast into any detector's numbering enum) ...
void copy_to_buffer(DigiIterator begin, DigiIterator end)
Copy adc counts from PixelDigis into the buffer, identify seeds.
void clear_buffer(DigiIterator begin, DigiIterator end)
Clear the internal buffer array.
Pixel cluster – collection of neighboring pixels above threshold.
edm::DetSet< PixelDigi >::const_iterator DigiIterator
virtual const PixelTopology & specificTopology() const
Returns a reference to the pixel proxy topology.
virtual int ncolumns() const =0
bool setup(const PixelGeomDetUnit *pixDet)
Private helper methods: