00001
00008 #include "ValBase.h"
00009
00010 #include "GaudiKernel/IDataProviderSvc.h"
00011 #include "GaudiKernel/SmartDataPtr.h"
00012 #include "GaudiKernel/IIncidentSvc.h"
00013 #include "GaudiKernel/MsgStream.h"
00014
00015 #include "Event/TopLevel/EventModel.h"
00016 #include "Event/TopLevel/Event.h"
00017
00018 #include <algorithm>
00019 #include <cassert>
00020
00021 const int ValBase::s_badVal = -9999;
00022
00023 ValBase::ValBase(const std::string& type,
00024 const std::string& name,
00025 const IInterface* parent)
00026 : AlgTool( type, name, parent ), m_loadOrder(-1) { }
00027
00028
00029 StatusCode ValBase::initialize()
00030 {
00031
00032 IIncidentSvc* incsvc = 0;
00033 IDataProviderSvc* eventsvc = 0;
00034
00035 m_newEvent = true;
00036 m_check = CHECK;
00037 m_calcCount = 0;
00038
00039 m_ntupleMap.clear();
00040
00041 MsgStream log(msgSvc(), name());
00042
00043 StatusCode sc = StatusCode::FAILURE;
00044
00045 log << MSG::INFO << "ValBase is initializing" << endreq;
00046
00047 if (serviceLocator()) {
00048 sc = serviceLocator()->service( "IncidentSvc", incsvc, true );
00049 if(sc.isFailure()){
00050 log << MSG::ERROR << "Could not find IncidentSvc" << std::endl;
00051 return sc;
00052 }
00053 m_incSvc = incsvc;
00054
00055 sc = serviceLocator()->service( "EventDataSvc", eventsvc, true );
00056 if(sc.isFailure()){
00057 log << MSG::ERROR << "Could not find EventDataSvc" << std::endl;
00058 return sc;
00059 }
00060 m_pEventSvc = eventsvc;
00061 }
00062
00063
00064 incsvc->addListener(this, "BeginEvent", 100);
00065 return sc;
00066 }
00067
00068 ValBase::~ValBase()
00069 {
00070 mapIter it = m_ntupleMap.begin();
00071 for ( ; it!=m_ntupleMap.end(); ++it) {
00072 delete (*it)->second;
00073 delete (*it);
00074 }
00075 }
00076
00077 void ValBase::zeroVals()
00078 {
00079 mapIter it = m_ntupleMap.begin();
00080 for ( ; it!=m_ntupleMap.end(); ++it) {
00081 TypedPointer* ptr = ((*it)->second);
00082 void* vPtr = ptr->getPointer();
00083 valType type = ptr->getType();
00084 int dim = ptr->getDim();
00085
00086
00087
00088 int i;
00089 for (i=0; i<dim; ++i) {
00090 switch (type) {
00091 case FLOAT:
00092 *(reinterpret_cast<float*>(vPtr)+i) = 0.0;
00093
00094 break;
00095 case DOUBLE:
00096 *(reinterpret_cast<double*>(vPtr)+i) = 0.0;
00097 break;
00098 case INT:
00099 *(reinterpret_cast<int*>(vPtr)+i) = 0;
00100 break;
00101 case UINT:
00102 *(reinterpret_cast<unsigned int*>(vPtr)+i) = 0;
00103
00104 break;
00105 case ULONG64:
00106 *(reinterpret_cast<unsigned long long*>(vPtr)+i) = 0;
00107
00108 break;
00109 case STRING:
00110 if (i==0) strcpy(reinterpret_cast<char*>(vPtr), "_");
00111
00112
00113 break;
00114 }
00115 }
00116 }
00117 }
00118
00119 std::string ValBase::getFullName(std::string varName, int dim)
00120 {
00121 char buffer[6];
00122 sprintf(buffer, "[%i]", dim);
00123 std::string fullName = varName+buffer;
00124 return fullName;
00125 }
00126
00127 bool ValBase::getArrayArg(std::string varName, std::string& baseName, int& arg)
00128 {
00129 MsgStream log(msgSvc(), name());
00130
00131 arg = -1;
00132 baseName = varName;
00133 bool hasArg = false;
00134
00135 int pos1, pos2;
00136 pos1 = varName.find("[");
00137 if (pos1!=-1) {
00138 pos2 = varName.find("]");
00139 if (pos2<pos1+2) {
00140 log << MSG::ERROR << "variable " << varName << " out of range or malformed" << endreq;
00141 log << MSG::ERROR << "Character positions " << pos1 << " " << pos2 << endreq;
00142 assert(pos2<pos1+2);
00143 return hasArg;
00144 } else {
00145 std::string strDim = varName.substr(pos1+1, pos2-pos1-1);
00146 arg = atoi(strDim.c_str());
00147 if(arg<0) {
00148 log << MSG::ERROR << "variable " << varName << " out of range or malformed" << endreq;
00149 log << MSG::ERROR << "argString = " << strDim << ", arg = " << arg << endreq;
00150 assert(arg<0);
00151 return hasArg;
00152 }
00153 baseName = varName.substr(0,pos1);
00154 hasArg = true;
00155 return hasArg;
00156 }
00157 } else {
00158 arg = 1;
00159 return hasArg;
00160 }
00161 }
00162
00163
00164
00165
00166 void ValBase::addItem(std::string varName, double* pValue)
00167 {
00168 std::string baseName;
00169 int dim;
00170 getArrayArg(varName, baseName, dim);
00171 TypedPointer* ptr = new TypedPointer(DOUBLE, (void*) pValue, dim);
00172 valPair* pair = new valPair(baseName, ptr);
00173
00174 m_ntupleMap.push_back(pair);
00175 }
00176
00177 void ValBase::addItem(std::string varName, float* pValue)
00178 {
00179 std::string baseName;
00180 int dim;
00181 getArrayArg(varName, baseName, dim);
00182 TypedPointer* ptr = new TypedPointer(FLOAT, (void*) pValue, dim);
00183 valPair* pair = new valPair(baseName, ptr);
00184
00185 m_ntupleMap.push_back(pair);
00186 }
00187 void ValBase::addItem(std::string varName, int* pValue)
00188 {
00189 std::string baseName;
00190 int dim;
00191 getArrayArg(varName, baseName, dim);
00192 TypedPointer* ptr = new TypedPointer(INT, (void*) pValue, dim);
00193 valPair* pair = new valPair(baseName, ptr);
00194
00195 m_ntupleMap.push_back(pair);
00196 }
00197
00198 void ValBase::addItem(std::string varName, unsigned int* pValue)
00199 {
00200 std::string baseName;
00201 int dim;
00202 getArrayArg(varName, baseName, dim);
00203 TypedPointer* ptr = new TypedPointer(UINT, (void*) pValue, dim);
00204 valPair* pair = new valPair(baseName, ptr);
00205
00206 m_ntupleMap.push_back(pair);
00207 }
00208
00209 void ValBase::addItem(std::string varName, unsigned long long* pValue)
00210 {
00211 std::string baseName;
00212 int dim;
00213 getArrayArg(varName, baseName, dim);
00214 TypedPointer* ptr = new TypedPointer(ULONG64, (void*) pValue, dim);
00215 valPair* pair = new valPair(baseName, ptr);
00216
00217 m_ntupleMap.push_back(pair);
00218 }
00219
00220 void ValBase::addItem(std::string varName, char* pValue)
00221 {
00222 std::string baseName;
00223 int dim;
00224 bool hasArg = getArrayArg(varName, baseName, dim);
00225 if(hasArg) {
00226 dim = 1;
00227 std::cout << std::endl << "AnalysisNtuple/varBase " << std::endl;
00228 std::cout << " " << varName << ": arrays of strings not allowed" << std::endl;
00229 std::cout << " first one will be used... " << std::endl << std::endl;
00230 }
00231
00232 TypedPointer* ptr = new TypedPointer(STRING, (void*) pValue, dim);
00233 valPair* pair = new valPair(baseName, ptr);
00234
00235 m_ntupleMap.push_back(pair);
00236 }
00237
00238 StatusCode ValBase::browse(MsgStream log, std::string varName0)
00239 {
00240
00241
00242 m_check = CALC;
00243
00244
00245
00246 std::string delim = "";
00247 std::string separator = " ";
00248 std::string indent = " ";
00249
00250 if(doCalcIfNotDone().isFailure()) {
00251 m_check = CHECK;
00252 return StatusCode::FAILURE;
00253 }
00254 m_check = CHECK;
00255
00256 std::string varName;
00257 int element;
00258 bool hasArg = getArrayArg(varName0, varName, element);
00259 if (!hasArg) element = 0;
00260 bool doAll = !hasArg;
00261
00262
00263 if (varName!="") {
00264 log << MSG::INFO << " Variable " ;
00265 } else {
00266 log << MSG::INFO << " Values of the variables:" << endreq << indent;
00267 }
00268 int length = indent.size();
00269 constMapIter it = m_ntupleMap.begin();
00270
00271 for ( ; it!=m_ntupleMap.end(); ++it) {
00272 valPair* pair = *it;
00273 if (varName!="" && varName!=pair->first) continue;
00274 int valLen = 13;
00275 int deltaL= (pair->first).size() + 2*delim.size() + separator.size() + valLen + 2;
00276 length += deltaL;
00277 if(length>78) {
00278 log << MSG::INFO << endreq << indent ;
00279 length = indent.size() + deltaL;
00280 }
00281 log << delim << pair->first << delim << ": " ;
00282
00283 TypedPointer* ptr = (*it)->second;
00284 valType type = ptr->getType();
00285 int dim = ptr->getDim();
00286 if(element>=dim || element<0) {
00287 log << MSG::ERROR << "Browse: error in arg: " << element << endreq;
00288 assert(element>=dim || element<0);
00289 }
00290
00291 int start = (doAll ? 0 : element);
00292 int end = (doAll ? dim-1 : element);
00293 void* vPtr = ptr->getPointer();
00294
00295 int i;
00296 if (doAll && dim>1) log << "(";
00297
00298
00299
00300 for (i=start; i<=end; ++i) {
00301
00302 switch (type) {
00303 case FLOAT:
00304 log << *(reinterpret_cast<float*>(vPtr)+i);
00305 break;
00306 case DOUBLE:
00307 log << *(reinterpret_cast<double*>(vPtr)+i);
00308 break;
00309 case INT:
00310 log << *(reinterpret_cast<int*>(vPtr)+i);
00311 break;
00312 case UINT:
00313 log << *(reinterpret_cast<unsigned int*>(vPtr)+i);
00314 break;
00315 case ULONG64:
00316 log << *(reinterpret_cast<unsigned long long*>(vPtr)+i);
00317 break;
00318 default:
00319 break;
00320 }
00321
00322 if(doAll && dim>1) {
00323 log << (i==dim-1 ? ")" : ",");
00324 }
00325 log << separator;
00326 }
00327
00328 }
00329 log << endreq;
00330 return StatusCode::SUCCESS;
00331 }
00332
00333 StatusCode ValBase::doCalcIfNotDone()
00334 {
00335 StatusCode sc = StatusCode::SUCCESS;
00336
00337 MsgStream log(msgSvc(), name());
00338
00339
00340
00341
00342
00343 if(m_check!=NOCALC) {
00344 if(m_newEvent || m_check==CALC) {
00345 if (!m_pEventSvc) return StatusCode::FAILURE;
00346 zeroVals();
00347 ++m_calcCount;
00348 sc = calculate();
00349
00350
00351 if(m_check==CHECK) m_newEvent = false;
00352 }
00353 }
00354 return sc;
00355 }
00356
00357
00358
00359 StatusCode ValBase::getValCheck(std::string varName, double& value)
00360 {
00361
00362 return getVal(varName, value, CHECK);
00363 }
00364 StatusCode ValBase::getValCheck(std::string varName, float& value)
00365 {
00366
00367 return getVal(varName, value, CHECK);
00368 }
00369 StatusCode ValBase::getValCheck(std::string varName, int& value)
00370 {
00371
00372 return getVal(varName, value, CHECK);
00373 }
00374
00375 StatusCode ValBase::getValCheck(std::string varName, unsigned int& value)
00376 {
00377
00378 return getVal(varName, value, CHECK);
00379 }
00380
00381 StatusCode ValBase::getValCheck(std::string varName, unsigned long long& value)
00382 {
00383
00384 return getVal(varName, value, CHECK);
00385 }
00386 StatusCode ValBase::getValCheck(std::string varName, std::string& value)
00387 {
00388
00389 return getVal(varName, value, CHECK);
00390 }
00391
00392 StatusCode ValBase::getTypedPointer(std::string varName, TypedPointer*& ptr, int check)
00393 {
00394
00395
00396 StatusCode sc = StatusCode::SUCCESS;
00397
00398 m_check = check;
00399
00400 constMapIter it = m_ntupleMap.begin();
00401 for ( ; it!=m_ntupleMap.end(); ++it) {
00402 if ((*it)->first == varName) break;
00403 }
00404
00405 if (it==m_ntupleMap.end()) {
00406 announceBadName(varName);
00407 m_check = CHECK;
00408 return StatusCode::FAILURE;
00409 } else {
00410 if(doCalcIfNotDone().isFailure()) {
00411 m_check = CHECK;
00412 return StatusCode::FAILURE;
00413 }
00414 ptr = (*it)->second;
00415 }
00416 m_check = CHECK;
00417 return sc;
00418 }
00419
00420 StatusCode ValBase::getVal(std::string varName, std::string& value, int check)
00421 {
00422 MsgStream log(msgSvc(), name());
00423
00424 char buffer[80];
00425 TypedPointer* ptr = 0;
00426 value = "";
00427
00428 std::string baseName;
00429 int element;
00430 bool hasArg = getArrayArg(varName, baseName, element);
00431 if(!hasArg) element = 0;
00432 StatusCode sc = getTypedPointer(baseName, ptr, check);
00433 if(sc.isFailure()) return sc;
00434
00435 void* vPtr = ptr->getPointer();
00436
00437 int dim = ptr->getDim();
00438 if (element>=dim || element<0)
00439 {
00440 log << MSG::ERROR << "GetVal: element " << varName << " out of range" << endreq;
00441 assert(element<dim && element>-1);
00442 }
00443
00444 valType type = ptr->getType();
00445
00446
00447
00448 if(sc.isSuccess()) {
00449 if (type==FLOAT) { sprintf(buffer, "%g",
00450 *(reinterpret_cast<float*>(vPtr)+element));}
00451 else if (type==DOUBLE) { sprintf(buffer, "%g",
00452 *(reinterpret_cast<double*>(vPtr)+element));}
00453 else if (type==INT) { sprintf(buffer, "%i",
00454 *(reinterpret_cast<int*>(vPtr)+element));}
00455 else if (type==UINT) { sprintf(buffer, "%u",
00456 *(reinterpret_cast<unsigned int*>(vPtr)+element));}
00457 else if (type==ULONG64) { sprintf(buffer, "%u",
00458 *(reinterpret_cast<unsigned long long*>(vPtr)+element));}
00459 }
00460 value = std::string(buffer);
00461 return sc;
00462 }
00463
00464
00465
00466 StatusCode ValBase::getVal(std::string varName, int& value, int check)
00467 {
00468 MsgStream log(msgSvc(), name());
00469 TypedPointer* ptr = 0;
00470 value = 0;
00471
00472 std::string baseName;
00473 int element;
00474 bool hasArg = getArrayArg(varName, baseName, element);
00475 if(!hasArg) element = 0;
00476
00477 StatusCode sc = getTypedPointer(baseName, ptr, check);
00478 if(sc.isFailure()) return sc;
00479
00480 int dim = ptr->getDim();
00481 if (element>=dim || element<0)
00482 {
00483 log << MSG::ERROR << "GetVal: element " << varName << " out of range" << endreq;
00484 assert(element<dim && element>-1);
00485 }
00486
00487 value = *(reinterpret_cast<int*>(ptr->getPointer())+element);
00488
00489 return sc;
00490 }
00491
00492 StatusCode ValBase::getVal(std::string varName, unsigned int& value, int check)
00493 {
00494 MsgStream log(msgSvc(), name());
00495 TypedPointer* ptr = 0;
00496 value = 0;
00497
00498 std::string baseName;
00499 int element;
00500 bool hasArg = getArrayArg(varName, baseName, element);
00501
00502 StatusCode sc = getTypedPointer(baseName, ptr, check);
00503 if(sc.isFailure()) return sc;
00504
00505 if(!hasArg) element = 0;
00506 int dim = ptr->getDim();
00507 if (element>=dim || element<0)
00508 {
00509 log << MSG::ERROR << "GetVal: element " << varName << " out of range" << endreq;
00510 assert(element<dim && element>-1);
00511 }
00512
00513 value = *(reinterpret_cast<unsigned int*>(ptr->getPointer())+element);
00514
00515 return sc;
00516 }
00517
00518 StatusCode ValBase::getVal(std::string varName, unsigned long long& value, int check)
00519 {
00520 MsgStream log(msgSvc(), name());
00521 TypedPointer* ptr = 0;
00522 value = 0;
00523
00524 std::string baseName;
00525 int element;
00526 bool hasArg = getArrayArg(varName, baseName, element);
00527
00528 StatusCode sc = getTypedPointer(baseName, ptr, check);
00529 if(sc.isFailure()) return sc;
00530
00531 if(!hasArg) element = 0;
00532 int dim = ptr->getDim();
00533 if (element>=dim || element<0)
00534 {
00535 log << MSG::ERROR << "GetVal: element " << varName << " out of range" << endreq;
00536 assert(element<dim && element>-1);
00537 }
00538
00539 value = *(reinterpret_cast<unsigned long long*>(ptr->getPointer())+element);
00540
00541 return sc;
00542 }
00543
00544
00545 StatusCode ValBase::getVal(std::string varName, double& value, int check)
00546 {
00547 MsgStream log(msgSvc(), name());
00548 TypedPointer* ptr = 0;
00549 value = 0.0;
00550
00551 std::string baseName;
00552 int element;
00553 bool hasArg = getArrayArg(varName, baseName, element);
00554 if(!hasArg) element = 0;
00555
00556 StatusCode sc = getTypedPointer(baseName, ptr, check);
00557 if(sc.isFailure()) return sc;
00558 int dim = ptr->getDim();
00559 if (element>=dim || element<0)
00560 {
00561 log << MSG::ERROR << "GetVal: element " << varName << " out of range" << endreq;
00562 assert(element<dim && element>-1);
00563 }
00564
00565 value = *(reinterpret_cast<double*>(ptr->getPointer())+element);
00566
00567 return sc;
00568 }
00569
00570 StatusCode ValBase::getVal(std::string varName, float& value, int check)
00571 {
00572 MsgStream log(msgSvc(), name());
00573 TypedPointer* ptr = 0;
00574 value = 0.0;
00575
00576 std::string baseName;
00577 int element;
00578 bool hasArg = getArrayArg(varName, baseName, element);
00579
00580 StatusCode sc = getTypedPointer(baseName, ptr, check);
00581 if(sc.isFailure()) return sc;
00582
00583 int dim = ptr->getDim();
00584 if(!hasArg) element = 0;
00585 if (element>=dim || element<0)
00586 {
00587 log << MSG::ERROR << "GetVal: element " << varName << " out of range" << endreq;
00588 assert(element<dim && element>-1);
00589 }
00590
00591 value = *(reinterpret_cast<float*>(ptr->getPointer())+element);
00592
00593 return sc;
00594 }
00595
00596 void ValBase::announceBadName(std::string varName)
00597 {
00598 MsgStream log(msgSvc(), name());
00599
00600 std::string delim = "";
00601 std::string separator = " ";
00602 std::string indent = " ";
00603
00604 std::cout << " ValsTool called with unknown name: " << delim << varName << delim << std::endl;
00605
00606
00607
00608
00609
00610
00611
00612
00613
00614
00615
00616
00617
00618
00619
00620
00621
00622
00623
00624
00625
00626
00627
00628 }
00629
00630 StatusCode ValBase::calculate() {
00631
00632 MsgStream log(msgSvc(), name());
00633
00634 std::cout << "No specific calc routine defined!" << std::endl;
00635 return StatusCode::SUCCESS;
00636 }
00637
00638 void ValBase::handle(const Incident & inc)
00639 {
00640 MsgStream log(msgSvc(), name());
00641
00642 if(inc.type()=="BeginEvent") {
00643
00644 m_newEvent = true;
00645 m_calcCount = 0;
00646 }
00647 }
00648
00649 IValsTool::Visitor::eVisitorRet ValBase::traverse(IValsTool::Visitor* v,
00650 const bool checkCalc)
00651 {
00652 IValsTool::Visitor::eVisitorRet ret = IValsTool::Visitor::DONE;
00653
00654 if (checkCalc) {
00655 if(doCalcIfNotDone().isFailure()) return IValsTool::Visitor::ERROR;
00656 }
00657
00658 constMapIter it = m_ntupleMap.begin();
00659 for ( ; it!=m_ntupleMap.end(); ++it) {
00660 valPair* pair = *it;
00661 TypedPointer* ptr = pair->second;
00662 valType type = ptr->getType();
00663 void* vPtr = ptr->getPointer();
00664 std::string varName = pair->first;
00665
00666
00667 std::string fullName = varName;
00668 int dim = ptr->getDim();
00669 if (dim>1) {
00670 fullName = getFullName(varName, dim);
00671 }
00672
00673
00674
00675
00676 switch (type) {
00677 case FLOAT:
00678 ret = v->analysisValue(fullName, *(reinterpret_cast<float*>(vPtr)));
00679
00680 break;
00681 case DOUBLE:
00682 ret = v->analysisValue(fullName, *(reinterpret_cast<double*>(vPtr)));
00683 break;
00684 case UINT:
00685 ret = v->analysisValue(fullName, *(reinterpret_cast<unsigned int*>(vPtr)));
00686 break;
00687 case ULONG64:
00688 ret = v->analysisValue(fullName, *(reinterpret_cast<unsigned long long*>(vPtr)));
00689 break;
00690 case INT:
00691 ret = v->analysisValue(fullName, *(reinterpret_cast<int*>(vPtr)));
00692
00693 break;
00694 case STRING:
00695 ret = v->analysisValue(fullName, (reinterpret_cast<char*>(vPtr)));
00696
00697 break;
00698 }
00699
00700 if (ret!= IValsTool::Visitor::CONT) return ret;
00701 }
00702 return IValsTool::Visitor::DONE;
00703 }
00704
00705 void ValBase::printHeader(MsgStream& log)
00706 {
00707 SmartDataPtr<Event::EventHeader> header(m_pEventSvc, EventModel::EventHeader);
00708 unsigned long evtId = (header) ? header->event() : 0;
00709 long runId = (header) ? header->run() : -1;
00710 log << MSG::WARNING << "Caught exception (run,event): ( "
00711 << runId << ", " << evtId << " ) " << endreq;
00712 }
00713
00714 void ValBase::setAnaTupBit()
00715 {
00716 SmartDataPtr<Event::EventHeader> header(m_pEventSvc, EventModel::EventHeader);
00717 if(header) header->setAnalysisNtupleError();
00718 }