00001 #include "TFile.h"
00002 #include "TTree.h"
00003 #include "TBranch.h"
00004 #include "TChain.h"
00005 #include "TClonesArray.h"
00006
00007 #include "RootCnvSvc/RootInterface.h"
00008 #include "RootEventData/TJobInfo.h"
00009 #include "DataInfoSvc/DataInfoSvc.h"
00010 #include "DataInfoSvc/IDataInfoSvc.h"
00011
00012 #include "GaudiKernel/SmartIF.h"
00013 #include "GaudiKernel/Bootstrap.h"
00014 #include "GaudiKernel/IAppMgrUI.h"
00015 #include "GaudiKernel/IProperty.h"
00016 #include "GaudiKernel/ISvcLocator.h"
00017
00018 #include <algorithm>
00019 #include <iostream>
00020 #include <fstream>
00021 #include <string>
00022 RootInterface* RootInterface::m_rootInterface = 0;
00023
00024
00025 RootInterface *RootInterface::Instance(MsgStream log) {
00026 if (m_rootInterface) return m_rootInterface;
00027 m_rootInterface=new RootInterface(log);
00028 return m_rootInterface;
00029 }
00030
00031 RootInterface::RootInterface(MsgStream str) : log(str)
00032 {
00033
00034 m_branches= new TClonesArray("TBranch",1);
00035 m_branchesRead= new TClonesArray("TBranch",1);
00036 m_entries=-1;
00037 m_EOF=false;
00038 m_ENDFILE = false ;
00039 m_fileNum = 0;
00040 }
00041
00042
00043 RootInterface::~RootInterface()
00044 {
00045 }
00046
00047 std::string RootInterface::getJobOptions()
00048 {
00049 IInterface* iface = Gaudi::createApplicationMgr();
00050 SmartIF<IProperty> propMgr (iface );
00051 std::string path;
00052 propMgr->getProperty( "JobOptionsPath", path);
00053 log << MSG::INFO << "JobOptions file for current job: " <<path << endreq;
00054 ifstream fin(path.c_str());
00055 string jobOptions;
00056 string tempString;
00057 while(getline(fin,tempString))
00058 {
00059 if( tempString.size()>0 && tempString.find("//")>tempString.size() )
00060 {
00061 jobOptions += tempString;
00062 jobOptions += "\n";
00063 }
00064 }
00065 log << MSG::INFO << "JobOptions: " << endreq
00066 << jobOptions << endreq;
00067 return jobOptions;
00068 }
00069
00070 std::string RootInterface::getDecayOptions()
00071 {
00072 ISvcLocator* svcLocator = Gaudi::svcLocator();
00073 IDataInfoSvc *tmpInfoSvc;
00074 DataInfoSvc* jobInfoSvc;
00075 string decayOptions;
00076 StatusCode status = svcLocator->service("DataInfoSvc",tmpInfoSvc);
00077 if (status.isSuccess()) {
00078 log << MSG::INFO << "get the DataInfoSvc" << endreq;
00079 jobInfoSvc=dynamic_cast<DataInfoSvc *>(tmpInfoSvc);
00080 decayOptions = jobInfoSvc->getDecayOptions();
00081 log << MSG::INFO << "get decay options" << endreq
00082 << decayOptions << endreq;
00083 }else {
00084 log << MSG::WARNING << "could not get the DataInfoSvc. Ignore it." << endreq;
00085 }
00086 return decayOptions;
00087 }
00088
00089 std::vector<int> RootInterface::getTotEvtNo()
00090 {
00091 ISvcLocator* svcLocator = Gaudi::svcLocator();
00092 IDataInfoSvc *tmpInfoSvc;
00093 DataInfoSvc* jobInfoSvc;
00094 std::vector<int> totEvtNo;
00095 StatusCode status = svcLocator->service("DataInfoSvc",tmpInfoSvc);
00096 if (status.isSuccess()) {
00097 log << MSG::INFO << "get the DataInfoSvc" << endreq;
00098 jobInfoSvc=dynamic_cast<DataInfoSvc *>(tmpInfoSvc);
00099 totEvtNo = jobInfoSvc->getTotEvtNo();
00100 log << MSG::INFO << "get total event number for each run" << endreq;
00101 }else {
00102 log << MSG::WARNING << "could not get the DataInfoSvc. Ignore it." << endreq;
00103 }
00104 return totEvtNo;
00105 }
00106
00107 StatusCode RootInterface::finalize() {
00108
00109
00110 log << MSG::INFO << "finalize() in RootInterface" << endreq;
00111
00112
00113 std::vector<TTree *>::const_iterator trees;
00114 for (trees=m_outputTrees.begin();trees<m_outputTrees.end();trees++)
00115 if (*trees) {
00116 int treenr=(*trees)->GetUniqueID();
00117 if (m_outputFiles[treenr]) {
00118 if (!m_outputFiles[treenr]->IsOpen()) {
00119 log << MSG::ERROR << "Could not open file for writing" << endreq;
00120 return StatusCode::FAILURE;
00121 } else {
00122 log << MSG::DEBUG<<" Closing file "<<treenr<<", tree "<<(*trees)->GetName()<<endreq;
00123 TDirectory *saveDir = gDirectory;
00124 m_outputFiles[treenr]->cd();
00125
00126 TJobInfo* jobInfo = new TJobInfo;
00127 TTree* m_jobInfoTree = new TTree("JobInfoTree","Job info");
00128 m_jobInfoTree->Branch("JobInfo",&jobInfo);
00129
00130 m_bossVer = getenv("BES_RELEASE");
00131 log << MSG::INFO << "fill boss version: "<<m_bossVer << endreq;
00132
00133 string tmpJobOptions = getJobOptions();
00134 m_jobOptions.push_back( tmpJobOptions );
00135
00136 if(m_decayOptions.size()==0)
00137 m_decayOptions = getDecayOptions();
00138
00139 m_totEvtNo = getTotEvtNo();
00140 jobInfo->setBossVer(m_bossVer);
00141 jobInfo->setJobOptions(m_jobOptions);
00142 jobInfo->setDecayOptions(m_decayOptions);
00143 jobInfo->setTotEvtNo(m_totEvtNo);
00144 m_jobInfoTree->Fill();
00145
00146
00147 int st =1;
00148 st = m_outputFiles[treenr]->Write();
00149 if(st==0){
00150 log << MSG::FATAL<<" can not write the file "<< m_outputFilenames[treenr].c_str()<<endreq;
00151 exit(1);
00152 }
00153
00154 m_outputFiles[treenr]->Close();
00155 saveDir->cd();
00156 }
00157 }
00158 }
00159 if(m_outputTrees.size()>0) m_outputTrees.clear();
00160 return StatusCode::SUCCESS;
00161 }
00162
00163 StatusCode RootInterface::addInput(const std::string& treename,const std::string& file) {
00164 log << MSG::DEBUG << "addInput for Tree "<<treename<<endreq;
00165 StatusCode sc=StatusCode::SUCCESS;
00166 m_fileNames.push_back(file);
00167 m_otherTrees.push_back(NULL);
00168 inputFiles.push_back(NULL);
00169 unsigned int treenr;
00170 sc=getTreeNr(treename,treenr,true);
00171 m_inputFilenames[treenr]=file;
00172 m_inputFiles[treenr]=NULL;
00173 m_inputTrees[treenr]=NULL;
00174 m_currentFileName = m_fileNames[treenr].c_str();
00175 return sc;
00176 }
00177
00178
00179 void RootInterface::setTagInputFile(std::vector<std::string> input)
00180 {
00181
00182 for(int i=0; i<input.size(); i++)
00183 {
00184 log << MSG::DEBUG <<"input tag file: "<<i<<" "<<input[i]<<endreq;
00185 m_tagInputFile.push_back(input[i]);
00186 }
00187 }
00188
00189 StatusCode RootInterface::addOutput(const std::string& treename,const std::string& file,int split, int bufsize, int compression) {
00190 static int i =0;
00191 i ++;
00192 log << MSG::DEBUG << "addOutput for Tree "<<treename<<endreq;
00193 StatusCode sc=StatusCode::SUCCESS;
00194 unsigned int treenr;
00195 sc=getTreeNr(treename,treenr,true);
00196 m_outputFilenames[treenr]=file;
00197 m_outputFiles[treenr]=NULL;
00198 m_outputTrees[treenr]=NULL;
00199 m_splitModes[treenr]=split;
00200 m_bufSizes[treenr]=bufsize;
00201 m_compressionLevels[treenr]=compression;
00202
00203 return sc;
00204 }
00205
00206 StatusCode RootInterface::createBranch(const std::string& treename,const std::string& branchname ,const char *classname,void *addr,int & branchnr){
00207
00208 log << MSG::DEBUG << "CreateBranch, Tree "<<treename<<" branch "<<branchname<<endreq;
00209
00210 TBranch *branch;
00211 unsigned int treenr;
00212 StatusCode sc=getTreeNr(treename,treenr);
00213 if (!sc.isSuccess()) return sc;
00214
00215 if ( m_outputFilenames[treenr].empty() ) {
00216 log << MSG::DEBUG << "No corresponding output file specified, ignore createBranch: "<<branchname<<endreq;
00217 return StatusCode::SUCCESS;
00218 }
00219
00220 if(!m_outputTrees[treenr]) sc=this->createTree(treenr,treename);
00221 if (!sc.isSuccess()) return sc;
00222 TTree * tree=m_outputTrees[treenr];
00223 tree->SetUniqueID(treenr);
00224
00225 branch = tree->Branch(branchname.c_str(),classname,addr,m_bufSizes[treenr],m_splitModes[treenr]);
00226 branch->SetUniqueID(treenr);
00227 branchnr=m_branches->GetEntriesFast()+1;
00228 m_branches->Expand(branchnr);
00229 TClonesArray &a = *m_branches;
00230 a[branchnr-1]=branch;
00231 tree->SetBasketSize(branchname.c_str(),m_bufSizes[treenr]);
00232 return StatusCode::SUCCESS;
00233 }
00234
00235
00236 StatusCode RootInterface::createTree(const unsigned int treenr,const std::string treename)
00237 {
00238
00239
00240 TDirectory *saveDir = gDirectory;
00241
00242
00243 m_outputFiles[treenr] =new TFile(m_outputFilenames[treenr].c_str(), "RECREATE");
00244 if(m_outputFiles[treenr]->IsZombie()){
00245 std::cout<<"RootInterface ERROR::Can't not open file"<<m_outputFilenames[treenr].c_str()<<std::endl;
00246 exit(1);
00247 }
00248 if (!m_outputFiles[treenr]->IsOpen()) {
00249 log << MSG::FATAL << "ROOT file " << m_outputFilenames[treenr]
00250 << " could not be opened for writing." << endreq;
00251 exit(1);
00252 return StatusCode::FAILURE;
00253 }
00254 log << MSG::INFO << "RootInterface::opened file for output:" << m_outputFilenames[treenr].c_str() <<endreq;
00255
00256 m_outputFiles[treenr]->cd();
00257 m_outputFiles[treenr]->SetCompressionLevel(m_compressionLevels[treenr]);
00258 std::string title=treename+" from conversion";
00259 m_outputTrees[treenr]= new TTree(treename.c_str(), title.c_str());
00260 TTree::SetMaxTreeSize(20000000000LL);
00261
00262 saveDir->cd();
00263
00264 return StatusCode::SUCCESS;
00265 }
00266
00267 TTree * RootInterface::getTree(const std::string treename)
00268 {
00269
00270
00271 log<<MSG::INFO<<"RootInterface:;getTree"<<endreq;
00272 unsigned int treenr;
00273 getTreeNr(treename,treenr);
00274
00275 if (m_inputTrees[treenr]) return m_inputTrees[treenr];
00276 if (!m_inputFiles[treenr] ) {
00277 m_inputFiles[treenr] = TFile::Open(m_fileNames[treenr].c_str(), "READ");
00278 if (!m_inputFiles[treenr]->IsOpen()) {
00279 log << MSG::ERROR << "ROOT file " << m_inputFiles[treenr]->GetName()
00280 << " could not be opened for reading." << endreq;
00281 delete m_inputFiles[treenr];
00282 m_inputFiles[treenr]=NULL;
00283 m_EOF=true;
00284 return NULL;
00285 }
00286 }
00287 log << MSG::INFO << "RootInterface::opened file for input:" << m_fileNames[treenr].c_str() <<endreq;
00288 m_currentFileName = m_fileNames[treenr].c_str();
00289 TTree *tree= (TTree *)m_inputFiles[treenr]->Get(treename.c_str());
00290 if (!tree) {
00291 log << MSG::ERROR << "ROOT file " << m_inputFiles[treenr]->GetName()
00292 << " does not contain requested TTree: " << treename <<endreq;
00293 return NULL;
00294 }
00295 if (tree->GetEntries()<=0)
00296 {
00297 log << MSG::ERROR << "ROOT file "<< m_inputFiles[treenr]->GetName()<< " entries <= 0" << endreq;
00298 exit(1);
00299 }
00300
00301 m_inputTrees[treenr]=tree;
00302 if (m_entries<=0 ) {
00303 m_entries=(Int_t)tree->GetEntries();
00304 }
00305
00306 printJobInfo( m_inputFiles[treenr],1);
00307
00308 return tree;
00309 }
00310
00311 void RootInterface::printJobInfo(TFile* file, int level)
00312 {
00313 TTree* tree2 = (TTree *)file->Get("JobInfoTree");
00314 if(!tree2)
00315 {
00316 std::cout<<"no JobInfoTree for file "<<file->GetName()<<std::endl;
00317 exit(1);
00318 }
00319 else
00320 {
00321 log << MSG::INFO << "get JobInfoTree" << endreq;
00322 TBranch* branch = tree2->GetBranch("JobInfo");
00323 if(!branch)
00324 {
00325 std::cout<<"ERROR! No branch in JobInfoTree"<<std::endl;
00326 exit(1);
00327 }
00328 else
00329 {
00330 TJobInfo* jobInfo= new TJobInfo;
00331 branch->SetAddress(&jobInfo);
00332 branch->GetEntry(0);
00333 m_bossVer = jobInfo->getBossVer() ;
00334 std::cout<<std::endl
00335 << "**************************************************" << std::endl
00336 <<"Print JobInfo for data file: "<< file->GetName()<<std::endl
00337 << " BOSS version: "<< m_bossVer << std::endl
00338 << "**************************************************" << std::endl
00339 << std::endl;
00340
00341 m_decayOptions = jobInfo->getDecayOptions();
00342 if(m_decayOptions.size()>0)
00343 {
00344 std::cout<< std::endl
00345 <<"**************************************************" << std::endl
00346 <<" Decay Options: "<<std::endl
00347 <<m_decayOptions << std::endl
00348 <<"**************************************************" << std::endl
00349 << std::endl;
00350 }
00351
00352 ISvcLocator* svcLocator = Gaudi::svcLocator();
00353 IDataInfoSvc *tmpInfoSvc;
00354 DataInfoSvc* jobInfoSvc;
00355 StatusCode status = svcLocator->service("DataInfoSvc",tmpInfoSvc);
00356 if (status.isSuccess()) {
00357 log << MSG::INFO << "get the DataInfoSvc" << endreq;
00358 jobInfoSvc=dynamic_cast<DataInfoSvc *>(tmpInfoSvc);
00359 }else {
00360 log << MSG::WARNING << "could not get the DataInfoSvc." << endreq;
00361 }
00362
00363 m_totEvtNo = jobInfo->getTotEvtNo();
00364 jobInfoSvc->setTotEvtNo(m_totEvtNo);
00365
00366 if(level>0)
00367 {
00368 std::cout<<std::endl
00369 <<"**************************************************" << std::endl
00370 <<" JobOptions for this data file: " << std::endl
00371 << std::endl;
00372
00373
00374 m_jobOptions = jobInfo->getJobOptions();
00375 vector<std::string> vs = m_jobOptions;
00376 int nv = vs.size();
00377 if(nv>0)
00378 {
00379 for(int i=0;i<nv;i++)
00380 {
00381 std::cout<<vs[i]<<std::endl;
00382 std::cout<<" end of the jobOptions file " << std::endl;
00383 std::cout<<"**************************************************" << std::endl
00384 <<std::endl;
00385 }
00386 }
00387 }
00388 }
00389 }
00390 }
00391
00392 TTree * RootInterface::getOtherTree(const std::string treename){
00393
00394 log<<MSG::INFO<<"RootInterface:;getOtherTree"<<endreq;
00395 m_ENDFILE = false ;
00396 if(m_otherTrees[m_fileNum]) return m_otherTrees[m_fileNum];
00397
00398 inputFiles[m_fileNum] = TFile::Open(m_fileNames[m_fileNum].c_str(),"READ");
00399
00400 if(!inputFiles[m_fileNum]->IsOpen()){
00401 log<<MSG::ERROR<<"ROOT File" <<inputFiles[m_fileNum]->GetName()<<"Coult not be opened for reading."<<endreq;
00402 delete inputFiles[m_fileNum];
00403 inputFiles[m_fileNum] = NULL;
00404 return NULL;
00405 }
00406 m_EOF = false;
00407 log<<MSG::INFO<<"RootIntrFace:;Opened File for input:"<<m_fileNames[m_fileNum].c_str()<<endreq;
00408 m_currentFileName = m_fileNames[m_fileNum].c_str();
00409
00410 TTree* tree =(TTree*)inputFiles[m_fileNum]->Get(treename.c_str());
00411 if(!tree){
00412 log << MSG::ERROR << "ROOT file " << inputFiles[m_fileNum]->GetName()
00413 << " does not contain requested TTree: " << treename <<endreq;
00414 return NULL;
00415 }
00416
00417 if(tree->GetEntries()<=0)
00418 {
00419 log << MSG::ERROR << "ROOT file "<< m_fileNames[m_fileNum].c_str()<< " entries <= 0" << endreq;
00420 exit(1);
00421 }
00422
00423 m_otherTrees[m_fileNum] = tree;
00424 if (m_entries<=0){
00425 m_entries=(Int_t)tree->GetEntries();
00426 log<<MSG::INFO<<"m_entries = "<<m_entries<<endreq;
00427 }
00428
00429 printJobInfo(inputFiles[m_fileNum],0);
00430
00431
00432
00433 return tree;
00434 }
00435
00436 bool RootInterface::checkEndOfTree(){
00437
00438 if ( m_fileNum >= int(m_fileNames.size())-1 ){
00439 if(m_inputFiles[0]){
00440 delete m_inputFiles[0];
00441 m_inputFiles[0] = NULL;
00442 }
00443 return true;
00444 }
00445
00446 (*m_branchesRead).Clear();
00447 unsigned int treenr;
00448 getTreeNr("Event",treenr);
00449 if(m_inputFiles[treenr]){
00450 delete m_inputFiles[treenr];
00451 m_inputFiles[treenr] = NULL;
00452 }
00453 if(m_inputTrees[treenr]){
00454
00455 m_inputTrees[treenr] = NULL;
00456 }
00457 if(m_otherTrees[m_fileNum]) delete m_otherTrees[m_fileNum];
00458 if(inputFiles[m_fileNum]) delete inputFiles[m_fileNum];
00459
00460 m_ENDFILE = true;
00461 m_fileNum++;
00462 m_currentFileName = m_fileNames[m_fileNum].c_str();
00463
00464 m_entries=-1;
00465 m_EOF = false;
00466 return false;
00467 }
00468
00469
00470
00471
00472
00473
00474
00475
00476
00477
00478
00479
00480
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490
00491
00492
00493
00494
00495
00496 StatusCode RootInterface::setBranchAddress(const std::string treename, const std::string branchname, void *addr,int &branchnr)
00497 {
00498 log << MSG::DEBUG <<"RootInterface::setbranch address, treename: "<<treename <<", branch "<<branchname <<endreq;
00499
00500 branchnr=-1;
00501
00502 TTree * tree;
00503
00504 if(m_fileNum != 0){
00505
00506 tree = getOtherTree(treename);
00507 }else{
00508 tree = getTree(treename);
00509 }
00510
00511
00512 if (!tree) {
00513 log << MSG::ERROR << "Could not find tree " << treename <<endreq;
00514 log << MSG::ERROR << "terminate the process handly"<<endreq;
00515 exit(1);
00516 return StatusCode::FAILURE;
00517 }
00518 tree->SetMakeClass(1);
00519
00520
00521 TBranch *b = tree->GetBranch(branchname.c_str());
00522 if (!b) {
00523
00524 log << MSG::DEBUG << "Could not find branch xx" << branchname <<"xx"<<endreq;
00525 return StatusCode::FAILURE;
00526 }
00527
00528
00529 b->SetAddress(addr);
00530
00531 branchnr=m_branchesRead->GetEntries();
00532
00533 TClonesArray &a = *m_branchesRead;
00534 m_branchesRead->Expand(branchnr+1);
00535 a[branchnr]=b;
00536 return StatusCode::SUCCESS;
00537 }
00538
00539 StatusCode RootInterface::getBranchEntry(int nr, int entry, void * addr, int& nb)
00540 {
00541 log << MSG::DEBUG <<"RootInterface::getBranchEntry: "<<", branch nr "<<nr <<", entry "<<entry <<endreq;
00542
00543 if (nr <0) return StatusCode::FAILURE;
00544 TBranch *branch=(TBranch *)m_branchesRead->At(nr);
00545 if (!branch) {
00546 log << MSG::ERROR << "Could not find branch " << nr <<endreq;
00547 return StatusCode::FAILURE;
00548 }
00549
00550 branch->SetAddress(addr);
00551 nb=branch->GetEntry(entry);
00552
00553 if (nb<=0){
00554 m_EOF=true;
00555
00556 }
00557 return StatusCode::SUCCESS;
00558 }
00559
00560
00561 StatusCode RootInterface::getBranchEntry(int nr, int entry, int& nb)
00562 {
00563 log << MSG::DEBUG <<"RootInterface::getBranchEntry: "<<", branch nr "<<nr <<", entry "<<entry <<endreq;
00564
00565 if (nr <0) return StatusCode::FAILURE;
00566 TBranch *branch=(TBranch *)m_branchesRead->At(nr);
00567 if (!branch) {
00568 log << MSG::ERROR << "Could not find branch " << nr <<endreq;
00569 return StatusCode::FAILURE;
00570 }
00571 nb=branch->GetEntry(entry);
00572
00573 if (nb<=0){
00574 m_EOF=true;
00575
00576 }
00577
00578 return StatusCode::SUCCESS;
00579 }
00580
00581 StatusCode RootInterface::getTreeNr(const std::string treename,unsigned int& treenr,bool doAdd) {
00582
00583
00584 std::vector<std::string>::iterator where=std::find(m_treenames.begin(),m_treenames.end(),treename);
00585 if (where == m_treenames.end()) {
00586 if (doAdd) {
00587 treenr=m_treenames.size();
00588 m_treenames.push_back(treename);
00589 m_inputFilenames.push_back("");
00590 m_inputFiles.push_back(NULL);
00591 m_inputTrees.push_back(NULL);
00592 m_outputFilenames.push_back("");
00593 m_outputFiles.push_back(NULL);
00594 m_outputTrees.push_back(NULL);
00595 m_splitModes.push_back(0);
00596 m_bufSizes.push_back(0);
00597 m_compressionLevels.push_back(0);
00598 return StatusCode::SUCCESS;
00599 }else {
00600 log << MSG::ERROR << "Invalid tree name: " <<treename<< endreq;
00601 return StatusCode::FAILURE;
00602 }
00603 }
00604 treenr=where-m_treenames.begin();
00605 return StatusCode::SUCCESS;
00606 }
00607
00608 StatusCode RootInterface::fillTrees() {
00609
00610 StatusCode sc=StatusCode::FAILURE;
00611 int nb;
00612 std::vector<TTree *>::const_iterator trees;
00613 for (trees=m_outputTrees.begin();trees<m_outputTrees.end();trees++) {
00614 if ((*trees)==NULL) continue;
00615 int treenr=(*trees)->GetUniqueID();
00616 if(m_outputFiles[treenr]->IsZombie()||(!m_outputFiles[treenr]->IsOpen())){
00617 std::cout<<"RootInterface ERROR::The ROOT File:"<<m_outputFilenames[treenr].c_str()<<"status is false"<<std::endl;
00618 exit(1);
00619 }
00620 nb=(*trees)->Fill();
00621 m_outputFiles[treenr] = (*trees)->GetCurrentFile();
00622 log << MSG::DEBUG << "filled tree "<<(* trees)->GetName() <<" with "<<nb<<" bytes"<< endreq;
00623 if(nb==-1){
00624 log << MSG::FATAL << "Error in filling tree "<<(* trees)->GetName() <<" with "<<nb<<" bytes"<< endreq;
00625 exit(1);
00626 }
00627 sc=StatusCode::SUCCESS;
00628 }
00629 return sc;
00630 }
00631
00632
00633
00634
00635
00636 StatusCode RootInterface::f_addOutput(const std::string& treename,
00637 const std::string& file,
00638 int splitx, int bufsize, int compression){
00639 log << MSG::INFO << "addOutput to single event" << endreq;
00640 StatusCode status = StatusCode::FAILURE;
00641 unsigned int treenr;
00642
00643 status = f_getTreeNr(treename, treenr, true);
00644 m_single_compressionLevels[treenr] = compression;
00645 m_single_outputFileNames[treenr] = file;
00646 m_single_outputFiles[treenr] = NULL;
00647 m_single_outputTrees[treenr] = NULL;
00648 m_single_splitModes[treenr] = splitx;
00649 m_single_bufSizes[treenr] = bufsize;
00650
00651 std::cout << "finish f_addOutput to single event" << std::endl;
00652 return status;
00653 }
00654
00655 StatusCode RootInterface::f_createTree(unsigned int treenr,
00656 const std::string treename){
00657 log << MSG::INFO << "f_createTree()" << endreq;
00658
00659 TDirectory *saveDir = gDirectory;
00660
00661 m_single_outputFiles[treenr] =
00662 new TFile(m_single_outputFileNames[treenr].c_str(), "RECREATE");
00663 if ( !m_single_outputFiles[treenr]->IsOpen()){
00664 log << MSG::ERROR << "ROOT share file: "
00665 << m_single_outputFileNames[treenr]
00666 << " could not be opened for writing"
00667 << endreq;
00668 return StatusCode::FAILURE;
00669 }
00670 log << MSG::INFO << "f_createTree()::open share file for writing: "
00671 << m_single_outputFileNames[treenr] << endreq;
00672
00673 m_single_outputFiles[treenr]->cd();
00674 m_single_outputFiles[treenr]->SetCompressionLevel(m_single_compressionLevels[treenr]);
00675
00676 std::string title = treename + " for share";
00677 m_single_outputTrees[treenr] = new TTree(treename.c_str(), title.c_str());
00678 saveDir->cd();
00679
00680 return StatusCode::SUCCESS;
00681 }
00682
00683 StatusCode RootInterface::f_createBranch(const std::string& treename,
00684 const std::string& branchname,
00685 const char *classname,
00686 void *addr, int & branchnr){
00687 log << MSG::INFO << "f_craeteBranch() create branch, tree name:"
00688 << treename << ", branch name:" << branchname << endreq;
00689
00690 TBranch *branch;
00691 unsigned int treenr;
00692 StatusCode status = f_getTreeNr(treename, treenr);
00693 if ( !status.isSuccess()) return status;
00694
00695 if ( !m_single_outputTrees[treenr])
00696 status = this->f_createTree(treenr, treename);
00697 if ( !status.isSuccess()) return status;
00698
00699 TTree* tree = m_single_outputTrees[treenr];
00700 tree->SetUniqueID(treenr);
00701
00702 branch = tree->Branch(branchname.c_str(),
00703 classname,
00704 addr,
00705 m_single_bufSizes[treenr],
00706 m_single_splitModes[treenr]);
00707
00708 }
00709
00710 StatusCode RootInterface::f_getTreeNr(const std::string treename,
00711 unsigned int& treenr,bool doAdd){
00712
00713 std::vector<std::string>::iterator where =
00714 std::find(m_single_treenames.begin(), m_single_treenames.end(), treename);
00715
00716 if ( where == m_single_treenames.end()){
00717 if ( doAdd){
00718 treenr = m_single_treenames.size();
00719 m_single_treenames.push_back(treename);
00720
00721 m_single_outputFileNames.push_back("");
00722 m_single_outputFiles.push_back(NULL);
00723 m_single_outputTrees.push_back(NULL);
00724 m_single_splitModes.push_back(0);
00725 m_single_bufSizes.push_back(0);
00726 m_single_compressionLevels.push_back(0);
00727
00728 return StatusCode::SUCCESS;
00729 }
00730 else {
00731 log << MSG::ERROR << "Invalid share tree name: "
00732 << treename << endreq;
00733 return StatusCode::FAILURE;
00734 }
00735 }
00736 treenr = where - m_single_treenames.begin();
00737 return StatusCode::SUCCESS;
00738 }
00739
00740 StatusCode RootInterface::f_fillTrees(){
00741 StatusCode status = StatusCode::FAILURE;
00742 int byte;
00743
00744 std::vector<TTree *>::const_iterator tree;
00745 for ( tree = m_single_outputTrees.begin(); tree < m_single_outputTrees.end(); tree++){
00746 if ( (*tree) == NULL) continue;
00747 byte = (*tree)->Fill();
00748 (*tree)->Print();
00749 log << MSG::INFO << "f_fillTrees() filled tree " << (*tree)->GetName()
00750 << " with " << byte << " bytes!" << endreq;
00751 status = StatusCode::SUCCESS;
00752 }
00753
00754 return status;
00755 }
00756
00757 StatusCode RootInterface::f_finalize(){
00758 log << MSG::INFO << "f_finalize() in RootInterface" << endreq;
00759
00760 std::vector<TTree *>::const_iterator tree;
00761 for ( tree = m_single_outputTrees.begin(); tree < m_single_outputTrees.end(); tree++){
00762 if ( *tree){
00763 unsigned int treenr = (*tree)->GetUniqueID();
00764 log << MSG::INFO << "tree id: " << treenr << endreq;
00765 if ( m_single_outputFiles[treenr] ){
00766 if ( !m_single_outputFiles[treenr]->IsOpen()){
00767 log << MSG::ERROR << "f_finalize could not open share file for writing"
00768 << endreq;
00769 return StatusCode::FAILURE;
00770 }
00771 else {
00772 log << MSG::INFO << "Closing file:" << treenr
00773 << ", tree:" << (*tree)->GetName() << endreq;
00774
00775 TDirectory *saveDir = gDirectory;
00776 m_single_outputFiles[treenr]->cd();
00777 log <<MSG::INFO << "WREITE TO FILE BYTES: "
00778 << m_single_outputFiles[treenr]->Write()
00779 << endreq;
00780 m_single_outputFiles[treenr]->Close();
00781 saveDir->cd();
00782 }
00783 }
00784 }
00785 }
00786 return StatusCode::SUCCESS;
00787 }