SFrame 3.6
|
00001 // $Id: SCycleBaseNTuple.cxx 335 2012-11-21 14:11:47Z krasznaa $ 00002 /*************************************************************************** 00003 * @Project: SFrame - ROOT-based analysis framework for ATLAS 00004 * @Package: Core 00005 * 00006 * @author Stefan Ask <Stefan.Ask@cern.ch> - Manchester 00007 * @author David Berge <David.Berge@cern.ch> - CERN 00008 * @author Johannes Haller <Johannes.Haller@cern.ch> - Hamburg 00009 * @author A. Krasznahorkay <Attila.Krasznahorkay@cern.ch> - CERN/Debrecen 00010 * 00011 ***************************************************************************/ 00012 00013 // System include(s): 00014 #include <string.h> 00015 00016 // STL include(s): 00017 #include <algorithm> 00018 #include <typeinfo> 00019 00020 // ROOT include(s): 00021 #include <TFile.h> 00022 #include <TTree.h> 00023 #include <TChain.h> 00024 #include <TBranch.h> 00025 #include <TROOT.h> 00026 #include <TList.h> 00027 #include <TFriendElement.h> 00028 #include <TVirtualIndex.h> 00029 #include <TTreeFormula.h> 00030 00031 // Local include(s): 00032 #include "../include/SCycleBaseNTuple.h" 00033 #include "../include/SInputData.h" 00034 #include "../include/SCycleConfig.h" 00035 #include "../include/SCycleOutput.h" 00036 #include "../include/STreeType.h" 00037 00038 static const Double_t EPSILON = 1e-15; 00039 00040 #ifndef DOXYGEN_IGNORE 00041 ClassImp( SCycleBaseNTuple ) 00042 #endif // DOXYGEN_IGNORE 00043 00047 SCycleBaseNTuple::SCycleBaseNTuple() 00048 : SCycleBaseBase(), m_inputTrees(), m_inputBranches(), 00049 m_outputTrees(), m_metaInputTrees(), m_outputVarPointers(), m_output( 0 ) { 00050 00051 REPORT_VERBOSE( "SCycleBaseNTuple constructed" ); 00052 } 00053 00057 SCycleBaseNTuple::~SCycleBaseNTuple() { 00058 00059 DeleteInputVariables(); 00060 REPORT_VERBOSE( "SCycleBaseNTuple destructed" ); 00061 } 00062 00063 void SCycleBaseNTuple::SetNTupleOutput( TList* output ) { 00064 00065 m_output = output; 00066 return; 00067 } 00068 00069 TList* SCycleBaseNTuple::GetNTupleOutput() const { 00070 00071 return m_output; 00072 } 00073 00085 TTree* SCycleBaseNTuple::GetMetadataTree( const char* name ) const throw( SError ) { 00086 00087 // The result tree: 00088 TTree* result = 0; 00089 00090 // See if this is an input tree: 00091 try { 00092 result = GetInputMetadataTree( name ); 00093 return result; 00094 } catch( const SError& error ) { 00095 if( error.request() <= SError::SkipFile ) { 00096 REPORT_VERBOSE( "Input metadata tree with name \"" << name << "\" not found" ); 00097 } else { 00098 REPORT_ERROR( "Exception message caught with message: " << error.what() ); 00099 throw; 00100 } 00101 } 00102 00103 // See if this is an output tree: 00104 try { 00105 result = GetOutputMetadataTree( name ); 00106 return result; 00107 } catch( const SError& error ) { 00108 if( error.request() <= SError::SkipFile ) { 00109 REPORT_VERBOSE( "Output metadata tree with name \"" << name << "\" not found" ); 00110 } else { 00111 REPORT_ERROR( "Exception message caught with message: " << error.what() ); 00112 throw; 00113 } 00114 } 00115 00116 // 00117 // Throw an exception if the tree hasn't been found: 00118 // 00119 SError error( SError::SkipFile ); 00120 error << "Couldn't find metadata TTree with name: " << name; 00121 throw error; 00122 00123 return result; 00124 } 00125 00134 TTree* SCycleBaseNTuple::GetInputMetadataTree( const char* name ) const throw( SError ) { 00135 00136 // 00137 // Strip off the directory name from the given tree name: 00138 // 00139 TString tname( name ); 00140 if( tname.Contains( "/" ) ) { 00141 REPORT_VERBOSE( "Tokenizing the metadata tree name: " << tname ); 00142 TObjArray* array = tname.Tokenize( "/" ); 00143 TObjString* real_name = dynamic_cast< TObjString* >( array->Last() ); 00144 tname = real_name->GetString(); 00145 delete array; 00146 } 00147 00148 REPORT_VERBOSE( "Looking for input metadata tree with name: " << tname ); 00149 00150 // 00151 // Look for such a metadata tree: 00152 // 00153 for( std::vector< TTree* >::const_iterator it = m_metaInputTrees.begin(); 00154 it != m_metaInputTrees.end(); ++it ) { 00155 if( *it ) { 00156 if( tname == ( *it )->GetName() ) { 00157 REPORT_VERBOSE( "Found input metadata tree with name " << tname 00158 << " at " << ( *it ) ); 00159 return *it; 00160 } 00161 } 00162 } 00163 00164 // 00165 // Throw an exception if the tree hasn't been found: 00166 // 00167 SError error( SError::SkipFile ); 00168 error << "Couldn't find input metadata TTree with name: " << tname; 00169 throw error; 00170 00171 return 0; 00172 } 00173 00182 TTree* SCycleBaseNTuple::GetOutputMetadataTree( const char* name ) const throw( SError ) { 00183 00184 // 00185 // Strip off the directory name from the given tree name: 00186 // 00187 TString tname( name ); 00188 if( tname.Contains( "/" ) ) { 00189 REPORT_VERBOSE( "Tokenizing the metadata tree name: " << tname ); 00190 TObjArray* array = tname.Tokenize( "/" ); 00191 TObjString* real_name = dynamic_cast< TObjString* >( array->Last() ); 00192 tname = real_name->GetString(); 00193 delete array; 00194 } 00195 00196 REPORT_VERBOSE( "Looking for output metadata tree with name: " << tname ); 00197 00198 // 00199 // Look for such a metadata tree: 00200 // 00201 for( std::vector< TTree* >::const_iterator it = m_metaOutputTrees.begin(); 00202 it != m_metaOutputTrees.end(); ++it ) { 00203 if( *it ) { 00204 if( tname == ( *it )->GetName() ) { 00205 REPORT_VERBOSE( "Found output metadata tree with name " << tname 00206 << " at " << ( *it ) ); 00207 return *it; 00208 } 00209 } 00210 } 00211 00212 // 00213 // Throw an exception if the tree hasn't been found: 00214 // 00215 SError error( SError::SkipFile ); 00216 error << "Couldn't find input metadata TTree with name: " << tname; 00217 throw error; 00218 00219 return 0; 00220 } 00221 00227 TTree* SCycleBaseNTuple::GetInputTree( const char* treeName ) const throw( SError ) { 00228 00229 // 00230 // Look for such input tree: 00231 // 00232 TString tname( treeName ); 00233 for( std::vector< TTree* >::const_iterator it = m_inputTrees.begin(); 00234 it != m_inputTrees.end(); ++it ) { 00235 if( *it ) { 00236 if( tname == ( *it )->GetName() ) { 00237 REPORT_VERBOSE( "Found input tree with name " << treeName 00238 << " at " << ( *it ) ); 00239 return *it; 00240 } 00241 } 00242 } 00243 00244 // 00245 // Throw an exception if the tree hasn't been found: 00246 // 00247 SError error( SError::SkipFile ); 00248 error << "Couldn't find input TTree with name: " << treeName; 00249 throw error; 00250 00251 return 0; 00252 } 00253 00254 TTree* SCycleBaseNTuple::GetOutputTree( const char* treeName ) const throw( SError ) { 00255 00256 // 00257 // Look for such output tree: 00258 // 00259 TString tname( treeName ); 00260 for( std::vector< TTree* >::const_iterator it = m_outputTrees.begin(); 00261 it != m_outputTrees.end(); ++it ) { 00262 if( *it ) { 00263 if( tname == ( *it )->GetName() ) { 00264 REPORT_VERBOSE( "Found output tree with name " << treeName 00265 << " at " << ( *it ) ); 00266 return *it; 00267 } 00268 } 00269 } 00270 00271 // 00272 // Throw an exception if the tree hasn't been found: 00273 // 00274 SError error( SError::SkipFile ); 00275 error << "Couldn't find output TTree with name: " << treeName; 00276 throw error; 00277 00278 return 0; 00279 } 00280 00292 void SCycleBaseNTuple::CreateOutputTrees( const SInputData& iD, 00293 std::vector< TTree* >& outTrees, 00294 TFile* outputFile ) throw( SError ) { 00295 00296 // sanity checks 00297 if( outTrees.size() ) { 00298 m_logger << WARNING << "Vector of output trees is not empty in " 00299 << "\"CreateOutputTrees\"!" << SLogger::endmsg; 00300 } 00301 00302 // Clear the vector of output trees: 00303 m_outputTrees.clear(); 00304 m_metaOutputTrees.clear(); 00305 00306 // Clear the vector of output variable pointers: 00307 m_outputVarPointers.clear(); 00308 00309 const std::vector< STree >* sOutTree = iD.GetTrees( STreeType::OutputSimpleTree ); 00310 00311 // Open output file / create output trees 00312 gROOT->cd(); 00313 00314 // 00315 // Create all the regular output trees, but don't create any branches in them 00316 // just yet. 00317 // 00318 const Int_t branchStyle = 1; 00319 const Int_t autoSave = 10000000; 00320 if( sOutTree ) { 00321 for( std::vector< STree >::const_iterator st = sOutTree->begin(); 00322 st != sOutTree->end(); ++st ) { 00323 00324 m_logger << DEBUG << "Creating output event tree with name: " 00325 << st->treeName << SLogger::endmsg; 00326 00327 TTree* tree = new TTree( st->treeName.Data(), TString( "Format: User" ) + 00328 ", data type: " + iD.GetType() ); 00329 00330 tree->SetAutoSave( autoSave ); 00331 TTree::SetBranchStyle( branchStyle ); 00332 00333 outTrees.push_back( tree ); 00334 m_outputTrees.push_back( tree ); 00335 00336 if( outputFile ) { 00337 tree->SetDirectory( outputFile ); 00338 REPORT_VERBOSE( "Attached TTree \"" << st->treeName.Data() 00339 << "\" to file: " << outputFile->GetName() ); 00340 } else { 00341 SCycleOutput* out = new SCycleOutput( tree, st->treeName ); 00342 m_output->Add( out ); 00343 REPORT_VERBOSE( "Keeping TTree \"" << st->treeName.Data() 00344 << "\" in memory" ); 00345 } 00346 } 00347 } 00348 00349 // 00350 // Create the metadata output trees. These don't have to be reported back to the 00351 // caller, since the user will be responsible for filling them. 00352 // 00353 const std::vector< STree >* sMetaTrees = iD.GetTrees( STreeType::OutputMetaTree ); 00354 if( sMetaTrees ) { 00355 for( std::vector< STree >::const_iterator mt = sMetaTrees->begin(); 00356 mt != sMetaTrees->end(); ++mt ) { 00357 00358 // 00359 // Split the name into the name of the tree and the name of the 00360 // directory: 00361 // 00362 TString tname( mt->treeName ), dirname( "" ); 00363 if( tname.Contains( "/" ) ) { 00364 REPORT_VERBOSE( "Tokenizing the metadata tree name: " << tname ); 00365 TObjArray* array = tname.Tokenize( "/" ); 00366 TObjString* real_name = dynamic_cast< TObjString* >( array->Last() ); 00367 tname = real_name->GetString(); 00368 if( array->GetSize() > 1 ) { 00369 for( Int_t i = 0; i < array->GetSize() - 1; ++i ) { 00370 TObjString* dirletname = dynamic_cast< TObjString* >( array->At( i ) ); 00371 if( ! dirletname ) continue; 00372 if( dirletname->GetString() == "" ) continue; 00373 if( dirletname->GetString() == tname ) break; 00374 dirname += ( dirname == "" ? dirletname->GetString() : "/" + dirletname->GetString() ); 00375 } 00376 } 00377 delete array; 00378 } 00379 00380 m_logger << DEBUG << "Creating output metadata tree with name: " 00381 << tname << " in directory: " << dirname << SLogger::endmsg; 00382 00383 TTree* tree = new TTree( tname, TString( "Format: User" ) + 00384 ", data type: " + iD.GetType() ); 00385 00386 tree->SetAutoSave( autoSave ); 00387 TTree::SetBranchStyle( branchStyle ); 00388 00389 m_metaOutputTrees.push_back( tree ); 00390 00391 if( outputFile ) { 00392 tree->SetDirectory( MakeSubDirectory( dirname, outputFile ) ); 00393 REPORT_VERBOSE( "Attached TTree \"" << mt->treeName 00394 << "\" to file: " << outputFile->GetName() ); 00395 } else { 00396 SCycleOutput* out = new SCycleOutput( tree, tname, dirname ); 00397 m_output->Add( out ); 00398 REPORT_VERBOSE( "Keeping TTree \"" << mt->treeName 00399 << "\" in memory" ); 00400 } 00401 } 00402 } 00403 00404 return; 00405 } 00406 00415 void SCycleBaseNTuple::SaveOutputTrees( TDirectory* /*output*/ ) throw( SError ) { 00416 00417 // Remember which directory we were in: 00418 TDirectory* savedir = gDirectory; 00419 00420 // Save each regular output tree: 00421 for( std::vector< TTree* >::iterator tree = m_outputTrees.begin(); 00422 tree != m_outputTrees.end(); ++tree ) { 00423 TDirectory* dir = ( *tree )->GetDirectory(); 00424 if( dir ) dir->cd(); 00425 ( *tree )->Write(); 00426 ( *tree )->AutoSave(); 00427 ( *tree )->SetDirectory( 0 ); 00428 delete ( *tree ); 00429 } 00430 00431 // Save each metadata output tree: 00432 for( std::vector< TTree* >::iterator tree = m_metaOutputTrees.begin(); 00433 tree != m_metaOutputTrees.end(); ++tree ) { 00434 TDirectory* dir = ( *tree )->GetDirectory(); 00435 if( dir ) dir->cd(); 00436 ( *tree )->Write(); 00437 ( *tree )->AutoSave(); 00438 ( *tree )->SetDirectory( 0 ); 00439 delete ( *tree ); 00440 } 00441 00442 // Go back to the original directory: 00443 gDirectory = savedir; 00444 00445 return; 00446 } 00447 00459 void SCycleBaseNTuple::LoadInputTrees( const SInputData& iD, 00460 TTree* main_tree, 00461 TFile*& inputFile ) throw( SError ) { 00462 00463 REPORT_VERBOSE( "Loading/accessing the event-level input trees" ); 00464 00465 // 00466 // Initialize some variables: 00467 // 00468 const std::vector< STree >* sInTree = iD.GetTrees( STreeType::InputSimpleTree ); 00469 const std::vector< STree >* sMetaTree = iD.GetTrees( STreeType::InputMetaTree ); 00470 Bool_t firstPassed = kFALSE; 00471 Int_t nEvents = 0; 00472 m_inputTrees.clear(); 00473 m_inputBranches.clear(); 00474 DeleteInputVariables(); 00475 m_metaInputTrees.clear(); 00476 00477 // 00478 // Access the physical file that is currently being opened: 00479 // 00480 inputFile = 0; 00481 if( GetConfig().GetRunMode() == SCycleConfig::LOCAL ) { 00482 TChain* chain = dynamic_cast< TChain* >( main_tree ); 00483 if( ! chain ) { 00484 throw SError( "In LOCAL running the input TTree is not a TChain!", 00485 SError::StopExecution ); 00486 } 00487 inputFile = chain->GetFile(); 00488 } else if( GetConfig().GetRunMode() == SCycleConfig::PROOF ) { 00489 inputFile = main_tree->GetCurrentFile(); 00490 } else { 00491 throw SError( "Running mode not recongnised", SError::SkipCycle ); 00492 return; 00493 } 00494 if( ! inputFile ) { 00495 throw SError( "Couldn't get the input file pointer!", SError::SkipFile ); 00496 return; 00497 } 00498 REPORT_VERBOSE( "Accessed the pointer to the input file: " << inputFile ); 00499 00500 // 00501 // Handle the regular input trees: 00502 // 00503 if( sInTree ) { 00504 for( std::vector< STree >::const_iterator st = sInTree->begin(); st != sInTree->end(); 00505 ++st ) { 00506 00507 REPORT_VERBOSE( "Now trying to access TTree: " << st->treeName ); 00508 00509 TTree* tree = dynamic_cast< TTree* >( inputFile->Get( st->treeName ) ); 00510 if( ! tree ) { 00511 SError error( SError::SkipFile ); 00512 error << "Tree " << st->treeName << " doesn't exist in File " 00513 << inputFile->GetName(); 00514 throw error; 00515 } 00516 00517 // do we need this at all now that we loop over the branches 00518 // one-by-one? 00519 00520 // Remove friends if any, for better performance 00521 bool skipFriends = true; // can be made configurable 00522 if( skipFriends ) { 00523 TList* flist = tree->GetListOfFriends(); 00524 TIter nextf( flist ); 00525 TFriendElement* fe = 0; 00526 while( ( fe = ( TFriendElement* ) nextf() ) ) { 00527 m_logger << DEBUG << "Remove friend " << fe->GetName() << " from tree " 00528 << tree->GetName() << SLogger::endmsg; 00529 flist->Remove( fe ); 00530 delete fe; 00531 fe = 0; 00532 } 00533 } 00534 // Delete index if any, for better performance 00535 bool deleteIndex = true; // can be made configurable 00536 if( deleteIndex ) { 00537 if( tree->GetTreeIndex() ) { 00538 m_logger << DEBUG << "Delete index from tree " 00539 << tree->GetName() << SLogger::endmsg; 00540 tree->SetTreeIndex( 0 ); 00541 delete tree->GetTreeIndex(); 00542 } 00543 } 00544 00545 m_inputTrees.push_back( tree ); 00546 if( firstPassed && tree->GetEntries() != nEvents ) { 00547 SError error( SError::SkipFile ); 00548 error << "Conflict in number of entries - Tree " << tree->GetName() 00549 << " has " << tree->GetEntries() << ", NOT " 00550 << nEvents; 00551 throw error; 00552 } else if( ! firstPassed ) { 00553 firstPassed = kTRUE; 00554 nEvents = tree->GetEntries(); 00555 } 00556 } 00557 } 00558 00559 // 00560 // Handle the metadata trees: 00561 // 00562 if( sMetaTree ) { 00563 for( std::vector< STree >::const_iterator mt = sMetaTree->begin(); 00564 mt != sMetaTree->end(); ++mt ) { 00565 00566 TTree* tree = dynamic_cast< TTree* >( inputFile->Get( mt->treeName ) ); 00567 if( ! tree ) { 00568 SError error( SError::SkipFile ); 00569 error << "Tree " << mt->treeName << " doesn't exist in File " 00570 << inputFile->GetName(); 00571 throw error; 00572 } else { 00573 m_metaInputTrees.push_back( tree ); 00574 } 00575 } 00576 } 00577 00578 return; 00579 } 00580 00589 void SCycleBaseNTuple::GetEvent( Long64_t entry ) throw( SError ) { 00590 00591 // Tell all trees to update their cache: 00592 for( std::vector< TTree* >::const_iterator it = m_inputTrees.begin(); 00593 it != m_inputTrees.end(); ++it ) { 00594 ( *it )->LoadTree( entry ); 00595 } 00596 00597 // Load the current entry for all the regular input variables: 00598 for( std::vector< TBranch* >::const_iterator it = m_inputBranches.begin(); 00599 it != m_inputBranches.end(); ++it ) { 00600 ( *it )->GetEntry( entry ); 00601 } 00602 00603 return; 00604 } 00605 00614 Double_t SCycleBaseNTuple::CalculateWeight( const SInputData& inputData, 00615 Long64_t entry ) { 00616 00617 // the type of this input data 00618 const TString& type = inputData.GetType(); 00619 const TString& version = inputData.GetVersion(); 00620 00621 Double_t weight = 0.; 00622 Double_t totlum = 0.; 00623 00624 if( inputData.GetType() == "data" ) { 00625 REPORT_VERBOSE( "Data" ); 00626 weight = 1.; 00627 return weight; 00628 } 00629 00630 //iterate over vector of input data and addup the weight for the type of this input data 00631 for( std::vector< SInputData >::const_iterator iD = GetConfig().GetInputData().begin(); 00632 iD != GetConfig().GetInputData().end(); ++iD ) { 00633 00634 if( ( iD->GetType() == type ) && ( iD->GetVersion() == version ) ) { 00635 00636 const std::vector< SGeneratorCut >& sgencuts = iD->GetSGeneratorCuts(); 00637 Bool_t inside = kTRUE; 00638 00639 for( std::vector< SGeneratorCut >::const_iterator sgc = sgencuts.begin(); 00640 sgc != sgencuts.end(); ++sgc ) { 00641 00642 // loop over the trees 00643 for( std::vector< TTree* >::const_iterator it = m_inputTrees.begin(); 00644 it != m_inputTrees.end(); ++it ) { 00645 00646 // consider the one with the correct name 00647 if( ( *it )->GetName() == sgc->GetTreeName() ) { 00648 // check for this entry, if Formula is true 00649 TString teststring = sgc->GetFormula(); 00650 TTreeFormula f( "testFormula", teststring.Data(), *it ); 00651 // if true for all cuts, then add the Lumi of this input data to totlum 00652 if( ! f.EvalInstance( entry ) ) inside = kFALSE; 00653 break; 00654 } 00655 00656 } 00657 } 00658 if( inside ) totlum += iD->GetScaledLumi(); 00659 } 00660 } 00661 00662 if( totlum > EPSILON ) 00663 weight = ( GetConfig().GetTargetLumi() / totlum ); 00664 00665 return weight; 00666 } 00667 00673 void SCycleBaseNTuple::ClearCachedTrees() { 00674 00675 m_inputTrees.clear(); 00676 m_inputBranches.clear(); 00677 m_outputTrees.clear(); 00678 m_metaInputTrees.clear(); 00679 m_metaOutputTrees.clear(); 00680 00681 DeleteInputVariables(); 00682 00683 return; 00684 } 00685 00696 const char* SCycleBaseNTuple::RootType( const char* typeid_type ) throw( SError ) { 00697 00698 if( strlen( typeid_type ) != 1 ) { 00699 throw SError( "SCycleBaseNTuple::RootType received complex object description", 00700 SError::StopExecution ); 00701 } 00702 00703 switch( typeid_type[ 0 ] ) { 00704 00705 case 'c': 00706 return "B"; 00707 break; 00708 case 'h': 00709 return "b"; 00710 break; 00711 case 's': 00712 return "S"; 00713 break; 00714 case 't': 00715 return "s"; 00716 break; 00717 case 'i': 00718 return "I"; 00719 break; 00720 case 'j': 00721 return "i"; 00722 break; 00723 case 'f': 00724 return "F"; 00725 break; 00726 case 'd': 00727 return "D"; 00728 break; 00729 case 'x': 00730 return "L"; 00731 break; 00732 case 'y': 00733 return "l"; 00734 break; 00735 case 'b': 00736 return "O"; 00737 break; 00738 00739 } 00740 00741 throw SError( "Unknown primitive type encountered: " + TString( typeid_type ), 00742 SError::StopExecution ); 00743 return ""; 00744 } 00745 00753 const char* SCycleBaseNTuple::TypeidType( const char* root_type ) throw( SError ) { 00754 00755 if( ! strcmp( root_type, "Char_t" ) ) { 00756 return "c"; 00757 } else if( ! strcmp( root_type, "UChar_t" ) ) { 00758 return "h"; 00759 } else if( ! strcmp( root_type, "Short_t" ) ) { 00760 return "s"; 00761 } else if( ! strcmp( root_type, "UShort_t" ) ) { 00762 return "t"; 00763 } else if( ! strcmp( root_type, "Int_t" ) ) { 00764 return "i"; 00765 } else if( ! strcmp( root_type, "UInt_t" ) ) { 00766 return "j"; 00767 } else if( ! strcmp( root_type, "Float_t" ) ) { 00768 return "f"; 00769 } else if( ! strcmp( root_type, "Double_t" ) ) { 00770 return "d"; 00771 } else if( ! strcmp( root_type, "Long64_t" ) ) { 00772 return "x"; 00773 } else if( ! strcmp( root_type, "ULong64_t" ) ) { 00774 return "y"; 00775 } else if( ! strcmp( root_type, "Bool_t" ) ) { 00776 return "b"; 00777 } 00778 00779 throw SError( "Unknown ROOT primitive type encountered: " + TString( root_type ), 00780 SError::StopExecution ); 00781 return ""; 00782 } 00783 00788 void SCycleBaseNTuple::RegisterInputBranch( TBranch* br ) throw( SError ) { 00789 00790 if( std::find( m_inputBranches.begin(), m_inputBranches.end(), br ) != 00791 m_inputBranches.end() ) { 00792 m_logger << DEBUG << "Branch '" << br->GetName() << "' already registered!" 00793 << SLogger::endmsg; 00794 } else { 00795 m_inputBranches.push_back( br ); 00796 } 00797 00798 return; 00799 } 00800 00807 void SCycleBaseNTuple::DeleteInputVariables() { 00808 00809 for( std::list< TObject* >::iterator it = m_inputVarPointers.begin(); 00810 it != m_inputVarPointers.end(); ++it ) { 00811 delete ( *it ); 00812 } 00813 m_inputVarPointers.clear(); 00814 00815 return; 00816 } 00817 00826 TDirectory* 00827 SCycleBaseNTuple::MakeSubDirectory( const TString& path, 00828 TDirectory* dir ) const throw( SError ) { 00829 00830 if( ! path.Length() ) return dir; 00831 00832 TDirectory* result = 0; 00833 if( ! ( result = dir->GetDirectory( path ) ) ) { 00834 00835 REPORT_VERBOSE( "Creating directory: " 00836 << dir->GetPath() << "/" << path ); 00837 00838 // 00839 // Break up the path name at the slashes: 00840 // 00841 TObjArray* directories = path.Tokenize( "/" ); 00842 00843 // 00844 // Create each necessary directory: 00845 // 00846 result = dir; 00847 TDirectory* tempDir = 0; 00848 for( Int_t i = 0; i < directories->GetSize(); ++i ) { 00849 00850 TObjString* path_element = dynamic_cast< TObjString* >( directories->At( i ) ); 00851 if( ! path_element ) continue; 00852 if( path_element->GetString() == "" ) continue; 00853 00854 REPORT_VERBOSE( "Accessing directory: " << path_element->GetString() ); 00855 if( ! ( tempDir = result->GetDirectory( path_element->GetString() ) ) ) { 00856 REPORT_VERBOSE( "Directory doesn't exist, creating it..." ); 00857 if( ! ( tempDir = result->mkdir( path_element->GetString(), "dummy title" ) ) ) { 00858 SError error( SError::SkipInputData ); 00859 error << "Couldn't create directory: " << path 00860 << " in the output file!"; 00861 throw error; 00862 } 00863 } 00864 result = tempDir; 00865 00866 } 00867 00868 // Delete the object created by TString::Tokenize(...): 00869 delete directories; 00870 00871 } 00872 00873 return result; 00874 }