00001 #include "CalibCalorimetry/CaloTPG/src/CaloTPGTranscoderULUT.h"
00002 #include "FWCore/Utilities/interface/Exception.h"
00003 #include "Geometry/HcalTowerAlgo/interface/HcalTrigTowerGeometry.h"
00004 #include "FWCore/Utilities/interface/Exception.h"
00005 #include <iostream>
00006 #include <fstream>
00007 #include <math.h>
00008
00009
00010 #include "FWCore/Framework/interface/EventSetup.h"
00011 #include "CondFormats/DataRecord/interface/HcalLutMetadataRcd.h"
00012
00013 using namespace std;
00014
00015 HcalTrigTowerGeometry theTrigTowerGeometry;
00016
00017 CaloTPGTranscoderULUT::CaloTPGTranscoderULUT(const std::string& compressionFile,
00018 const std::string& decompressionFile)
00019 : isLoaded_(false), nominal_gain_(0.), rctlsb_factor_(0.),
00020 compressionFile_(compressionFile),
00021 decompressionFile_(decompressionFile)
00022 {
00023 for (int i = 0; i < NOUTLUTS; i++) outputLUT_[i] = 0;
00024 }
00025
00026 CaloTPGTranscoderULUT::~CaloTPGTranscoderULUT() {
00027 for (int i = 0; i < NOUTLUTS; i++) {
00028 if (outputLUT_[i] != 0) delete [] outputLUT_[i];
00029 }
00030 }
00031
00032 void CaloTPGTranscoderULUT::loadHCALCompress() const{
00033
00034
00035 if (OUTPUT_LUT_SIZE != (unsigned int) 0x400) std::cout << "Error: Analytic compression expects 10-bit LUT; found LUT with " << OUTPUT_LUT_SIZE << " entries instead" << std::endl;
00036
00037 std::vector<unsigned int> analyticalLUT(OUTPUT_LUT_SIZE, 0);
00038 std::vector<unsigned int> identityLUT(OUTPUT_LUT_SIZE, 0);
00039
00040
00041 for (unsigned int i=0; i < OUTPUT_LUT_SIZE; i++) {
00042 analyticalLUT[i] = (unsigned int)(sqrt(14.94*log(1.+i/14.94)*i) + 0.5);
00043 identityLUT[i] = min(i,0xffu);
00044 }
00045
00046 for (int ieta=-32; ieta <= 32; ieta++){
00047 for (int iphi = 1; iphi <= 72; iphi++){
00048 if (!HTvalid(ieta,iphi)) continue;
00049 int lutId = getOutputLUTId(ieta,iphi);
00050
00051 if (outputLUT_[lutId] != 0){
00052 std::cout << "Error: LUT with (ieta,iphi) = (" << ieta << "," << iphi << ") has been previously allocated!" << std::endl;
00053 continue;
00054 }
00055
00056 outputLUT_[lutId] = new LUT[OUTPUT_LUT_SIZE];
00057
00058 HcalTrigTowerDetId id(ieta, iphi);
00059 const HcalLutMetadatum *meta = lutMetadata_->getValues(id);
00060 int threshold = meta->getOutputLutThreshold();
00061
00062 for (int i = 0; i < threshold; ++i)
00063 outputLUT_[lutId][i] = 0;
00064
00065 for (unsigned int i = threshold; i < OUTPUT_LUT_SIZE; ++i)
00066 outputLUT_[lutId][i] = (abs(ieta) < theTrigTowerGeometry.firstHFTower()) ? analyticalLUT[i] : identityLUT[i];
00067 }
00068 }
00069 }
00070
00071 void CaloTPGTranscoderULUT::loadHCALCompress(const std::string& filename) const{
00072 int tool;
00073 std::ifstream userfile;
00074 std::vector< std::vector<LUT> > outputluts;
00075
00076 std::cout << "Initializing compression LUT's from " << (char *)filename.data() << std::endl;
00077 for (int i = 0; i < NOUTLUTS; i++) outputLUT_[i] = 0;
00078 int maxid = 0, minid = 0x7FFFFFFF, rawid = 0;
00079 for (int ieta=-32; ieta <= 32; ieta++) {
00080 for (int iphi = 1; iphi <= 72; iphi++) {
00081 if (HTvalid(ieta,iphi)) {
00082 rawid = getOutputLUTId(ieta, iphi);
00083 if (outputLUT_[rawid] != 0) std::cout << "Error: LUT with (ieta,iphi) = (" << ieta << "," << iphi << ") has been previously allocated!" << std::endl;
00084 else outputLUT_[rawid] = new LUT[OUTPUT_LUT_SIZE];
00085 if (rawid < minid) minid = rawid;
00086 if (rawid > maxid) maxid = rawid;
00087 }
00088 }
00089 }
00090
00091 userfile.open((char *)filename.data());
00092
00093 if( userfile ) {
00094 int nluts = 0;
00095 std::string s;
00096 std::vector<int> loieta,hiieta;
00097 std::vector<int> loiphi,hiiphi;
00098 getline(userfile,s);
00099
00100 getline(userfile,s);
00101
00102 unsigned int index = 0;
00103 while (index < s.length()) {
00104 while (isspace(s[index])) index++;
00105 if (index < s.length()) nluts++;
00106 while (!isspace(s[index])) index++;
00107 }
00108 for (unsigned int i=0; i<=s.length(); i++) userfile.unget();
00109 outputluts.resize(nluts);
00110 for (int i=0; i<nluts; i++) outputluts[i].resize(OUTPUT_LUT_SIZE);
00111
00112
00113 for (int i=0; i<nluts; i++) {
00114 userfile >> tool;
00115 loieta.push_back(tool);
00116 }
00117
00118 for (int i=0; i<nluts; i++) {
00119 userfile >> tool;
00120 hiieta.push_back(tool);
00121 }
00122
00123 for (int i=0; i<nluts; i++) {
00124 userfile >> tool;
00125 loiphi.push_back(tool);
00126
00127 }
00128
00129 for (int i=0; i<nluts; i++) {
00130 userfile >> tool;
00131 hiiphi.push_back(tool);
00132
00133 }
00134
00135 for (unsigned int j=0; j<OUTPUT_LUT_SIZE; j++) {
00136 for(int i=0; i <nluts; i++) {
00137 userfile >> tool;
00138 if (tool < 0) {
00139 std::cout << "Error: LUT can't have negative numbers; 0 used instead: " << i << ", " << j << " : = " << tool << std::endl;
00140 tool = 0;
00141 } else if (tool > 0xff) {
00142 std::cout << "Error: LUT can't have >8-bit numbers; 0xff used instead: " << i << ", " << j << " : = " << tool << std::endl;
00143 tool = 0xff;
00144 }
00145 outputluts[i][j] = tool;
00146 if (userfile.eof()) std::cout << "Error: LUT file is truncated or has a wrong format: " << i << "," << j << std::endl;
00147 }
00148 }
00149 userfile.close();
00150
00151 HcalDetId cell;
00152 int id, ntot = 0;
00153 for (int i=0; i < nluts; i++) {
00154 int nini = 0;
00155 for (int iphi = loiphi[i]; iphi <= hiiphi[i]; iphi++) {
00156 for (int ieta=loieta[i]; ieta <= hiieta[i]; ieta++) {
00157 if (HTvalid(ieta,iphi)) {
00158 id = getOutputLUTId(ieta,iphi);
00159 if (outputLUT_[id] == 0) throw cms::Exception("PROBLEM: outputLUT_ has not been initialized for ieta, iphi, id = ") << ieta << ", " << iphi << ", " << id << std::endl;
00160 for (int j = 0; j <= 0x3ff; j++) outputLUT_[id][j] = outputluts[i][j];
00161 nini++;
00162 ntot++;
00163 }
00164 }
00165 }
00166
00167 }
00168
00169 } else {
00170
00171 loadHCALCompress();
00172 }
00173 }
00174
00175 void CaloTPGTranscoderULUT::loadHCALUncompress() const {
00176 hcaluncomp_.clear();
00177 for (int i = 0; i < NOUTLUTS; i++){
00178 RCTdecompression decompressionTable(TPGMAX,0);
00179 hcaluncomp_.push_back(decompressionTable);
00180 }
00181
00182 for (int ieta = -32; ieta <= 32; ++ieta){
00183
00184 double eta_low = 0., eta_high = 0.;
00185 theTrigTowerGeometry.towerEtaBounds(ieta,eta_low,eta_high);
00186 double cosh_ieta = fabs(cosh((eta_low + eta_high)/2.));
00187
00188 for (int iphi = 1; iphi <= 72; iphi++) {
00189 if (!HTvalid(ieta, iphi)) continue;
00190
00191 int lutId = getOutputLUTId(ieta,iphi);
00192 HcalTrigTowerDetId id(ieta, iphi);
00193
00194 const HcalLutMetadatum *meta = lutMetadata_->getValues(id);
00195 double factor = 0.;
00196
00197
00198 if (abs(ieta) >= theTrigTowerGeometry.firstHFTower())
00199 factor = rctlsb_factor_;
00200
00201 else
00202 factor = nominal_gain_ / cosh_ieta * meta->getLutGranularity();
00203
00204
00205 unsigned int tpg = outputLUT_[lutId][0];
00206 int low = 0;
00207 for (unsigned int i = 0; i < OUTPUT_LUT_SIZE; ++i){
00208 if (outputLUT_[lutId][i] != tpg){
00209 unsigned int mid = (low + i)/2;
00210 hcaluncomp_[lutId][tpg] = (tpg == 0 ? low : factor * mid);
00211 low = i;
00212 tpg = outputLUT_[lutId][i];
00213 }
00214 }
00215 hcaluncomp_[lutId][tpg] = factor * low;
00216 }
00217 }
00218 }
00219
00220 void CaloTPGTranscoderULUT::loadHCALUncompress(const std::string& filename) const {
00221 std::ifstream userfile;
00222 userfile.open(filename.c_str());
00223
00224 hcaluncomp_.resize(NOUTLUTS);
00225 for (int i = 0; i < NOUTLUTS; i++) hcaluncomp_[i].resize(TPGMAX);
00226
00227 static const int etabound = 32;
00228 if( userfile ) {
00229 double et;
00230 for (int i=0; i<TPGMAX; i++) {
00231 for(int j = 1; j <=etabound; j++) {
00232 userfile >> et;
00233 for (int iphi = 1; iphi <= 72; iphi++) {
00234 int itower = getOutputLUTId(j,iphi);
00235 if (itower >= 0) hcaluncomp_[itower][i] = et;
00236 itower = getOutputLUTId(-j,iphi);
00237 if (itower >= 0) hcaluncomp_[itower][i] = et;
00238 }
00239 }
00240 }
00241 userfile.close();
00242 }
00243 else {
00244
00245 loadHCALUncompress();
00246 }
00247 }
00248
00249 HcalTriggerPrimitiveSample CaloTPGTranscoderULUT::hcalCompress(const HcalTrigTowerDetId& id, unsigned int sample, bool fineGrain) const {
00250 int ieta = id.ieta();
00251 int iphi = id.iphi();
00252
00253 int itower = getOutputLUTId(ieta,iphi);
00254
00255 if (itower < 0) cms::Exception("Invalid Data") << "No trigger tower found for ieta, iphi = " << ieta << ", " << iphi;
00256 if (sample >= OUTPUT_LUT_SIZE) {
00257
00258 throw cms::Exception("Out of Range") << "LUT has 1024 entries for " << itower << " but " << sample << " was requested.";
00259 sample=OUTPUT_LUT_SIZE - 1;
00260 }
00261
00262 return HcalTriggerPrimitiveSample(outputLUT_[itower][sample],fineGrain,0,0);
00263 }
00264
00265 double CaloTPGTranscoderULUT::hcaletValue(const int& ieta, const int& iphi, const int& compET) const {
00266 if (hcaluncomp_.empty()) {
00267
00268 CaloTPGTranscoderULUT::loadHCALUncompress(decompressionFile_);
00269 }
00270 double etvalue = 0.;
00271 int itower = getOutputLUTId(ieta,iphi);
00272 if (itower < 0) std::cout << "hcaletValue error: no decompression LUT found for ieta, iphi = " << ieta << ", " << iphi << std::endl;
00273 else if (compET < 0 || compET > 0xff) std::cout << "hcaletValue error: compressed value out of range: eta, phi, cET = " << ieta << ", " << iphi << ", " << compET << std::endl;
00274 else etvalue = hcaluncomp_[itower][compET];
00275 return(etvalue);
00276 }
00277
00278 double CaloTPGTranscoderULUT::hcaletValue(const int& ieta, const int& compET) const {
00279
00280
00281
00282 if (hcaluncomp_.empty()) {
00283 std::cout << "Initializing the RCT decompression table from the file: " << decompressionFile_ << std::endl;
00284 CaloTPGTranscoderULUT::loadHCALUncompress(decompressionFile_);
00285 }
00286
00287 double etvalue = 0.;
00288 if (compET < 0 || compET > 0xff) std::cout << "hcaletValue error: compressed value out of range: eta, cET = " << ieta << ", " << compET << std::endl;
00289 else {
00290 int nphi = 0;
00291 for (int iphi=1; iphi <= 72; iphi++) {
00292 if (HTvalid(ieta,iphi)) {
00293 nphi++;
00294 int itower = getOutputLUTId(ieta,iphi);
00295 etvalue += hcaluncomp_[itower][compET];
00296 }
00297 }
00298 if (nphi > 0) etvalue /= nphi;
00299 else std::cout << "hcaletValue error: no decompression LUTs found for any iphi for ieta = " << ieta << std::endl;
00300 }
00301 return(etvalue);
00302 }
00303
00304 double CaloTPGTranscoderULUT::hcaletValue(const HcalTrigTowerDetId& hid, const HcalTriggerPrimitiveSample& hc) const {
00305 if (hcaluncomp_.empty()) loadHCALUncompress(decompressionFile_);
00306
00307 int ieta = hid.ieta();
00308 int iphi = hid.iphi();
00309 int compET = hc.compressedEt();
00310 int itower = getOutputLUTId(ieta,iphi);
00311 double etvalue = hcaluncomp_[itower][compET];
00312 return(etvalue);
00313 }
00314
00315 EcalTriggerPrimitiveSample CaloTPGTranscoderULUT::ecalCompress(const EcalTrigTowerDetId& id, unsigned int sample, bool fineGrain) const {
00316 throw cms::Exception("Not Implemented") << "CaloTPGTranscoderULUT::ecalCompress";
00317 }
00318
00319 void CaloTPGTranscoderULUT::rctEGammaUncompress(const HcalTrigTowerDetId& hid, const HcalTriggerPrimitiveSample& hc,
00320 const EcalTrigTowerDetId& eid, const EcalTriggerPrimitiveSample& ec,
00321 unsigned int& et, bool& egVecto, bool& activity) const {
00322 throw cms::Exception("Not Implemented") << "CaloTPGTranscoderULUT::rctEGammaUncompress";
00323 }
00324 void CaloTPGTranscoderULUT::rctJetUncompress(const HcalTrigTowerDetId& hid, const HcalTriggerPrimitiveSample& hc,
00325 const EcalTrigTowerDetId& eid, const EcalTriggerPrimitiveSample& ec,
00326 unsigned int& et) const {
00327 throw cms::Exception("Not Implemented") << "CaloTPGTranscoderULUT::rctJetUncompress";
00328 }
00329
00330 bool CaloTPGTranscoderULUT::HTvalid(const int ieta, const int iphiin) const {
00331 int iphi = iphiin;
00332 if (iphi <= 0 || iphi > 72 || ieta == 0 || abs(ieta) > 32) return false;
00333 if (abs(ieta) > 28) {
00334 if (newHFphi) {
00335 if ((iphi/4)*4 + 1 != iphi) return false;
00336 iphi = iphi/4 + 1;
00337 }
00338 if (iphi > 18) return false;
00339 }
00340 return true;
00341 }
00342
00343 int CaloTPGTranscoderULUT::getOutputLUTId(const int ieta, const int iphiin) const {
00344 int iphi = iphiin;
00345 if (HTvalid(ieta, iphi)) {
00346 int offset = 0, ietaabs;
00347 ietaabs = abs(ieta);
00348 if (ieta < 0) offset = NOUTLUTS/2;
00349 if (ietaabs < 29) return 72*(ietaabs - 1) + (iphi - 1) + offset;
00350 else {
00351 if (newHFphi) iphi = iphi/4 + 1;
00352 return 18*(ietaabs - 29) + iphi + 2015 + offset;
00353 }
00354 } else return -1;
00355 }
00356
00357 std::vector<unsigned char> CaloTPGTranscoderULUT::getCompressionLUT(HcalTrigTowerDetId id) const {
00358 std::vector<unsigned char> lut;
00359 int itower = getOutputLUTId(id.ieta(),id.iphi());
00360 if (itower >= 0) {
00361 lut.resize(OUTPUT_LUT_SIZE);
00362 for (unsigned int i = 0; i < OUTPUT_LUT_SIZE; i++) lut[i]=outputLUT_[itower][i];
00363 }
00364 return lut;
00365 }
00366
00367 void CaloTPGTranscoderULUT::setup(const edm::EventSetup& es, Mode mode=All) const{
00368 if (isLoaded_) return;
00369
00370 es.get<HcalLutMetadataRcd>().get(lutMetadata_);
00371
00372 nominal_gain_ = lutMetadata_->getNominalGain();
00373 float rctlsb =lutMetadata_->getRctLsb();
00374 if (rctlsb != 0.25 && rctlsb != 0.5)
00375 throw cms::Exception("RCTLSB") << " value=" << rctlsb << " (should be 0.25 or 0.5)" << std::endl;
00376 rctlsb_factor_ = rctlsb;
00377
00378 if (compressionFile_.empty() && decompressionFile_.empty()) {
00379 loadHCALCompress();
00380 }
00381 else {
00382
00383 std::cout << "From Text File:" << std::endl;
00384 loadHCALCompress(compressionFile_);
00385 }
00386 isLoaded_ = true;
00387 }
00388
00389 void CaloTPGTranscoderULUT::printDecompression() const{
00390 std::cout << "RCT Decompression table" << std::endl;
00391 for (int i=0; i < 256; i++) {
00392 for (int j=1; j <= theTrigTowerGeometry.nTowers(); j++)
00393 std::cout << int(hcaletValue(j,i)*100. + 0.5)/100. << " ";
00394 std::cout << std::endl;
00395 for (int j=1; j <= theTrigTowerGeometry.nTowers(); j++)
00396 if (hcaletValue(j,i) != hcaletValue(-j,i))
00397 cout << "Error: decompression table for ieta = +/- " << j << " disagree! " << hcaletValue(-j,i) << ", " << hcaletValue(j,i) << endl;
00398 }
00399 }
00400
00401
00402
00403
00404
00405
00406
00407
00408
00409
00410
00411
00412
00413
00414
00415
00416