00001 00002 // File: ZeroSuppressFP420.cc 00003 // Date: 12.2006 00004 // Description: ZeroSuppressFP420 for FP420 00005 // Modifications: 00007 #include "SimRomanPot/SimFP420/interface/ZeroSuppressFP420.h" 00008 #include "FWCore/MessageLogger/interface/MessageLogger.h" 00009 //#define mydigidebug9 00010 00011 ZeroSuppressFP420::ZeroSuppressFP420(const edm::ParameterSet& conf, float noise) : conf_(conf), theNumFEDalgos(4) 00012 { 00013 noiseInAdc=noise; 00014 initParams(conf_); 00015 //initParams(); 00016 #ifdef mydigidebug9 00017 std::cout << "ZeroSuppressFP420: constructor: noiseInAdc= " << noiseInAdc << std::endl; 00018 #endif 00019 } 00020 00021 /* 00022 * The zero suppression algorithm, implemented in the trkFEDclusterizer method. 00023 * The class publically inherits from the ZSuppressFP420 class, which requires 00024 * the use of a method named zeroSuppress. 00025 */ 00026 00027 void ZeroSuppressFP420::initParams(edm::ParameterSet const& conf_) 00028 { 00029 verbosity = conf_.getUntrackedParameter<int>("VerbosityLevel"); 00030 algoConf = conf_.getParameter<int>("FedFP420Algorithm"); //FedFP420Algorithm: =1 (,2,3,4) 00031 lowthreshConf = conf_.getParameter<double>("FedFP420LowThreshold"); // FedFP420LowThreshold =3. 00032 highthreshConf = conf_.getParameter<double>("FedFP420HighThreshold"); // FedFP420HighThreshold =4. 00033 00034 /* 00035 * There are four possible algorithms, the default of which (4) 00036 * has different thresholds for isolated channels and ones in clusters. 00037 * It also merges clusters (single or multi channels) that are only separated 00038 * by one hole. This channel is selected as signal even though it is below 00039 * both thresholds. 00040 */ 00041 00042 theFEDalgorithm = algoConf; 00043 theFEDlowThresh = lowthreshConf * noiseInAdc; 00044 theFEDhighThresh = highthreshConf * noiseInAdc; 00045 00046 if(verbosity>0) { 00047 std::cout << "ZeroSuppressFP420: initParams: !!! theFEDalgorithm= " << theFEDalgorithm << std::endl; 00048 std::cout << " lowthreshConf= " << lowthreshConf << " highthreshConf= " << highthreshConf << " theFEDlowThresh= " << theFEDlowThresh << " theFEDhighThresh= " << theFEDhighThresh << std::endl; 00049 } 00050 00051 //Check zero suppress algorithm 00052 if (theFEDalgorithm < 1 || theFEDalgorithm > theNumFEDalgos) { 00053 edm::LogError("FP420DigiInfo")<<"ZeroSuppressFP420 FATAL ERROR: Unknown zero suppress algorithm "<<theFEDalgorithm; 00054 exit(1); 00055 } 00056 00057 //Check thresholds 00058 if (theFEDlowThresh > theFEDhighThresh) { 00059 edm::LogError("FP420DigiInfo")<<"ZeroSuppressFP420 FATAL ERROR: Low threshold exceeds high threshold: "<<theFEDlowThresh<<" > "<<theFEDhighThresh; 00060 exit(2); 00061 } 00062 } 00063 00064 //Zero suppress method, which called the ZeroSuppressFP420::trkFEDclusterizer 00065 ZSuppressFP420::DigitalMapType ZeroSuppressFP420::zeroSuppress(const DigitalMapType& notZeroSuppressedMap) 00066 { 00067 00068 return trkFEDclusterizer(notZeroSuppressedMap); 00069 #ifdef mydigidebug9 00070 std::cout << "zeroSuppress: return trkFEDclusterizer(notZeroSuppressedMap)" << std::endl; 00071 #endif 00072 } 00073 00074 //This performs the zero suppression 00075 ZSuppressFP420::DigitalMapType ZeroSuppressFP420::trkFEDclusterizer(const DigitalMapType &in) 00076 { 00077 const string s2("ZeroSuppressFP420::trkFEDclusterizer1"); 00078 00079 DigitalMapType selectedSignal; 00080 register DigitalMapType::const_iterator i, iPrev, iNext, iPrev2, iNext2; 00081 00082 #ifdef mydigidebug9 00083 std::cout << "Before For loop" << std::endl; 00084 #endif 00085 for (i = in.begin(); i != in.end(); i++) { 00086 00087 //Find adc values for neighbouring strips 00088 int strip = i->first; 00089 int adc = i->second; 00090 iPrev = in.find(strip - 1); 00091 iNext = in.find(strip + 1); 00092 #ifdef mydigidebug9 00093 std::cout << "Inside For loop trkFEDclusterizer: strip= " << strip << " adc= " << adc << std::endl; 00094 #endif 00095 //Set values for channels just outside module to infinity. 00096 //This is to avoid losing channels at the edges, 00097 //which otherwise would pass cuts if strips were next to each other. 00098 int adcPrev = -99999; 00099 int adcNext = -99999; 00100 if ( ((strip)%128) == 127) adcNext = 99999; 00101 if ( ((strip)%128) == 0) adcPrev = 99999; 00102 //Otherwise if channel was found then find it's ADC count. 00103 if ( iPrev != in.end() ) adcPrev = iPrev->second; 00104 if ( iNext != in.end() ) adcNext = iNext->second; 00105 int adcMaxNeigh = max(adcPrev, adcNext); 00106 #ifdef mydigidebug9 00107 std::cout << "adcPrev= " << adcPrev << " adcNext= " << adcNext << " adcMaxNeigh= " << adcMaxNeigh << std::endl; 00108 #endif 00109 00110 //Find adc values for next neighbouring channes 00111 iPrev2 = in.find(strip - 2); 00112 iNext2 = in.find(strip + 2); 00113 //See above 00114 int adcPrev2 = -99999; 00115 int adcNext2 = -99999; 00116 if ( ((strip)%128) == 126) adcNext2 = 99999; 00117 if ( ((strip)%128) == 1) adcPrev2 = 99999; 00118 if ( iPrev2 != in.end() ) adcPrev2 = iPrev2->second; 00119 if ( iNext2 != in.end() ) adcNext2 = iNext2->second; 00120 #ifdef mydigidebug9 00121 std::cout << "adcPrev2= " << adcPrev2 << " adcNext2= " << adcNext2 << std::endl; 00122 std::cout << "To be accepted or not? adc= " << adc << " >= theFEDlowThresh=" << theFEDlowThresh << std::endl; 00123 #endif 00124 // Decide if this channel should be accepted. 00125 bool accept = false; 00126 switch (theFEDalgorithm) { 00127 00128 case 1: 00129 accept = (adc >= theFEDlowThresh); 00130 break; 00131 00132 case 2: 00133 accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh && 00134 adcMaxNeigh >= theFEDlowThresh)); 00135 break; 00136 00137 case 3: 00138 accept = (adc >= theFEDhighThresh || (adc >= theFEDlowThresh && 00139 adcMaxNeigh >= theFEDhighThresh)); 00140 break; 00141 00142 case 4: 00143 accept = ((adc >= theFEDhighThresh) || //Test for adc>highThresh (same as algorithm 2) 00144 ((adc >= theFEDlowThresh) && //Test for adc>lowThresh, with neighbour adc>lowThresh (same as algorithm 2) 00145 (adcMaxNeigh >= theFEDlowThresh)) || 00146 ((adc < theFEDlowThresh) && //Test for adc<lowThresh 00147 (((adcPrev >= theFEDhighThresh) && //with both neighbours>highThresh 00148 (adcNext >= theFEDhighThresh)) || 00149 ((adcPrev >= theFEDhighThresh) && //OR with previous neighbour>highThresh and 00150 (adcNext >= theFEDlowThresh) && //both the next neighbours>lowThresh 00151 (adcNext2 >= theFEDlowThresh)) || 00152 ((adcNext >= theFEDhighThresh) && //OR with next neighbour>highThresh and 00153 (adcPrev >= theFEDlowThresh) && //both the previous neighbours>lowThresh 00154 (adcPrev2 >= theFEDlowThresh)) || 00155 ((adcNext >= theFEDlowThresh) && //OR with both next neighbours>lowThresh and 00156 (adcNext2 >= theFEDlowThresh) && //both the previous neighbours>lowThresh 00157 (adcPrev >= theFEDlowThresh) && 00158 (adcPrev2 >= theFEDlowThresh))))); 00159 break; 00160 } 00161 00162 /* 00163 * When a channel satisfying only the lower threshold is at the edge of an APV or module, 00164 * the trkFEDclusterizer method assumes that every channel just outside an APV or module has a hit on it. 00165 * This is to avoid channel inefficiencies at the edges of APVs and modules. 00166 */ 00167 if (accept) { 00168 selectedSignal[strip] = adc; 00169 #ifdef mydigidebug9 00170 std::cout << "selected strips = " << strip << " adc= " << adc << std::endl; 00171 #endif 00172 } 00173 } 00174 #ifdef mydigidebug9 00175 std::cout << "last line of trkFEDclusterizer: return selectedSignal" << std::endl; 00176 #endif 00177 return selectedSignal; 00178 } 00179