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
00031
00032 #include <stack>
00033 #include <vector>
00034 #include <iostream>
00035 using namespace std;
00036
00037
00041
00042 PixelThresholdClusterizer::PixelThresholdClusterizer
00043 (edm::ParameterSet const& conf) :
00044 conf_(conf), bufferAlreadySet(false), theNumOfRows(0), theNumOfCols(0), detid_(0)
00045 {
00046
00047 thePixelThreshold =
00048 conf_.getParameter<int>("ChannelThreshold");
00049 theSeedThreshold =
00050 conf_.getParameter<int>("SeedThreshold");
00051 theClusterThreshold =
00052 conf_.getParameter<double>("ClusterThreshold");
00053 theConversionFactor =
00054 conf_.getParameter<int>("VCaltoElectronGain");
00055 theOffset =
00056 conf_.getParameter<int>("VCaltoElectronOffset");
00057
00058
00059
00060 doMissCalibrate=conf_.getUntrackedParameter<bool>("MissCalibrate",true);
00061 doSplitClusters = conf.getParameter<bool>("SplitClusters");
00062 theBuffer.setSize( theNumOfRows, theNumOfCols );
00063 }
00065 PixelThresholdClusterizer::~PixelThresholdClusterizer() {}
00066
00067
00070
00071 bool PixelThresholdClusterizer::setup(const PixelGeomDetUnit * pixDet)
00072 {
00073
00074 const PixelTopology & topol = pixDet->specificTopology();
00075
00076
00077 int nrows = topol.nrows();
00078 int ncols = topol.ncolumns();
00079
00080 theNumOfRows = nrows;
00081 theNumOfCols = ncols;
00082
00083 if ( nrows > theBuffer.rows() ||
00084 ncols > theBuffer.columns() )
00085 {
00086
00087
00088
00089
00090
00091
00092 theBuffer.setSize(nrows,ncols);
00093 bufferAlreadySet = true;
00094 }
00095
00096 return true;
00097 }
00098
00104
00105 void PixelThresholdClusterizer::clusterizeDetUnit( const edm::DetSet<PixelDigi> & input,
00106 const PixelGeomDetUnit * pixDet,
00107 const std::vector<short>& badChannels,
00108 edmNew::DetSetVector<SiPixelCluster>::FastFiller& output) {
00109
00110 DigiIterator begin = input.begin();
00111 DigiIterator end = input.end();
00112
00113
00114
00115
00116
00117 if ( !setup(pixDet) )
00118 return;
00119
00120 detid_ = input.detId();
00121
00122
00123
00124 copy_to_buffer(begin, end);
00125
00126
00127
00128
00129
00130
00131
00132
00133
00134 for (unsigned int i = 0; i < theSeeds.size(); i++)
00135 {
00136
00137
00138
00139 if ( theBuffer(theSeeds[i]) >= theSeedThreshold )
00140 {
00141
00142 SiPixelCluster cluster = make_cluster( theSeeds[i] , output);
00143
00144
00145
00146 if ( cluster.charge() >= theClusterThreshold)
00147 {
00148
00149 output.push_back( cluster );
00150 }
00151 }
00152 }
00153
00154
00155 theSeeds.clear();
00156
00157
00158 clear_buffer(begin, end);
00159
00160 }
00161
00162
00170
00171 void PixelThresholdClusterizer::clear_buffer( DigiIterator begin, DigiIterator end )
00172 {
00173 for(DigiIterator di = begin; di != end; ++di )
00174 {
00175 theBuffer.set_adc( di->row(), di->column(), 0 );
00176 }
00177 }
00178
00179
00181
00182 void PixelThresholdClusterizer::copy_to_buffer( DigiIterator begin, DigiIterator end )
00183 {
00184 for(DigiIterator di = begin; di != end; ++di)
00185 {
00186 int row = di->row();
00187 int col = di->column();
00188 int adc = calibrate(di->adc(),col,row);
00189 if ( adc >= thePixelThreshold)
00190 {
00191 theBuffer.set_adc( row, col, adc);
00192 if ( adc >= theSeedThreshold)
00193 {
00194 theSeeds.push_back( SiPixelCluster::PixelPos(row,col) );
00195 }
00196 }
00197 }
00198 }
00199
00200
00201
00202
00203 int PixelThresholdClusterizer::calibrate(int adc, int col, int row)
00204 {
00205 int electrons = 0;
00206
00207 if ( doMissCalibrate )
00208 {
00209
00210
00211 if ( !theSiPixelGainCalibrationService_->isDead(detid_,col,row) &&
00212 !theSiPixelGainCalibrationService_->isNoisy(detid_,col,row) )
00213 {
00214
00215
00216
00217
00218
00219
00220
00221
00222
00223 float DBgain = theSiPixelGainCalibrationService_->getGain(detid_, col, row);
00224 float DBpedestal = theSiPixelGainCalibrationService_->getPedestal(detid_, col, row) * DBgain;
00225
00226
00227
00228
00229
00230
00231 float vcal = adc * DBgain - DBpedestal;
00232
00233
00234
00235
00236
00237
00238
00239
00240
00241
00242
00243
00244
00245
00246 electrons = int( vcal * theConversionFactor + theOffset);
00247 }
00248 }
00249 else
00250 {
00251
00252 const float gain = 135.;
00253 const float pedestal = 0.;
00254 electrons = int(adc * gain + pedestal);
00255 }
00256
00257 return electrons;
00258 }
00259
00260
00262
00263 SiPixelCluster
00264 PixelThresholdClusterizer::make_cluster( const SiPixelCluster::PixelPos& pix,
00265 edmNew::DetSetVector<SiPixelCluster>::FastFiller& output)
00266 {
00267
00268
00269 int seed_adc;
00270 stack<SiPixelCluster::PixelPos, vector<SiPixelCluster::PixelPos> > pixel_stack;
00271 stack<SiPixelCluster::PixelPos, vector<SiPixelCluster::PixelPos> > dead_pixel_stack;
00272
00273
00274
00275
00276
00277
00278
00279 if ( theSiPixelGainCalibrationService_->isDead(detid_,pix.col(),pix.row()) ||
00280 theSiPixelGainCalibrationService_->isNoisy(detid_,pix.col(),pix.row()) )
00281 {
00282 seed_adc = 0;
00283 theBuffer.set_adc(pix, 1);
00284 }
00285 else
00286 {
00287 seed_adc = theBuffer(pix.row(), pix.col());
00288 theBuffer.set_adc( pix, 1);
00289 }
00290
00291 SiPixelCluster cluster( pix, seed_adc );
00292
00293
00294 pixel_stack.push( pix);
00295 bool dead_flag = false;
00296 while ( ! pixel_stack.empty())
00297 {
00298
00299 SiPixelCluster::PixelPos curpix = pixel_stack.top(); pixel_stack.pop();
00300 for ( int r = curpix.row()-1; r <= curpix.row()+1; ++r)
00301 {
00302 for ( int c = curpix.col()-1; c <= curpix.col()+1; ++c)
00303 {
00304 if ( theBuffer(r,c) >= thePixelThreshold)
00305 {
00306
00307 SiPixelCluster::PixelPos newpix(r,c);
00308 cluster.add( newpix, theBuffer(r,c));
00309 theBuffer.set_adc( newpix, 1);
00310 pixel_stack.push( newpix);
00311 }
00312
00313
00314
00315
00316
00317
00318
00319
00320
00321
00322
00323
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338
00339
00340 }
00341 }
00342
00343 }
00344
00345
00346
00347 if (dead_flag && doSplitClusters)
00348 {
00349
00350 SiPixelCluster first_cluster = cluster;
00351 bool have_second_cluster = false;
00352 while ( !dead_pixel_stack.empty() )
00353 {
00354
00355 SiPixelCluster::PixelPos deadpix = dead_pixel_stack.top(); dead_pixel_stack.pop();
00356 theBuffer.set_adc(deadpix, 1);
00357
00358
00359 SiPixelCluster second_cluster = make_cluster(deadpix, output);
00360
00361
00362 if ( second_cluster.charge() >= theClusterThreshold &&
00363 first_cluster.charge() >= theClusterThreshold )
00364 {
00365 output.push_back( second_cluster );
00366 have_second_cluster = true;
00367 }
00368
00369
00370
00371 const std::vector<SiPixelCluster::Pixel>& branch_pixels = second_cluster.pixels();
00372 for ( unsigned int i = 0; i<branch_pixels.size(); i++)
00373 {
00374 int temp_x = branch_pixels[i].x;
00375 int temp_y = branch_pixels[i].y;
00376 int temp_adc = branch_pixels[i].adc;
00377 SiPixelCluster::PixelPos newpix(temp_x, temp_y);
00378 cluster.add(newpix, temp_adc);}
00379 }
00380
00381
00382 if ( first_cluster.charge() >= theClusterThreshold && have_second_cluster)
00383 {
00384 output.push_back( first_cluster );
00385 }
00386 }
00387
00388 return cluster;
00389 }
00390