CMS 3D CMS Logo

/data/doxygen/doxygen-1.7.3/gen/CMSSW_4_2_8/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, 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    std::vector<int> ietaU;
00085    std::vector<int> ietaL;
00086    std::vector<int> iphiU;
00087    std::vector<int> iphiL;
00088    std::vector<int> depU;
00089    std::vector<int> depL;
00090    std::vector< Lut > lutFromFile(nCol);
00091    LutElement lutValue;
00092 
00093    for (size_t i=0; i<nCol; ++i) {
00094       int ieta;
00095       file >> ieta;
00096       ietaL.push_back(ieta);
00097    }
00098 
00099    for (size_t i=0; i<nCol; ++i) {
00100       int ieta;
00101       file >> ieta;
00102       ietaU.push_back(ieta);
00103    }
00104 
00105    for (size_t i=0; i<nCol; ++i) {
00106       int iphi;
00107       file >> iphi;
00108       iphiL.push_back(iphi);
00109    }
00110 
00111    for (size_t i=0; i<nCol; ++i) {
00112       int iphi;
00113       file >> iphi;
00114       iphiU.push_back(iphi);
00115    }
00116 
00117    for (size_t i=0; i<nCol; ++i) {
00118       int dep;
00119       file >> dep;
00120       depL.push_back(dep);
00121    }
00122 
00123    for (size_t i=0; i<nCol; ++i) {
00124       int dep;
00125       file >> dep;
00126       depU.push_back(dep);
00127    }
00128 
00129    // Read Lut Entry
00130    for (size_t i=0; file >> lutValue; i = (i+1) % nCol){
00131       lutFromFile[i].push_back(lutValue);
00132    }
00133 
00134    // Check lut size
00135    for (size_t i=0; i<nCol; ++i) assert(lutFromFile[i].size() == INPUT_LUT_SIZE);
00136 
00137    for (size_t i=0; i<nCol; ++i){
00138       for (int ieta = ietaL[i]; ieta <= ietaU[i]; ++ieta){
00139          for (int iphi = iphiL[i]; iphi <= iphiU[i]; ++iphi){
00140             for (int depth = depL[i]; depth <= depU[i]; ++depth){
00141                if (!HcalDetId::validDetId(subdet[i], ieta, iphi, depth)) continue;
00142                HcalDetId id(subdet[i], ieta, iphi, depth);
00143                int lutId = getLUTId(id);
00144                for (size_t adc = 0; adc < INPUT_LUT_SIZE; ++adc){
00145                   if (appendMSB){
00146                      // Append FG bit LUT to MSB
00147                      // MSB = Most Significant Bit = bit 10
00148                      // Overwrite bit 10
00149                      LutElement msb = (lutFromFile[i][adc] != 0 ? 0x400 : 0);
00150                      inputLUT_[lutId][adc] = (msb | (inputLUT_[lutId][adc] & 0x3FF));
00151                   }
00152                   else inputLUT_[lutId][adc] = lutFromFile[i][adc];
00153                }// for adc
00154             }// for depth
00155          }// for iphi
00156       }// for ieta
00157    }// for nCol
00158 }
00159 
00160 void HcaluLUTTPGCoder::updateXML(const char* filename) {
00161    HcalTopology theTopo;
00162    LutXml * _xml = new LutXml(filename);
00163    _xml->create_lut_map();
00164    HcalSubdetector subdet[3] = {HcalBarrel, HcalEndcap, HcalForward};
00165    for (int ieta=-41; ieta<=41; ++ieta){
00166       for (int iphi=1; iphi<=72; ++iphi){
00167          for (int depth=1; depth<=3; ++depth){
00168             for (int isub=0; isub<3; ++isub){
00169                HcalDetId detid(subdet[isub], ieta, iphi, depth);
00170                if (!theTopo.valid(detid)) continue;
00171                int id = getLUTId(subdet[isub], ieta, iphi, depth);
00172                std::vector<unsigned int>* lut = _xml->getLutFast(detid);
00173                if (lut==0) throw cms::Exception("PROBLEM: No inputLUT_ in xml file for ") << detid << std::endl;
00174                if (lut->size()!=128) throw cms::Exception ("PROBLEM: Wrong inputLUT_ size in xml file for ") << detid << std::endl;
00175                for (int i=0; i<128; ++i) inputLUT_[id][i] = (LutElement)lut->at(i);
00176             }
00177          }
00178       }
00179    }
00180    delete _xml;
00181    XMLProcessor::getInstance()->terminate();
00182 }
00183 
00184 void HcaluLUTTPGCoder::update(const HcalDbService& conditions) {
00185 
00186    const HcalQIEShape* shape = conditions.getHcalShape();
00187    HcalCalibrations calibrations;
00188    const HcalLutMetadata *metadata = conditions.getHcalLutMetadata();
00189    assert(metadata !=0);
00190    float nominalgain_ = metadata->getNominalGain();
00191 
00192    std::map<int, float> cosh_ieta;
00193    for (int i = 0; i < 13; ++i)
00194       cosh_ieta[i+29] = cosh((theHFEtaBounds[i+1] + theHFEtaBounds[i])/2.);
00195 
00196    HcalSubdetector subdets[] = {HcalBarrel, HcalEndcap, HcalForward};
00197    for (int isub = 0; isub < 3; ++isub){
00198       HcalSubdetector subdet = subdets[isub];
00199       for (int ieta = -41; ieta <= 41; ++ieta){
00200          for (int iphi = 1; iphi <= 72; ++iphi){
00201             for (int depth = 1; depth <= 3; ++depth){
00202                if (!HcalDetId::validDetId(subdet, ieta, iphi, depth)) continue;
00203 
00204                HcalDetId cell(subdet, ieta, iphi, depth);
00205                const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
00206                HcalCoderDb coder (*channelCoder, *shape);
00207                const HcalLutMetadatum *meta = metadata->getValues(cell);
00208 
00209 
00210                int lutId = getLUTId(subdet, ieta, iphi, depth);
00211                float ped = 0;
00212                float gain = 0;
00213                uint32_t status = 0;
00214 
00215                if (LUTGenerationMode_){
00216                   const HcalCalibrations& calibrations = conditions.getHcalCalibrations(cell);
00217                   for (int capId = 0; capId < 4; ++capId){
00218                      ped += calibrations.pedestal(capId);
00219                      gain += calibrations.LUTrespcorrgain(capId);
00220                   }
00221                   ped /= 4.0;
00222                   gain /= 4.0;
00223 
00224                   //Get Channel Quality
00225                   const HcalChannelStatus* channelStatus = conditions.getHcalChannelStatus(cell);
00226                   status = channelStatus->getValue();
00227                }
00228                else {
00229                   const HcalL1TriggerObject* myL1TObj = conditions.getHcalL1TriggerObject(cell);
00230                   ped = myL1TObj->getPedestal();
00231                   gain = myL1TObj->getRespGain();
00232                   status = myL1TObj->getFlag();
00233                } // LUTGenerationMode_
00234 
00235                ped_[lutId] = ped;
00236                gain_[lutId] = gain;
00237                bool isMasked = ( (status & bitToMask_) > 0 );
00238                float rcalib = meta->getRCalib();
00239 
00240                // Input LUT for HB/HE/HF
00241                if (subdet == HcalBarrel || subdet == HcalEndcap){
00242                   HBHEDataFrame frame(cell);
00243                   frame.setSize(1);
00244                   CaloSamples samples(cell, 1);
00245 
00246                   int granularity = meta->getLutGranularity();
00247 
00248                   for (int adc = 0; adc <= 0x7F; ++adc) {
00249                      frame.setSample(0,HcalQIESample(adc));
00250                      coder.adc2fC(frame,samples);
00251                      float adc2fC = samples[0];
00252 
00253                      if (isMasked) inputLUT_[lutId][adc] = 0;
00254                      else inputLUT_[lutId][adc] = (LutElement) std::min(std::max(0, int((adc2fC -ped) * gain * rcalib / nominalgain_ / granularity)), 0x3FF);
00255                   }
00256                }  // endif HBHE
00257                else if (subdet == HcalForward){
00258                   HFDataFrame frame(cell);
00259                   frame.setSize(1);
00260                   CaloSamples samples(cell, 1);
00261 
00262                   float one_adc2fC = 0.0;
00263                   for (int capId = 0; capId < 4; ++capId)
00264                      one_adc2fC += channelCoder->charge(*shape, 1, capId) - channelCoder->charge(*shape, 0, capId);
00265                   one_adc2fC /= 4.0;
00266                   // Lumi offset of 1 adc (in fC) for the four rings used to measure lumi
00267                   float offset = (abs(ieta) >= 33 && abs(ieta) <= 36) ? one_adc2fC : 0; 
00268                   
00269                   for (int adc = 0; adc <= 0x7F; ++adc) {
00270                      frame.setSample(0,HcalQIESample(adc));
00271                      coder.adc2fC(frame,samples);
00272                      float adc2fC = samples[0];
00273                      if (isMasked) inputLUT_[lutId][adc] = 0;
00274                      else inputLUT_[lutId][adc] = std::min(std::max(0,int((adc2fC - ped + offset) * gain * rcalib / lsb_ / cosh_ieta[abs(ieta)] )), 0x3FF);
00275                   }
00276                } // endif HF
00277             } // for depth
00278          } // for iphi
00279       } // for iphi
00280    }// for subdet
00281 }
00282 
00283 void HcaluLUTTPGCoder::adc2Linear(const HBHEDataFrame& df, IntegerCaloSamples& ics) const {
00284    int lutId = getLUTId(df.id());
00285    const Lut& lut = inputLUT_.at(lutId);
00286    for (int i=0; i<df.size(); i++){
00287       ics[i] = (lut.at(df[i].adc()) & 0x3FF);
00288    }
00289 }
00290 
00291 void HcaluLUTTPGCoder::adc2Linear(const HFDataFrame& df, IntegerCaloSamples& ics) const {
00292    int lutId = getLUTId(df.id());
00293    const Lut& lut = inputLUT_.at(lutId);
00294    for (int i=0; i<df.size(); i++){
00295       ics[i] = (lut.at(df[i].adc()) & 0x3FF);
00296    }
00297 }
00298 
00299 unsigned short HcaluLUTTPGCoder::adc2Linear(HcalQIESample sample, HcalDetId id) const {
00300    int lutId = getLUTId(id);
00301    return ((inputLUT_.at(lutId)).at(sample.adc()) & 0x3FF);
00302 }
00303 
00304 float HcaluLUTTPGCoder::getLUTPedestal(HcalDetId id) const {
00305    int lutId = getLUTId(id);
00306    return ped_.at(lutId);
00307 }
00308 
00309 float HcaluLUTTPGCoder::getLUTGain(HcalDetId id) const {
00310    int lutId = getLUTId(id);
00311    return gain_.at(lutId);
00312 }
00313 
00314 std::vector<unsigned short> HcaluLUTTPGCoder::getLinearizationLUTWithMSB(const HcalDetId& id) const{
00315    int lutId = getLUTId(id);
00316    return inputLUT_.at(lutId);
00317 }
00318 
00319 void HcaluLUTTPGCoder::lookupMSB(const HBHEDataFrame& df, std::vector<bool>& msb) const{
00320    msb.resize(df.size());
00321    for (int i=0; i<df.size(); ++i)
00322       msb[i] = getMSB(df.id(), df.sample(i).adc());
00323 }
00324 
00325 bool HcaluLUTTPGCoder::getMSB(const HcalDetId& id, int adc) const{
00326    int lutId = getLUTId(id);
00327    const Lut& lut = inputLUT_.at(lutId);
00328    return (lut.at(adc) & 0x400);
00329 }