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
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
00077
00078 index += 2;
00079 index = buffer.find("H", index);
00080 }
00081
00082
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
00130 for (size_t i=0; file >> lutValue; i = (i+1) % nCol){
00131 lutFromFile[i].push_back(lutValue);
00132 }
00133
00134
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
00147
00148
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 }
00154 }
00155 }
00156 }
00157 }
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
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 }
00234
00235 ped_[lutId] = ped;
00236 gain_[lutId] = gain;
00237 bool isMasked = ( (status & bitToMask_) > 0 );
00238 float rcalib = meta->getRCalib();
00239
00240
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 }
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
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 }
00277 }
00278 }
00279 }
00280 }
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 }