00001
00002
00003 #include <cstdlib>
00004
00005 #include "GaudiKernel/DataObject.h"
00006 #include "GaudiKernel/Tokenizer.h"
00007 #include "GaudiKernel/SvcFactory.h"
00008 #include "GaudiKernel/GaudiException.h"
00009 #include "GaudiKernel/ISvcLocator.h"
00010 #include "GaudiKernel/IConversionSvc.h"
00011 #include "GaudiKernel/GenericAddress.h"
00012 #include "GaudiKernel/MsgStream.h"
00013 #include "GaudiKernel/Property.h"
00014 #include "GaudiKernel/IRegistry.h"
00015
00016 #include "AIDATupleSvc.h"
00017
00018
00019
00020 #include "CLHEP/Random/RandGauss.h"
00021 #include "CLHEP/Random/DRand48Engine.h"
00022 #include <math.h>
00023
00024
00025 namespace CLHEP { }
00026 using namespace CLHEP;
00027
00034 StatusCode AIDATupleSvc::myTest()
00035 {
00036 MsgStream log ( msgSvc(), name() );
00037 log << MSG::INFO << "Welcome to myTest!" << endmsg;
00038
00039
00040 std::string description = "float px; float py; float pz; float mass";
00041
00042 pi_aida::Proxy_Store* store = new pi_aida::Proxy_Store("ntuple.root","POOL",0,"CAT=xmlcatalog_file:anotherCatalog.xml,SUB=POOL_ROOTTREE");
00043 pi_aida::Tuple tuple(*store, "1", "tuple1", description);
00044
00045
00046 DRand48Engine randomEngine;
00047 RandGauss rBeamEnergy( randomEngine, 90, 5 );
00048 RandGauss rTracksSpread( randomEngine, 0, 2 );
00049 RandGauss rMomentum( randomEngine, 0, 3 );
00050 RandGauss rMass( randomEngine, 1, 0.1 );
00051
00052 std::cout << "Tuple created ... starting to fill " << std::endl;
00053
00054 int i_px = tuple.findColumn( "px" );
00055 int i_py = tuple.findColumn( "py" );
00056 int i_pz = tuple.findColumn( "pz" );
00057 int i_mass = tuple.findColumn( "mass" );
00058
00059 for ( unsigned int i = 0; i < 1000; i++ ) {
00060
00061 tuple.fill( i_px, rMomentum.fire() );
00062 tuple.fill( i_py, rMomentum.fire() );
00063 tuple.fill( i_pz, rMomentum.fire() );
00064 tuple.fill( i_mass, rMass.fire() );
00065 tuple.addRow();
00066 }
00067 std::cout << "Filled the tuple with " << tuple.rows() << " rows" << std::endl;
00068 store->close();
00069 delete store;
00070
00071 pi_aida::Proxy_Store* store1 = new pi_aida::Proxy_Store("ntuple.root","POOL",3,"CAT=xmlcatalog_file:anotherCatalog.xml,SUB=POOL_ROOTTREE");
00072 pi_aida::Tuple tuple1 = store1->retrieveTuple("1");
00073
00074
00075
00076
00077 std::cout << "FOUND TUPLE WITH " << tuple1.rows() << " ROWS" << std::endl;
00078
00079 tuple1.start();
00080 int i = 0;
00081 while( tuple1.next() ) {
00082 i++;
00083 std::cout << "ROW " << i << std::endl;
00084 std::cout << "px: " << tuple1.getFloat(i_px) << std::endl;
00085 std::cout << "py: " << tuple1.getFloat(i_py) << std::endl;
00086 std::cout << "pz: " << tuple1.getFloat(i_pz) << std::endl;
00087 std::cout << "mass: " << tuple1.getFloat(i_mass) << std::endl;
00088 }
00089 store1->close();
00090 delete store1;
00091 return StatusCode::SUCCESS;
00092 }
00093
00094
00095
00096
00097
00098 AIDA::ITuple* AIDATupleSvc::book( const std::string& fullPath,
00099 const std::string& title,
00100 const std::string& columns )
00101 {
00102 std::string dirPath, objPath, storePath, storeObj;
00103 parsePath( fullPath, dirPath, objPath, storePath, storeObj);
00104
00105 Connections::iterator i = m_connections.find(storePath);
00106 if( i != m_connections.end() ) {
00107 pi_aida::Tuple* tmp = new pi_aida::Tuple( *(*i).second, storeObj, title, columns );
00108 AIDA::ITuple* tuple = tmp;
00109
00110 if( registerObject(dirPath, objPath, tuple).isSuccess() )
00111 return tuple;
00112 else {
00113 delete tuple;
00114 throw GaudiException("Cannot book tuple " + title,"AIDATupleSvc", StatusCode::FAILURE);
00115 }
00116 }
00117 else
00118 throw GaudiException("Cannot find store " + storePath, "AIDATupleSvc", StatusCode::FAILURE);
00119 }
00120
00121
00122 AIDA::ITuple* AIDATupleSvc::book( const std::string& parentPath,
00123 const std::string& objPath,
00124 const std::string& title,
00125 const std::string& columns )
00126 {
00127 std::string fullPath = parentPath+"/"+objPath;
00128 return book( fullPath, title, columns );
00129 }
00130
00131
00132 AIDA::ITuple* AIDATupleSvc::book( const std::string& parentPath,
00133 int tupleID,
00134 const std::string& title,
00135 const std::string& columns )
00136 {
00137 char objPath[32];
00138 ::_itoa(tupleID, objPath, 10);
00139 std::string fullPath = parentPath+"/"+objPath;
00140 return book( fullPath, title, columns );
00141 }
00142
00143
00144 AIDA::ITuple* AIDATupleSvc::book( DataObject* pParent,
00145 const std::string& objPath,
00146 const std::string& title,
00147 const std::string& columns )
00148 {
00149 IRegistry* tmp = pParent->registry();
00150 std::string fullPath, parentPath;
00151 parentPath = tmp->identifier();
00152 fullPath = fullPath = parentPath+"/"+objPath;
00153 return book( fullPath, title, columns );
00154 }
00155
00156
00157 AIDA::ITuple* AIDATupleSvc::book( DataObject* pParent,
00158 int tupleID,
00159 const std::string& title,
00160 const std::string& columns )
00161 {
00162 char txt[32];
00163 return book( pParent, ::_itoa(tupleID, txt, 10), title, columns );
00164 }
00165
00166
00167
00168
00169
00170 StatusCode AIDATupleSvc::registerObject( const std::string& dirPath,
00171 const std::string& objPath,
00172 AIDA::ITuple* tObj )
00173 {
00174 DataObject* pParent = 0;
00175 pParent = createPath( dirPath );
00176 return registerObject( pParent, objPath, tObj );
00177
00178 }
00179
00180 StatusCode AIDATupleSvc::registerObject( DataObject* pParent,
00181 const std::string& objPath,
00182 AIDA::ITuple* tObj )
00183 {
00184
00185 if ( objPath[0] == SEPARATOR ) {
00186 if ( !tObj->annotation().addItem( "id", objPath.substr(1) ) )
00187 tObj->annotation().setValue( "id", objPath.substr(1) );
00188 }
00189 else {
00190 if ( !tObj->annotation().addItem( "id", objPath ) )
00191 tObj->annotation().setValue( "id", objPath );
00192 }
00193
00194
00195 StatusCode status = DataSvc::registerObject( pParent,
00196 objPath,
00197 dynamic_cast<DataObject*>(tObj) );
00198 return status;
00199 }
00200
00201
00202
00203
00204
00205 StatusCode AIDATupleSvc::unregisterObject( AIDA::ITuple* tObj )
00206 {
00207 StatusCode status = DataSvc::unregisterObject( dynamic_cast<DataObject*>(tObj) );
00208 return status;
00209 }
00210
00211
00212 StatusCode AIDATupleSvc::unregisterObject( AIDA::ITuple* tObj,
00213 const std::string& objPath )
00214 {
00215 StatusCode status = DataSvc::unregisterObject( dynamic_cast<DataObject*>(tObj),
00216 objPath );
00217 return status;
00218 }
00219
00220
00221
00222
00223
00224 StatusCode AIDATupleSvc::retrieveObject( const std::string& fullPath,
00225 AIDA::ITuple*& tObj )
00226 {
00227 MsgStream log ( msgSvc(), name() );
00228 StatusCode status;
00229 status = findObject(fullPath, tObj);
00230
00231
00232 if( status.isSuccess() )
00233 return status;
00234
00235 std::string dirPath, objPath, storePath, storeObj;
00236 parsePath( fullPath, dirPath, objPath, storePath, storeObj);
00237
00238
00239 Connections::iterator i = m_connections.find(storePath);
00240 if( i != m_connections.end() ) {
00241 pi_aida::Tuple* tmp = new pi_aida::Tuple(((*i).second)->retrieveTuple(storeObj));
00242
00243 tObj = dynamic_cast<AIDA::ITuple*>(tmp);
00244 return StatusCode::SUCCESS;
00245 }
00246 log << MSG::ERROR << "Could not retrieve tuple " << fullPath << endmsg;
00247 return StatusCode::FAILURE;
00248 }
00249
00250
00251 StatusCode AIDATupleSvc::retrieveObject( const std::string& parentPath,
00252 const std::string& objPath,
00253 AIDA::ITuple*& tObj )
00254 {
00255 std::string fullPath = parentPath+'/'+objPath;
00256 return retrieveObject( fullPath, tObj );
00257 }
00258
00259
00260 StatusCode AIDATupleSvc::retrieveObject( DataObject* pParent,
00261 const std::string& objPath,
00262 AIDA::ITuple*& tObj )
00263 {
00264 IRegistry* tmpReg = pParent->registry();
00265 std::string parentPath = tmpReg->identifier();
00266 std::string fullPath = parentPath+'/'+objPath;
00267
00268 return retrieveObject( fullPath, tObj );
00269 }
00270
00271
00272
00273
00274
00275 StatusCode AIDATupleSvc::findObject( const std::string& fullPath,
00276 AIDA::ITuple*& tObj )
00277 {
00278 DataObject* pObject = 0;
00279 StatusCode sc = DataSvc::findObject( fullPath, pObject );
00280 tObj = dynamic_cast<AIDA::ITuple*>(pObject);
00281 return sc;
00282 }
00283
00284
00285 StatusCode AIDATupleSvc::findObject( IRegistry* pRegistry,
00286 const std::string& path,
00287 AIDA::ITuple*& tObj )
00288 {
00289 DataObject* pObject = 0;
00290 StatusCode sc = DataSvc::findObject( pRegistry, path, pObject );
00291 tObj = dynamic_cast<AIDA::ITuple*>(pObject);
00292 return sc;
00293 }
00294
00295
00296 StatusCode AIDATupleSvc::findObject( const std::string& parentPath,
00297 const std::string& objPath,
00298 AIDA::ITuple*& tObj )
00299 {
00300 DataObject* pObject = 0;
00301 StatusCode sc = DataSvc::findObject( parentPath, objPath, pObject );
00302 tObj = dynamic_cast<AIDA::ITuple*>(pObject);
00303 return sc;
00304 }
00305
00306
00307 StatusCode AIDATupleSvc::findObject( DataObject* parentObj,
00308 const std::string& objPath,
00309 AIDA::ITuple*& tObj )
00310 {
00311 DataObject* pObject = 0;
00312 StatusCode sc = DataSvc::findObject( parentObj, objPath, pObject );
00313 tObj = dynamic_cast<AIDA::ITuple*>(pObject);
00314 return sc;
00315 }
00316
00317
00318 void AIDATupleSvc::setCriteria( AIDA::ITuple*& tObj,
00319 const std::string& criteria )
00320 {
00321 pi_aida::Tuple* t = dynamic_cast<pi_aida::Tuple*>(tObj);
00322 t->setCriteria(criteria);
00323 }
00324
00325
00326
00327
00328
00329
00330
00331
00332
00333
00334
00335
00336
00337
00338 StatusCode AIDATupleSvc::connect( const std::string& ident,
00339 int mode )
00340 {
00341 MsgStream log ( msgSvc(), name() );
00342 DataObject* p0 = 0;
00343 StatusCode status = DataSvc::findObject(m_rootName, p0);
00344 if (status.isSuccess() ) {
00345 Tokenizer tok(true);
00346 long loc = ident.find(" ");
00347 int open_mode = 0;
00348 std::string file, typ = "", tmp_typ = "", opt = "";
00349 std::string logname = ident.substr(0,loc);
00350 tok.analyse(ident.substr(loc+1,ident.length()), " ", "", "", "=", "'", "'");
00351 for ( Tokenizer::Items::iterator i = tok.items().begin(); i != tok.items().end(); i++) {
00352 const std::string& tag = (*i).tag();
00353 switch( ::toupper(tag[0]) ) {
00354 case 'F':
00355 case 'D':
00356 file = (*i).value();
00357 break;
00358 case 'O':
00359 switch( ::toupper((*i).value()[0]) ) {
00360 case 'A':
00361 if( mode == 0 )
00362 open_mode = 3;
00363 else
00364 open_mode = 1;
00365 break;
00366 case 'O':
00367 if( mode == 0 )
00368 throw GaudiException("Input file " + file + " with improper option (OVERWRITE)", "AIDATupleSvc", StatusCode::FAILURE);
00369 else
00370 open_mode = 1;
00371 break;
00372 case 'C':
00373 if( mode == 0 )
00374 throw GaudiException("Input file " + file + " with improper option (CREATE)", "AIDATupleSvc", StatusCode::FAILURE);
00375 else
00376 open_mode = 2;
00377 break;
00378 case 'R':
00379 if( mode == 1 )
00380 throw GaudiException("Output file " + file + " with improper option (READONLY)", "AIDATupleSvc", StatusCode::FAILURE);
00381 else
00382 open_mode = 3;
00383 break;
00384 case 'U':
00385 if( mode == 0 )
00386 throw GaudiException("Input file " + file + " with improper option (UPDATE)", "AIDATupleSvc", StatusCode::FAILURE);
00387 else
00388 open_mode = 4;
00389 break;
00390 }
00391 break;
00392 case 'T':
00393 typ = (*i).value();
00394 break;
00395 default:
00396 opt += (*i).tag() + "=" + (*i).value() + ",";
00397 break;
00398 }
00399 }
00400
00401
00402 if (typ == "") {
00403 log << MSG::WARNING << "File type not specified at job options."
00404 << " Setting 'HistogramPersistency' type as default"
00405 << endmsg;
00406
00407 IProperty* appPropMgr = 0;
00408 status = serviceLocator()->queryInterface(IProperty::interfaceID(),(void **)&appPropMgr );
00409 if( !status.isSuccess() ) {
00410
00411 log << MSG::ERROR << "Could not get PropMgr" << endmsg;
00412 return status;
00413 }
00414 StringProperty sp("HistogramPersistency","");
00415 status = appPropMgr->getProperty( &sp );
00416 if ( !status.isSuccess() ) {
00417 log << MSG::ERROR << "Could not get NTuple Persistency format"
00418 << " from ApplicationMgr properties" << endmsg;
00419 return status;
00420 }
00421 tmp_typ = sp.value();
00422 if (tmp_typ == "ROOT" || tmp_typ == "XML" || tmp_typ == "HBOOK" || tmp_typ == "POOL")
00423 typ = tmp_typ;
00424 else {
00425 log << MSG::ERROR << "Unknown persistency format at 'HistogramPersistency' option"
00426 << endmsg;
00427 return StatusCode::FAILURE;
00428 }
00429 }
00430
00431
00432 pi_aida::Proxy_Store* storePtr = new pi_aida::Proxy_Store( file, typ, open_mode, opt );
00433 m_connections.insert(Connections::value_type(m_rootName+'/'+logname, storePtr));
00434
00435 return StatusCode::SUCCESS;
00436 }
00437 log << MSG::ERROR << "Cannot add " << ident << " invalid filename!" << endmsg;
00438 return StatusCode::FAILURE;
00439
00440 }
00441
00442
00443 StatusCode AIDATupleSvc::closeAIDAStores()
00444 {
00445 for( Connections::iterator k = m_connections.begin(); k != m_connections.end(); k++ ) {
00446 if ( (*k).second->isOpen()) {
00447 (*k).second->close();
00448 (*k).second = 0;
00449 }
00450 }
00451
00452 m_connections.erase(m_connections.begin(), m_connections.end());
00453 return StatusCode::SUCCESS;
00454 }
00455
00456
00457 void AIDATupleSvc::parsePath( const std::string& fullPath,
00458 std::string& dirPath,
00459 std::string& objPath,
00460 std::string& storePath,
00461 std::string& storeObj )
00462 {
00463 std::string tmpPath = fullPath;
00464 if ( tmpPath[0] != SEPARATOR ) {
00465
00466 tmpPath.insert(tmpPath.begin(), SEPARATOR);
00467 tmpPath.insert(tmpPath.begin(), m_rootName.begin(), m_rootName.end());
00468 }
00469
00470 if (tmpPath.rfind(SEPARATOR) == tmpPath.length()-1) {
00471 tmpPath.erase(tmpPath.rfind(SEPARATOR),1);
00472 }
00473 int sep = tmpPath.rfind(SEPARATOR);
00474 dirPath = tmpPath.substr(0, sep);
00475 objPath = tmpPath.substr(sep, tmpPath.length()-sep );
00476 sep = tmpPath.find(SEPARATOR, m_rootName.length()+1);
00477 storePath = tmpPath.substr(0, sep);
00478 storeObj = tmpPath.substr(sep+1, tmpPath.length()-sep );
00479 }
00480
00481
00482 DataObject* AIDATupleSvc::createPath( const std::string& newPath )
00483 {
00484 std::string tmpPath = newPath;
00485 if ( tmpPath[0] != SEPARATOR ) {
00486 tmpPath.insert(tmpPath.begin(), SEPARATOR);
00487 tmpPath.insert(tmpPath.begin(), m_rootName.begin(), m_rootName.end());
00488 }
00489
00490 if (tmpPath.rfind(SEPARATOR) == tmpPath.length()-1) {
00491 tmpPath.erase(tmpPath.rfind(SEPARATOR),1);
00492 }
00493
00494 DataObject* pObject = 0;
00495 StatusCode sc = DataSvc::findObject( tmpPath, pObject );
00496 if( sc.isSuccess() ) {
00497 return pObject;
00498 }
00499
00500 int sep = tmpPath.rfind(SEPARATOR);
00501 std::string rest( tmpPath, sep+1, tmpPath.length()-sep );
00502 std::string subPath( tmpPath, 0, sep );
00503 if( 0 != sep ) {
00504 createPath( subPath );
00505 }
00506 else {
00507 MsgStream log( msgSvc(), name() );
00508 log << MSG::ERROR << "Unable to create the tuple path" << endmsg;
00509 return 0;
00510 }
00511
00512 pObject = createDirectory( subPath, rest );
00513 return pObject;
00514 }
00515
00516
00517 DataObject* AIDATupleSvc::createDirectory( const std::string& parentDir,
00518 const std::string& subDir )
00519 {
00520
00521 StatusCode status = StatusCode::FAILURE;
00522 DataObject* directory = new DataObject();
00523
00524 if ( 0 != directory ) {
00525 DataObject* pnode;
00526 status = DataSvc::findObject( parentDir, pnode );
00527 if( status.isSuccess() ) {
00528 status = DataSvc::registerObject( pnode, subDir, directory );
00529 if ( !status.isSuccess() ) {
00530 MsgStream log( msgSvc(), name() );
00531 log << MSG::ERROR << "Unable to create the directory: "
00532 << parentDir << "/" << subDir << endmsg;
00533 delete directory;
00534 return 0;
00535 }
00536 }
00537 else {
00538 MsgStream log( msgSvc(), name() );
00539 log << MSG::ERROR << "Unable to create the directory: "
00540 << parentDir << "/" << subDir << endmsg;
00541 delete directory;
00542 return 0;
00543 }
00544 }
00545 return directory;
00546 }
00547
00548
00549
00550
00551 AIDATupleSvc::AIDATupleSvc( const std::string& name, ISvcLocator* svc )
00552 : DataSvc( name, svc )
00553 {
00554
00555 m_rootName = "/NTUPLES";
00556 m_rootCLID = CLID_DataObject;
00557 declareProperty("Input", m_input);
00558 declareProperty("Output", m_output);
00559 }
00560
00561
00562 AIDATupleSvc::~AIDATupleSvc()
00563 {
00564 clearStore().ignore();
00565 }
00566
00567
00568 StatusCode AIDATupleSvc::initialize()
00569 {
00570 MsgStream log( msgSvc(), name() );
00571 StatusCode status = DataSvc::initialize();
00572
00573 if( status.isSuccess() ){
00574 DataObject* rootObj = new DataObject();
00575 status = setRoot( m_rootName, rootObj );
00576 if( !status.isSuccess() ) {
00577 log << MSG::ERROR << "Unable to set NTuple data store root." << endmsg;
00578 delete rootObj;
00579 return status;
00580 }
00581
00582
00583 for( DBaseEntries::iterator i = m_input.begin(); i != m_input.end(); i++ ) {
00584 status = connect(*i, 0);
00585 if( !status.isSuccess() )
00586 return status;
00587 }
00588
00589 for( DBaseEntries::iterator j = m_output.begin(); j != m_output.end(); j++ ) {
00590 status = connect(*j, 1);
00591 if( !status.isSuccess() )
00592 return status;
00593 }
00594 }
00595 return status;
00596 }
00597
00598
00599 StatusCode AIDATupleSvc::reinitialize()
00600 {
00601 return StatusCode::SUCCESS;
00602 }
00603
00604
00605 StatusCode AIDATupleSvc::finalize()
00606 {
00607 MsgStream log( msgSvc(), name() );
00608 StatusCode status = DataSvc::finalize();
00609 if( status.isSuccess() ) {
00610 status = closeAIDAStores();
00611 if( status.isSuccess() )
00612 return status;
00613 }
00614 log << MSG::ERROR << "Error finalizing AIDATupleSvc." << endmsg;
00615 return status;
00616 }
00617
00618
00619
00620 DECLARE_SERVICE_FACTORY(AIDATupleSvc)