CMS 3D CMS Logo

/data/refman/pasoursint/CMSSW_4_1_8_patch9/src/CalibCalorimetry/CaloTPG/src/CaloTPGTranscoderULUT.cc

Go to the documentation of this file.
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 //#include "FWCore/Framework/interface/Frameworkfwd.h"
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 // Initialize analytical compression LUT's here
00034    // TODO cms::Error log
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   // Compute compression LUT
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         // TODO cms::Error log
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      } //for iphi
00068   } //for ieta
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(); //rewind last line
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          // HF
00198          if (abs(ieta) >= theTrigTowerGeometry.firstHFTower())
00199             factor = rctlsb_factor_;
00200          // HBHE
00201          else 
00202             factor = nominal_gain_ / cosh_ieta * meta->getLutGranularity();
00203 
00204          // tpg - compressed value
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                 } // for phi
00217         } // for ieta
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 //  if (abs(ieta) > 28) iphi = iphi/4 + 1; // Changing iphi index from 1, 5, ..., 69 to 1, 2, ..., 18
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 // This is now an obsolete method; we return the AVERAGE over all the allowed iphi channels if it's invoked
00280 // The user is encouraged to use hcaletValue(const int& ieta, const int& iphi, const int& compET) instead
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();                        // No need to check the validity,
00308   int iphi = hid.iphi();                        // as the values are guaranteed
00309   int compET = hc.compressedEt();       // to be within the range by the class
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    // TODO Try/except
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       // TODO Message to discourage using txt.
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 //int CaloTPGTranscoderULUT::getLutGranularity(const DetId& id) const{
00402 //   int ieta = id.ietaAbs();
00403 //   if (ieta < 18) return 1;
00404 //   else if (ieta < 27) return 2;
00405 //   else if (ieta < 29) return 5;
00406 //   return 0;
00407 //}
00408 //
00409 //int CaloTPGTranscoderULUT::getLutThreshold(const DetId& id) const{
00410 //   int ieta = id.ietaAbs();
00411 //   if (ieta < 18) return 4;
00412 //   else if (ieta < 27) return 2;
00413 //   else if (ieta < 29) return 1;
00414 //   return 0;
00415 //}
00416 //