CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_5_3_3/src/SimCalorimetry/HcalTrigPrimAlgos/src/HcalTriggerPrimitiveAlgo.cc

Go to the documentation of this file.
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    //No peak finding setting (for Fastsim)
00029    if (!peakfind_){
00030       numberOfSamples_ = 1; 
00031       numberOfPresamples_ = 0;
00032    }
00033    // Switch to integer for comparisons - remove compiler warning
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    // do the HB/HE digis
00058    for(HBHEDigiCollection::const_iterator hbheItr = hbheDigis.begin();
00059    hbheItr != hbheDigis.end(); ++hbheItr) {
00060       addSignal(*hbheItr);
00061    }
00062 
00063    // and the HF digis
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    //Hack for 300_pre10, should be removed.
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       // make a second trigprim for the other one, and split the energy
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       // Don't add to final collection yet
00121       // HF PMT veto sum is calculated in analyzerHF()
00122       IntegerCaloSamples zero_samples(ids[0], frame.size());
00123       zero_samples.setPresamples(frame.presamples());
00124       addSignal(zero_samples);
00125 
00126       // Mask off depths: fgid is the same for both depths
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       // If find
00140       if (sumFGItr != sumFG.end()) {
00141          for (int i=0; i<samples.size(); ++i) (*sumFGItr)[i] += samples[i];
00142       }
00143       else {
00144          //Copy samples (change to fgid)
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       // set veto to true if Long or Short less than threshold
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       // wish CaloSamples had a +=
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    //slide algo window
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          //add up value * scale factor
00189          algosumvalue += int(samples[ibin+i] * weights_[i]);
00190       }
00191       if (algosumvalue<0) sum[ibin]=0;            // low-side
00192                                                   //high-side
00193       //else if (algosumvalue>0x3FF) sum[ibin]=0x3FF;
00194       else sum[ibin] = algosumvalue;              //assign value to sum[]
00195    }
00196 
00197    IntegerCaloSamples output(samples.id(), numberOfSamples_);
00198    output.setPresamples(numberOfPresamples_);
00199 
00200    // Align digis and TP
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       // ibin - index for output TP
00210       // idx - index for samples + shift
00211       int idx = ibin + shift;
00212 
00213       //Peak finding
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          // Not a peak
00232          else output[ibin] = 0;
00233       }
00234       else { // No peak finding, just output running sum
00235          output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00236          finegrain[ibin] = msb[idx];
00237       }
00238 
00239       // Only Pegged for 1-TS algo.
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    // Align digis and TP
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    // Loop over all L+S pairs that mapped from samples.id()
00263    // Note: 1 samples.id() = 6 x (L+S) without noZS
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          // if not vetod, add L+S to total sum and calculate FG
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             //valid = true;
00337           }
00338         }
00339       }
00340     }
00341   }
00342 
00343   // Loop over TP collection
00344   // Set TP to zero if there is FE Format Error
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 }