CMS 3D CMS Logo

CMSSW_4_4_3_patch1/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 
00247 void SiStripFedZeroSuppression::suppress(const std::vector<int16_t>& in, const uint16_t& firstAPV,  edm::DetSet<SiStripDigi>& out){
00248 
00249   const uint32_t detID = out.id;
00250   size_t size = in.size();
00251 #ifdef DEBUG_SiStripZeroSuppression_
00252   if (edm::isDebugEnabled())
00253     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] Zero suppression on std::vector<int16_t>: detID " << detID << " size = " << in.size();
00254 #endif
00255 
00256   fillThresholds_(detID, size+firstAPV*128); // want to decouple this from the other cost
00257 
00258 
00259   std::vector<int16_t>::const_iterator in_iter=in.begin();
00260   uint16_t strip = firstAPV*128;
00261   for (; strip < size+firstAPV*128; ++strip, ++in_iter){
00262 
00263     size_t strip_mod_128 = strip & 127;
00264 #ifdef DEBUG_SiStripZeroSuppression_
00265     if (edm::isDebugEnabled())
00266       LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress]  detID= " << detID << " strip= " <<  strip << "  adc= " << *in_iter;
00267 #endif    
00268     adc   = *in_iter;
00269 
00270     theFEDlowThresh  = lowThr_[strip];
00271     theFEDhighThresh = highThr_[strip];
00272 
00273     //Find adc values for neighbouring strips
00274 
00275      /*
00276       If a strip is the last one on the chip
00277       set its next neighbor's thresholds to infinity
00278       because the FED does not merge clusters across
00279       chip boundaries right now
00280     */
00281 
00282     //adcPrev = -9999;  // useless, they are set
00283     //adcNext = -9999;  // in the next lines in any case
00284     if ( strip_mod_128 == 127 ) {
00285       adcNext = 0;      
00286       theNextFEDlowThresh  = 9999;
00287       theNextFEDhighThresh = 9999;
00288     } else {
00289       adcNext = *(in_iter+1);
00290       theNextFEDlowThresh  = lowThr_[strip+1];
00291       theNextFEDhighThresh = highThr_[strip+1];
00292     }
00293     
00294     /*
00295       Similarily, for the first strip 
00296       on a chip
00297     */
00298     if ( strip_mod_128 == 0 ) {
00299       adcPrev = 0;
00300       thePrevFEDlowThresh  = 9999;
00301       thePrevFEDhighThresh = 9999;   
00302     } else {
00303       adcPrev = *(in_iter-1);
00304       thePrevFEDlowThresh  = lowThr_[strip-1];
00305       thePrevFEDhighThresh = highThr_[strip-1];
00306     }
00307 
00308     if ( adcNext < adcPrev){
00309       adcMaxNeigh = adcPrev;
00310       theNeighFEDlowThresh  = thePrevFEDlowThresh;
00311       theNeighFEDhighThresh = thePrevFEDhighThresh;
00312     } else {
00313       adcMaxNeigh = adcNext;
00314       theNeighFEDlowThresh  = theNextFEDlowThresh;
00315       theNeighFEDhighThresh = theNextFEDhighThresh;
00316     }
00317     
00318     //Find adc values for next neighbouring strips
00319     //adcPrev2 = -9999;           //
00320     //adcNext2 = -9999;           // useless to set them here
00321     //thePrev2FEDlowThresh  = 1;  // they are overwritten always in the next 8 lines
00322     //theNext2FEDlowThresh  = 1;  //
00323     if ( strip_mod_128 >=126 ) {
00324       adcNext2 = 0;
00325       theNext2FEDlowThresh  = 9999;
00326     //} else if ( strip_mod_128 < 126 ) { // if it's not >= then is <, no need to "if" again
00327     } else {
00328       adcNext2 = *(in_iter+2);
00329       theNext2FEDlowThresh  = lowThr_[strip+2];
00330     }
00331     if ( strip_mod_128 <= 1 ) {
00332       adcPrev2 = 0; 
00333       thePrev2FEDlowThresh  = 9999;
00334     //} else if ( strip_mod_128 > 1 ) { // same as above
00335     } else {
00336       adcPrev2 = *(in_iter-2);
00337       thePrev2FEDlowThresh  = lowThr_[strip-2];;
00338     }
00339     
00340     if (IsAValidDigi()){
00341 #ifdef DEBUG_SiStripZeroSuppression_
00342       if (edm::isDebugEnabled())
00343         LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] DetId " << out.id << " strip " << strip << " adc " << *in_iter << " digiCollection size " << out.data.size() ;
00344 #endif            
00345       //GB 23/6/08: truncation should be done at the very beginning
00346       out.push_back(SiStripDigi(strip, (*in_iter<0 ? 0 : truncate( *in_iter ) )));
00347     }
00348   }
00349 }
00350 
00351 
00352 bool SiStripFedZeroSuppression::IsAValidDigi()
00353 {
00354 
00355 #ifdef DEBUG_SiStripZeroSuppression_
00356 
00357 
00358   if (edm::isDebugEnabled()){
00359 
00360     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] "
00361                                        << "\n\t adc " << adc 
00362                                        << "\n\t adcPrev " << adcPrev
00363                                        << "\n\t adcNext " << adcNext 
00364                                        << "\n\t adcMaxNeigh " << adcMaxNeigh 
00365                                        << "\n\t adcPrev2 " << adcPrev2 
00366                                        << "\n\t adcNext2 " << adcNext2 
00367                                        <<std::endl;
00368   
00369     LogTrace("SiStripZeroSuppression") << "[SiStripFedZeroSuppression::suppress] "
00370                                        << "\n\t theFEDlowThresh " <<  theFEDlowThresh 
00371                                        << "\n\t theFEDhighThresh " << theFEDhighThresh 
00372                                        << "\n\t thePrevFEDlowThresh " <<  thePrevFEDlowThresh 
00373                                        << "\n\t thePrevFEDhighThresh " << thePrevFEDhighThresh 
00374                                        << "\n\t theNextFEDlowThresh " <<  theNextFEDlowThresh 
00375                                        << "\n\t theNextFEDhighThresh " << theNextFEDhighThresh 
00376                                        << "\n\t theNeighFEDlowThresh " <<  theNeighFEDlowThresh 
00377                                        << "\n\t theNeighFEDhighThresh " << theNeighFEDhighThresh 
00378                                        << "\n\t thePrev2FEDlowThresh " <<  thePrev2FEDlowThresh 
00379                                        << "\n\t theNext2FEDlowThresh " <<  theNext2FEDlowThresh
00380                                        <<std::endl;
00381   }
00382 #endif  
00383   // Decide if this strip should be accepted.
00384   bool accept = false;
00385   switch (theFEDalgorithm) {
00386   case 1:
00387     accept = (adc >= theFEDlowThresh);
00388     break;
00389   case 2:
00390     accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh &&
00391                                           adcMaxNeigh >= theNeighFEDlowThresh));
00392     break;
00393   case 3:
00394     accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh &&
00395                                           adcMaxNeigh >= theNeighFEDhighThresh));
00396     break;
00397   case 4:
00398     accept = (
00399               (adc >= theFEDhighThresh)            //Test for adc>highThresh (same as algorithm 2)
00400               ||
00401               (
00402                (adc >= theFEDlowThresh)            //Test for adc>lowThresh, with neighbour adc>lowThresh (same as algorithm 2)
00403                &&
00404                (adcMaxNeigh >= theNeighFEDlowThresh)
00405                ) 
00406               ||
00407               (
00408                (adc < theFEDlowThresh)        //Test for adc<lowThresh
00409                &&     
00410                (
00411                 (
00412                  (adcPrev  >= thePrevFEDhighThresh)    //with both neighbours>highThresh
00413                  &&
00414                  (adcNext  >= theNextFEDhighThresh)
00415                  ) 
00416                 ||
00417                 (
00418                  (adcPrev  >= thePrevFEDhighThresh)    //OR with previous neighbour>highThresh and
00419                  &&
00420                  (adcNext  >= theNextFEDlowThresh)     //both the next neighbours>lowThresh
00421                  &&
00422                  (adcNext2 >= theNext2FEDlowThresh)
00423                  )  
00424                 ||
00425                 (
00426                  (adcNext  >= theNextFEDhighThresh)    //OR with next neighbour>highThresh and
00427                  &&
00428                  (adcPrev  >= thePrevFEDlowThresh)     //both the previous neighbours>lowThresh
00429                  &&
00430                  (adcPrev2 >= thePrev2FEDlowThresh)
00431                  )  
00432                 ||
00433                 (
00434                  (adcNext  >= theNextFEDlowThresh)     //OR with both next neighbours>lowThresh and
00435                  &&
00436                  (adcNext2 >= theNext2FEDlowThresh)   //both the previous neighbours>lowThresh
00437                  &&
00438                  (adcPrev  >= thePrevFEDlowThresh)  
00439                  &&
00440                  (adcPrev2 >= thePrev2FEDlowThresh)
00441                  )
00442                 )
00443                )
00444               );
00445     break;
00446   }
00447   return accept;
00448 }
00449