SFrame 3.6
|
00001 // $Id: SCycleConfig.cxx 331 2012-11-20 17:12:44Z krasznaa $ 00002 00003 // System include(s): 00004 #include <ctime> 00005 #include <locale> 00006 00007 // STL include(s): 00008 #include <map> 00009 00010 // ROOT include(s): 00011 #include <TSystem.h> 00012 00013 // Local include(s): 00014 #include "../include/SCycleConfig.h" 00015 #include "../include/SLogger.h" 00016 00017 #ifndef DOXYGEN_IGNORE 00018 ClassImp( SCycleConfig ) 00019 #endif // DOXYGEN_IGNORE 00020 00021 SCycleConfig::SCycleConfig( const char* name ) 00022 : TNamed( name, "SFrame cycle configuration" ), 00023 m_cycleName( "Unknown" ), m_mode( LOCAL ), 00024 m_server( "" ), m_workdir( "" ), m_nodes( -1 ), m_properties(), 00025 m_inputData(), m_targetLumi( 1. ), m_outputDirectory( "" ), 00026 m_postFix( "" ), m_msgLevel( INFO ), m_useTreeCache( kFALSE ), 00027 m_cacheSize( 30000000 ), m_cacheLearnEntries( 100 ), 00028 m_processOnlyLocal( kFALSE ) { 00029 00030 } 00031 00032 const TString& SCycleConfig::GetCycleName() const { 00033 00034 return m_cycleName; 00035 } 00036 00037 void SCycleConfig::SetCycleName( const TString& name ) { 00038 00039 m_cycleName = name; 00040 return; 00041 } 00042 00043 SCycleConfig::RunMode SCycleConfig::GetRunMode() const { 00044 00045 return m_mode; 00046 } 00047 00048 void SCycleConfig::SetRunMode( SCycleConfig::RunMode mode ) { 00049 00050 m_mode = mode; 00051 return; 00052 } 00053 00054 const TString& SCycleConfig::GetProofServer() const { 00055 00056 return m_server; 00057 } 00058 00059 void SCycleConfig::SetProofServer( const TString& server ) { 00060 00061 m_server = server; 00062 return; 00063 } 00064 00065 const Int_t& SCycleConfig::GetProofNodes() const { 00066 00067 return m_nodes; 00068 } 00069 00070 void SCycleConfig::SetProofNodes( const Int_t nodes ) { 00071 00072 m_nodes = nodes; 00073 return; 00074 } 00075 00076 const TString& SCycleConfig::GetProofWorkDir() const { 00077 00078 return m_workdir; 00079 } 00080 00081 void SCycleConfig::SetProofWorkDir( const TString& workdir ) { 00082 00083 m_workdir = workdir; 00084 return; 00085 } 00086 00087 const SCycleConfig::property_type& SCycleConfig::GetProperties() const { 00088 00089 return m_properties; 00090 } 00091 00092 void SCycleConfig::SetProperty( const std::string& name, const std::string& value ) { 00093 00094 m_properties.push_back( std::make_pair( name, value ) ); 00095 return; 00096 } 00097 00098 const SCycleConfig::id_type& SCycleConfig::GetInputData() const { 00099 00100 return m_inputData; 00101 } 00102 00103 void SCycleConfig::AddInputData( const SInputData& id ) { 00104 00105 m_inputData.push_back( id ); 00106 return; 00107 } 00108 00109 void SCycleConfig::SetOutputDirectory( const TString& outDir ) { 00110 00111 m_outputDirectory = outDir; 00112 return; 00113 } 00114 00115 const TString& SCycleConfig::GetOutputDirectory() const { 00116 00117 return m_outputDirectory; 00118 } 00119 00120 void SCycleConfig::SetPostFix( const TString& postFix ) { 00121 00122 m_postFix = postFix; 00123 return; 00124 } 00125 00126 const TString& SCycleConfig::GetPostFix() const { 00127 00128 return m_postFix; 00129 } 00130 00131 void SCycleConfig::SetMsgLevel( SMsgType level ) { 00132 00133 m_msgLevel = level; 00134 return; 00135 } 00136 00137 SMsgType SCycleConfig::GetMsgLevel() const { 00138 00139 return m_msgLevel; 00140 } 00141 00142 void SCycleConfig::SetUseTreeCache( Bool_t status ) { 00143 00144 m_useTreeCache = status; 00145 return; 00146 } 00147 00148 Bool_t SCycleConfig::GetUseTreeCache() const { 00149 00150 return m_useTreeCache; 00151 } 00152 00153 void SCycleConfig::SetCacheSize( Long64_t size ) { 00154 00155 m_cacheSize = size; 00156 return; 00157 } 00158 00159 Long64_t SCycleConfig::GetCacheSize() const { 00160 00161 return m_cacheSize; 00162 } 00163 00164 void SCycleConfig::SetCacheLearnEntries( Int_t entries ) { 00165 00166 m_cacheLearnEntries = entries; 00167 return; 00168 } 00169 00170 Int_t SCycleConfig::GetCacheLearnEntries() const { 00171 00172 return m_cacheLearnEntries; 00173 } 00174 00175 void SCycleConfig::SetProcessOnlyLocal( Bool_t flag ) { 00176 00177 m_processOnlyLocal = flag; 00178 return; 00179 } 00180 00181 Bool_t SCycleConfig::GetProcessOnlyLocal() const { 00182 00183 return m_processOnlyLocal; 00184 } 00185 00186 void SCycleConfig::PrintConfig() const { 00187 00188 SLogger logger( "SCycleConfig" ); 00189 logger << INFO << "===========================================================" 00190 << SLogger::endmsg; 00191 logger << INFO << " Cycle configuration" << SLogger::endmsg; 00192 logger << INFO << " - Running mode: " 00193 << ( m_mode == LOCAL ? "LOCAL" : "PROOF" ) << SLogger::endmsg; 00194 if( m_mode == PROOF ) { 00195 logger << INFO << " - PROOF server: " << m_server << SLogger::endmsg; 00196 logger << INFO << " - PROOF nodes: " << m_nodes << SLogger::endmsg; 00197 } 00198 logger << INFO << " - Target luminosity: " << m_targetLumi << SLogger::endmsg; 00199 logger << INFO << " - Output directory: " << m_outputDirectory << SLogger::endmsg; 00200 logger << INFO << " - Post-fix: " << m_postFix << SLogger::endmsg; 00201 if( m_useTreeCache ) { 00202 logger << INFO << " - Using TTreeCache with size: " << m_cacheSize << SLogger::endmsg; 00203 if( m_cacheLearnEntries > 0 ) { 00204 logger << INFO << " learn entries: " << m_cacheLearnEntries 00205 << SLogger::endmsg; 00206 } else if( m_cacheLearnEntries < 0 ) { 00207 logger << INFO << " All branches added to the cache" << SLogger::endmsg; 00208 } else { 00209 logger << INFO << " The user is expected to choose branches to cache" 00210 << SLogger::endmsg; 00211 } 00212 } 00213 if( m_processOnlyLocal ) { 00214 logger << INFO << " - Workers will only process local files" 00215 << SLogger::endmsg; 00216 } 00217 00218 for( id_type::const_iterator id = m_inputData.begin(); id != m_inputData.end(); 00219 ++id ) { 00220 id->Print(); 00221 } 00222 00223 logger << INFO << "===========================================================" 00224 << SLogger::endmsg; 00225 00226 return; 00227 } 00228 00229 void SCycleConfig::ArrangeInputData() throw ( SError ) { 00230 00231 // multimap to hold all type strings of InputData objects; will be 00232 // used to search InputData objects with the same name, to make 00233 // sure these will be processed directly consecutively so that they 00234 // end up in the same output file 00235 std::multimap< std::string, int > inputDataHelper; 00236 std::vector< SInputData >::iterator be = m_inputData.begin(); 00237 std::vector< SInputData >::iterator en = m_inputData.end(); 00238 int index = 0; 00239 00240 // loop over InputData vector and copy the type names into the 00241 // multimap, remembering the position in the vector 00242 for( ; be != en; ++be,++index ) { 00243 inputDataHelper.insert( std::make_pair( be->GetType(), index ) ); 00244 } 00245 00246 std::multimap< std::string, int >::iterator help1 = inputDataHelper.begin(); 00247 std::multimap< std::string, int >::iterator help2 = inputDataHelper.end(); 00248 index = 0; 00249 std::vector< SInputData > tmpInput; 00250 00251 // Now copy the InputData objects to a temporary vector in the 00252 // order we want them to be processed 00253 for( ; help1 != help2; ++help1,++index ) { 00254 if( help1->second != index ) { 00255 SLogger logger( "SCycleConfig" ); 00256 logger << WARNING << "InputData of type \"" << help1->first 00257 << "\" was given as input number " << ( help1->second + 1 ) 00258 << " but will be repositioned and instead processed as number " 00259 << ( index + 1 ) << SLogger::endmsg; 00260 } 00261 tmpInput.push_back( m_inputData[ help1->second ] ); 00262 } 00263 00264 // Sanity check 00265 if( m_inputData.size() != tmpInput.size() ) { 00266 SError error( SError::StopExecution ); 00267 error << "Inconsistent InputData vectors: size " << m_inputData.size() 00268 << " and " << tmpInput.size(); 00269 throw error; 00270 } 00271 00272 // Now copy the objects back into the vector we use for processing 00273 for( size_t i = 0; i < tmpInput.size(); ++i ) { 00274 m_inputData[ i ] = tmpInput[ i ]; 00275 } 00276 00277 return; 00278 } 00279 00280 void SCycleConfig::ValidateInput() { 00281 00282 for( id_type::iterator id = m_inputData.begin(); id != m_inputData.end(); ++id ) { 00283 id->ValidateInput( m_server ); 00284 } 00285 00286 return; 00287 } 00288 00299 TString SCycleConfig::GetStringConfig( const SInputData* id ) const { 00300 00301 // The result string: 00302 TString result; 00303 00304 // Get the system information: 00305 SysInfo_t sysInfo; 00306 gSystem->GetSysInfo( &sysInfo ); 00307 00308 // Get the user information: 00309 UserGroup_t* userInfo = gSystem->GetUserInfo(); 00310 00311 // Get the current time: 00312 time_t rawtime = time( NULL ); 00313 const char* currentTime = ctime( &rawtime ); 00314 TString printedTime = currentTime ? currentTime : "unknown"; 00315 if( printedTime.EndsWith( "\n" ) ) { 00316 printedTime.Remove( printedTime.Length() - 1 ); 00317 } 00318 00319 // Interestingly enough, it's not needed to delete the return value of 00320 // ctime(...). It even causes problems if I try to do it. Even though 00321 // it actually returns "char*" and not "const char*". Very strange... 00322 00323 // Some disclaimer: 00324 result += "<!-- Archived cycle configuration -->\n"; 00325 result += TString::Format( "<!-- host: %s -->\n", gSystem->HostName() ); 00326 result += TString::Format( "<!-- syst: %s / %s -->\n", sysInfo.fOS.Data(), 00327 sysInfo.fModel.Data() ); 00328 result += TString::Format( "<!-- user: %s (%s) -->\n", 00329 ( userInfo ? userInfo->fUser.Data() : 00330 "unknown" ), 00331 ( userInfo ? userInfo->fRealName.Data() : 00332 "N/A" ) ); 00333 result += TString::Format( "<!-- time: %s -->\n\n", printedTime.Data() ); 00334 00335 // Delete the created object(s): 00336 if( userInfo ) delete userInfo; 00337 00338 // Put together the <Cycle...> part of the configuration: 00339 result += TString::Format( "<Cycle Name=\"%s\"\n", m_cycleName.Data() ); 00340 result += TString::Format( " OutputDirectory=\"%s\"\n", 00341 m_outputDirectory.Data() ); 00342 result += TString::Format( " PostFix=\"%s\"\n", 00343 m_postFix.Data() ); 00344 result += TString::Format( " TargetLumi=\"%g\"\n", m_targetLumi ); 00345 result += " RunMode=\""; 00346 if( m_mode == LOCAL ) { 00347 result += "LOCAL"; 00348 } else if( m_mode == PROOF ) { 00349 result += "PROOF"; 00350 } else { 00351 result += "UNKNOWN"; 00352 } 00353 result += "\"\n"; 00354 result += TString::Format( " ProofServer=\"%s\"\n", 00355 m_server.Data() ); 00356 result += TString::Format( " ProofNodes=\"%i\"\n", m_nodes ); 00357 result += TString::Format( " ProofWorkDir=\"%s\"\n", 00358 m_workdir.Data() ); 00359 result += TString::Format( " UseTreeCache=\"%s\"\n", 00360 ( m_useTreeCache ? "True" : "False" ) ); 00361 result += TString::Format( " TreeCacheSize=\"%lld\"\n", m_cacheSize ); 00362 result += TString::Format( " TreeCacheLearnEntries=\"%i\"\n", 00363 m_cacheLearnEntries ); 00364 result += TString::Format( " ProcessOnlyLocal=\"%s\">\n\n", 00365 ( m_processOnlyLocal ? "True" : "False" ) ); 00366 00367 // Decide how to add the input data information: 00368 if( id ) { 00369 // Add just this one SInputData to the output: 00370 result += TString::Format( "%s\n\n", id->GetStringConfig().Data() ); 00371 } else { 00372 // Put all the InputData options in there: 00373 id_type::const_iterator i_itr = m_inputData.begin(); 00374 id_type::const_iterator i_end = m_inputData.end(); 00375 for( ; i_itr != i_end; ++i_itr ) { 00376 result += TString::Format( "%s\n\n", i_itr->GetStringConfig().Data() ); 00377 } 00378 } 00379 00380 // Put all the user configuration options in there: 00381 result += " <UserConfig>\n"; 00382 property_type::const_iterator p_itr = m_properties.begin(); 00383 property_type::const_iterator p_end = m_properties.end(); 00384 for( ; p_itr != p_end; ++p_itr ) { 00385 result += TString::Format( " <Item Name=\"%s\" Value=\"%s\"/>\n", 00386 p_itr->first.c_str(), 00387 p_itr->second.c_str() ); 00388 } 00389 result += " </UserConfig>\n"; 00390 00391 // Close the <Cycle> block: 00392 result += "</Cycle>"; 00393 00394 // Return the string that we just made: 00395 return result; 00396 } 00397 00398 void SCycleConfig::ClearConfig() { 00399 00400 m_mode = LOCAL; 00401 m_server = ""; 00402 m_workdir = ""; 00403 m_nodes = -1; 00404 m_properties.clear(); 00405 m_inputData.clear(); 00406 m_targetLumi = 1.0; 00407 m_outputDirectory = "./"; 00408 m_postFix = ""; 00409 m_msgLevel = INFO; 00410 m_useTreeCache = kFALSE; 00411 m_cacheSize = 30000000; 00412 m_cacheLearnEntries = 100; 00413 00414 return; 00415 }