00001 #include "SimCalorimetry/HcalTrigPrimAlgos/interface/HcalTriggerPrimitiveAlgo.h"
00002 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00003
00004 #include <iostream>
00005 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00006 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
00007 #include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
00008 #include "DataFormats/FEDRawData/interface/FEDNumbering.h"
00009 #include "DataFormats/HcalDetId/interface/HcalElectronicsId.h"
00010 #include "EventFilter/HcalRawToDigi/interface/HcalDCCHeader.h"
00011 #include "EventFilter/HcalRawToDigi/interface/HcalHTRData.h"
00012
00013 using namespace std;
00014
00015 HcalTriggerPrimitiveAlgo::HcalTriggerPrimitiveAlgo( bool pf, const std::vector<double>& w, int latency,
00016 uint32_t FG_threshold, uint32_t ZS_threshold,
00017 int numberOfSamples, int numberOfPresamples,
00018 uint32_t minSignalThreshold, uint32_t PMT_NoiseThreshold)
00019 : incoder_(0), outcoder_(0),
00020 theThreshold(0), peakfind_(pf), weights_(w), latency_(latency),
00021 FG_threshold_(FG_threshold), ZS_threshold_(ZS_threshold),
00022 numberOfSamples_(numberOfSamples),
00023 numberOfPresamples_(numberOfPresamples),
00024 minSignalThreshold_(minSignalThreshold),
00025 PMT_NoiseThreshold_(PMT_NoiseThreshold),
00026 peak_finder_algorithm_(2)
00027 {
00028
00029 if (!peakfind_){
00030 numberOfSamples_ = 1;
00031 numberOfPresamples_ = 0;
00032 }
00033
00034 ZS_threshold_I_ = ZS_threshold_;
00035 }
00036
00037
00038 HcalTriggerPrimitiveAlgo::~HcalTriggerPrimitiveAlgo() {
00039 }
00040
00041
00042 void HcalTriggerPrimitiveAlgo::run(const HcalTPGCoder* incoder,
00043 const HcalTPGCompressor* outcoder,
00044 const HBHEDigiCollection& hbheDigis,
00045 const HFDigiCollection& hfDigis,
00046 HcalTrigPrimDigiCollection& result,
00047 float rctlsb) {
00048
00049 incoder_=dynamic_cast<const HcaluLUTTPGCoder*>(incoder);
00050 outcoder_=outcoder;
00051
00052 theSumMap.clear();
00053 theTowerMapFGSum.clear();
00054 HF_Veto.clear();
00055 fgMap_.clear();
00056
00057
00058 for(HBHEDigiCollection::const_iterator hbheItr = hbheDigis.begin();
00059 hbheItr != hbheDigis.end(); ++hbheItr) {
00060 addSignal(*hbheItr);
00061 }
00062
00063
00064 for(HFDigiCollection::const_iterator hfItr = hfDigis.begin();
00065 hfItr != hfDigis.end(); ++hfItr) {
00066 addSignal(*hfItr);
00067
00068 }
00069
00070 for(SumMap::iterator mapItr = theSumMap.begin(); mapItr != theSumMap.end(); ++mapItr) {
00071 result.push_back(HcalTriggerPrimitiveDigi(mapItr->first));
00072 HcalTrigTowerDetId detId(mapItr->second.id());
00073 if(detId.ietaAbs() >= theTrigTowerGeometry.firstHFTower())
00074 { analyzeHF(mapItr->second, result.back(), rctlsb);}
00075 else{analyze(mapItr->second, result.back());}
00076 }
00077 return;
00078 }
00079
00080
00081 void HcalTriggerPrimitiveAlgo::addSignal(const HBHEDataFrame & frame) {
00082
00083 if (frame.id().depth()==5) return;
00084
00085 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry.towerIds(frame.id());
00086 assert(ids.size() == 1 || ids.size() == 2);
00087 IntegerCaloSamples samples1(ids[0], int(frame.size()));
00088
00089 samples1.setPresamples(frame.presamples());
00090 incoder_->adc2Linear(frame, samples1);
00091
00092 std::vector<bool> msb;
00093 incoder_->lookupMSB(frame, msb);
00094
00095 if(ids.size() == 2) {
00096
00097 IntegerCaloSamples samples2(ids[1], samples1.size());
00098 for(int i = 0; i < samples1.size(); ++i) {
00099 samples1[i] = uint32_t(samples1[i]*0.5);
00100 samples2[i] = samples1[i];
00101 }
00102 samples2.setPresamples(frame.presamples());
00103 addSignal(samples2);
00104 addFG(ids[1], msb);
00105 }
00106 addSignal(samples1);
00107 addFG(ids[0], msb);
00108 }
00109
00110
00111 void HcalTriggerPrimitiveAlgo::addSignal(const HFDataFrame & frame) {
00112
00113 if(frame.id().depth() == 1 || frame.id().depth() == 2) {
00114 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry.towerIds(frame.id());
00115 assert(ids.size() == 1);
00116 IntegerCaloSamples samples(ids[0], frame.size());
00117 samples.setPresamples(frame.presamples());
00118 incoder_->adc2Linear(frame, samples);
00119
00120
00121
00122 IntegerCaloSamples zero_samples(ids[0], frame.size());
00123 zero_samples.setPresamples(frame.presamples());
00124 addSignal(zero_samples);
00125
00126
00127 uint32_t fgid = (frame.id().rawId() | 0x1c000) ;
00128
00129 if ( theTowerMapFGSum.find(ids[0]) == theTowerMapFGSum.end() ) {
00130 SumFGContainer sumFG;
00131 theTowerMapFGSum.insert(std::pair<HcalTrigTowerDetId, SumFGContainer >(ids[0], sumFG));
00132 }
00133
00134 SumFGContainer& sumFG = theTowerMapFGSum[ids[0]];
00135 SumFGContainer::iterator sumFGItr;
00136 for ( sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
00137 if (sumFGItr->id() == fgid) break;
00138 }
00139
00140 if (sumFGItr != sumFG.end()) {
00141 for (int i=0; i<samples.size(); ++i) (*sumFGItr)[i] += samples[i];
00142 }
00143 else {
00144
00145 IntegerCaloSamples sumFGSamples(DetId(fgid), samples.size());
00146 sumFGSamples.setPresamples(samples.presamples());
00147 for (int i=0; i<samples.size(); ++i) sumFGSamples[i] = samples[i];
00148 sumFG.push_back(sumFGSamples);
00149 }
00150
00151
00152 if (HF_Veto.find(fgid) == HF_Veto.end()) {
00153 vector<bool> vetoBits(samples.size(), false);
00154 HF_Veto[fgid] = vetoBits;
00155 }
00156 for (int i=0; i<samples.size(); ++i)
00157 if (samples[i] < minSignalThreshold_)
00158 HF_Veto[fgid][i] = true;
00159 }
00160 }
00161
00162
00163 void HcalTriggerPrimitiveAlgo::addSignal(const IntegerCaloSamples & samples) {
00164 HcalTrigTowerDetId id(samples.id());
00165 SumMap::iterator itr = theSumMap.find(id);
00166 if(itr == theSumMap.end()) {
00167 theSumMap.insert(std::make_pair(id, samples));
00168 }
00169 else {
00170
00171 for(int i = 0; i < samples.size(); ++i) {
00172 (itr->second)[i] += samples[i];
00173 }
00174 }
00175 }
00176
00177
00178 void HcalTriggerPrimitiveAlgo::analyze(IntegerCaloSamples & samples, HcalTriggerPrimitiveDigi & result) {
00179 int shrink = weights_.size() - 1;
00180 std::vector<bool> finegrain(numberOfSamples_,false);
00181 std::vector<bool>& msb = fgMap_[samples.id()];
00182 IntegerCaloSamples sum(samples.id(), samples.size());
00183
00184
00185 for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
00186 int algosumvalue = 0;
00187 for(unsigned int i = 0; i < weights_.size(); i++) {
00188
00189 algosumvalue += int(samples[ibin+i] * weights_[i]);
00190 }
00191 if (algosumvalue<0) sum[ibin]=0;
00192
00193
00194 else sum[ibin] = algosumvalue;
00195 }
00196
00197 IntegerCaloSamples output(samples.id(), numberOfSamples_);
00198 output.setPresamples(numberOfPresamples_);
00199
00200
00201 int shift = samples.presamples() - numberOfPresamples_;
00202 if (peakfind_) {
00203 assert (shift >= (peakfind_ ? shrink : 0));
00204 assert(shift + numberOfSamples_ + shrink <= samples.size() - (peak_finder_algorithm_ - 1));
00205 }
00206
00207
00208 for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00209
00210
00211 int idx = ibin + shift;
00212
00213
00214 if (peakfind_) {
00215 bool isPeak = false;
00216 switch (peak_finder_algorithm_) {
00217 case 1 :
00218 isPeak = (samples[idx] > samples[idx-1] && samples[idx] >= samples[idx+1] && samples[idx] > theThreshold);
00219 break;
00220 case 2:
00221 isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
00222 break;
00223 default:
00224 break;
00225 }
00226
00227 if (isPeak){
00228 output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00229 finegrain[ibin] = msb[idx];
00230 }
00231
00232 else output[ibin] = 0;
00233 }
00234 else {
00235 output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00236 finegrain[ibin] = msb[idx];
00237 }
00238
00239
00240 if (peak_finder_algorithm_ == 1) {
00241 if (samples[idx] >= 0x3FF)
00242 output[ibin] = 0x3FF;
00243 }
00244 outcoder_->compress(output, finegrain, result);
00245 }
00246 }
00247
00248
00249 void HcalTriggerPrimitiveAlgo::analyzeHF(IntegerCaloSamples & samples, HcalTriggerPrimitiveDigi & result, float rctlsb) {
00250 std::vector<bool> finegrain(numberOfSamples_, false);
00251 HcalTrigTowerDetId detId(samples.id());
00252
00253
00254 int shift = samples.presamples() - numberOfPresamples_;
00255 assert(shift >= 0);
00256 assert((shift + numberOfSamples_) <= samples.size());
00257
00258 TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
00259 assert(tower2fg != theTowerMapFGSum.end());
00260
00261 const SumFGContainer& sumFG = tower2fg->second;
00262
00263
00264 for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
00265 const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
00266 for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00267 int idx = ibin + shift;
00268
00269 if (!(veto[idx] && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
00270 samples[idx] += (*sumFGItr)[idx];
00271 finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
00272 }
00273 }
00274 }
00275
00276 IntegerCaloSamples output(samples.id(), numberOfSamples_);
00277 output.setPresamples(numberOfPresamples_);
00278
00279 for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00280 int idx = ibin + shift;
00281 output[ibin] = samples[idx] / (rctlsb == 0.25 ? 4 : 8);
00282 if (output[ibin] > 0x3FF) output[ibin] = 0x3FF;
00283 }
00284 outcoder_->compress(output, finegrain, result);
00285 }
00286
00287 void HcalTriggerPrimitiveAlgo::runZS(HcalTrigPrimDigiCollection & result){
00288 for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
00289 bool ZS = true;
00290 for (int i=0; i<tp->size(); ++i) {
00291 if (tp->sample(i).compressedEt() > ZS_threshold_I_) {
00292 ZS=false;
00293 break;
00294 }
00295 }
00296 if (ZS) tp->setZSInfo(false,true);
00297 else tp->setZSInfo(true,false);
00298 }
00299 }
00300
00301 void HcalTriggerPrimitiveAlgo::runFEFormatError(const FEDRawDataCollection* rawraw,
00302 const HcalElectronicsMap *emap,
00303 HcalTrigPrimDigiCollection & result
00304 ){
00305 std::set<uint32_t> FrontEndErrors;
00306
00307 for(int i=FEDNumbering::MINHCALFEDID; i<=FEDNumbering::MAXHCALFEDID; ++i) {
00308 const FEDRawData& raw = rawraw->FEDData(i);
00309 if (raw.size()<12) continue;
00310 const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00311 if(!dccHeader) continue;
00312 HcalHTRData htr;
00313 for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00314 if (!dccHeader->getSpigotPresent(spigot)) continue;
00315 dccHeader->getSpigotData(spigot,htr,raw.size());
00316 int dccid = dccHeader->getSourceId();
00317 int errWord = htr.getErrorsWord() & 0x1FFFF;
00318 bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800)!=0);
00319
00320 if(HTRError) {
00321 bool valid =false;
00322 for(int fchan=0; fchan<3 && !valid; fchan++) {
00323 for(int fib=0; fib<9 && !valid; fib++) {
00324 HcalElectronicsId eid(fchan,fib,spigot,dccid-FEDNumbering::MINHCALFEDID);
00325 eid.setHTR(htr.readoutVMECrateId(),htr.htrSlot(),htr.htrTopBottom());
00326 DetId detId = emap->lookup(eid);
00327 if(detId.null()) continue;
00328 HcalSubdetector subdet=(HcalSubdetector(detId.subdetId()));
00329 if (detId.det()!=4||
00330 (subdet!=HcalBarrel && subdet!=HcalEndcap &&
00331 subdet!=HcalForward )) continue;
00332 std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry.towerIds(detId);
00333 for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId=ids.begin(); triggerId != ids.end(); ++triggerId) {
00334 FrontEndErrors.insert(triggerId->rawId());
00335 }
00336
00337 }
00338 }
00339 }
00340 }
00341 }
00342
00343
00344
00345 HcalTriggerPrimitiveSample zeroSample(0);
00346 for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
00347 if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
00348 for (int i=0; i<tp->size(); ++i) tp->setSample(i, zeroSample);
00349 }
00350 }
00351 }
00352
00353 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb){
00354 FGbitMap::iterator itr = fgMap_.find(id);
00355 if (itr != fgMap_.end()){
00356 std::vector<bool>& _msb = itr->second;
00357 for (size_t i=0; i<msb.size(); ++i)
00358 _msb[i] = _msb[i] || msb[i];
00359 }
00360 else fgMap_[id] = msb;
00361 }
00362
00363 void HcalTriggerPrimitiveAlgo::setPeakFinderAlgorithm(int algo){
00364 if (algo <=0 && algo>2)
00365 throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
00366 peak_finder_algorithm_ = algo;
00367 }