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
00022 const float HcaluLUTTPGCoder::nominal_gain = 0.177;
00023
00024 HcaluLUTTPGCoder::HcaluLUTTPGCoder(const char* filename, bool read_Ascii_LUTs) {
00025 AllocateLUTs();
00026
00027 if (read_Ascii_LUTs == true) {
00028 update(filename);
00029 }
00030 else {
00031 getRecHitCalib(filename);
00032 }
00033 }
00034
00035 void HcaluLUTTPGCoder::PrintTPGMap() {
00036 HcalTopology theTopo;
00037 HcalDetId did;
00038
00039
00040
00041
00042 for (int ieta=1; ieta <= 41; ieta++) {
00043 for (int depth = 1; depth <= 3; depth++) {
00044 bool newdepth = true, OK = false;
00045 int lastphi = 0;
00046 for (int iphi = 1; iphi <= 72; iphi++) {
00047 did=HcalDetId(HcalBarrel,ieta,iphi,depth);
00048 if (theTopo.valid(did)) {
00049 if (newdepth) {
00050
00051 newdepth = false;
00052 OK = true;
00053 }
00054 if (lastphi == 0) std::cout << iphi << " ";
00055 lastphi = iphi;
00056 } else lastphi = 0;
00057 }
00058
00059
00060 }
00061 }
00062
00063
00064
00065
00066 for (int ieta=-41; ieta <= 41; ieta++) {
00067 for (int depth = 1; depth <= 3; depth++) {
00068 bool newdepth = true, OK = false;
00069 int lastphi = 0;
00070 for (int iphi = 1; iphi <= 72; iphi++) {
00071 did=HcalDetId(HcalEndcap,ieta,iphi,depth);
00072 if (theTopo.valid(did)) {
00073 if (newdepth) {
00074
00075 newdepth = false;
00076 OK = true;
00077 }
00078 if (lastphi == 0) std::cout << iphi << " ";
00079 lastphi = iphi;
00080 } else lastphi = 0;
00081 }
00082
00083
00084 }
00085 }
00086
00087
00088
00089
00090 for (int ieta=1; ieta <= 41; ieta++) {
00091 for (int depth = 1; depth <= 3; depth++) {
00092 bool newdepth = true, OK = false;
00093 int lastphi = 0;
00094 for (int iphi = 1; iphi <= 72; iphi++) {
00095 did=HcalDetId(HcalForward,ieta,iphi,depth);
00096 if (theTopo.valid(did)) {
00097 if (newdepth) {
00098
00099 newdepth = false;
00100 OK = true;
00101 }
00102 if (lastphi == 0) std::cout << iphi << " ";
00103 lastphi = iphi;
00104 } else lastphi = 0;
00105 }
00106
00107
00108 }
00109 }
00110
00111
00112 HcalDetId dd;
00113 HcalTrigTowerDetId tt;
00114 HcalTrigTowerGeometry tg;
00115 std::vector<HcalTrigTowerDetId> towerids;
00116 std::vector<HcalDetId> detids;
00117 std::vector<HcalDetId> ttmap[64][72];
00118
00119
00120 for (int ieta=1; ieta <= 41; ieta++) {
00121 for (int depth = 1; depth <= 3; depth++) {
00122 for (int iphi = 1; iphi <= 72; iphi++) {
00123 did=HcalDetId(HcalBarrel,ieta,iphi,depth);
00124 if (theTopo.valid(did)) {
00125 tt = HcalTrigTowerDetId(did.rawId());
00126
00127 towerids = tg.towerIds(did.rawId());
00128 for(unsigned int n = 0; n < towerids.size(); ++n)
00129 {
00130
00131 int ie = towerids[n].ieta();
00132 if (ie < 0) ie = 32 - ie;
00133 int ip = towerids[n].iphi();
00134 ttmap[ie-1][ip-1].push_back(did);
00135 }
00136 }
00137 }
00138 }
00139 }
00140
00141 for (int ieta=1; ieta <= 41; ieta++) {
00142 for (int depth = 1; depth <= 3; depth++) {
00143 for (int iphi = 1; iphi <= 72; iphi++) {
00144 did=HcalDetId(HcalEndcap,ieta,iphi,depth);
00145 if (theTopo.valid(did)) {
00146 tt = HcalTrigTowerDetId(did.rawId());
00147
00148 towerids = tg.towerIds(did.rawId());
00149 for(unsigned int n = 0; n < towerids.size(); ++n)
00150 {
00151 int ie = towerids[n].ieta();
00152 if (ie < 0) ie = 32 - ie;
00153 int ip = towerids[n].iphi();
00154 ttmap[ie-1][ip-1].push_back(did);
00155
00156 }
00157 }
00158 }
00159 }
00160 }
00161
00162 for (int ieta=1; ieta <= 41; ieta++) {
00163 for (int iphi = 1; iphi <= 72; iphi++) {
00164 for (int depth = 1; depth <= 3; depth++) {
00165 did=HcalDetId(HcalForward,ieta,iphi,depth);
00166 if (theTopo.valid(did)) {
00167 tt = HcalTrigTowerDetId(did.rawId());
00168
00169 towerids = tg.towerIds(did.rawId());
00170 for(unsigned int n = 0; n < towerids.size(); ++n)
00171 {
00172 int ie = towerids[n].ieta();
00173 if (ie < 0) ie = 32 - ie;
00174 int ip = towerids[n].iphi();
00175 ttmap[ie-1][ip-1].push_back(did);
00176
00177
00178
00179 }
00180
00181 }
00182 }
00183 }
00184 }
00185
00186 for (int ieta = 1; ieta <= 32; ieta++) {
00187 for (int iphi = 1; iphi <=72; iphi++) {
00188 if (ttmap[ieta-1][iphi-1].size() > 0) {
00189
00190
00191
00192 }
00193 }
00194 }
00195 }
00196
00197 void HcaluLUTTPGCoder::compress(const IntegerCaloSamples& ics, const std::vector<bool>& featureBits, HcalTriggerPrimitiveDigi& tp) const {
00198 throw cms::Exception("PROBLEM: This method should never be invoked!");
00199 }
00200
00201 HcaluLUTTPGCoder::~HcaluLUTTPGCoder() {
00202 for (int i = 0; i < nluts; i++) {
00203 if (inputLUT[i] != 0) delete [] inputLUT[i];
00204 }
00205 delete [] _gain;
00206 delete [] _ped;
00207 }
00208
00209 void HcaluLUTTPGCoder::AllocateLUTs() {
00210 HcalTopology theTopo;
00211 HcalDetId did;
00212
00213
00214
00215 _ped = new float[nluts];
00216 _gain = new float[nluts];
00217 for (int i = 0; i < nluts; i++) inputLUT[i] = 0;
00218 int maxid = 0, minid = 0x7FFFFFFF, rawid = 0;
00219 for (int ieta=-41; ieta <= 41; ieta++) {
00220 for (int iphi = 1; iphi <= 72; iphi++) {
00221 for (int depth = 1; depth <= 3; depth++) {
00222 did=HcalDetId(HcalBarrel,ieta,iphi,depth);
00223 if (theTopo.valid(did)) {
00224 rawid = GetLUTID(HcalBarrel, ieta, iphi, depth);
00225 if (inputLUT[rawid] != 0) std::cout << "Error: LUT with (ieta,iphi,depth) = (" << ieta << "," << iphi << "," << depth << ") has been previously allocated!" << std::endl;
00226 else inputLUT[rawid] = new LUT[INPUT_LUT_SIZE];
00227 if (rawid < minid) minid = rawid;
00228 if (rawid > maxid) maxid = rawid;
00229 }
00230
00231 did=HcalDetId(HcalEndcap,ieta,iphi,depth);
00232 if (theTopo.valid(did)) {
00233 rawid = GetLUTID(HcalEndcap, ieta, iphi, depth);
00234 if (inputLUT[rawid] != 0) std::cout << "Error: LUT with (ieta,iphi,depth) = (" << ieta << "," << iphi << "," << depth << ") has been previously allocated!" << std::endl;
00235 else inputLUT[rawid] = new LUT[INPUT_LUT_SIZE];
00236 if (rawid < minid) minid = rawid;
00237 if (rawid > maxid) maxid = rawid;
00238 }
00239 did=HcalDetId(HcalForward,ieta,iphi,depth);
00240 if (theTopo.valid(did)) {
00241 rawid = GetLUTID(HcalForward, ieta, iphi, depth);
00242 if (inputLUT[rawid] != 0) std::cout << "Error: LUT with (ieta,iphi,depth) = (" << ieta << "," << iphi << "," << depth << ") has been previously allocated!" << std::endl;
00243 else inputLUT[rawid] = new LUT[INPUT_LUT_SIZE];
00244 if (rawid < minid) minid = rawid;
00245 if (rawid > maxid) maxid = rawid;
00246 }
00247 }
00248 }
00249 }
00250
00251 }
00252
00253 int HcaluLUTTPGCoder::GetLUTID(HcalSubdetector id, int ieta, int iphi, int depth) const {
00254 int detid = 0;
00255 if (id == HcalEndcap) detid = 1;
00256 else if (id == HcalForward) detid = 2;
00257 return iphi + 72 * ((ieta + 41) + 83 * (depth + 3 * detid)) - 7777;
00258 }
00259
00260 void HcaluLUTTPGCoder::getRecHitCalib(const char* filename) {
00261
00262 std::ifstream userfile;
00263 userfile.open(filename);
00264 int tool;
00265 float Rec_calib_[87];
00266
00267 if (userfile) {
00268 userfile >> tool;
00269
00270 if (tool != 86) {
00271 std::cout << "Wrong RecHit calibration filesize: " << tool << " (expect 86)" << std::endl;
00272 }
00273 for (int j=1; j<87; j++) {
00274 userfile >> Rec_calib_[j];
00275 Rcalib[j] = Rec_calib_[j] ;
00276 }
00277
00278 userfile.close();
00279 }
00280 else std::cout << "File " << filename << " with RecHit calibration factors not found" << std::endl;
00281 }
00282
00283 void HcaluLUTTPGCoder::update(const char* filename) {
00284 HcalTopology theTopo;
00285 int tool;
00286 std::string HCAL[3] = {"HB", "HE", "HF"};
00287 std::ifstream userfile;
00288 userfile.open(filename);
00289 std::cout << filename << std::endl;
00290 if( userfile ) {
00291 int nluts = 0;
00292 std::string s;
00293 std::vector<int> loieta,hiieta;
00294 std::vector<int> loiphi,hiiphi;
00295 std::vector<int> loidep,hiidep;
00296 std::vector<int> idet;
00297 getline(userfile,s);
00298
00299 getline(userfile,s);
00300
00301 unsigned int index = s.find("H",0);
00302 while (index < s.length()) {
00303 std::string det = s.substr(index,2);
00304 if (det == "HB") idet.push_back(0);
00305 else if (det == "HE") idet.push_back(1);
00306 else if (det == "HF") idet.push_back(2);
00307 else std::cout << "Wrong LUT detector description in " << s << std::endl;
00308
00309 nluts++;
00310 index +=2;
00311 index = s.find("H",index);
00312 }
00313
00314
00315
00316 inputluts_.resize(nluts);
00317 for (int i=0; i<nluts; i++) {
00318 inputluts_[i].resize(INPUT_LUT_SIZE);
00319 }
00320
00321
00322 for (int i=0; i<nluts; i++) {
00323 userfile >> tool;
00324 loieta.push_back(tool);
00325
00326 }
00327
00328 for (int i=0; i<nluts; i++) {
00329 userfile >> tool;
00330 hiieta.push_back(tool);
00331
00332 }
00333
00334 for (int i=0; i<nluts; i++) {
00335 userfile >> tool;
00336 loiphi.push_back(tool);
00337
00338 }
00339
00340 for (int i=0; i<nluts; i++) {
00341 userfile >> tool;
00342 hiiphi.push_back(tool);
00343
00344 }
00345
00346 for (int i=0; i<nluts; i++) {
00347 userfile >> tool;
00348 loidep.push_back(tool);
00349
00350 }
00351
00352 for (int i=0; i<nluts; i++) {
00353 userfile >> tool;
00354 hiidep.push_back(tool);
00355
00356 }
00357
00358
00359 for (int j=0; j<INPUT_LUT_SIZE; j++) {
00360 for(int i = 0; i <nluts; i++) {
00361 userfile >> inputluts_[i][j];
00362 if (userfile.eof()) std::cout << "Error: LUT file is truncated or has a wrong format: " << i << "," << j << std::endl;
00363 }
00364 }
00365 userfile.close();
00366
00367 HcalDetId cell;
00368 int id, ntot = 0;
00369 for (int i=0; i < nluts; i++) {
00370 int nini = 0;
00371 for (int depth = loidep[i]; depth <= hiidep[i]; depth++) {
00372 for (int iphi = loiphi[i]; iphi <= hiiphi[i]; iphi++) {
00373 for (int ieta=loieta[i]; ieta <= hiieta[i]; ieta++) {
00374 if (idet[i] == 0) cell = HcalDetId(HcalBarrel,ieta,iphi,depth);
00375 else if (idet[i] == 1) cell = HcalDetId(HcalEndcap,ieta,iphi,depth);
00376 else if (idet[i] == 2) cell = HcalDetId(HcalForward,ieta,iphi,depth);
00377 if (theTopo.valid(cell)) {
00378 if (idet[i] == 0) id = GetLUTID(HcalBarrel,ieta,iphi,depth);
00379 else if (idet[i] == 1) id = GetLUTID(HcalEndcap,ieta,iphi,depth);
00380 else if (idet[i] == 2) id = GetLUTID(HcalForward,ieta,iphi,depth);
00381 if (inputLUT[id] == 0) throw cms::Exception("PROBLEM: inputLUT has not been initialized for idet, ieta, iphi, depth, id = ") << idet[i] << "," << ieta << "," << iphi << "," << depth << "," << id << std::endl;
00382 for (int j = 0; j <= 0x7F; j++) inputLUT[id][j] = inputluts_[i][j];
00383 nini++;
00384 ntot++;
00385 }
00386 }
00387 }
00388 }
00389
00390 }
00391
00392 }
00393 }
00394
00395 void HcaluLUTTPGCoder::update(const HcalDbService& conditions) {
00396 const HcalQIEShape* shape = conditions.getHcalShape();
00397 HcalCalibrations calibrations;
00398 int id;
00399 float divide;
00400 HcalTopology theTopo;
00401
00402 float cosheta_[41], lsb_ = 1./16.;
00403 for (int i = 0; i < 13; i++) cosheta_[i+29] = cosh((theHFEtaBounds[i+1] + theHFEtaBounds[i])/2.);
00404
00405 for (int depth = 1; depth <= 3; depth++) {
00406 for (int iphi = 1; iphi <= 72; iphi++) {
00407 divide = 1.*nominal_gain;
00408 for (int ieta=-16; ieta <= 16; ieta++) {
00409 HcalDetId cell(HcalBarrel,ieta,iphi,depth);
00410 if (theTopo.valid(cell)) {
00411 id = GetLUTID(HcalBarrel,ieta,iphi,depth);
00412 if (inputLUT[id] == 0) throw cms::Exception("PROBLEM: inputLUT has not been initialized for HB, ieta, iphi, depth, id = ") << ieta << "," << iphi << "," << depth << "," << id << std::endl;
00413
00414 HcalCalibrations calibrations = conditions.getHcalCalibrations(cell);
00415
00416 const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
00417 HcalCoderDb coder (*channelCoder, *shape);
00418 float ped_ = (calibrations.pedestal(0)+calibrations.pedestal(1)+calibrations.pedestal(2)+calibrations.pedestal(3))/4;
00419 float gain_= (calibrations.respcorrgain(0)+calibrations.respcorrgain(1)+calibrations.respcorrgain(2)+calibrations.respcorrgain(3))/4;
00420 HBHEDataFrame frame(cell);
00421 frame.setSize(1);
00422 CaloSamples samples(cell, 1);
00423 _ped[id] = ped_;
00424 _gain[id] = gain_;
00425 for (int j = 0; j <= 0x7F; j++) {
00426 HcalQIESample adc(j);
00427 frame.setSample(0,adc);
00428 coder.adc2fC(frame,samples);
00429 float adc2fC_ = samples[0];
00430 if (ieta <0 )inputLUT[id][j] = (LUT) std::min(std::max(0,int((adc2fC_ - ped_)*gain_*Rcalib[abs(ieta)]/divide)), 0x3FF);
00431 else inputLUT[id][j] = (LUT) std::min(std::max(0,int((adc2fC_ - ped_)*gain_*Rcalib[abs(ieta)+43]/divide)), 0x3FF);
00432 }
00433 }
00434 }
00435 for (int ieta=-29; ieta <= 29; ieta++) {
00436 HcalDetId cell(HcalEndcap,ieta,iphi,depth);
00437 if (theTopo.valid(cell)) {
00438 if (abs(ieta) < 21) divide = 1.*nominal_gain;
00439 else if (abs(ieta) < 27) divide = 2.*nominal_gain;
00440 else divide = 5.*nominal_gain;
00441 id = GetLUTID(HcalEndcap,ieta,iphi,depth);
00442 if (inputLUT[id] == 0) throw cms::Exception("PROBLEM: inputLUT has not been initialized for HE, ieta, iphi, depth, id = ") << ieta << "," << iphi << "," << depth << "," << id << std::endl;
00443
00444 HcalCalibrations calibrations = conditions.getHcalCalibrations(cell);
00445 const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
00446 HcalCoderDb coder (*channelCoder, *shape);
00447 float ped_ = (calibrations.pedestal(0)+calibrations.pedestal(1)+calibrations.pedestal(2)+calibrations.pedestal(3))/4;
00448 float gain_= (calibrations.respcorrgain(0)+calibrations.respcorrgain(1)+calibrations.respcorrgain(2)+calibrations.respcorrgain(3))/4;
00449 HBHEDataFrame frame(cell);
00450 frame.setSize(1);
00451 CaloSamples samples(cell, 1);
00452 _ped[id] = ped_;
00453 _gain[id] = gain_;
00454 for (int j = 0; j <= 0x7F; j++) {
00455 HcalQIESample adc(j);
00456 frame.setSample(0,adc);
00457 coder.adc2fC(frame,samples);
00458 float adc2fC_ = samples[0];
00459 if ( ieta < 0 ) inputLUT[id][j] = (LUT) std::min(std::max(0,int((adc2fC_ - ped_)*gain_*Rcalib[abs(ieta)+1]/divide)), 0x3FF);
00460 else inputLUT[id][j] = (LUT) std::min(std::max(0,int((adc2fC_ - ped_)*gain_*Rcalib[abs(ieta)+44]/divide)), 0x3FF);
00461 }
00462 }
00463 }
00464 for (int ieta=-41; ieta <= 41; ieta++) {
00465 HcalDetId cell(HcalForward,ieta,iphi,depth);
00466 if (theTopo.valid(cell)) {
00467 id = GetLUTID(HcalForward,ieta,iphi,depth);
00468 if (inputLUT[id] == 0) throw cms::Exception("PROBLEM: inputLUT has not been initialized for HF, ieta, iphi, depth, id = ") << ieta << "," << iphi << "," << depth << "," << id << std::endl;
00469
00470 HcalCalibrations calibrations = conditions.getHcalCalibrations(cell);
00471 const HcalQIECoder* channelCoder = conditions.getHcalCoder (cell);
00472 HcalCoderDb coder (*channelCoder, *shape);
00473 float ped_ = (calibrations.pedestal(0)+calibrations.pedestal(1)+calibrations.pedestal(2)+calibrations.pedestal(3))/4;
00474 float gain_= (calibrations.respcorrgain(0)+calibrations.respcorrgain(1)+calibrations.respcorrgain(2)+calibrations.respcorrgain(3))/4;
00475
00476
00477 HFDataFrame frame(cell);
00478 frame.setSize(1);
00479 CaloSamples samples(cell, 1);
00480 _ped[id] = ped_;
00481 _gain[id] = gain_;
00482 for (int j = 0; j <= 0x7F; j++) {
00483 HcalQIESample adc(j);
00484 frame.setSample(0,adc);
00485 coder.adc2fC(frame,samples);
00486 float adc2fC_ = samples[0];
00487 if (ieta < 0 ) inputLUT[id][j] = (LUT) std::min(std::max(0,int((adc2fC_ - ped_)*Rcalib[abs(ieta)+2]*gain_/lsb_/cosheta_[abs(ieta)])), 0x3FF);
00488 else inputLUT[id][j] = (LUT) std::min(std::max(0,int((adc2fC_ - ped_)*Rcalib[abs(ieta)+45]*gain_/lsb_/cosheta_[abs(ieta)])), 0x3FF);
00489 }
00490 }
00491 }
00492 }
00493 }
00494 }
00495
00496 void HcaluLUTTPGCoder::adc2Linear(const HBHEDataFrame& df, IntegerCaloSamples& ics) const {
00497 int id = GetLUTID(df.id().subdet(), df.id().ieta(), df.id().iphi(), df.id().depth());
00498 if (inputLUT[id]==0) {
00499 throw cms::Exception("Missing Data") << "No LUT for " << df.id();
00500 }
00501 else {
00502 for (int i=0; i<df.size(); i++){
00503 if (df[i].adc() >= INPUT_LUT_SIZE || df[i].adc() < 0) throw cms::Exception("ADC overflow for HBHE tower: ") << i << " adc= " << df[i].adc();
00504 if (inputLUT[id] !=0) ics[i]=inputLUT[id][df[i].adc()];
00505 }
00506 }
00507 }
00508
00509 void HcaluLUTTPGCoder::adc2Linear(const HFDataFrame& df, IntegerCaloSamples& ics) const{
00510 int id = GetLUTID(df.id().subdet(), df.id().ieta(), df.id().iphi(), df.id().depth());
00511 if (inputLUT[id]==0) {
00512 throw cms::Exception("Missing Data") << "No LUT for " << df.id();
00513 } else {
00514 for (int i=0; i<df.size(); i++){
00515 if (df[i].adc() >= INPUT_LUT_SIZE || df[i].adc() < 0)
00516 throw cms::Exception("ADC overflow for HF tower: ") << i << " adc= " << df[i].adc();
00517 if (inputLUT[id] !=0) ics[i]=inputLUT[id][df[i].adc()];
00518 }
00519 }
00520 }
00521
00522 unsigned short HcaluLUTTPGCoder::adc2Linear(HcalQIESample sample, HcalDetId id) const {
00523 int ref = GetLUTID(id.subdet(), id.ieta(), id.iphi(), id.depth());
00524 return inputLUT[ref][sample.adc()];
00525 }
00526
00527 float HcaluLUTTPGCoder::getLUTPedestal(HcalDetId id) const {
00528 int ref = GetLUTID(id.subdet(), id.ieta(), id.iphi(), id.depth());
00529 return _ped[ref];
00530 }
00531
00532 float HcaluLUTTPGCoder::getLUTGain(HcalDetId id) const {
00533 int ref = GetLUTID(id.subdet(), id.ieta(), id.iphi(), id.depth());
00534 return _gain[ref];
00535 }