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