CMS 3D CMS Logo

/afs/cern.ch/work/a/aaltunda/public/www/CMSSW_6_2_5/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                                    const HcalTrigTowerGeometry* trigTowerGeometry,
00048                                    float rctlsb) {
00049    theTrigTowerGeometry = trigTowerGeometry;
00050     
00051    incoder_=dynamic_cast<const HcaluLUTTPGCoder*>(incoder);
00052    outcoder_=outcoder;
00053 
00054    theSumMap.clear();
00055    theTowerMapFGSum.clear();
00056    HF_Veto.clear();
00057    fgMap_.clear();
00058 
00059    // do the HB/HE digis
00060    for(HBHEDigiCollection::const_iterator hbheItr = hbheDigis.begin();
00061    hbheItr != hbheDigis.end(); ++hbheItr) {
00062       addSignal(*hbheItr);
00063    }
00064 
00065    // and the HF digis
00066    for(HFDigiCollection::const_iterator hfItr = hfDigis.begin();
00067    hfItr != hfDigis.end(); ++hfItr) {
00068       addSignal(*hfItr);
00069 
00070    }
00071 
00072    for(SumMap::iterator mapItr = theSumMap.begin(); mapItr != theSumMap.end(); ++mapItr) {
00073       result.push_back(HcalTriggerPrimitiveDigi(mapItr->first));
00074       HcalTrigTowerDetId detId(mapItr->second.id());
00075       if(detId.ietaAbs() >= theTrigTowerGeometry->firstHFTower())
00076          { analyzeHF(mapItr->second, result.back(), rctlsb);}
00077          else{analyze(mapItr->second, result.back());}
00078    }
00079    return;
00080 }
00081 
00082 
00083 void HcalTriggerPrimitiveAlgo::addSignal(const HBHEDataFrame & frame) {
00084    //Hack for 300_pre10, should be removed.
00085    if (frame.id().depth()==5) return;
00086 
00087    std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
00088    assert(ids.size() == 1 || ids.size() == 2);
00089    IntegerCaloSamples samples1(ids[0], int(frame.size()));
00090 
00091    samples1.setPresamples(frame.presamples());
00092    incoder_->adc2Linear(frame, samples1);
00093 
00094    std::vector<bool> msb;
00095    incoder_->lookupMSB(frame, msb);
00096 
00097    if(ids.size() == 2) {
00098       // make a second trigprim for the other one, and split the energy
00099       IntegerCaloSamples samples2(ids[1], samples1.size());
00100       for(int i = 0; i < samples1.size(); ++i) {
00101          samples1[i] = uint32_t(samples1[i]*0.5);
00102          samples2[i] = samples1[i];
00103       }
00104       samples2.setPresamples(frame.presamples());
00105       addSignal(samples2);
00106       addFG(ids[1], msb);
00107    }
00108    addSignal(samples1);
00109    addFG(ids[0], msb);
00110 }
00111 
00112 
00113 void HcalTriggerPrimitiveAlgo::addSignal(const HFDataFrame & frame) {
00114 
00115    if(frame.id().depth() == 1 || frame.id().depth() == 2) {
00116       std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(frame.id());
00117       assert(ids.size() == 1);
00118       IntegerCaloSamples samples(ids[0], frame.size());
00119       samples.setPresamples(frame.presamples());
00120       incoder_->adc2Linear(frame, samples);
00121 
00122       // Don't add to final collection yet
00123       // HF PMT veto sum is calculated in analyzerHF()
00124       IntegerCaloSamples zero_samples(ids[0], frame.size());
00125       zero_samples.setPresamples(frame.presamples());
00126       addSignal(zero_samples);
00127 
00128       // Mask off depths: fgid is the same for both depths
00129       uint32_t fgid = (frame.id().rawId() | 0x1c000) ;
00130 
00131       if ( theTowerMapFGSum.find(ids[0]) == theTowerMapFGSum.end() ) {
00132          SumFGContainer sumFG;
00133          theTowerMapFGSum.insert(std::pair<HcalTrigTowerDetId, SumFGContainer >(ids[0], sumFG));
00134       }
00135 
00136       SumFGContainer& sumFG = theTowerMapFGSum[ids[0]];
00137       SumFGContainer::iterator sumFGItr;
00138       for ( sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
00139          if (sumFGItr->id() == fgid) break;
00140       }
00141       // If find
00142       if (sumFGItr != sumFG.end()) {
00143          for (int i=0; i<samples.size(); ++i) (*sumFGItr)[i] += samples[i];
00144       }
00145       else {
00146          //Copy samples (change to fgid)
00147          IntegerCaloSamples sumFGSamples(DetId(fgid), samples.size());
00148          sumFGSamples.setPresamples(samples.presamples());
00149          for (int i=0; i<samples.size(); ++i) sumFGSamples[i] = samples[i];
00150          sumFG.push_back(sumFGSamples);
00151       }
00152 
00153       // set veto to true if Long or Short less than threshold
00154       if (HF_Veto.find(fgid) == HF_Veto.end()) {
00155          vector<bool> vetoBits(samples.size(), false);
00156          HF_Veto[fgid] = vetoBits;
00157       }
00158       for (int i=0; i<samples.size(); ++i)
00159          if (samples[i] < minSignalThreshold_)
00160             HF_Veto[fgid][i] = true;
00161    }
00162 }
00163 
00164 
00165 void HcalTriggerPrimitiveAlgo::addSignal(const IntegerCaloSamples & samples) {
00166    HcalTrigTowerDetId id(samples.id());
00167    SumMap::iterator itr = theSumMap.find(id);
00168    if(itr == theSumMap.end()) {
00169       theSumMap.insert(std::make_pair(id, samples));
00170    }
00171    else {
00172       // wish CaloSamples had a +=
00173       for(int i = 0; i < samples.size(); ++i) {
00174          (itr->second)[i] += samples[i];
00175       }
00176    }
00177 }
00178 
00179 
00180 void HcalTriggerPrimitiveAlgo::analyze(IntegerCaloSamples & samples, HcalTriggerPrimitiveDigi & result) {
00181    int shrink = weights_.size() - 1;
00182    std::vector<bool> finegrain(numberOfSamples_,false);
00183    std::vector<bool>& msb = fgMap_[samples.id()];
00184    IntegerCaloSamples sum(samples.id(), samples.size());
00185 
00186    //slide algo window
00187    for(int ibin = 0; ibin < int(samples.size())- shrink; ++ibin) {
00188       int algosumvalue = 0;
00189       for(unsigned int i = 0; i < weights_.size(); i++) {
00190          //add up value * scale factor
00191          algosumvalue += int(samples[ibin+i] * weights_[i]);
00192       }
00193       if (algosumvalue<0) sum[ibin]=0;            // low-side
00194                                                   //high-side
00195       //else if (algosumvalue>0x3FF) sum[ibin]=0x3FF;
00196       else sum[ibin] = algosumvalue;              //assign value to sum[]
00197    }
00198 
00199    IntegerCaloSamples output(samples.id(), numberOfSamples_);
00200    output.setPresamples(numberOfPresamples_);
00201 
00202    // Align digis and TP
00203    int shift = samples.presamples() - numberOfPresamples_;
00204    if (peakfind_) {
00205       assert (shift >= (peakfind_ ? shrink : 0));
00206       assert(shift + numberOfSamples_ + shrink <= samples.size() - (peak_finder_algorithm_ - 1));
00207    }
00208 
00209 
00210    for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00211       // ibin - index for output TP
00212       // idx - index for samples + shift
00213       int idx = ibin + shift;
00214 
00215       //Peak finding
00216       if (peakfind_) {
00217          bool isPeak = false;
00218          switch (peak_finder_algorithm_) {
00219             case 1 :
00220                isPeak = (samples[idx] > samples[idx-1] && samples[idx] >= samples[idx+1] && samples[idx] > theThreshold);
00221                break;
00222             case 2:
00223                isPeak = (sum[idx] > sum[idx-1] && sum[idx] >= sum[idx+1] && sum[idx] > theThreshold);
00224                break;
00225             default:
00226                break;
00227          }
00228 
00229          if (isPeak){
00230             output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00231             finegrain[ibin] = msb[idx];
00232          }
00233          // Not a peak
00234          else output[ibin] = 0;
00235       }
00236       else { // No peak finding, just output running sum
00237          output[ibin] = std::min<unsigned int>(sum[idx],0x3FF);
00238          finegrain[ibin] = msb[idx];
00239       }
00240 
00241       // Only Pegged for 1-TS algo.
00242       if (peak_finder_algorithm_ == 1) {
00243          if (samples[idx] >= 0x3FF)
00244             output[ibin] = 0x3FF;
00245       }
00246       outcoder_->compress(output, finegrain, result);
00247    }
00248 }
00249 
00250 
00251 void HcalTriggerPrimitiveAlgo::analyzeHF(IntegerCaloSamples & samples, HcalTriggerPrimitiveDigi & result, float rctlsb) {
00252    std::vector<bool> finegrain(numberOfSamples_, false);
00253    HcalTrigTowerDetId detId(samples.id());
00254 
00255    // Align digis and TP
00256    int shift = samples.presamples() - numberOfPresamples_;
00257    assert(shift >=  0);
00258    assert((shift + numberOfSamples_) <=  samples.size());
00259 
00260    TowerMapFGSum::const_iterator tower2fg = theTowerMapFGSum.find(detId);
00261    assert(tower2fg != theTowerMapFGSum.end());
00262 
00263    const SumFGContainer& sumFG = tower2fg->second;
00264    // Loop over all L+S pairs that mapped from samples.id()
00265    // Note: 1 samples.id() = 6 x (L+S) without noZS
00266    for (SumFGContainer::const_iterator sumFGItr = sumFG.begin(); sumFGItr != sumFG.end(); ++sumFGItr) {
00267       const std::vector<bool>& veto = HF_Veto[sumFGItr->id().rawId()];
00268       for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00269          int idx = ibin + shift;
00270          // if not vetod, add L+S to total sum and calculate FG
00271          if (!(veto[idx] && (*sumFGItr)[idx] > PMT_NoiseThreshold_)) {
00272             samples[idx] += (*sumFGItr)[idx];
00273             finegrain[ibin] = (finegrain[ibin] || (*sumFGItr)[idx] >= FG_threshold_);
00274          }
00275       }
00276    }
00277 
00278    IntegerCaloSamples output(samples.id(), numberOfSamples_);
00279    output.setPresamples(numberOfPresamples_);
00280 
00281    for (int ibin = 0; ibin < numberOfSamples_; ++ibin) {
00282       int idx = ibin + shift;
00283       output[ibin] = samples[idx] / (rctlsb == 0.25 ? 4 : 8);
00284       if (output[ibin] > 0x3FF) output[ibin] = 0x3FF;
00285    }
00286    outcoder_->compress(output, finegrain, result);
00287 }
00288 
00289 void HcalTriggerPrimitiveAlgo::runZS(HcalTrigPrimDigiCollection & result){
00290    for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
00291       bool ZS = true;
00292       for (int i=0; i<tp->size(); ++i) {
00293          if (tp->sample(i).compressedEt()  > ZS_threshold_I_) {
00294             ZS=false;
00295             break;
00296          }
00297       }
00298       if (ZS) tp->setZSInfo(false,true);
00299       else tp->setZSInfo(true,false);
00300    }
00301 }
00302 
00303 void HcalTriggerPrimitiveAlgo::runFEFormatError(const FEDRawDataCollection* rawraw,
00304                                                 const HcalElectronicsMap *emap,
00305                                                 HcalTrigPrimDigiCollection & result
00306                                                 ){
00307   std::set<uint32_t> FrontEndErrors;
00308 
00309   for(int i=FEDNumbering::MINHCALFEDID; i<=FEDNumbering::MAXHCALFEDID; ++i) {
00310     const FEDRawData& raw = rawraw->FEDData(i);
00311     if (raw.size()<12) continue;
00312     const HcalDCCHeader* dccHeader=(const HcalDCCHeader*)(raw.data());
00313     if(!dccHeader) continue;
00314     HcalHTRData htr;
00315     for (int spigot=0; spigot<HcalDCCHeader::SPIGOT_COUNT; spigot++) {
00316       if (!dccHeader->getSpigotPresent(spigot)) continue;
00317       dccHeader->getSpigotData(spigot,htr,raw.size());
00318       int dccid = dccHeader->getSourceId();
00319       int errWord = htr.getErrorsWord() & 0x1FFFF;
00320       bool HTRError = (!htr.check() || htr.isHistogramEvent() || (errWord & 0x800)!=0);
00321 
00322       if(HTRError) {
00323         bool valid =false;
00324         for(int fchan=0; fchan<3 && !valid; fchan++) {
00325           for(int fib=0; fib<9 && !valid; fib++) {
00326             HcalElectronicsId eid(fchan,fib,spigot,dccid-FEDNumbering::MINHCALFEDID);
00327             eid.setHTR(htr.readoutVMECrateId(),htr.htrSlot(),htr.htrTopBottom());
00328             DetId detId = emap->lookup(eid);
00329             if(detId.null()) continue;
00330             HcalSubdetector subdet=(HcalSubdetector(detId.subdetId()));
00331             if (detId.det()!=4||
00332               (subdet!=HcalBarrel && subdet!=HcalEndcap &&
00333               subdet!=HcalForward )) continue;
00334             std::vector<HcalTrigTowerDetId> ids = theTrigTowerGeometry->towerIds(detId);
00335             for (std::vector<HcalTrigTowerDetId>::const_iterator triggerId=ids.begin(); triggerId != ids.end(); ++triggerId) {
00336               FrontEndErrors.insert(triggerId->rawId());
00337             }
00338             //valid = true;
00339           }
00340         }
00341       }
00342     }
00343   }
00344 
00345   // Loop over TP collection
00346   // Set TP to zero if there is FE Format Error
00347   HcalTriggerPrimitiveSample zeroSample(0);
00348   for (HcalTrigPrimDigiCollection::iterator tp = result.begin(); tp != result.end(); ++tp){
00349     if (FrontEndErrors.find(tp->id().rawId()) != FrontEndErrors.end()) {
00350       for (int i=0; i<tp->size(); ++i) tp->setSample(i, zeroSample);
00351     }
00352   }
00353 }
00354 
00355 void HcalTriggerPrimitiveAlgo::addFG(const HcalTrigTowerDetId& id, std::vector<bool>& msb){
00356    FGbitMap::iterator itr = fgMap_.find(id);
00357    if (itr != fgMap_.end()){
00358       std::vector<bool>& _msb = itr->second;
00359       for (size_t i=0; i<msb.size(); ++i)
00360          _msb[i] = _msb[i] || msb[i];
00361    }
00362    else fgMap_[id] = msb;
00363 }
00364 
00365 void HcalTriggerPrimitiveAlgo::setPeakFinderAlgorithm(int algo){
00366    if (algo <=0 && algo>2)
00367       throw cms::Exception("ERROR: Only algo 1 & 2 are supported.") << std::endl;
00368    peak_finder_algorithm_ = algo;
00369 }