00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014 #include <iostream>
00015 #include <string>
00016 #include <vector>
00017 #include <sstream>
00018 #include <iconv.h>
00019 #include <sys/time.h>
00020
00021 #include "CalibCalorimetry/HcalTPGAlgos/interface/LutXml.h"
00022 #include "CalibCalorimetry/HcalTPGAlgos/interface/XMLProcessor.h"
00023 #include "FWCore/Utilities/interface/md5.h"
00024 #include "CalibCalorimetry/HcalTPGAlgos/interface/HcalEmap.h"
00025 #include "DataFormats/HcalDetId/interface/HcalDetId.h"
00026 #include "DataFormats/HcalDetId/interface/HcalTrigTowerDetId.h"
00027
00028 using namespace std;
00029
00030
00031
00032
00033
00034
00035
00036
00037
00038
00039
00040
00041
00042
00043
00044
00045
00046
00047
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062
00063
00064
00065
00066 LutXml::Config::_Config()
00067 {
00068 ieta = -1000;
00069 iphi = -1000;
00070 depth = -1;
00071 crate = -1;
00072 slot = -1;
00073 topbottom = -1;
00074 fiber = -1;
00075 fiberchan = -1;
00076 lut_type = -1;
00077 creationtag = "default_tag";
00078
00079 char timebuf[50];
00080 time_t _time = time( NULL );
00081
00082
00083 strftime( timebuf, 50, "%Y-%m-%d %H:%M:%S", gmtime( &_time ) );
00084 creationstamp = timebuf;
00085
00086 formatrevision = "default_revision";
00087 targetfirmware = "default_revision";
00088 generalizedindex = -1;
00089 }
00090
00091 LutXml::LutXml() : XMLDOMBlock( "CFGBrickSet", 1 )
00092 {
00093 init();
00094 }
00095
00096
00097 LutXml::LutXml(InputSource & _source ) : XMLDOMBlock( _source )
00098 {
00099 init();
00100 }
00101
00102
00103 LutXml::LutXml( std::string filename ) : XMLDOMBlock( filename )
00104 {
00105 init();
00106 }
00107
00108
00109 LutXml::~LutXml()
00110 {
00111
00112 XMLString::release(&root);
00113 XMLString::release(&brick);
00114
00115 }
00116
00117
00118 void LutXml::init( void )
00119 {
00120 root = XMLString::transcode("CFGBrickSet");
00121 brick = XMLString::transcode("CFGBrick");
00122 brickElem = 0;
00123
00124 }
00125
00126
00127 std::vector<unsigned int> * LutXml::getLutFast( uint32_t det_id ){
00128
00129
00130
00131
00132
00133
00134
00135
00136
00137 if (lut_map.find(det_id) != lut_map.end()) return &(lut_map)[det_id];
00138 std::cerr << "LUT not found, null pointer is returned" << std::endl;
00139 return 0;
00140 }
00141
00142
00143
00144
00145
00146
00147
00148
00149
00150
00151
00152
00153
00154
00155
00156
00157
00158
00159
00160
00161
00162
00163
00164
00165
00166
00167
00168
00169
00170
00171
00172
00173
00174
00175
00176
00177
00178
00179
00180
00181
00182
00183
00184
00185
00186
00187
00188
00189
00190
00191
00192
00193
00194
00195
00196
00197
00198
00199
00200
00201
00202
00203
00204
00205
00206
00207
00208
00209
00210 void LutXml::addLut( LutXml::Config & _config, XMLDOMBlock * checksums_xml )
00211 {
00212 DOMElement * rootElem = document -> getDocumentElement();
00213
00214 brickElem = document->createElement( XMLProcessor::_toXMLCh("CFGBrick") );
00215 rootElem->appendChild(brickElem);
00216
00217 addParameter( "IETA", "int", _config.ieta );
00218 addParameter( "IPHI", "int", _config.iphi );
00219 addParameter( "CRATE", "int", _config.crate );
00220 addParameter( "SLOT", "int", _config.slot );
00221 addParameter( "TOPBOTTOM", "int", _config.topbottom );
00222 addParameter( "LUT_TYPE", "int", _config.lut_type );
00223 addParameter( "CREATIONTAG", "string", _config.creationtag );
00224 addParameter( "CREATIONSTAMP", "string", _config.creationstamp );
00225 addParameter( "FORMATREVISION", "string", _config.formatrevision );
00226 addParameter( "TARGETFIRMWARE", "string", _config.targetfirmware );
00227 addParameter( "GENERALIZEDINDEX", "int", _config.generalizedindex );
00228 addParameter( "CHECKSUM", "string", get_checksum( _config.lut ) );
00229
00230 if(_config.lut_type==1){
00231 addParameter( "FIBER", "int", _config.fiber );
00232 addParameter( "FIBERCHAN", "int", _config.fiberchan );
00233 addParameter( "DEPTH", "int", _config.depth );
00234 addData( "128", "hex", _config.lut );
00235 }
00236 else if(_config.lut_type==2){
00237 addParameter( "SLB", "int", _config.fiber );
00238 addParameter( "SLBCHAN", "int", _config.fiberchan );
00239 addData( "1024", "hex", _config.lut );
00240 }
00241 else{
00242 std::cout << "Unknown LUT type...produced XML will be incorrect" << std::endl;
00243 }
00244
00245
00246
00247
00248 if ( checksums_xml ){
00249 add_checksum( checksums_xml->getDocument(), _config );
00250 }
00251 }
00252
00253 DOMElement * LutXml::addData( std::string _elements, std::string _encoding, std::vector<unsigned int> _lut )
00254 {
00255 DOMElement * child = document -> createElement( XMLProcessor::_toXMLCh( "Data" ) );
00256 child -> setAttribute( XMLProcessor::_toXMLCh("elements"), XMLProcessor::_toXMLCh( _elements ) );
00257 child -> setAttribute( XMLProcessor::_toXMLCh("encoding"), XMLProcessor::_toXMLCh( _encoding ) );
00258
00259 std::stringstream buf;
00260
00261 for (std::vector<unsigned int>::const_iterator iter = _lut.begin();iter!=_lut.end();iter++){
00262 char buf2[8];
00263 sprintf(buf2,"%x",(*iter));
00264 buf << buf2 << " ";
00265
00266 }
00267
00268 std::string _value = buf . str();
00269
00270 DOMText * data_value = document -> createTextNode( XMLProcessor::_toXMLCh(_value));
00271 child -> appendChild( data_value );
00272
00273 brickElem -> appendChild( child );
00274
00275 return child;
00276 }
00277
00278
00279
00280 DOMElement * LutXml::add_checksum( DOMDocument * parent, Config & config )
00281 {
00282
00283
00284
00285 DOMElement * child = parent -> createElement( XMLProcessor::_toXMLCh( "Data" ) );
00286 child -> setAttribute( XMLProcessor::_toXMLCh("crate"), XMLProcessor::_toXMLCh( config.crate ) );
00287 child -> setAttribute( XMLProcessor::_toXMLCh("slot"), XMLProcessor::_toXMLCh( config.slot ) );
00288 child -> setAttribute( XMLProcessor::_toXMLCh("fpga"), XMLProcessor::_toXMLCh( config.topbottom ) );
00289 child -> setAttribute( XMLProcessor::_toXMLCh("fiber"), XMLProcessor::_toXMLCh( config.fiber ) );
00290 child -> setAttribute( XMLProcessor::_toXMLCh("fiberchan"), XMLProcessor::_toXMLCh( config.fiberchan ) );
00291 child -> setAttribute( XMLProcessor::_toXMLCh("luttype"), XMLProcessor::_toXMLCh( config.lut_type ) );
00292 child -> setAttribute( XMLProcessor::_toXMLCh("elements"), XMLProcessor::_toXMLCh( "1" ) );
00293 child -> setAttribute( XMLProcessor::_toXMLCh("encoding"), XMLProcessor::_toXMLCh( "hex" ) );
00294 DOMText * checksum_value = parent -> createTextNode( XMLProcessor::_toXMLCh( get_checksum(config.lut) ));
00295 child -> appendChild( checksum_value );
00296
00297 parent -> getDocumentElement() -> appendChild( child );
00298
00299 return child;
00300 }
00301
00302
00303
00304 DOMElement * LutXml::addParameter( std::string _name, std::string _type, std::string _value )
00305 {
00306 DOMElement * child = document -> createElement( XMLProcessor::_toXMLCh( "Parameter" ) );
00307 child -> setAttribute( XMLProcessor::_toXMLCh("name"), XMLProcessor::_toXMLCh( _name ) );
00308 child -> setAttribute( XMLProcessor::_toXMLCh("type"), XMLProcessor::_toXMLCh( _type ) );
00309 DOMText * parameter_value = document -> createTextNode( XMLProcessor::_toXMLCh(_value));
00310 child -> appendChild( parameter_value );
00311
00312 brickElem -> appendChild( child );
00313
00314 return child;
00315 }
00316
00317
00318
00319 DOMElement * LutXml::addParameter( std::string _name, std::string _type, int _value )
00320 {
00321 char buf[128];
00322 sprintf(buf, "%d", _value);
00323 std::string str_value = buf;
00324 return addParameter( _name, _type, str_value );
00325 }
00326
00327
00328
00329
00330 std::string & LutXml::getCurrentBrick( void )
00331 {
00332 return getString( brickElem );
00333 }
00334
00335
00336
00337
00338 std::string LutXml::get_checksum( std::vector<unsigned int> & lut )
00339 {
00340 std::stringstream result;
00341 md5_state_t md5er;
00342 md5_byte_t digest[16];
00343 md5_init(&md5er);
00344
00345 if ( lut . size() == 128 ){
00346 unsigned char tool[2];
00347 for (int i=0; i<128; i++) {
00348 tool[0]=lut[i]&0xFF;
00349 tool[1]=(lut[i]>>8)&0xFF;
00350 md5_append(&md5er,tool,2);
00351 }
00352 }
00353
00354 else if ( lut . size() == 1024 ){
00355 unsigned char tool;
00356 for (int i=0; i<1024; i++) {
00357 tool=lut[i]&0xFF;
00358 md5_append(&md5er,&tool,1);
00359 }
00360 }
00361 else{
00362 std::cout << "ERROR: irregular LUT size, do not know how to compute checksum, exiting..." << std::endl;
00363 exit(-1);
00364 }
00365 md5_finish(&md5er,digest);
00366 for (int i=0; i<16; i++) result << std::hex << (((int)(digest[i]))&0xFF);
00367
00368
00369
00370
00371
00372 return result . str();
00373 }
00374
00375
00376 int LutXml::test_access( std::string filename ){
00377
00378
00379 std::cout << "Created map size: " << lut_map.size() << std::endl;
00380
00381 struct timeval _t;
00382 gettimeofday( &_t, NULL );
00383 double _time =(double)(_t . tv_sec) + (double)(_t . tv_usec)/1000000.0;
00384
00385 HcalEmap _emap("./backup/official_emap_v6.04_080905.txt");
00386 std::vector<HcalEmap::HcalEmapRow> & _map = _emap.get_map();
00387 std::cout << "HcalEmap contains " << _map . size() << " entries" << std::endl;
00388
00389 int _counter=0;
00390 for (std::vector<HcalEmap::HcalEmapRow>::const_iterator row=_map.begin(); row!=_map.end(); row++){
00391 if (row->subdet=="HB"){
00392 HcalDetId det_id(HcalBarrel,row->ieta,row->iphi,row->idepth);
00393 uint32_t raw_id = det_id.rawId();
00394 std::vector<unsigned int> * l = getLutFast(raw_id);
00395 if (l) _counter++;
00396 }
00397 if (row->subdet=="HE"){
00398 HcalDetId det_id(HcalEndcap,row->ieta,row->iphi,row->idepth);
00399 uint32_t raw_id = det_id.rawId();
00400 std::vector<unsigned int> * l = getLutFast(raw_id);
00401 if (l) _counter++;
00402 }
00403 if (row->subdet=="HF"){
00404 HcalDetId det_id(HcalForward,row->ieta,row->iphi,row->idepth);
00405 uint32_t raw_id = det_id.rawId();
00406 std::vector<unsigned int> * l = getLutFast(raw_id);
00407 if (l) _counter++;
00408 }
00409 if (row->subdet=="HO"){
00410 HcalDetId det_id(HcalOuter,row->ieta,row->iphi,row->idepth);
00411 uint32_t raw_id = det_id.rawId();
00412 std::vector<unsigned int> * l = getLutFast(raw_id);
00413 if (l) _counter++;
00414 }
00415 }
00416 gettimeofday( &_t, NULL );
00417 std::cout << "access to " << _counter << " HCAL channels took: " << (double)(_t . tv_sec) + (double)(_t . tv_usec)/1000000.0 - _time << "sec" << std::endl;
00418
00419
00420
00421
00422
00423
00424
00425 return 0;
00426 }
00427
00428
00429
00430
00431
00432
00433
00434
00435
00436
00437
00438
00439
00440
00441
00442
00443
00444
00445
00446
00447
00448
00449
00450
00451
00452
00453
00454
00455
00456
00457
00458
00459 HcalSubdetector LutXml::subdet_from_crate(int crate, int eta, int depth){
00460 HcalSubdetector result;
00461
00462
00463
00464
00465 if (crate==2 || crate==9 || crate==12) result=HcalForward;
00466 else if (crate==3 || crate==6 || crate==7 || crate==13) result=HcalOuter;
00467 else if (crate==0 || crate==1 || crate==4 || crate==5 || crate==10 || crate==11 || crate==14 || crate==15 || crate==17){
00468 if (eta<16) result=HcalBarrel;
00469 else if (eta>16) result=HcalEndcap;
00470 else if (eta==16 && depth!=3) result=HcalBarrel;
00471 else if (eta==16 && depth==3) result=HcalEndcap;
00472 else{
00473 std::cerr << "Impossible to determine HCAL subdetector!!!" << std::endl;
00474 exit(-1);
00475 }
00476 }
00477 else{
00478 std::cerr << "Impossible to determine HCAL subdetector!!!" << std::endl;
00479 exit(-1);
00480 }
00481
00482 return result;
00483 }
00484
00485
00486 int LutXml::a_to_i(char * inbuf){
00487 int result;
00488 sscanf(inbuf,"%d",&result);
00489 return result;
00490 }
00491
00492
00493
00494
00495
00496
00497 int LutXml::create_lut_map( void ){
00498
00499 lut_map.clear();
00500
00501
00502 if (document){
00503
00504 DOMNodeList * brick_list = document->getDocumentElement()->getElementsByTagName(brick);
00505 int n_of_bricks = brick_list->getLength();
00506 for(int i=0; i!=n_of_bricks; i++){
00507 DOMElement * aBrick = (DOMElement *)(brick_list->item(i));
00508 DOMNodeList * par_list = aBrick->getElementsByTagName(XMLString::transcode("Parameter"));
00509 int n_of_par = par_list->getLength();
00510 int ieta=-99;
00511 int iphi=-99;
00512 int depth=-99;
00513 int crate=-99;
00514 int lut_type=-99;
00515 HcalSubdetector subdet;
00516 for(int j=0; j!=n_of_par; j++){
00517
00518 DOMElement * aPar = (DOMElement *)(par_list->item(j));
00519 char * aName = XMLString::transcode( aPar->getAttribute(XMLProcessor::_toXMLCh("name")) );
00520 if ( strcmp(aName, "IETA")==0 ) ieta=a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
00521 if ( strcmp(aName, "IPHI")==0 ) iphi=a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
00522 if ( strcmp(aName, "DEPTH")==0 ) depth=a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
00523 if ( strcmp(aName, "CRATE")==0 ) crate=a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
00524 if ( strcmp(aName, "LUT_TYPE")==0 ) lut_type=a_to_i(XMLString::transcode(aPar->getFirstChild()->getNodeValue()));
00525 }
00526 subdet=subdet_from_crate(crate,abs(ieta),depth);
00527
00528 DOMElement * _data = (DOMElement *)(aBrick->getElementsByTagName(XMLString::transcode("Data"))->item(0));
00529 char * _str = XMLString::transcode(_data->getFirstChild()->getNodeValue());
00530
00531
00532
00533 int _string_length = strlen(_str);
00534 std::vector<unsigned int> _lut;
00535 unsigned int _base = 16;
00536 unsigned int _item=0;
00537 for (int i=0; i!=_string_length; i++){
00538 bool _range;
00539 char ch_cur = _str[i];
00540 if (_base==16) _range = (ch_cur>='0' and ch_cur<='9') || (ch_cur>='a' and ch_cur<='f') || (ch_cur>='A' and ch_cur<='F');
00541 else if (_base==10) _range = (ch_cur>='0' and ch_cur<='9');
00542 if ( _range ){
00543 if ( ch_cur>='a' and ch_cur<='f' ) ch_cur += 10-'a';
00544 else if ( ch_cur>='A' and ch_cur<='F' ) ch_cur += 10-'A';
00545 else if ( ch_cur>='0' and ch_cur<='9' ) ch_cur += -'0';
00546 _item = _item*_base;
00547 _item += ch_cur;
00548 bool last_digit = false;
00549 if ( (i+1)==_string_length ) last_digit=true;
00550 else{
00551 char ch_next = _str[i+1];
00552 bool _range_next;
00553 if (_base==16) _range_next = (ch_next>='0' and ch_next<='9') || (ch_next>='a' and ch_next<='f') || (ch_next>='A' and ch_next<='F');
00554 else if (_base==10) _range_next = (ch_next>='0' and ch_next<='9');
00555 if ( !_range_next ) last_digit=true;
00556 }
00557 if (last_digit){
00558 _lut.push_back(_item);
00559 _item=0;
00560 }
00561 }
00562 }
00564
00565
00566 uint32_t _key = 0;
00567 if (lut_type==1){
00568 HcalDetId _id(subdet,ieta,iphi,depth);
00569 _key = _id.rawId();
00570 }
00571 else if (lut_type==2){
00572 HcalTrigTowerDetId _id(ieta,iphi);
00573 _key = _id.rawId();
00574 }
00575
00576 lut_map.insert(std::pair<uint32_t,std::vector<unsigned int> >(_key,_lut));
00577 }
00578 }
00579 else{
00580 std::cerr << "XML file with LUTs is not loaded, cannot create map!" << std::endl;
00581 }
00582
00583
00584
00585 return 0;
00586 }
00587
00588 LutXml::const_iterator LutXml::begin() const{
00589 return lut_map.begin();
00590 }
00591
00592 LutXml::const_iterator LutXml::end() const{
00593 return lut_map.end();
00594 }
00595
00596 LutXml::const_iterator LutXml::find(uint32_t id) const{
00597 return lut_map.find(id);
00598 }