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
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 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
00132 for (size_t i=0; file >> lutValue; i = (i+1) % nCol){
00133 lutFromFile[i].push_back(lutValue);
00134 }
00135
00136
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
00151
00152
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 }
00158 }
00159 }
00160 }
00161 }
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
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 }
00237
00238 ped_[lutId] = ped;
00239 gain_[lutId] = gain;
00240 bool isMasked = ( (status & bitToMask_) > 0 );
00241 float rcalib = meta->getRCalib();
00242
00243
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 }
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
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 }
00280 }
00281 }
00282 }
00283 }
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 }