CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_6_1_1/src/CalibCalorimetry/HcalTPGAlgos/src/HcaluLUTTPGCoder.cc

Go to the documentation of this file.
00001 #include <iostream>
00002 #include <fstream>
00003 #include <cmath>
00004 #include <string>
00005 #include "CalibCalorimetry/HcalTPGAlgos/interface/HcaluLUTTPGCoder.h"
00006 #include "Geometry/HcalTowerAlgo/src/HcalHardcodeGeometryData.h"
00007 #include "CalibFormats/HcalObjects/interface/HcalCoderDb.h"
00008 #include "CalibFormats/HcalObjects/interface/HcalCalibrations.h"
00009 #include "CalibFormats/HcalObjects/interface/HcalDbService.h"
00010 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
00011 #include "Geometry/Records/interface/IdealGeometryRecord.h"
00012 #include "Geometry/CaloGeometry/interface/CaloGeometry.h"
00013 #include "FWCore/Framework/interface/ESHandle.h"
00014 #include "FWCore/Utilities/interface/Exception.h"
00015 #include "FWCore/MessageLogger/interface/MessageLogger.h"
00016 #include "FWCore/Framework/interface/Event.h"
00017 #include "FWCore/Framework/interface/EventSetup.h"
00018 #include "FWCore/Framework/interface/Frameworkfwd.h"
00019 #include "FWCore/Framework/interface/MakerMacros.h"
00020 #include "FWCore/ParameterSet/interface/ParameterSet.h"
00021 #include "CalibCalorimetry/CaloTPG/src/CaloTPGTranscoderULUT.h"
00022 #include "CondFormats/HcalObjects/interface/HcalL1TriggerObjects.h"
00023 #include "CondFormats/HcalObjects/interface/HcalL1TriggerObject.h"
00024 #include "CalibCalorimetry/HcalAlgos/interface/HcalDbASCIIIO.h"
00025 #include "CalibCalorimetry/HcalTPGAlgos/interface/XMLProcessor.h"
00026 #include "CalibCalorimetry/HcalTPGAlgos/interface/LutXml.h"
00027 
00028 const float HcaluLUTTPGCoder::lsb_=1./16;
00029 
00030 HcaluLUTTPGCoder::HcaluLUTTPGCoder() : LUTGenerationMode_(true), bitToMask_(0),
00031                                        inputLUT_(nluts, Lut(INPUT_LUT_SIZE, 0)),
00032                                        gain_(nluts, 0.), ped_ (nluts, 0.){
00033 }
00034 
00035 void HcaluLUTTPGCoder::compress(const IntegerCaloSamples& ics, const std::vector<bool>& featureBits, HcalTriggerPrimitiveDigi& tp) const {
00036    throw cms::Exception("PROBLEM: This method should never be invoked!");
00037 }
00038 
00039 HcaluLUTTPGCoder::~HcaluLUTTPGCoder() {
00040 }
00041 
00042 int HcaluLUTTPGCoder::getLUTId(HcalSubdetector id, int ieta, int iphi, int depth) const {
00043    int detid = 0;
00044    if (id == HcalEndcap) detid = 1;
00045    else if (id == HcalForward) detid = 2;
00046    return iphi + 72 * ((ieta + 41) + 83 * (depth + 3 * detid)) - 7777;
00047 }
00048 
00049 int HcaluLUTTPGCoder::getLUTId(uint32_t rawid) const {
00050    HcalDetId detid(rawid);
00051    return getLUTId(detid.subdet(), detid.ieta(), detid.iphi(), detid.depth());
00052 }
00053 
00054 int HcaluLUTTPGCoder::getLUTId(const HcalDetId& detid) const {
00055    return getLUTId(detid.subdet(), detid.ieta(), detid.iphi(), detid.depth());
00056 }
00057 
00058 void HcaluLUTTPGCoder::update(const char* filename, const HcalTopology& theTopo, bool appendMSB){
00059 
00060    std::ifstream file(filename, std::ios::in);
00061    assert(file.is_open());
00062 
00063    std::vector<HcalSubdetector> subdet;
00064    std::string buffer;
00065 
00066    // Drop first (comment) line
00067    std::getline(file, buffer);
00068    std::getline(file, buffer);
00069 
00070    unsigned int index = buffer.find("H", 0);
00071    while (index < buffer.length()){
00072       std::string subdetStr = buffer.substr(index, 2);
00073       if (subdetStr == "HB") subdet.push_back(HcalBarrel);
00074       else if (subdetStr == "HE") subdet.push_back(HcalEndcap);
00075       else if (subdetStr == "HF") subdet.push_back(HcalForward);
00076       //TODO Check subdet
00077       //else exception
00078       index += 2;
00079       index = buffer.find("H", index);
00080    }
00081 
00082    // Get upper/lower ranges for ieta/iphi/depth
00083    size_t nCol = subdet.size();
00084    assert(nCol > 0);
00085 
00086    std::vector<int> ietaU;
00087    std::vector<int> ietaL;
00088    std::vector<int> iphiU;
00089    std::vector<int> iphiL;
00090    std::vector<int> depU;
00091    std::vector<int> depL;
00092    std::vector< Lut > lutFromFile(nCol);
00093    LutElement lutValue;
00094 
00095    for (size_t i=0; i<nCol; ++i) {
00096       int ieta;
00097       file >> ieta;
00098       ietaL.push_back(ieta);
00099    }
00100 
00101    for (size_t i=0; i<nCol; ++i) {
00102       int ieta;
00103       file >> ieta;
00104       ietaU.push_back(ieta);
00105    }
00106 
00107    for (size_t i=0; i<nCol; ++i) {
00108       int iphi;
00109       file >> iphi;
00110       iphiL.push_back(iphi);
00111    }
00112 
00113    for (size_t i=0; i<nCol; ++i) {
00114       int iphi;
00115       file >> iphi;
00116       iphiU.push_back(iphi);
00117    }
00118 
00119    for (size_t i=0; i<nCol; ++i) {
00120       int dep;
00121       file >> dep;
00122       depL.push_back(dep);
00123    }
00124 
00125    for (size_t i=0; i<nCol; ++i) {
00126       int dep;
00127       file >> dep;
00128       depU.push_back(dep);
00129    }
00130 
00131    // Read Lut Entry
00132    for (size_t i=0; file >> lutValue; i = (i+1) % nCol){
00133       lutFromFile[i].push_back(lutValue);
00134    }
00135 
00136    // Check lut size
00137    for (size_t i=0; i<nCol; ++i) assert(lutFromFile[i].size() == INPUT_LUT_SIZE);
00138 
00139    for (size_t i=0; i<nCol; ++i){
00140       for (int ieta = ietaL[i]; ieta <= ietaU[i]; ++ieta){
00141          for (int iphi = iphiL[i]; iphi <= iphiU[i]; ++iphi){
00142             for (int depth = depL[i]; depth <= depU[i]; ++depth){
00143               
00144                HcalDetId id(subdet[i], ieta, iphi, depth);
00145                if (!theTopo.valid(id)) continue;
00146 
00147                int lutId = getLUTId(id);
00148                for (size_t adc = 0; adc < INPUT_LUT_SIZE; ++adc){
00149                   if (appendMSB){
00150                      // Append FG bit LUT to MSB
00151                      // MSB = Most Significant Bit = bit 10
00152                      // Overwrite bit 10
00153                      LutElement msb = (lutFromFile[i][adc] != 0 ? 0x400 : 0);
00154                      inputLUT_[lutId][adc] = (msb | (inputLUT_[lutId][adc] & 0x3FF));
00155                   }
00156                   else inputLUT_[lutId][adc] = lutFromFile[i][adc];
00157                }// for adc
00158             }// for depth
00159          }// for iphi
00160       }// for ieta
00161    }// for nCol
00162 }
00163 
00164 void HcaluLUTTPGCoder::updateXML(const char* filename, const HcalTopology& theTopo) {
00165    LutXml * _xml = new LutXml(filename);
00166    _xml->create_lut_map();
00167    HcalSubdetector subdet[3] = {HcalBarrel, HcalEndcap, HcalForward};
00168    for (int ieta=-41; ieta<=41; ++ieta){
00169       for (int iphi=1; iphi<=72; ++iphi){
00170          for (int depth=1; depth<=3; ++depth){
00171             for (int isub=0; isub<3; ++isub){
00172                HcalDetId detid(subdet[isub], ieta, iphi, depth);
00173                if (!theTopo.valid(detid)) continue;
00174                int id = getLUTId(subdet[isub], ieta, iphi, depth);
00175                std::vector<unsigned int>* lut = _xml->getLutFast(detid);
00176                if (lut==0) throw cms::Exception("PROBLEM: No inputLUT_ in xml file for ") << detid << std::endl;
00177                if (lut->size()!=128) throw cms::Exception ("PROBLEM: Wrong inputLUT_ size in xml file for ") << detid << std::endl;
00178                for (int i=0; i<128; ++i) inputLUT_[id][i] = (LutElement)lut->at(i);
00179             }
00180          }
00181       }
00182    }
00183    delete _xml;
00184    XMLProcessor::getInstance()->terminate();
00185 }
00186 
00187 void HcaluLUTTPGCoder::update(const HcalDbService& conditions) {
00188 
00189    HcalCalibrations calibrations;
00190    const HcalLutMetadata *metadata = conditions.getHcalLutMetadata();
00191    assert(metadata !=0);
00192    float nominalgain_ = metadata->getNominalGain();
00193 
00194    std::map<int, float> cosh_ieta;
00195    for (int i = 0; i < 13; ++i)
00196       cosh_ieta[i+29] = cosh((theHFEtaBounds[i+1] + theHFEtaBounds[i])/2.);
00197 
00198    HcalSubdetector subdets[] = {HcalBarrel, HcalEndcap, HcalForward};
00199    for (int isub = 0; isub < 3; ++isub){
00200       HcalSubdetector subdet = subdets[isub];
00201       for (int ieta = -41; ieta <= 41; ++ieta){
00202          for (int iphi = 1; iphi <= 72; ++iphi){
00203             for (int depth = 1; depth <= 3; ++depth){
00204                HcalDetId cell(subdet, ieta, iphi, depth);
00205                if (!metadata->topo()->valid(cell)) continue;
00206 
00207                const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
00208                const HcalQIEShape* shape = conditions.getHcalShape(cell);
00209                HcalCoderDb coder (*channelCoder, *shape);
00210                const HcalLutMetadatum *meta = metadata->getValues(cell);
00211 
00212 
00213                int lutId = getLUTId(subdet, ieta, iphi, depth);
00214                float ped = 0;
00215                float gain = 0;
00216                uint32_t status = 0;
00217 
00218                if (LUTGenerationMode_){
00219                   const HcalCalibrations& calibrations = conditions.getHcalCalibrations(cell);
00220                   for (int capId = 0; capId < 4; ++capId){
00221                      ped += calibrations.pedestal(capId);
00222                      gain += calibrations.LUTrespcorrgain(capId);
00223                   }
00224                   ped /= 4.0;
00225                   gain /= 4.0;
00226 
00227                   //Get Channel Quality
00228                   const HcalChannelStatus* channelStatus = conditions.getHcalChannelStatus(cell);
00229                   status = channelStatus->getValue();
00230                }
00231                else {
00232                   const HcalL1TriggerObject* myL1TObj = conditions.getHcalL1TriggerObject(cell);
00233                   ped = myL1TObj->getPedestal();
00234                   gain = myL1TObj->getRespGain();
00235                   status = myL1TObj->getFlag();
00236                } // LUTGenerationMode_
00237 
00238                ped_[lutId] = ped;
00239                gain_[lutId] = gain;
00240                bool isMasked = ( (status & bitToMask_) > 0 );
00241                float rcalib = meta->getRCalib();
00242 
00243                // Input LUT for HB/HE/HF
00244                if (subdet == HcalBarrel || subdet == HcalEndcap){
00245                   HBHEDataFrame frame(cell);
00246                   frame.setSize(1);
00247                   CaloSamples samples(cell, 1);
00248 
00249                   int granularity = meta->getLutGranularity();
00250 
00251                   for (int adc = 0; adc <= 0x7F; ++adc) {
00252                      frame.setSample(0,HcalQIESample(adc));
00253                      coder.adc2fC(frame,samples);
00254                      float adc2fC = samples[0];
00255 
00256                      if (isMasked) inputLUT_[lutId][adc] = 0;
00257                      else inputLUT_[lutId][adc] = (LutElement) std::min(std::max(0, int((adc2fC -ped) * gain * rcalib / nominalgain_ / granularity)), 0x3FF);
00258                   }
00259                }  // endif HBHE
00260                else if (subdet == HcalForward){
00261                   HFDataFrame frame(cell);
00262                   frame.setSize(1);
00263                   CaloSamples samples(cell, 1);
00264 
00265                   float one_adc2fC = 0.0;
00266                   for (int capId = 0; capId < 4; ++capId)
00267                      one_adc2fC += channelCoder->charge(*shape, 1, capId) - channelCoder->charge(*shape, 0, capId);
00268                   one_adc2fC /= 4.0;
00269                   // Lumi offset of 1 adc (in fC) for the four rings used to measure lumi
00270                   float offset = (abs(ieta) >= 33 && abs(ieta) <= 36) ? one_adc2fC : 0; 
00271                   
00272                   for (int adc = 0; adc <= 0x7F; ++adc) {
00273                      frame.setSample(0,HcalQIESample(adc));
00274                      coder.adc2fC(frame,samples);
00275                      float adc2fC = samples[0];
00276                      if (isMasked) inputLUT_[lutId][adc] = 0;
00277                      else inputLUT_[lutId][adc] = std::min(std::max(0,int((adc2fC - ped + offset) * gain * rcalib / lsb_ / cosh_ieta[abs(ieta)] )), 0x3FF);
00278                   }
00279                } // endif HF
00280             } // for depth
00281          } // for iphi
00282       } // for iphi
00283    }// for subdet
00284 }
00285 
00286 void HcaluLUTTPGCoder::adc2Linear(const HBHEDataFrame& df, IntegerCaloSamples& ics) const {
00287    int lutId = getLUTId(df.id());
00288    const Lut& lut = inputLUT_.at(lutId);
00289    for (int i=0; i<df.size(); i++){
00290       ics[i] = (lut.at(df[i].adc()) & 0x3FF);
00291    }
00292 }
00293 
00294 void HcaluLUTTPGCoder::adc2Linear(const HFDataFrame& df, IntegerCaloSamples& ics) const {
00295    int lutId = getLUTId(df.id());
00296    const Lut& lut = inputLUT_.at(lutId);
00297    for (int i=0; i<df.size(); i++){
00298       ics[i] = (lut.at(df[i].adc()) & 0x3FF);
00299    }
00300 }
00301 
00302 unsigned short HcaluLUTTPGCoder::adc2Linear(HcalQIESample sample, HcalDetId id) const {
00303    int lutId = getLUTId(id);
00304    return ((inputLUT_.at(lutId)).at(sample.adc()) & 0x3FF);
00305 }
00306 
00307 float HcaluLUTTPGCoder::getLUTPedestal(HcalDetId id) const {
00308    int lutId = getLUTId(id);
00309    return ped_.at(lutId);
00310 }
00311 
00312 float HcaluLUTTPGCoder::getLUTGain(HcalDetId id) const {
00313    int lutId = getLUTId(id);
00314    return gain_.at(lutId);
00315 }
00316 
00317 std::vector<unsigned short> HcaluLUTTPGCoder::getLinearizationLUTWithMSB(const HcalDetId& id) const{
00318    int lutId = getLUTId(id);
00319    return inputLUT_.at(lutId);
00320 }
00321 
00322 void HcaluLUTTPGCoder::lookupMSB(const HBHEDataFrame& df, std::vector<bool>& msb) const{
00323    msb.resize(df.size());
00324    for (int i=0; i<df.size(); ++i)
00325       msb[i] = getMSB(df.id(), df.sample(i).adc());
00326 }
00327 
00328 bool HcaluLUTTPGCoder::getMSB(const HcalDetId& id, int adc) const{
00329    int lutId = getLUTId(id);
00330    const Lut& lut = inputLUT_.at(lutId);
00331    return (lut.at(adc) & 0x400);
00332 }