3#include "TClonesArray.h"
7#include "DataInfoSvc/IDataInfoSvc.h"
8#include "RootCnvSvc/RootInterface.h"
9#include "RootEventData/TJobInfo.h"
11#include "GaudiKernel/Bootstrap.h"
12#include "GaudiKernel/IAppMgrUI.h"
13#include "GaudiKernel/IMessageSvc.h"
14#include "GaudiKernel/IProperty.h"
15#include "GaudiKernel/ISvcLocator.h"
16#include "GaudiKernel/SmartIF.h"
25 if ( m_rootInterface )
return m_rootInterface;
27 return m_rootInterface;
31 auto msgSvc = Gaudi::svcLocator()->service<IMessageSvc>(
"MessageSvc" );
32 m_log =
new MsgStream(
msgSvc, name );
34 m_branches =
new TClonesArray(
"TBranch", 1 );
35 m_branchesRead =
new TClonesArray(
"TBranch", 1 );
45 IInterface* iface = Gaudi::createApplicationMgr();
46 SmartIF<IProperty> propMgr( iface );
48 propMgr->getProperty(
"JobOptionsPath", path );
49 msg() << MSG::INFO <<
"JobOptions file for current job: " << path << endmsg;
50 ifstream fin( path.c_str() );
53 while ( getline( fin, tempString ) )
55 if ( tempString.size() > 0 && tempString.find(
"//" ) > tempString.size() )
57 jobOptions += tempString;
61 msg() << MSG::INFO <<
"JobOptions: " << endmsg << jobOptions << endmsg;
66 ISvcLocator* svcLocator = Gaudi::svcLocator();
69 StatusCode status = svcLocator->service(
"DataInfoSvc", jobInfoSvc );
70 if ( status.isSuccess() )
72 msg() << MSG::INFO <<
"get the DataInfoSvc" << endmsg;
74 msg() << MSG::INFO <<
"get decay options" << endmsg << decayOptions << endmsg;
76 else { msg() << MSG::WARNING <<
"could not get the DataInfoSvc. Ignore it." << endmsg; }
81 ISvcLocator* svcLocator = Gaudi::svcLocator();
83 std::vector<int> totEvtNo;
84 StatusCode status = svcLocator->service(
"DataInfoSvc", jobInfoSvc );
85 if ( status.isSuccess() )
87 msg() << MSG::INFO <<
"get the DataInfoSvc" << endmsg;
89 msg() << MSG::INFO <<
"get total event number for each run" << endmsg;
91 else { msg() << MSG::WARNING <<
"could not get the DataInfoSvc. Ignore it." << endmsg; }
98 msg() << MSG::INFO <<
"finalize() in RootInterface" << endmsg;
101 std::vector<TTree*>::const_iterator trees;
102 for ( trees = m_outputTrees.begin(); trees < m_outputTrees.end(); trees++ )
105 int treenr = ( *trees )->GetUniqueID();
106 if ( m_outputFiles[treenr] )
108 if ( !m_outputFiles[treenr]->IsOpen() )
110 msg() << MSG::ERROR <<
"Could not open file for writing" << endmsg;
111 return StatusCode::FAILURE;
115 msg() << MSG::DEBUG <<
" Closing file " << treenr <<
", tree "
116 << ( *trees )->GetName() << endmsg;
117 TDirectory* saveDir = gDirectory;
118 m_outputFiles[treenr]->cd();
121 TTree* m_jobInfoTree =
new TTree(
"JobInfoTree",
"Job info" );
122 m_jobInfoTree->Branch(
"JobInfo", &jobInfo );
124 m_bossVer = getenv(
"BES_RELEASE" );
125 msg() << MSG::INFO <<
"fill boss version: " << m_bossVer << endmsg;
128 m_jobOptions.push_back( tmpJobOptions );
137 m_jobInfoTree->Fill();
141 st = m_outputFiles[treenr]->Write();
144 msg() << MSG::FATAL <<
" can not write the file "
145 << m_outputFilenames[treenr].c_str() << endmsg;
149 m_outputFiles[treenr]->Close();
154 if ( m_outputTrees.size() > 0 ) m_outputTrees.clear();
158 return StatusCode::SUCCESS;
162 msg() << MSG::DEBUG <<
"addInput for Tree " << treename << endmsg;
163 StatusCode sc = StatusCode::SUCCESS;
164 m_fileNames.push_back(
file );
165 m_otherTrees.push_back( NULL );
166 inputFiles.push_back( NULL );
168 sc = getTreeNr( treename, treenr,
true );
169 m_inputFilenames[treenr] =
file;
170 m_inputFiles[treenr] = NULL;
171 m_inputTrees[treenr] = NULL;
172 m_currentFileName = m_fileNames[treenr].c_str();
178 for (
int i = 0; i < input.size(); i++ )
180 msg() << MSG::DEBUG <<
"input tag file: " << i <<
" " << input[i] << endmsg;
181 m_tagInputFile.push_back( input[i] );
186 int split,
int bufsize,
int compression ) {
189 msg() << MSG::DEBUG <<
"addOutput for Tree " << treename << endmsg;
190 StatusCode sc = StatusCode::SUCCESS;
192 sc = getTreeNr( treename, treenr,
true );
193 m_outputFilenames[treenr] =
file;
194 m_outputFiles[treenr] = NULL;
195 m_outputTrees[treenr] = NULL;
196 m_splitModes[treenr] = split;
197 m_bufSizes[treenr] = bufsize;
198 m_compressionLevels[treenr] = compression;
204 const std::string& branchname,
const char* classname,
205 void* addr,
int& branchnr ) {
207 msg() << MSG::DEBUG <<
"CreateBranch, Tree " << treename <<
" branch " << branchname
212 StatusCode sc = getTreeNr( treename, treenr );
213 if ( !sc.isSuccess() )
return sc;
215 if ( m_outputFilenames[treenr].empty() )
218 <<
"No corresponding output file specified, ignore createBranch: " << branchname
220 return StatusCode::SUCCESS;
223 if ( !m_outputTrees[treenr] ) sc = this->createTree( treenr, treename );
224 if ( !sc.isSuccess() )
return sc;
225 TTree* tree = m_outputTrees[treenr];
226 tree->SetUniqueID( treenr );
228 branch = tree->Branch( branchname.c_str(), classname, addr, m_bufSizes[treenr],
229 m_splitModes[treenr] );
230 branch->SetUniqueID( treenr );
231 branchnr = m_branches->GetEntriesFast() + 1;
232 m_branches->Expand( branchnr );
233 TClonesArray& a = *m_branches;
234 a[branchnr - 1] = branch;
235 tree->SetBasketSize( branchname.c_str(),
236 m_bufSizes[treenr] );
238 return StatusCode::SUCCESS;
241StatusCode RootInterface::createTree(
const unsigned int treenr,
const std::string treename ) {
244 TDirectory* saveDir = gDirectory;
247 m_outputFiles[treenr] = TFile::Open( m_outputFilenames[treenr].c_str(),
"RECREATE" );
248 if ( m_outputFiles[treenr]->IsZombie() )
250 std::cout <<
"RootInterface ERROR::Can't not open file"
251 << m_outputFilenames[treenr].c_str() << std::endl;
254 if ( !m_outputFiles[treenr]->IsOpen() )
256 msg() << MSG::FATAL <<
"ROOT file " << m_outputFilenames[treenr]
257 <<
" could not be opened for writing." << endmsg;
259 return StatusCode::FAILURE;
262 <<
"RootInterface::opened file for output:" << m_outputFilenames[treenr].c_str()
265 m_outputFiles[treenr]->cd();
266 m_outputFiles[treenr]->SetCompressionLevel( m_compressionLevels[treenr] );
267 std::string
title = treename +
" from conversion";
268 m_outputTrees[treenr] =
new TTree( treename.c_str(),
title.c_str() );
269 TTree::SetMaxTreeSize( 20000000000LL );
273 return StatusCode::SUCCESS;
276TTree* RootInterface::getTree(
const std::string treename ) {
279 msg() << MSG::INFO <<
"RootInterface:;getTree" << endmsg;
281 getTreeNr( treename, treenr );
283 if ( m_inputTrees[treenr] )
return m_inputTrees[treenr];
284 if ( !m_inputFiles[treenr] )
286 m_inputFiles[treenr] = TFile::Open( m_fileNames[treenr].
c_str(),
"READ" );
287 if ( !m_inputFiles[treenr]->IsOpen() )
289 msg() << MSG::ERROR <<
"ROOT file " << m_inputFiles[treenr]->GetName()
290 <<
" could not be opened for reading." << endmsg;
291 delete m_inputFiles[treenr];
292 m_inputFiles[treenr] = NULL;
297 msg() << MSG::INFO <<
"RootInterface::opened file for input:" << m_fileNames[treenr].c_str()
299 m_currentFileName = m_fileNames[treenr].c_str();
300 TTree* tree = (TTree*)m_inputFiles[treenr]->Get( treename.c_str() );
303 msg() << MSG::ERROR <<
"ROOT file " << m_inputFiles[treenr]->GetName()
304 <<
" does not contain requested TTree: " << treename << endmsg;
307 if ( tree->GetEntries() <= 0 )
309 msg() << MSG::ERROR <<
"ROOT file " << m_inputFiles[treenr]->GetName() <<
" entries <= 0"
314 m_inputTrees[treenr] = tree;
315 if ( m_entries <= 0 ) { m_entries = (Int_t)tree->GetEntries(); }
323 TTree* tree2 = (TTree*)
file->Get(
"JobInfoTree" );
326 std::cout <<
"no JobInfoTree for file " <<
file->GetName() << std::endl;
331 msg() << MSG::INFO <<
"get JobInfoTree" << endmsg;
332 TBranch* branch = tree2->GetBranch(
"JobInfo" );
335 std::cout <<
"ERROR! No branch in JobInfoTree" << std::endl;
341 branch->SetAddress( &jobInfo );
342 branch->GetEntry( 0 );
344 std::cout << std::endl
345 <<
"**************************************************" << std::endl
346 <<
"Print JobInfo for data file: " <<
file->GetName() << std::endl
347 <<
" BOSS version: " << m_bossVer << std::endl
348 <<
"**************************************************" << std::endl
352 if ( m_decayOptions.size() > 0 )
354 std::cout << std::endl
355 <<
"**************************************************" << std::endl
356 <<
" Decay Options: " << std::endl
357 << m_decayOptions << std::endl
358 <<
"**************************************************" << std::endl
362 ISvcLocator* svcLocator = Gaudi::svcLocator();
364 StatusCode status = svcLocator->service(
"DataInfoSvc", jobInfoSvc );
365 if ( status.isSuccess() ) { msg() << MSG::INFO <<
"get the DataInfoSvc" << endmsg; }
366 else { msg() << MSG::WARNING <<
"could not get the DataInfoSvc." << endmsg; }
373 std::cout << std::endl
374 <<
"**************************************************" << std::endl
375 <<
" JobOptions for this data file: " << std::endl
379 vector<std::string> vs = m_jobOptions;
383 for (
int i = 0; i < nv; i++ )
385 std::cout << vs[i] << std::endl;
386 std::cout <<
" end of the jobOptions file " << std::endl;
387 std::cout <<
"**************************************************" << std::endl
396TTree* RootInterface::getOtherTree(
const std::string treename ) {
398 msg() << MSG::INFO <<
"RootInterface:;getOtherTree" << endmsg;
400 if ( m_otherTrees[m_fileNum] )
return m_otherTrees[m_fileNum];
402 inputFiles[m_fileNum] = TFile::Open( m_fileNames[m_fileNum].c_str(),
"READ" );
404 if ( !inputFiles[m_fileNum]->IsOpen() )
406 msg() << MSG::ERROR <<
"ROOT File" << inputFiles[m_fileNum]->GetName()
407 <<
"Coult not be opened for reading." << endmsg;
408 delete inputFiles[m_fileNum];
409 inputFiles[m_fileNum] = NULL;
414 <<
"RootIntrFace:;Opened File for input:" << m_fileNames[m_fileNum].c_str() << endmsg;
415 m_currentFileName = m_fileNames[m_fileNum].c_str();
417 TTree* tree = (TTree*)inputFiles[m_fileNum]->Get( treename.c_str() );
420 msg() << MSG::ERROR <<
"ROOT file " << inputFiles[m_fileNum]->GetName()
421 <<
" does not contain requested TTree: " << treename << endmsg;
425 if ( tree->GetEntries() <= 0 )
427 msg() << MSG::ERROR <<
"ROOT file " << m_fileNames[m_fileNum].c_str() <<
" entries <= 0"
432 m_otherTrees[m_fileNum] = tree;
433 if ( m_entries <= 0 )
435 m_entries = (Int_t)tree->GetEntries();
436 msg() << MSG::INFO <<
"m_entries = " << m_entries << endmsg;
448 if ( m_fileNum >=
int( m_fileNames.size() ) - 1 )
450 if ( m_inputFiles[0] )
452 delete m_inputFiles[0];
453 m_inputFiles[0] = NULL;
458 ( *m_branchesRead ).Clear();
460 getTreeNr(
"Event", treenr );
461 if ( m_inputFiles[treenr] )
463 delete m_inputFiles[treenr];
464 m_inputFiles[treenr] = NULL;
466 if ( m_inputTrees[treenr] )
469 m_inputTrees[treenr] = NULL;
471 if ( m_otherTrees[m_fileNum] )
delete m_otherTrees[m_fileNum];
472 if ( inputFiles[m_fileNum] )
delete inputFiles[m_fileNum];
476 m_currentFileName = m_fileNames[m_fileNum].c_str();
510 const std::string branchname,
void* addr,
512 msg() << MSG::DEBUG <<
"RootInterface::setbranch address, treename: " << treename
513 <<
", branch " << branchname << endmsg;
519 if ( m_fileNum != 0 ) { tree = getOtherTree( treename ); }
520 else { tree = getTree( treename ); }
525 msg() << MSG::ERROR <<
"Could not find tree " << treename << endmsg;
526 msg() << MSG::ERROR <<
"terminate the process handly" << endmsg;
528 return StatusCode::FAILURE;
530 tree->SetMakeClass( 1 );
533 TBranch* b = tree->GetBranch( branchname.c_str() );
537 msg() << MSG::DEBUG <<
"Could not find branch xx" << branchname <<
"xx" << endmsg;
538 return StatusCode::FAILURE;
542 b->SetAddress( addr );
544 branchnr = m_branchesRead->GetEntries();
546 TClonesArray& a = *m_branchesRead;
547 m_branchesRead->Expand( branchnr + 1 );
549 return StatusCode::SUCCESS;
553 msg() << MSG::DEBUG <<
"RootInterface::getBranchEntry: "
554 <<
", branch nr " << nr <<
", entry " << entry << endmsg;
556 if ( nr < 0 )
return StatusCode::FAILURE;
557 TBranch* branch = (TBranch*)m_branchesRead->At( nr );
560 msg() << MSG::ERROR <<
"Could not find branch " << nr << endmsg;
561 return StatusCode::FAILURE;
564 branch->SetAddress( addr );
565 nb = branch->GetEntry( entry );
567 if ( nb <= 0 ) { m_EOF =
true; }
568 return StatusCode::SUCCESS;
572 msg() << MSG::DEBUG <<
"RootInterface::getBranchEntry: "
573 <<
", branch nr " << nr <<
", entry " << entry << endmsg;
575 if ( nr < 0 )
return StatusCode::FAILURE;
576 TBranch* branch = (TBranch*)m_branchesRead->At( nr );
579 msg() << MSG::ERROR <<
"Could not find branch " << nr << endmsg;
580 return StatusCode::FAILURE;
582 nb = branch->GetEntry( entry );
584 if ( nb <= 0 ) { m_EOF =
true; }
586 return StatusCode::SUCCESS;
589StatusCode RootInterface::getTreeNr(
const std::string treename,
unsigned int& treenr,
593 std::vector<std::string>::iterator where =
594 std::find( m_treenames.begin(), m_treenames.end(), treename );
595 if ( where == m_treenames.end() )
599 treenr = m_treenames.size();
600 m_treenames.push_back( treename );
601 m_inputFilenames.push_back(
"" );
602 m_inputFiles.push_back( NULL );
603 m_inputTrees.push_back( NULL );
604 m_outputFilenames.push_back(
"" );
605 m_outputFiles.push_back( NULL );
606 m_outputTrees.push_back( NULL );
607 m_splitModes.push_back( 0 );
608 m_bufSizes.push_back( 0 );
609 m_compressionLevels.push_back( 0 );
610 return StatusCode::SUCCESS;
614 msg() << MSG::ERROR <<
"Invalid tree name: " << treename << endmsg;
615 return StatusCode::FAILURE;
618 treenr = where - m_treenames.begin();
619 return StatusCode::SUCCESS;
624 StatusCode sc = StatusCode::FAILURE;
626 std::vector<TTree*>::const_iterator trees;
627 for ( trees = m_outputTrees.begin(); trees < m_outputTrees.end(); trees++ )
629 if ( ( *trees ) == NULL )
continue;
630 int treenr = ( *trees )->GetUniqueID();
631 if ( m_outputFiles[treenr]->IsZombie() || ( !m_outputFiles[treenr]->IsOpen() ) )
633 std::cout <<
"RootInterface ERROR::The ROOT File:" << m_outputFilenames[treenr].c_str()
634 <<
"status is false" << std::endl;
637 nb = ( *trees )->Fill();
638 m_outputFiles[treenr] = ( *trees )->GetCurrentFile();
639 msg() << MSG::DEBUG <<
"filled tree " << ( *trees )->GetName() <<
" with " << nb
640 <<
" bytes" << endmsg;
643 msg() << MSG::FATAL <<
"Error in filling tree " << ( *trees )->GetName() <<
" with "
644 << nb <<
" bytes" << endmsg;
647 sc = StatusCode::SUCCESS;
653 int splitx,
int bufsize,
int compression ) {
654 msg() << MSG::INFO <<
"addOutput to single event" << endmsg;
655 StatusCode status = StatusCode::FAILURE;
659 m_single_compressionLevels[treenr] = compression;
660 m_single_outputFileNames[treenr] =
file;
661 m_single_outputFiles[treenr] = NULL;
662 m_single_outputTrees[treenr] = NULL;
663 m_single_splitModes[treenr] = splitx;
664 m_single_bufSizes[treenr] = bufsize;
666 std::cout <<
"finish f_addOutput to single event" << std::endl;
671 msg() << MSG::INFO <<
"f_createTree()" << endmsg;
673 TDirectory* saveDir = gDirectory;
675 m_single_outputFiles[treenr] =
676 TFile::Open( m_single_outputFileNames[treenr].c_str(),
"RECREATE" );
677 if ( !m_single_outputFiles[treenr]->IsOpen() )
679 msg() << MSG::ERROR <<
"ROOT share file: " << m_single_outputFileNames[treenr]
680 <<
" could not be opened for writing" << endmsg;
681 return StatusCode::FAILURE;
684 <<
"f_createTree()::open share file for writing: " << m_single_outputFileNames[treenr]
687 m_single_outputFiles[treenr]->cd();
688 m_single_outputFiles[treenr]->SetCompressionLevel( m_single_compressionLevels[treenr] );
690 std::string
title = treename +
" for share";
691 m_single_outputTrees[treenr] =
new TTree( treename.c_str(),
title.c_str() );
694 return StatusCode::SUCCESS;
698 const std::string& branchname,
const char* classname,
699 void* addr,
int& branchnr ) {
700 msg() << MSG::INFO <<
"f_craeteBranch() create branch, tree name:" << treename
701 <<
", branch name:" << branchname << endmsg;
705 StatusCode status =
f_getTreeNr( treename, treenr );
706 if ( !status.isSuccess() )
return status;
708 if ( !m_single_outputTrees[treenr] ) status = this->
f_createTree( treenr, treename );
709 if ( !status.isSuccess() )
return status;
711 TTree* tree = m_single_outputTrees[treenr];
712 tree->SetUniqueID( treenr );
714 branch = tree->Branch( branchname.c_str(), classname, addr, m_single_bufSizes[treenr],
715 m_single_splitModes[treenr] );
717 return StatusCode::SUCCESS;
723 std::vector<std::string>::iterator where =
724 std::find( m_single_treenames.begin(), m_single_treenames.end(), treename );
726 if ( where == m_single_treenames.end() )
730 treenr = m_single_treenames.size();
731 m_single_treenames.push_back( treename );
733 m_single_outputFileNames.push_back(
"" );
734 m_single_outputFiles.push_back( NULL );
735 m_single_outputTrees.push_back( NULL );
736 m_single_splitModes.push_back( 0 );
737 m_single_bufSizes.push_back( 0 );
738 m_single_compressionLevels.push_back( 0 );
740 return StatusCode::SUCCESS;
744 msg() << MSG::ERROR <<
"Invalid share tree name: " << treename << endmsg;
745 return StatusCode::FAILURE;
748 treenr = where - m_single_treenames.begin();
749 return StatusCode::SUCCESS;
753 StatusCode status = StatusCode::FAILURE;
756 std::vector<TTree*>::const_iterator tree;
757 for ( tree = m_single_outputTrees.begin(); tree < m_single_outputTrees.end(); tree++ )
759 if ( ( *tree ) == NULL )
continue;
760 byte = ( *tree )->Fill();
762 msg() << MSG::INFO <<
"f_fillTrees() filled tree " << ( *tree )->GetName() <<
" with "
763 <<
byte <<
" bytes!" << endmsg;
764 status = StatusCode::SUCCESS;
771 msg() << MSG::INFO <<
"f_finalize() in RootInterface" << endmsg;
773 std::vector<TTree*>::const_iterator tree;
774 for ( tree = m_single_outputTrees.begin(); tree < m_single_outputTrees.end(); tree++ )
778 unsigned int treenr = ( *tree )->GetUniqueID();
779 msg() << MSG::INFO <<
"tree id: " << treenr << endmsg;
780 if ( m_single_outputFiles[treenr] )
782 if ( !m_single_outputFiles[treenr]->IsOpen() )
784 msg() << MSG::ERROR <<
"f_finalize could not open share file for writing" << endmsg;
785 return StatusCode::FAILURE;
789 msg() << MSG::INFO <<
"Closing file:" << treenr <<
", tree:" << ( *tree )->GetName()
792 TDirectory* saveDir = gDirectory;
793 m_single_outputFiles[treenr]->cd();
795 <<
"WREITE TO FILE BYTES: " << m_single_outputFiles[treenr]->Write() << endmsg;
796 m_single_outputFiles[treenr]->Close();
802 return StatusCode::SUCCESS;
virtual void setTotEvtNo(std::vector< int > i)=0
virtual std::vector< int > getTotEvtNo()=0
virtual string getDecayOptions()=0
virtual std::vector< int > getTotEvtNo()
virtual StatusCode f_createBranch(const std::string &treename, const std::string &branchname, const char *classname, void *addr, int &branchnr)
virtual StatusCode f_getTreeNr(const std::string treename, unsigned int &treenr, bool doAdd=false)
virtual StatusCode f_finalize()
virtual std::string getJobOptions()
virtual StatusCode getBranchEntry(int nr, int entry, int &nb)
get entry from this branch
virtual StatusCode f_fillTrees()
virtual StatusCode finalize()
virtual bool checkEndOfTree()
check if all the files is over 2005-11-28
virtual StatusCode createBranch(const std::string &tree, const std::string &branch, const char *classname, void *addr, int &branchnr)
create a branch in this tree
virtual void printJobInfo(TFile *file, int level)
virtual void setTagInputFile(std::vector< std::string > input)
static RootInterface * Instance(const std::string &name)
singleton behaviour
virtual StatusCode setBranchAddress(const std::string treename, const std::string branchname, void *addr, int &nb)
set branch address
virtual StatusCode addInput(const std::string &treename, const std::string &file)
add input tree to the list
virtual StatusCode f_addOutput(const std::string &treename, const std::string &file, int splitx=1, int bufsize=64000, int compression=1)
virtual StatusCode addOutput(const std::string &treename, const std::string &file, int splitx, int bufsize, int compression)
add output tree to the list
virtual StatusCode fillTrees()
fill in all trees
virtual StatusCode f_createTree(unsigned int treenr, const std::string treename)
RootInterface(const std::string &name)
virtual std::string getDecayOptions()
void setBossVer(string ver)
void setTotEvtNo(std::vector< int > i)
string getDecayOptions() const
void setDecayOptions(string opt)
vector< string > getJobOptions() const
std::vector< int > getTotEvtNo() const
string getBossVer() const
void setJobOptions(vector< string > opt)