00001
00020
00021
00022
00023 #include "RecoLocalTracker/SiPixelClusterizer/interface/PixelThresholdClusterizer.h"
00024 #include "RecoLocalTracker/SiPixelClusterizer/interface/SiPixelArrayBuffer.h"
00025 #include "CondFormats/SiPixelObjects/interface/SiPixelGainCalibrationOffline.h"
00026
00027 #include "Geometry/TrackerGeometryBuilder/interface/PixelGeomDetUnit.h"
00028 #include "Geometry/CommonTopologies/interface/PixelTopology.h"
00029
00030 #include "DataFormats/SiPixelDetId/interface/PXBDetId.h"
00031
00032
00033 #include <stack>
00034 #include <vector>
00035 #include <iostream>
00036 using namespace std;
00037
00038
00042
00043 PixelThresholdClusterizer::PixelThresholdClusterizer
00044 (edm::ParameterSet const& conf) :
00045 conf_(conf), bufferAlreadySet(false), theNumOfRows(0), theNumOfCols(0), detid_(0)
00046 {
00047
00048 thePixelThreshold =
00049 conf_.getParameter<int>("ChannelThreshold");
00050 theSeedThreshold =
00051 conf_.getParameter<int>("SeedThreshold");
00052 theClusterThreshold =
00053 conf_.getParameter<double>("ClusterThreshold");
00054 theConversionFactor =
00055 conf_.getParameter<int>("VCaltoElectronGain");
00056 theOffset =
00057 conf_.getParameter<int>("VCaltoElectronOffset");
00058 if ( conf_.exists("AdcFullScaleStack") ) theStackADC_=conf_.getParameter<int>("AdcFullScaleStack");
00059 else
00060 theStackADC_=255;
00061 if ( conf_.exists("FirstStackLayer") ) theFirstStack_=conf_.getParameter<int>("FirstStackLayer");
00062 else
00063 theFirstStack_=5;
00064
00065
00066 doMissCalibrate=conf_.getUntrackedParameter<bool>("MissCalibrate",true);
00067 doSplitClusters = conf.getParameter<bool>("SplitClusters");
00068 theBuffer.setSize( theNumOfRows, theNumOfCols );
00069 }
00071 PixelThresholdClusterizer::~PixelThresholdClusterizer() {}
00072
00073
00076
00077 bool PixelThresholdClusterizer::setup(const PixelGeomDetUnit * pixDet)
00078 {
00079
00080 const PixelTopology & topol = pixDet->specificTopology();
00081
00082
00083 int nrows = topol.nrows();
00084 int ncols = topol.ncolumns();
00085
00086 theNumOfRows = nrows;
00087 theNumOfCols = ncols;
00088
00089 if ( nrows > theBuffer.rows() ||
00090 ncols > theBuffer.columns() )
00091 {
00092
00093
00094
00095
00096
00097
00098 theBuffer.setSize(nrows,ncols);
00099 bufferAlreadySet = true;
00100 }
00101
00102 return true;
00103 }
00104
00110
00111 void PixelThresholdClusterizer::clusterizeDetUnit( const edm::DetSet<PixelDigi> & input,
00112 const PixelGeomDetUnit * pixDet,
00113 const std::vector<short>& badChannels,
00114 edmNew::DetSetVector<SiPixelCluster>::FastFiller& output) {
00115
00116 DigiIterator begin = input.begin();
00117 DigiIterator end = input.end();
00118
00119
00120
00121
00122
00123 if ( !setup(pixDet) )
00124 return;
00125
00126 detid_ = input.detId();
00127
00128
00129
00130 copy_to_buffer(begin, end);
00131
00132
00133
00134
00135
00136
00137
00138
00139
00140 for (unsigned int i = 0; i < theSeeds.size(); i++)
00141 {
00142
00143
00144
00145 if ( theBuffer(theSeeds[i]) >= theSeedThreshold )
00146 {
00147
00148 SiPixelCluster cluster = make_cluster( theSeeds[i] , output);
00149
00150
00151
00152 if ( cluster.charge() >= theClusterThreshold)
00153 {
00154
00155 output.push_back( cluster );
00156 }
00157 }
00158 }
00159
00160
00161 theSeeds.clear();
00162
00163
00164 clear_buffer(begin, end);
00165
00166 }
00167
00168
00176
00177 void PixelThresholdClusterizer::clear_buffer( DigiIterator begin, DigiIterator end )
00178 {
00179 for(DigiIterator di = begin; di != end; ++di )
00180 {
00181 theBuffer.set_adc( di->row(), di->column(), 0 );
00182 }
00183 }
00184
00185
00187
00188 void PixelThresholdClusterizer::copy_to_buffer( DigiIterator begin, DigiIterator end )
00189 {
00190 for(DigiIterator di = begin; di != end; ++di)
00191 {
00192 int row = di->row();
00193 int col = di->column();
00194 int adc = calibrate(di->adc(),col,row);
00195 if ( adc >= thePixelThreshold)
00196 {
00197 theBuffer.set_adc( row, col, adc);
00198 if ( adc >= theSeedThreshold)
00199 {
00200 theSeeds.push_back( SiPixelCluster::PixelPos(row,col) );
00201 }
00202 }
00203 }
00204 }
00205
00206
00207
00208
00209 int PixelThresholdClusterizer::calibrate(int adc, int col, int row)
00210 {
00211 int electrons = 0;
00212 int layer= 0;
00213 if (DetId(detid_).subdetId()==1){ layer = PXBDetId(detid_).layer();}
00214
00215 if ( doMissCalibrate )
00216 {
00217
00218
00219 if ( !theSiPixelGainCalibrationService_->isDead(detid_,col,row) &&
00220 !theSiPixelGainCalibrationService_->isNoisy(detid_,col,row) )
00221 {
00222
00223
00224
00225
00226
00227
00228
00229
00230
00231 float DBgain = theSiPixelGainCalibrationService_->getGain(detid_, col, row);
00232 float DBpedestal = theSiPixelGainCalibrationService_->getPedestal(detid_, col, row) * DBgain;
00233
00234
00235
00236
00237
00238
00239 float vcal = adc * DBgain - DBpedestal;
00240
00241
00242
00243
00244
00245
00246
00247
00248
00249
00250
00251
00252
00253
00254 electrons = int( vcal * theConversionFactor + theOffset);
00255 }
00256 }
00257 else
00258 {
00259
00260 const float gain = 135.;
00261 const float pedestal = 0.;
00262 electrons = int(adc * gain + pedestal);
00263 if (layer>=theFirstStack_) {
00264 if (theStackADC_==1&&adc==1)
00265 {
00266 electrons = int(255*135);
00267 }
00268 if (theStackADC_>1&&theStackADC_!=255&&adc>=1)
00269 {
00270 const float gain = 135.;
00271 electrons = int((adc-1) * gain * 255/float(theStackADC_-1));
00272 }
00273 }
00274 }
00275
00276 return electrons;
00277 }
00278
00279
00280 namespace {
00281
00282 struct AccretionCluster {
00283 typedef unsigned short UShort;
00284 static constexpr UShort MAXSIZE = 256;
00285 UShort adc[256];
00286 UShort x[256];
00287 UShort y[256];
00288 UShort xmin=16000;
00289 UShort ymin=16000;
00290 unsigned int isize=0;
00291 unsigned int curr=0;
00292
00293
00294 UShort top() const { return curr;}
00295 void pop() { ++curr;}
00296 bool empty() { return curr==isize;}
00297
00298 bool add(SiPixelCluster::PixelPos const & p, UShort const iadc) {
00299 if (isize==MAXSIZE) return false;
00300 xmin=std::min(xmin,(unsigned short)(p.row()));
00301 ymin=std::min(ymin,(unsigned short)(p.col()));
00302 adc[isize]=iadc;
00303 x[isize]=p.row();
00304 y[isize++]=p.col();
00305 return true;
00306 }
00307 };
00308
00309 }
00310
00311
00313
00314 SiPixelCluster
00315 PixelThresholdClusterizer::make_cluster( const SiPixelCluster::PixelPos& pix,
00316 edmNew::DetSetVector<SiPixelCluster>::FastFiller& output)
00317 {
00318
00319
00320 int seed_adc;
00321 stack<SiPixelCluster::PixelPos, vector<SiPixelCluster::PixelPos> > dead_pixel_stack;
00322
00323
00324
00325
00326
00327
00328
00329 if ( doMissCalibrate &&
00330 (theSiPixelGainCalibrationService_->isDead(detid_,pix.col(),pix.row()) ||
00331 theSiPixelGainCalibrationService_->isNoisy(detid_,pix.col(),pix.row())) )
00332 {
00333 seed_adc = 0;
00334 theBuffer.set_adc(pix, 1);
00335 }
00336 else
00337 {
00338 seed_adc = theBuffer(pix.row(), pix.col());
00339 theBuffer.set_adc( pix, 1);
00340 }
00341
00342 AccretionCluster acluster;
00343 acluster.add(pix, seed_adc);
00344
00345
00346 bool dead_flag = false;
00347 while ( ! acluster.empty())
00348 {
00349
00350 auto curInd = acluster.top(); acluster.pop();
00351 for ( auto r = acluster.x[curInd]-1; r <= acluster.x[curInd]+1; ++r)
00352 {
00353 for ( auto c = acluster.y[curInd]-1; c <= acluster.y[curInd]+1; ++c)
00354 {
00355 if ( theBuffer(r,c) >= thePixelThreshold)
00356 {
00357
00358 SiPixelCluster::PixelPos newpix(r,c);
00359 if (!acluster.add( newpix, theBuffer(r,c))) goto endClus;
00360 theBuffer.set_adc( newpix, 1);
00361 }
00362
00363
00364
00365
00366
00367
00368
00369
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380
00381
00382
00383
00384
00385
00386
00387
00388
00389
00390 }
00391 }
00392
00393 }
00394 endClus:
00395 SiPixelCluster cluster(acluster.isize,acluster.adc, acluster.x,acluster.y, acluster.xmin,acluster.ymin);
00396
00397
00398 if (dead_flag && doSplitClusters)
00399 {
00400
00401 SiPixelCluster first_cluster = cluster;
00402 bool have_second_cluster = false;
00403 while ( !dead_pixel_stack.empty() )
00404 {
00405
00406 SiPixelCluster::PixelPos deadpix = dead_pixel_stack.top(); dead_pixel_stack.pop();
00407 theBuffer.set_adc(deadpix, 1);
00408
00409
00410 SiPixelCluster second_cluster = make_cluster(deadpix, output);
00411
00412
00413 if ( second_cluster.charge() >= theClusterThreshold &&
00414 first_cluster.charge() >= theClusterThreshold )
00415 {
00416 output.push_back( second_cluster );
00417 have_second_cluster = true;
00418 }
00419
00420
00421
00422 const std::vector<SiPixelCluster::Pixel>& branch_pixels = second_cluster.pixels();
00423 for ( unsigned int i = 0; i<branch_pixels.size(); i++)
00424 {
00425 int temp_x = branch_pixels[i].x;
00426 int temp_y = branch_pixels[i].y;
00427 int temp_adc = branch_pixels[i].adc;
00428 SiPixelCluster::PixelPos newpix(temp_x, temp_y);
00429 cluster.add(newpix, temp_adc);}
00430 }
00431
00432
00433 if ( first_cluster.charge() >= theClusterThreshold && have_second_cluster)
00434 {
00435 output.push_back( first_cluster );
00436 }
00437 }
00438
00439 return cluster;
00440 }
00441