/search.css" rel="stylesheet" type="text/css"/> /search.js">
| Classes | Job Modules | Data Objects | Services | Algorithms | Tools | Packages | Directories | Tracs |

In This Package:

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

Generated on Fri May 16 2014 10:15:57 for DybIO by doxygen 1.7.4