00001 #include "RecoLocalTracker/SiStripZeroSuppression/interface/SiStripAPVRestorer.h"
00002
00003 #include <cmath>
00004 #include <iostream>
00005 #include <algorithm>
00006
00007
00008
00009
00010 SiStripAPVRestorer::SiStripAPVRestorer(const edm::ParameterSet& conf):
00011 quality_cache_id(-1), noise_cache_id(-1),
00012 ForceNoRestore_(conf.getParameter<bool>("ForceNoRestore")),
00013 SelfSelectRestoreAlgo_(conf.getParameter<bool>("SelfSelectRestoreAlgo")),
00014 InspectAlgo_(conf.getParameter<std::string>("APVInspectMode")),
00015 RestoreAlgo_(conf.getParameter<std::string>("APVRestoreMode")),
00016 useRealMeanCM_(conf.getParameter<bool>("useRealMeanCM")),
00017 fraction_(conf.getParameter<double>("Fraction")),
00018 deviation_(conf.getParameter<uint32_t>("Deviation")),
00019 restoreThreshold_(conf.getParameter<double>("restoreThreshold")),
00020 DeltaCMThreshold_(conf.getParameter<uint32_t>("DeltaCMThreshold")),
00021 nSigmaNoiseDerTh_(conf.getParameter<uint32_t>("nSigmaNoiseDerTh")),
00022 consecThreshold_(conf.getParameter<uint32_t>("consecThreshold")),
00023 hitStripThreshold_(conf.getParameter<uint32_t>("hitStripThreshold")),
00024 nSmooth_(conf.getParameter<uint32_t>("nSmooth")),
00025 minStripsToFit_(conf.getParameter<uint32_t>("minStripsToFit")),
00026 distortionThreshold_(conf.getParameter<uint32_t>("distortionThreshold")),
00027 CutToAvoidSignal_(conf.getParameter<double>("CutToAvoidSignal")),
00028 nSaturatedStrip_(conf.getParameter<uint32_t>("nSaturatedStrip"))
00029
00030
00031 {
00032 apvFlags_.clear();
00033 median_.clear();
00034 SmoothedMaps_.clear();
00035 BaselineMap_.erase(BaselineMap_.begin(), BaselineMap_.end());
00036 }
00037
00038
00039 void SiStripAPVRestorer::init(const edm::EventSetup& es){
00040 uint32_t n_cache_id = es.get<SiStripNoisesRcd>().cacheIdentifier();
00041 uint32_t q_cache_id = es.get<SiStripQualityRcd>().cacheIdentifier();
00042
00043 if(n_cache_id != noise_cache_id) {
00044 es.get<SiStripNoisesRcd>().get( noiseHandle );
00045 noise_cache_id = n_cache_id;
00046 } else {
00047 noise_cache_id = n_cache_id;
00048 }
00049 if(q_cache_id != quality_cache_id) {
00050 es.get<SiStripQualityRcd>().get( qualityHandle );
00051 quality_cache_id = q_cache_id;
00052 }else {
00053 quality_cache_id = q_cache_id;
00054 }
00055
00056
00057 }
00058
00059
00060 int16_t SiStripAPVRestorer::inspect( const uint32_t& detId,std::vector<int16_t>& digis, const std::vector< std::pair<short,float> >& vmedians) {
00061
00062 detId_ = detId;
00063
00064 apvFlags_.clear();
00065 median_.clear();
00066 SmoothedMaps_.clear();
00067 BaselineMap_.erase(BaselineMap_.begin(), BaselineMap_.end());
00068
00069 for(size_t i=0; i< vmedians.size(); ++i) median_.push_back(vmedians[i].second);
00070
00071 if(InspectAlgo_=="BaselineFollower") return this->BaselineFollowerInspect(digis);
00072 if(InspectAlgo_=="AbnormalBaseline") return this->AbnormalBaselineInspect(digis);
00073 if(InspectAlgo_=="Null") return this->NullInspect(digis);
00074 if(InspectAlgo_=="BaselineAndSaturation") return this->BaselineAndSaturationInspect(digis);
00075 throw cms::Exception("Unregistered Inspect Algorithm") << "SiStripAPVRestorer possibilities: (Null), (AbnormalBaseline),(BaselineFollower)";
00076
00077 }
00078
00079
00080 void SiStripAPVRestorer::restore( std::vector<int16_t>& digis ) {
00081
00082 if(ForceNoRestore_) return;
00083
00084 for( uint16_t APV=0; APV< digis.size()/128; ++APV){
00085 std::string algoToUse = *( apvFlags_.begin() + APV );
00086
00087 if ( algoToUse != ""){
00088 if(!SelfSelectRestoreAlgo_) algoToUse = RestoreAlgo_;
00089
00090 if(algoToUse=="Flat"){
00091 this->FlatRestore(digis, APV);
00092 }else if(algoToUse=="BaselineFollower"){
00093
00094 this->BaselineFollowerRestore(digis, APV, median_[APV]);
00095
00096
00097 }else{
00098 throw cms::Exception("Unregistered Restore Algorithm") << "SiStripAPVRestorer possibilities: (Flat), (BaselineFollower)";
00099 }
00100 }
00101 }
00102
00103 }
00104
00105
00106
00107
00108 template<typename T>
00109 inline
00110 int16_t SiStripAPVRestorer::BaselineFollowerInspect(std::vector<T>& digis){
00111 SiStripQuality::Range detQualityRange = qualityHandle->getRange(detId_);
00112
00113 std::vector<T> singleAPVdigi;
00114 singleAPVdigi.clear();
00115
00116
00117 int16_t nAPVflagged = 0;
00118
00119 CMMap::iterator itCMMap;
00120 if(useRealMeanCM_) itCMMap = MeanCMmap_.find(detId_);
00121
00122 for( uint16_t APV=0; APV< digis.size()/128; ++APV){
00123
00124 int MeanAPVCM = 128;
00125 if(useRealMeanCM_&&itCMMap!= MeanCMmap_.end()) MeanAPVCM =(itCMMap->second)[APV];
00126
00127 singleAPVdigi.clear();
00128 for(int16_t strip = APV*128; strip < (APV+1)*128; ++strip){
00129 singleAPVdigi.push_back(digis[strip]);
00130
00131 }
00132
00133
00134 float DeltaCM = median_[APV] -MeanAPVCM;
00135
00136
00137
00138
00139
00140 DigiMap smoothedmap;
00141 if(DeltaCM < 0 && std::abs(DeltaCM) > DeltaCMThreshold_){
00142
00143 bool isFlat= FlatRegionsFinder(singleAPVdigi,smoothedmap, median_[APV], APV);
00144 if(!isFlat){
00145 apvFlags_.push_back( "BaselineFollower" );
00146 nAPVflagged++;
00147 }else{
00148 apvFlags_.push_back( "" );
00149 }
00150 } else{
00151 apvFlags_.push_back( "" );
00152 }
00153 SmoothedMaps_.push_back(smoothedmap);
00154
00155 }
00156
00157 return nAPVflagged;
00158 }
00159
00160
00161 template<typename T>
00162 inline
00163 int16_t SiStripAPVRestorer::BaselineAndSaturationInspect(std::vector<T>& digis){
00164 SiStripQuality::Range detQualityRange = qualityHandle->getRange(detId_);
00165
00166
00167 std::vector<T> singleAPVdigi;
00168 singleAPVdigi.clear();
00169
00170
00171 int16_t nAPVflagged = 0;
00172
00173 CMMap::iterator itCMMap;
00174 if(useRealMeanCM_) itCMMap = MeanCMmap_.find(detId_);
00175
00176 for( uint16_t APV=0; APV< digis.size()/128; ++APV){
00177
00178 int MeanAPVCM = 128;
00179 if(useRealMeanCM_&&itCMMap!= MeanCMmap_.end()) MeanAPVCM =(itCMMap->second)[APV];
00180
00181 singleAPVdigi.clear();
00182
00183 uint16_t nSatStrip =0;
00184 for(int16_t strip = APV*128; strip < (APV+1)*128; ++strip){
00185 singleAPVdigi.push_back(digis[strip]);
00186 if(digis[strip] >=1023) ++nSatStrip;
00187 }
00188
00189 float DeltaCM = median_[APV] -MeanAPVCM;
00190
00191
00192 if(DeltaCM < 0 && std::abs(DeltaCM) > DeltaCMThreshold_&&nSatStrip>= nSaturatedStrip_){
00193
00194 apvFlags_.push_back( "RestoreAlgo_" );
00195 nAPVflagged++;
00196 } else{
00197 apvFlags_.push_back( "" );
00198 }
00199
00200 }
00201
00202 return nAPVflagged;
00203 }
00204
00205
00206 template<typename T>
00207 inline
00208 int16_t SiStripAPVRestorer::AbnormalBaselineInspect(std::vector<T>& digis){
00209
00210 SiStripQuality::Range detQualityRange = qualityHandle->getRange(detId_);
00211
00212 typename std::vector<T>::iterator fs;
00213
00214 int16_t nAPVflagged=0;
00215
00216 CMMap::iterator itCMMap;
00217 if(useRealMeanCM_) itCMMap = MeanCMmap_.find(detId_);
00218
00219
00220 int devCount = 0, qualityCount = 0, minstrip = 0;
00221 for( uint16_t APV=0; APV< digis.size()/128; ++APV){
00222 int MeanAPVCM = 128;
00223 if(useRealMeanCM_&&itCMMap!= MeanCMmap_.end()) MeanAPVCM =(itCMMap->second)[APV];
00224 for (uint16_t istrip=APV*128; istrip<(APV+1)*128; ++istrip){
00225 fs = digis.begin() + istrip;
00226 if ( !qualityHandle->IsStripBad(detQualityRange,istrip) ){
00227 qualityCount++;
00228 if ( std::abs((int) *fs - MeanAPVCM) > (int)deviation_ ) devCount++;
00229 minstrip = std::min((int) *fs, minstrip);
00230 }
00231 }
00232
00233 if( devCount > fraction_ * qualityCount ) {
00234 apvFlags_.push_back( RestoreAlgo_ );
00235 nAPVflagged++;
00236 } else {
00237 apvFlags_.push_back( "" );
00238 }
00239
00240 }
00241
00242 return nAPVflagged;
00243
00244 }
00245
00246
00247
00248 template<typename T>
00249 inline
00250 int16_t SiStripAPVRestorer::NullInspect(std::vector<T>& digis){
00251
00252 SiStripQuality::Range detQualityRange = qualityHandle->getRange(detId_);
00253
00254 typename std::vector<T>::iterator fs;
00255
00256 int16_t nAPVflagged = 0;
00257
00258 for( uint16_t APV=0; APV< digis.size()/128; ++APV){
00259 int zeroCount = 0, qualityCount = 0;
00260 for (uint16_t istrip=APV*128; istrip<(APV+1)*128; ++istrip){
00261 fs = digis.begin() + istrip;
00262 if ( !qualityHandle->IsStripBad(detQualityRange,istrip) ){
00263 qualityCount++;
00264 if ( (int) *fs < 1 ) zeroCount++;
00265 }
00266 }
00267
00268 if( zeroCount > restoreThreshold_ * qualityCount ) {
00269 apvFlags_.push_back( RestoreAlgo_ );
00270 nAPVflagged++;
00271 } else {
00272 apvFlags_.push_back( "" );
00273 }
00274
00275 }
00276
00277 return nAPVflagged;
00278
00279 }
00280
00281
00282
00283
00284
00285
00286
00287 template<typename T>
00288 inline
00289 void SiStripAPVRestorer::BaselineFollowerRestore( std::vector<T>& digis, uint16_t APVn , float median){
00290 typename std::vector<T>::iterator firstStrip(digis.begin() + APVn*128), lastStrip(firstStrip + 128), actualStrip;
00291
00292 std::vector<int16_t> baseline;
00293 baseline.clear();
00294 baseline.insert(baseline.begin(),128, 0);
00295
00296 std::vector<int16_t> adcs;
00297 adcs.clear();
00298
00299
00300
00301 for(actualStrip= firstStrip; actualStrip < lastStrip; ++actualStrip ) adcs.push_back(*actualStrip);
00302
00303
00304
00305
00306
00307
00308
00309
00310
00311
00312 if(SmoothedMaps_.size()){
00313 this->BaselineFollower(SmoothedMaps_[APVn], baseline, median);
00314
00315 } else {
00316 median=0;
00317 DigiMap smoothedpoints;
00318 this->FlatRegionsFinder(adcs,smoothedpoints, median, APVn );
00319 this->BaselineFollower(smoothedpoints, baseline, median);
00320
00321 }
00322
00323
00324
00325 for(int16_t itStrip= 0 ; itStrip< 128; ++itStrip){
00326
00327
00328 digis[itStrip+APVn*128] -= baseline[itStrip] - median;
00329 }
00330
00331
00332
00333 BaselineMap_.insert(BaselineMap_.end(), std::pair< uint16_t, std::vector < int16_t> >(APVn, baseline));
00334
00335
00336 }
00337
00338
00339 template<typename T>
00340 inline
00341 void SiStripAPVRestorer::FlatRestore( std::vector<T>& digis, uint16_t APVn ){
00342
00343 std::vector<int16_t> baseline;
00344 baseline.clear();
00345 baseline.insert(baseline.begin(),128, 150);
00346 baseline[0]=0; baseline[127]=0;
00347 BaselineMap_.insert(BaselineMap_.end(), std::pair< uint16_t, std::vector < int16_t> >(APVn, baseline));
00348
00349 typename std::vector<T>::iterator strip(digis.begin() + APVn*128), lastStrip(strip + 128);
00350
00351 int counter = 0;
00352 while (strip < lastStrip) {
00353 *strip = baseline[counter];
00354 counter++;
00355 strip++;
00356 }
00357
00358 }
00359
00360
00361
00362
00363
00364
00365 bool inline SiStripAPVRestorer::FlatRegionsFinder(std::vector<int16_t>& adcs, DigiMap& smoothedpoints, float median, uint16_t APVn ){
00366 SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detId_);
00367
00368 DigiMap consecpoints;
00369 DigiMapIter itConsecpoints, itSmoothedpoints;
00370 consecpoints.erase(consecpoints.begin(), consecpoints.end());
00371 smoothedpoints.erase(smoothedpoints.begin(), smoothedpoints.end());
00372
00373
00374
00375
00376 std::vector<float> adcsLocalMinSubtracted;
00377 adcsLocalMinSubtracted.clear();
00378 adcsLocalMinSubtracted.insert(adcsLocalMinSubtracted.begin(), 128,0);
00379 for(uint32_t istrip=0; istrip<128; ++istrip) {
00380 float localmin = 999.9;
00381 for(uint16_t jstrip=std::max(0,(int)(istrip-nSmooth_/2)); jstrip<std::min(128,(int)(istrip+nSmooth_/2)); ++jstrip) {
00382 float nextvalue = adcs[jstrip];
00383 if(nextvalue < localmin) localmin=nextvalue;
00384 }
00385 adcsLocalMinSubtracted[istrip] = adcs[istrip] - localmin;
00386 }
00387
00388
00389
00390 std::vector<uint16_t> nConsStrip;
00391 nConsStrip.clear();
00392
00393
00394 uint16_t consecStrips=0;
00395 for(uint32_t istrip=0; istrip<128; ++istrip) {
00396 int16_t adc = adcs[istrip];
00397
00398
00399 if( adcsLocalMinSubtracted[istrip] < nSigmaNoiseDerTh_ * (float)noiseHandle->getNoiseFast(istrip+APVn*128,detNoiseRange)
00400 && adc - median < hitStripThreshold_) {
00401
00402 consecpoints.insert(consecpoints.end(), std::pair<uint16_t, int16_t >(istrip, adc));
00403 ++consecStrips;
00404
00405 } else if (consecStrips >0){
00406 nConsStrip.push_back(consecStrips);
00407 consecStrips = 0;
00408 }
00409
00410
00411 }
00412
00413
00414 if(consecStrips >0) nConsStrip.push_back(consecStrips);
00415
00416
00417
00418 itConsecpoints = consecpoints.begin();
00419 float MinSmoothValue=2000., MaxSmoothValue=0.;
00420 for(std::vector<uint16_t>::iterator itnConsStrip = nConsStrip.begin(); itnConsStrip < nConsStrip.end(); ++itnConsStrip){
00421
00422 consecStrips = *itnConsStrip;
00423 if(consecStrips >=consecThreshold_){
00424 ++itConsecpoints;
00425 uint16_t nFirstStrip = itConsecpoints->first;
00426 uint16_t nLastStrip;
00427 float smoothValue = 0.0;
00428 float stripCount =1;
00429 for(uint16_t n =0; n < consecStrips-2; ++n){
00430 smoothValue += itConsecpoints->second;
00431 if(stripCount == consecThreshold_){
00432 smoothValue /= (float)stripCount;
00433 nLastStrip = nFirstStrip + stripCount -1;
00434 smoothedpoints.insert(smoothedpoints.end(), std::pair<uint16_t, int16_t >(nFirstStrip, smoothValue));
00435 smoothedpoints.insert(smoothedpoints.end(), std::pair<uint16_t, int16_t >(nLastStrip, smoothValue));
00436 if(smoothValue > MaxSmoothValue) MaxSmoothValue = smoothValue;
00437 if(smoothValue < MinSmoothValue) MinSmoothValue = smoothValue;
00438 nFirstStrip = nLastStrip+1;
00439 smoothValue=0;
00440 stripCount=0;
00441 }
00442 ++stripCount;
00443 ++itConsecpoints;
00444 }
00445 ++itConsecpoints;
00446
00447 if(smoothValue>0){
00448 --stripCount;
00449 smoothValue /= (float)(stripCount);
00450 nLastStrip = nFirstStrip + stripCount -1;
00451 smoothedpoints.insert(smoothedpoints.end(), std::pair<uint16_t, int16_t >(nFirstStrip, smoothValue));
00452 smoothedpoints.insert(smoothedpoints.end(), std::pair<uint16_t, int16_t >(nLastStrip, smoothValue));
00453 if(smoothValue > MaxSmoothValue) MaxSmoothValue = smoothValue;
00454 if(smoothValue < MinSmoothValue) MinSmoothValue = smoothValue;
00455 }
00456 } else{
00457 for(int n =0; n< consecStrips ; ++n) ++itConsecpoints;
00458
00459 }
00460 }
00461
00462 if( (MaxSmoothValue-MinSmoothValue) > distortionThreshold_) return false;
00463 return true;
00464 }
00465
00466
00467 void inline SiStripAPVRestorer::BaselineFollower(DigiMap& smoothedpoints, std::vector<int16_t>& baseline, float median){
00468
00469 baseline.clear();
00470 DigiMapIter itSmoothedpoints;
00471
00472
00473 if(smoothedpoints.size() < minStripsToFit_){
00474 baseline.clear();
00475 baseline.insert(baseline.begin(),128, median);
00476 } else {
00477 baseline.insert(baseline.begin(),128, 0);
00478
00479 DigiMapIter itSmoothedpointsBegin, itSmoothedpointsEnd;
00480 itSmoothedpointsBegin = smoothedpoints.begin();
00481 itSmoothedpointsEnd = --(smoothedpoints.end());
00482
00483
00484 uint16_t firstStripFlat = itSmoothedpointsBegin->first;
00485 uint16_t lastStripFlat = itSmoothedpointsEnd->first;
00486 int16_t firstStipFlatADC= itSmoothedpointsBegin->second;
00487 int16_t lastStipFlatADC= itSmoothedpointsEnd->second;
00488
00489
00490 baseline.erase(baseline.begin(), baseline.begin()+firstStripFlat);
00491 baseline.insert(baseline.begin(), firstStripFlat, firstStipFlatADC);
00492
00493 baseline.erase(baseline.begin()+lastStripFlat, baseline.end());
00494 baseline.insert(baseline.end(), 128 - lastStripFlat, lastStipFlatADC);
00495
00496
00497
00498 for(itSmoothedpoints = itSmoothedpointsBegin; itSmoothedpoints != itSmoothedpointsEnd; ++itSmoothedpoints){
00499 DigiMapIter itSmoothedpointsNext = itSmoothedpoints;
00500 ++itSmoothedpointsNext;
00501 float strip1 = itSmoothedpoints->first;
00502 float strip2 = itSmoothedpointsNext->first;
00503 float adc1 = itSmoothedpoints->second;
00504 float adc2 = itSmoothedpointsNext->second;
00505
00506 baseline[strip1] = adc1;
00507 baseline[strip2] = adc2;
00508 float m = (adc2 -adc1)/(strip2 -strip1);
00509 uint16_t itStrip = strip1 +1;
00510 float stripadc = adc1 + m;
00511 while(itStrip < strip2){
00512 baseline[itStrip] = stripadc;
00513 ++itStrip;
00514 stripadc+=m;
00515 }
00516
00517 }
00518
00519 }
00520 }
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538
00539
00540
00541
00542
00543
00544
00545
00546
00547 void SiStripAPVRestorer::fixAPVsCM(edm::DetSet<SiStripProcessedRawDigi>& cmdigis) {
00548
00549
00550
00551 if ( cmdigis.size() != apvFlags_.size() ) return;
00552
00553 edm::DetSet<SiStripProcessedRawDigi>::iterator cm_iter = cmdigis.begin();
00554 std::vector<std::string>::const_iterator apvf_iter = apvFlags_.begin();
00555
00556
00557
00558
00559
00560 std::vector<float> cmvalues;
00561 for( ; cm_iter != cmdigis.end(); ++cm_iter ) cmvalues.push_back( (*cm_iter).adc() );
00562 cmdigis.clear();
00563
00564 std::vector<float>::const_iterator cmv_iter = cmvalues.begin();
00565 while( apvf_iter != apvFlags_.end() ){
00566 if( *apvf_iter != "") {
00567
00568
00569 cmdigis.push_back( SiStripProcessedRawDigi( -999.) );
00570 }
00571 else
00572 cmdigis.push_back( SiStripProcessedRawDigi( *cmv_iter ) );
00573 apvf_iter++;
00574 cmv_iter++;
00575 }
00576 }
00577
00578 void SiStripAPVRestorer::LoadMeanCMMap(edm::Event& iEvent){
00579 if(useRealMeanCM_){
00580 edm::Handle< edm::DetSetVector<SiStripProcessedRawDigi> > inputCM;
00581 iEvent.getByLabel(inputTag_,inputCM);
00582 this->CreateCMMap(*inputCM);
00583 }
00584 }
00585
00586 void SiStripAPVRestorer::CreateCMMap(const edm::DetSetVector<SiStripProcessedRawDigi>& Input){
00587
00588 MeanCMmap_.erase(MeanCMmap_.begin(), MeanCMmap_.end());
00589
00590 uint32_t detId_;
00591 edm::DetSetVector<SiStripProcessedRawDigi>::const_iterator itInput;
00592 edm::DetSet<SiStripProcessedRawDigi>::const_iterator itCM;
00593 std::vector<float> MeanCMNValue;
00594
00595 for(itInput = Input.begin(); itInput != Input.end(); ++itInput){
00596 detId_ = itInput->id;
00597 MeanCMNValue.clear();
00598 for(itCM = itInput->begin(); itCM != itInput->end(); ++itCM) MeanCMNValue.push_back(itCM->adc());
00599 MeanCMmap_.insert(std::pair<uint32_t, std::vector<float> >(detId_,MeanCMNValue));
00600 }
00601
00602 }