| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

OutputFileRollerTool.cc

Go to the documentation of this file.
00001 #include "OutputFileRollerTool.h"
00002 
00003 #include "Event/RegistrationSequence.h"
00004 
00005 #include "TString.h"            // for Form()
00006 
00007 #include <cstdlib>              // for atoi()
00008 #include <sys/types.h>
00009 #include <sys/stat.h>
00010 #include <unistd.h>             // for stat
00011 
00012 using namespace std;
00013 using namespace DayaBay;
00014 
00015 OutputFileRollerTool::OutputFileRollerTool(const std::string& type,
00016                                            const std::string& name,
00017                                            const IInterface* parent)
00018     : GaudiTool(type,name,parent)
00019     , m_current_execnum(0)
00020     , m_rio(0), m_initialized(false)
00021 {
00022     declareInterface<IRegSeqVisitor>(this);
00023 
00024     declareProperty("Condition",m_condition="",
00025                     "Set the default condition for rolling to a new output file");
00026 
00027     declareProperty("StartNumber", m_startOffset=0,
00028                     "Set the starting file number offset, def=0 (first file gets 1).");
00029 
00030     // This condition map will be a trivial one just containing
00031     // "default" as set by the global condition above.  It can be made
00032     // non-trivial when/if RootIO can handle reading input streams
00033     // with non-common boundaries.  See #671.
00034 
00035     //declareProperty("ConditionMap",m_condpropmap,
00036     //                "Set the condition map for rolling each stream to a new output file");
00037 }
00038 
00039 OutputFileRollerTool::~OutputFileRollerTool()
00040 {
00041 }
00042     
00043 StatusCode OutputFileRollerTool::_initialize()
00044 {
00045     m_initialized = true;
00046 
00047     // Get IRootIOSvc
00048     StatusCode sc = this->service("RootIOCnvSvc",m_rio);
00049     if (sc.isFailure()) return sc;
00050 
00051     m_filemap = m_rio->fileMap();
00052     if (!m_filemap.size()) {
00053         info () << "Output filemap is empty, nothing for me to do." << endreq;
00054         return StatusCode::SUCCESS; // we just won't play this time
00055     }
00056     
00057     // munge the output filenames where needed
00058     {
00059         IRootIOSvc::FileMap::iterator it, done = m_filemap.end();
00060         for (it = m_filemap.begin(); it != done; ++it) {
00061             string fname = Form(it->second.c_str(),0);
00062             if (fname != it->second) {
00063                 continue;           // already has a %d code that does something
00064             }
00065             
00066             string::size_type ind = it->second.rfind(".");
00067             // shouldn't happen, but whatevs, we'll roll with it
00068             if (string::npos == ind) { 
00069                 ind = it->second.size(); 
00070             }
00071             
00072             // replace filename with one that has a %d code.
00073             fname = it->second.substr(0,ind) + "_%04d" + it->second.substr(ind);
00074             it->second = fname;
00075         }
00076     }
00077     
00078     // specifically set default condition if one is given
00079     if (m_condition.size()) {
00080         m_condpropmap["default"] = m_condition;
00081     }
00082 
00083     { // parse conditions map and strip out any explicit conditions
00084       // with no matching entry in output file map
00085         ConditionPropertyMap_t::iterator it, done = m_condpropmap.end();
00086         for (it=m_condpropmap.begin(); it != done; ++it) {
00087             string stream = it->first;
00088             string condition = it->second;
00089 
00090             if (stream != "default") {
00091                 IRootIOSvc::FileMap::iterator fit = m_filemap.find(stream);
00092                 if (fit == m_filemap.end()) {
00093                     error() << "Condition \"" << condition 
00094                             << "\" for stream \"" << stream 
00095                             << "\" has no output file.  " 
00096                             << "An entry can be specified with nuwa.py's"
00097                             << " -O/--output-stream option"
00098                             << endreq;
00099                     return StatusCode::FAILURE;
00100                 }
00101             }
00102             
00103             string::size_type clen = condition.size();
00104             if (!clen) {
00105                 error() << "Given a null condition for stream \""
00106                         << stream << "\"" << endreq;
00107                 return StatusCode::FAILURE;
00108             }
00109             int size = atoi(condition.substr(0,clen-1).c_str());
00110             char unit = condition[clen-1];
00111             ConditionData cd = ConditionData(size,unit);
00112             cd.cycles = size;   // special init, count down on this if an E condition
00113             m_cdmap[stream] = cd;
00114             info() << "Condition for stream " << stream << ": " << size << unit << endreq;
00115             sc = this->roll(stream,m_cdmap[stream]);
00116             if (sc.isFailure()) return sc;
00117         }
00118     }
00119 
00120     return StatusCode::SUCCESS;
00121 }
00122 StatusCode OutputFileRollerTool::roll(std::string stream, ConditionData& cd)
00123 {
00124     ++cd.count;
00125 
00126     IRootIOSvc::FileMap::iterator fit = m_filemap.find(stream);
00127     if (fit == m_filemap.end()) {
00128         error() << "Failed to find output filespec for \"" << stream << "\"" << endreq;
00129         return StatusCode::FAILURE;
00130     }
00131 
00132     string fname = Form(fit->second.c_str(),cd.count+m_startOffset);
00133     m_rio->associateOutput(fname.c_str(),stream.c_str());
00134 
00135     info() << "Rolled " << stream << " to file " << fname << endreq;
00136 
00137     return StatusCode::SUCCESS;
00138 }
00139 
00140 StatusCode OutputFileRollerTool::check_m(std::string stream, ConditionData& cd)
00141 {
00142     IRootIOSvc::FileMap fm = m_rio->fileMap();
00143     IRootIOSvc::FileMap::iterator fit = fm.find(stream);
00144     if (fit == fm.end()) {
00145         error() << "Failed to find an output file for stream \"" << stream << "\""
00146                 << endreq;
00147         return StatusCode::FAILURE;
00148     }
00149     string fname = fit->second;
00150     struct stat si;
00151     int err = stat(fname.c_str(), &si);
00152     if (err) {
00153         warning() << "Failed to stat " << fname
00154                   << ".  Maybe no output yet?  Letting it go."
00155                   << endreq;
00156         return StatusCode::SUCCESS;
00157     }
00158         
00159     if (si.st_size/1000000 < cd.size) {  // bytes to mibibytes
00160         return StatusCode::SUCCESS;
00161     }
00162     info () << "Reached " << cd.size << " MiB size" << endreq;
00163     return this->roll(stream,cd);
00164 }
00165 
00166 
00167 // check based on execution cycle count
00168 StatusCode OutputFileRollerTool::check_e(std::string stream, ConditionData& cd)
00169 {
00170     debug() << "check_e " << stream << " " << cd.cycles << " " << (void*)&cd << endreq;
00171 
00172     // check for first time
00173     if (cd.cycles < 0) {
00174         cd.cycles = cd.size;
00175     }
00176 
00177     if (cd.cycles>0) {
00178         --cd.cycles;
00179         return StatusCode::SUCCESS;
00180     }
00181     cd.cycles = cd.size-1;        // reset countdown
00182     info () << "Reached " << cd.size << " execution cycles" << endreq;
00183     return this->roll(stream,cd);
00184 }
00185 
00186 // for this to work, the algorithm must be placed after something that
00187 // loads data into the TES.
00188 StatusCode OutputFileRollerTool::check_s(std::string stream, ConditionData& cd)
00189 {
00190     RegistrationSequence* rs = 
00191         get<RegistrationSequence>(RegistrationSequence::defaultLocation());
00192 
00193     TimeStamp now = rs->earliest();
00194 
00195     // check for first time
00196     if (cd.timestamp == TimeStamp::GetBOT()) {
00197         cd.timestamp = now;
00198         return StatusCode::SUCCESS;
00199     }
00200 
00201     TimeStamp dt = now - cd.timestamp;
00202     int deltat = (int)((double)dt);
00203     if (deltat < cd.size) {     // not yet
00204         return StatusCode::SUCCESS;
00205     }
00206     
00207     cd.timestamp = now;
00208     info () << "Reached " << cd.size << " seconds at " << now << endreq;
00209     return this->roll(stream,cd);
00210 }
00211 
00212 StatusCode OutputFileRollerTool::visit(DayaBay::RegistrationSequence& rs)
00213 {
00214     if (!m_initialized) {
00215         // have to do explicit initialize as ToolSvc and thus this
00216         // tool gets initialized before RootIOCnvSvc does.
00217         this->_initialize();
00218     }
00219 
00220     if (!m_filemap.size()) {    // no output files, bail blissfully
00221         return StatusCode::SUCCESS;
00222     }
00223 
00224     TimeStamp now = rs.earliest();
00225     ++m_current_execnum;
00226     debug() << "Execution #" << m_current_execnum << " @ " << now << endreq;
00227 
00228     CDMap_t::iterator it, done = m_cdmap.end();
00229     for (it=m_cdmap.begin(); it != done; ++it) {
00230         string stream = it->first;
00231         ConditionData& cd = it->second;
00232 
00233         StatusCode sc;
00234 
00235         switch (cd.unit) {
00236         case 'M':
00237             sc = check_m(stream,cd);
00238             break;
00239         case 'E':
00240             sc = check_e(stream,cd);
00241             break;
00242         case 'S':
00243             sc = check_s(stream,cd);
00244             break;
00245         default:
00246             error() << "Unknown condition unit '" << cd.unit << "'" 
00247                     << " for stream \"" << stream << "\""
00248                     << endreq;
00249             sc = StatusCode::FAILURE;
00250         }
00251         if (sc.isFailure()) return sc;
00252     }
00253     return StatusCode::SUCCESS;
00254 }
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

Generated on Mon Apr 11 20:37:24 2011 for DybTool by doxygen 1.4.7