CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch12/src/RecoLocalTracker/SiStripZeroSuppression/src/SiStripFedZeroSuppression.cc

Go to the documentation of this file.
00001 #include "RecoLocalTracker/SiStripZeroSuppression/interface/SiStripFedZeroSuppression.h"
00002 
00003 #include "CondFormats/DataRecord/interface/SiStripNoisesRcd.h"
00004 #include "CondFormats/SiStripObjects/interface/SiStripNoises.h"
00005 #include "CondFormats/DataRecord/interface/SiStripThresholdRcd.h"
00006 #include "CondFormats/SiStripObjects/interface/SiStripThreshold.h"
00007 
00008 //#define DEBUG_SiStripZeroSuppression_
00009 //#define ML_DEBUG 
00010 using namespace std;
00011 
00012 void SiStripFedZeroSuppression::init(const edm::EventSetup& es){
00013   uint32_t n_cache_id = es.get<SiStripNoisesRcd>().cacheIdentifier();
00014   uint32_t t_cache_id = es.get<SiStripThresholdRcd>().cacheIdentifier();
00015 
00016   if(n_cache_id != noise_cache_id) {
00017     es.get<SiStripNoisesRcd>().get( noiseHandle );
00018     noise_cache_id = n_cache_id;
00019   }
00020   if(t_cache_id != threshold_cache_id) {
00021     es.get<SiStripThresholdRcd>().get( thresholdHandle );
00022     threshold_cache_id = t_cache_id;
00023   }
00024 }
00025 
00026 void SiStripFedZeroSuppression::suppress(const std::vector<SiStripDigi>& in, std::vector<SiStripDigi>& selectedSignal,const uint32_t& detID){
00027   suppress(in, selectedSignal, detID, noiseHandle, thresholdHandle);
00028 }
00029 
00030 void SiStripFedZeroSuppression::suppress(const std::vector<SiStripDigi>& in, std::vector<SiStripDigi>& selectedSignal,const uint32_t& detID, 
00031                                                         edm::ESHandle<SiStripNoises> & noiseHandle,edm::ESHandle<SiStripThreshold> & thresholdHandle){
00032 
00033   int i;  
00034   int inSize = in.size();
00035   SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
00036   SiStripThreshold::Range detThRange = thresholdHandle->getRange(detID);
00037 
00038   // reserving more than needed, but quicker than one at a time
00039   selectedSignal.clear();
00040   selectedSignal.reserve(inSize);
00041   for (i = 0; i < inSize; i++) {
00042     //Find adc values for neighbouring strips
00043     const uint32_t strip = (uint32_t) in[i].strip();
00044     
00045     adc   = in[i].adc();
00046 
00047     SiStripThreshold::Data thresholds=thresholdHandle->getData(strip,detThRange);
00048     theFEDlowThresh  = static_cast<int16_t>(thresholds.getLth()*noiseHandle->getNoiseFast(strip,detNoiseRange)+0.5);
00049     theFEDhighThresh = static_cast<int16_t>(thresholds.getHth()*noiseHandle->getNoiseFast(strip,detNoiseRange)+0.5);
00050 
00051     adcPrev  = -9999;
00052     adcNext  = -9999;
00053     adcPrev2 = -9999;
00054     adcNext2 = -9999;
00055     
00056     /*
00057       Since we are not running on 
00058       Raw data we need to initialize
00059       all the FED threshold
00060     */
00061     
00062     theNextFEDlowThresh  = theFEDlowThresh;
00063     theNext2FEDlowThresh = theFEDlowThresh;
00064     thePrevFEDlowThresh  = theFEDlowThresh;
00065     thePrev2FEDlowThresh = theFEDlowThresh;
00066     theNeighFEDlowThresh = theFEDlowThresh;
00067 
00068     theNextFEDhighThresh  = theFEDhighThresh;
00069     thePrevFEDhighThresh  = theFEDhighThresh;
00070     theNeighFEDhighThresh = theFEDhighThresh;
00071 
00072     if ( ((strip)%128) == 127){ 
00073       adcNext = 0;
00074       theNextFEDlowThresh  = 9999;
00075       theNextFEDhighThresh = 9999;
00076     }else if (i + 1 < inSize && in[i+1].strip() == strip + 1) {
00077       adcNext = in[i+1].adc();
00078       SiStripThreshold::Data thresholds_1=thresholdHandle->getData(strip+1,detThRange);
00079       theNextFEDlowThresh  = static_cast<int16_t>(thresholds_1.getLth()*noiseHandle->getNoiseFast(strip+1,detNoiseRange)+0.5);
00080       theNextFEDhighThresh = static_cast<int16_t>(thresholds_1.getHth()*noiseHandle->getNoiseFast(strip+1,detNoiseRange)+0.5);
00081       if ( ((strip)%128) == 126){ 
00082         adcNext2 = 0;
00083         theNext2FEDlowThresh  = 9999;
00084       }else if (i + 2 < inSize && in[i+2].strip() == strip + 2) {
00085         adcNext2 = in[i+2].adc();
00086         theNext2FEDlowThresh  = static_cast<int16_t>(thresholdHandle->getData(strip+2,detThRange).getLth()*noiseHandle->getNoiseFast(strip+2,detNoiseRange)+0.5);
00087       }
00088     }
00089 
00090     if ( ((strip)%128) == 0){   
00091       adcPrev = 0;
00092       thePrevFEDlowThresh  = 9999;
00093       thePrevFEDhighThresh = 9999;
00094     }else if (i - 1 >= 0 && in[i-1].strip() == strip - 1) {
00095       adcPrev = in[i-1].adc();
00096       SiStripThreshold::Data thresholds_1=thresholdHandle->getData(strip-1,detThRange);
00097       thePrevFEDlowThresh  = static_cast<int16_t>(thresholds_1.getLth()*noiseHandle->getNoiseFast(strip-1,detNoiseRange)+0.5);
00098       thePrevFEDhighThresh = static_cast<int16_t>(thresholds_1.getHth()*noiseHandle->getNoiseFast(strip-1,detNoiseRange)+0.5);
00099       if ( ((strip)%128) == 1){
00100         adcPrev2 = 0; 
00101         thePrev2FEDlowThresh  = 9999;
00102       }else if (i - 2 >= 0 && in[i-2].strip() == strip - 2) {
00103         adcPrev2 = in[i-2].adc();
00104         thePrev2FEDlowThresh  = static_cast<int16_t>(thresholdHandle->getData(strip-2,detThRange).getLth()*noiseHandle->getNoiseFast(strip-2,detNoiseRange)+0.5);
00105       }
00106     }
00107 
00108     if ( adcNext <= adcPrev){
00109       adcMaxNeigh = adcPrev;
00110       theNeighFEDlowThresh  = thePrevFEDlowThresh;
00111       theNeighFEDhighThresh = thePrevFEDhighThresh;
00112     } else {
00113       adcMaxNeigh = adcNext;
00114       theNeighFEDlowThresh  = theNextFEDlowThresh;
00115       theNeighFEDhighThresh = theNextFEDhighThresh;
00116     }
00117     
00118     if (IsAValidDigi()){
00119       selectedSignal.push_back(SiStripDigi(strip, adc));
00120     }
00121   }
00122 }
00123 
00124 void SiStripFedZeroSuppression::suppress(const edm::DetSet<SiStripRawDigi>& in, edm::DetSet<SiStripDigi>& out)
00125 {
00126   const uint32_t detID = out.id;
00127   SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
00128   SiStripThreshold::Range detThRange = thresholdHandle->getRange(detID);
00129 #ifdef DEBUG_SiStripZeroSuppression_
00130   if (edm::isDebugEnabled())
00131     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] Zero suppression on edm::DetSet<SiStripRawDigi>: detID " << detID << " size = " << in.data.size();
00132 #endif
00133   edm::DetSet<SiStripRawDigi>::const_iterator in_iter=in.data.begin();
00134   for (;in_iter!=in.data.end();in_iter++){
00135 
00136     const uint32_t strip = (uint32_t) (in_iter-in.data.begin());
00137 
00138 #ifdef DEBUG_SiStripZeroSuppression_
00139     if (edm::isDebugEnabled())
00140       LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] detID= " << detID << " strip= " <<  strip << "  adc= " << in_iter->adc();
00141 #endif    
00142     adc   = in_iter->adc();
00143 
00144     SiStripThreshold::Data thresholds=thresholdHandle->getData(strip,detThRange);
00145     theFEDlowThresh  = static_cast<int16_t>(thresholds.getLth()*noiseHandle->getNoiseFast(strip,detNoiseRange)+0.5);
00146     theFEDhighThresh = static_cast<int16_t>(thresholds.getHth()*noiseHandle->getNoiseFast(strip,detNoiseRange)+0.5);
00147 
00148     adcPrev = -9999;
00149     adcNext = -9999;
00150     /*
00151       If a strip is the last one on the chip
00152       set its next neighbor's thresholds to infinity
00153       because the FED does not merge clusters across
00154       chip boundaries right now
00155     */
00156     if ( strip%128 == 127 ) { 
00157       adcNext = 0;      
00158       theNextFEDlowThresh  = 9999;
00159       theNextFEDhighThresh = 9999;
00160     }
00161     else {
00162       adcNext = (in_iter+1)->adc();
00163       SiStripThreshold::Data thresholds_1=thresholdHandle->getData(strip+1,detThRange);
00164       theNextFEDlowThresh  = static_cast<int16_t>(thresholds_1.getLth()*noiseHandle->getNoiseFast(strip+1,detNoiseRange)+0.5);
00165       theNextFEDhighThresh = static_cast<int16_t>(thresholds_1.getHth()*noiseHandle->getNoiseFast(strip+1,detNoiseRange)+0.5);
00166     }
00167     /*
00168       Similarily, for the first strip 
00169       on a chip
00170     */
00171     if ( strip%128 == 0 ) {
00172       adcPrev = 0;
00173       thePrevFEDlowThresh  = 9999;
00174       thePrevFEDhighThresh = 9999;   
00175     }
00176     else {
00177       adcPrev = (in_iter-1)->adc();
00178       SiStripThreshold::Data thresholds_1=thresholdHandle->getData(strip-1,detThRange);
00179       thePrevFEDlowThresh  = static_cast<int16_t>(thresholds_1.getLth()*noiseHandle->getNoiseFast(strip-1,detNoiseRange)+0.5);
00180       thePrevFEDhighThresh = static_cast<int16_t>(thresholds_1.getHth()*noiseHandle->getNoiseFast(strip-1,detNoiseRange)+0.5);
00181     }
00182     if ( adcNext < adcPrev){
00183       adcMaxNeigh = adcPrev;
00184       theNeighFEDlowThresh  = thePrevFEDlowThresh;
00185       theNeighFEDhighThresh = thePrevFEDhighThresh;
00186     } else {
00187       adcMaxNeigh = adcNext;
00188       theNeighFEDlowThresh  = theNextFEDlowThresh;
00189       theNeighFEDhighThresh = theNextFEDhighThresh;
00190     }
00191     
00192     //Find adc values for next neighbouring strips
00193     adcPrev2 = -9999;
00194     adcNext2 = -9999;
00195     thePrev2FEDlowThresh  = 1;
00196     theNext2FEDlowThresh  = 1;
00197     if ( strip%128 >= 126 ) {
00198       adcNext2 = 0;
00199       theNext2FEDlowThresh  = 9999;
00200     }
00201     else if ( strip%128 < 126 ) {
00202       adcNext2 = (in_iter+2)->adc();
00203      theNext2FEDlowThresh  = static_cast<int16_t>(thresholdHandle->getData(strip+2,detThRange).getLth()*noiseHandle->getNoiseFast(strip+2,detNoiseRange)+0.5);
00204     }
00205     if ( strip%128 <= 1 ) {
00206       adcPrev2 = 0; 
00207       thePrev2FEDlowThresh  = 9999;
00208     }
00209     else if ( strip%128 > 1 ) {
00210       adcPrev2 = (in_iter-2)->adc();
00211      thePrev2FEDlowThresh  = static_cast<int16_t>(thresholdHandle->getData(strip-2,detThRange).getLth()*noiseHandle->getNoiseFast(strip-2,detNoiseRange)+0.5);
00212     }
00213     //GB 23/6/08: truncation should be done at the very beginning
00214     if (IsAValidDigi())
00215       out.data.push_back(SiStripDigi(strip, truncate(in_iter->adc())));
00216   }
00217 }
00218 
00219 void SiStripFedZeroSuppression::fillThresholds_(const uint32_t detID, size_t size) {
00220   SiStripNoises::Range detNoiseRange = noiseHandle->getRange(detID);
00221   SiStripThreshold::Range detThRange = thresholdHandle->getRange(detID);
00222 
00223   if (highThr_.size() != size) { 
00224     highThr_.resize(size); 
00225     lowThr_.resize(size);
00226     noises_.resize(size);
00227     highThrSN_.resize(size);
00228     lowThrSN_.resize(size);
00229   }
00230 
00231   noiseHandle->allNoises(noises_, detNoiseRange);
00232   thresholdHandle->allThresholds(lowThrSN_, highThrSN_, detThRange); // thresholds as S/N
00233   for (size_t strip = 0; strip < size; ++strip) {
00234     float noise     = noises_[strip];
00235     //  uncomment line below to check bluk noise decoding
00236     //assert( noise == noiseHandle->getNoiseFast(strip,detNoiseRange) ); 
00237     highThr_[strip] = static_cast<int16_t>(highThrSN_[strip]*noise+0.5+1e-6);
00238     lowThr_[strip]  = static_cast<int16_t>( lowThrSN_[strip]*noise+0.5+1e-6);
00239     // Note: it's a bit wierd, but there are some cases for which 'highThrSN_[strip]*noise' is an exact integer
00240     //   but due to roundoffs it gets rounded to the integer below if. 
00241     //   Apparently the optimized code inlines differently and this changes the roundoff.
00242     //   The +1e-6 fixes the problem.   [GPetruc]
00243   } 
00244 }
00245 
00246 void SiStripFedZeroSuppression::suppress(const std::vector<int16_t>& in, edm::DetSet<SiStripDigi>& out){
00247 
00248   const uint32_t detID = out.id;
00249   size_t size = in.size();
00250 #ifdef DEBUG_SiStripZeroSuppression_
00251   if (edm::isDebugEnabled())
00252     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] Zero suppression on std::vector<int16_t>: detID " << detID << " size = " << in.size();
00253 #endif
00254 
00255    fillThresholds_(detID, size); // want to decouple this from the other cost
00256 
00257   std::vector<int16_t>::const_iterator in_iter=in.begin();
00258   for (size_t strip = 0; strip < size; ++strip, ++in_iter){
00259 
00260     size_t strip_mod_128 = strip & 127;
00261 #ifdef DEBUG_SiStripZeroSuppression_
00262     if (edm::isDebugEnabled())
00263       LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress]  detID= " << detID << " strip= " <<  strip << "  adc= " << *in_iter;
00264 #endif    
00265     adc   = *in_iter;
00266 
00267     theFEDlowThresh  = lowThr_[strip];
00268     theFEDhighThresh = highThr_[strip];
00269 
00270     //Find adc values for neighbouring strips
00271 
00272      /*
00273       If a strip is the last one on the chip
00274       set its next neighbor's thresholds to infinity
00275       because the FED does not merge clusters across
00276       chip boundaries right now
00277     */
00278 
00279     //adcPrev = -9999;  // useless, they are set
00280     //adcNext = -9999;  // in the next lines in any case
00281     if ( strip_mod_128 == 127 ) {
00282       adcNext = 0;      
00283       theNextFEDlowThresh  = 9999;
00284       theNextFEDhighThresh = 9999;
00285     } else {
00286       adcNext = *(in_iter+1);
00287       theNextFEDlowThresh  = lowThr_[strip+1];
00288       theNextFEDhighThresh = highThr_[strip+1];
00289     }
00290     
00291     /*
00292       Similarily, for the first strip 
00293       on a chip
00294     */
00295     if ( strip_mod_128 == 0 ) {
00296       adcPrev = 0;
00297       thePrevFEDlowThresh  = 9999;
00298       thePrevFEDhighThresh = 9999;   
00299     } else {
00300       adcPrev = *(in_iter-1);
00301       thePrevFEDlowThresh  = lowThr_[strip-1];
00302       thePrevFEDhighThresh = highThr_[strip-1];
00303     }
00304 
00305     if ( adcNext < adcPrev){
00306       adcMaxNeigh = adcPrev;
00307       theNeighFEDlowThresh  = thePrevFEDlowThresh;
00308       theNeighFEDhighThresh = thePrevFEDhighThresh;
00309     } else {
00310       adcMaxNeigh = adcNext;
00311       theNeighFEDlowThresh  = theNextFEDlowThresh;
00312       theNeighFEDhighThresh = theNextFEDhighThresh;
00313     }
00314     
00315     //Find adc values for next neighbouring strips
00316     //adcPrev2 = -9999;           //
00317     //adcNext2 = -9999;           // useless to set them here
00318     //thePrev2FEDlowThresh  = 1;  // they are overwritten always in the next 8 lines
00319     //theNext2FEDlowThresh  = 1;  //
00320     if ( strip_mod_128 >=126 ) {
00321       adcNext2 = 0;
00322       theNext2FEDlowThresh  = 9999;
00323     //} else if ( strip_mod_128 < 126 ) { // if it's not >= then is <, no need to "if" again
00324     } else {
00325       adcNext2 = *(in_iter+2);
00326       theNext2FEDlowThresh  = lowThr_[strip+2];
00327     }
00328     if ( strip_mod_128 <= 1 ) {
00329       adcPrev2 = 0; 
00330       thePrev2FEDlowThresh  = 9999;
00331     //} else if ( strip_mod_128 > 1 ) { // same as above
00332     } else {
00333       adcPrev2 = *(in_iter-2);
00334       thePrev2FEDlowThresh  = lowThr_[strip-2];;
00335     }
00336     
00337     if (IsAValidDigi()){
00338 #ifdef DEBUG_SiStripZeroSuppression_
00339       if (edm::isDebugEnabled())
00340         LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] DetId " << out.id << " strip " << strip << " adc " << *in_iter << " digiCollection size " << out.data.size() ;
00341 #endif            
00342       //GB 23/6/08: truncation should be done at the very beginning
00343       out.push_back(SiStripDigi(strip, (*in_iter<0 ? 0 : truncate( *in_iter ) )));
00344     }
00345   }
00346 }
00347 
00348 
00349 bool SiStripFedZeroSuppression::IsAValidDigi()
00350 {
00351 
00352 #ifdef DEBUG_SiStripZeroSuppression_
00353 
00354 
00355   if (edm::isDebugEnabled()){
00356 
00357     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] "
00358                                        << "\n\t adc " << adc 
00359                                        << "\n\t adcPrev " << adcPrev
00360                                        << "\n\t adcNext " << adcNext 
00361                                        << "\n\t adcMaxNeigh " << adcMaxNeigh 
00362                                        << "\n\t adcPrev2 " << adcPrev2 
00363                                        << "\n\t adcNext2 " << adcNext2 
00364                                        <<std::endl;
00365   
00366     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] "
00367                                        << "\n\t theFEDlowThresh " <<  theFEDlowThresh 
00368                                        << "\n\t theFEDhighThresh " << theFEDhighThresh 
00369                                        << "\n\t thePrevFEDlowThresh " <<  thePrevFEDlowThresh 
00370                                        << "\n\t thePrevFEDhighThresh " << thePrevFEDhighThresh 
00371                                        << "\n\t theNextFEDlowThresh " <<  theNextFEDlowThresh 
00372                                        << "\n\t theNextFEDhighThresh " << theNextFEDhighThresh 
00373                                        << "\n\t theNeighFEDlowThresh " <<  theNeighFEDlowThresh 
00374                                        << "\n\t theNeighFEDhighThresh " << theNeighFEDhighThresh 
00375                                        << "\n\t thePrev2FEDlowThresh " <<  thePrev2FEDlowThresh 
00376                                        << "\n\t theNext2FEDlowThresh " <<  theNext2FEDlowThresh
00377                                        <<std::endl;
00378   }
00379 #endif  
00380   // Decide if this strip should be accepted.
00381   bool accept = false;
00382   switch (theFEDalgorithm) {
00383   case 1:
00384     accept = (adc >= theFEDlowThresh);
00385     break;
00386   case 2:
00387     accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh &&
00388                                           adcMaxNeigh >= theNeighFEDlowThresh));
00389     break;
00390   case 3:
00391     accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh &&
00392                                           adcMaxNeigh >= theNeighFEDhighThresh));
00393     break;
00394   case 4:
00395     accept = (
00396               (adc >= theFEDhighThresh)            //Test for adc>highThresh (same as algorithm 2)
00397               ||
00398               (
00399                (adc >= theFEDlowThresh)            //Test for adc>lowThresh, with neighbour adc>lowThresh (same as algorithm 2)
00400                &&
00401                (adcMaxNeigh >= theNeighFEDlowThresh)
00402                ) 
00403               ||
00404               (
00405                (adc < theFEDlowThresh)        //Test for adc<lowThresh
00406                &&     
00407                (
00408                 (
00409                  (adcPrev  >= thePrevFEDhighThresh)    //with both neighbours>highThresh
00410                  &&
00411                  (adcNext  >= theNextFEDhighThresh)
00412                  ) 
00413                 ||
00414                 (
00415                  (adcPrev  >= thePrevFEDhighThresh)    //OR with previous neighbour>highThresh and
00416                  &&
00417                  (adcNext  >= theNextFEDlowThresh)     //both the next neighbours>lowThresh
00418                  &&
00419                  (adcNext2 >= theNext2FEDlowThresh)
00420                  )  
00421                 ||
00422                 (
00423                  (adcNext  >= theNextFEDhighThresh)    //OR with next neighbour>highThresh and
00424                  &&
00425                  (adcPrev  >= thePrevFEDlowThresh)     //both the previous neighbours>lowThresh
00426                  &&
00427                  (adcPrev2 >= thePrev2FEDlowThresh)
00428                  )  
00429                 ||
00430                 (
00431                  (adcNext  >= theNextFEDlowThresh)     //OR with both next neighbours>lowThresh and
00432                  &&
00433                  (adcNext2 >= theNext2FEDlowThresh)   //both the previous neighbours>lowThresh
00434                  &&
00435                  (adcPrev  >= thePrevFEDlowThresh)  
00436                  &&
00437                  (adcPrev2 >= thePrev2FEDlowThresh)
00438                  )
00439                 )
00440                )
00441               );
00442     break;
00443   }
00444   return accept;
00445 }
00446