Main Page | Modules | Namespace List | Class Hierarchy | Alphabetical List | Class List | Directories | File List | Namespace Members | Class Members | File Members | Related Pages

DbuDaqFileModule.cxx

Go to the documentation of this file.
00001 
00002 // $Id: DbuDaqFileModule.cxx,v 1.12 2007/01/30 17:00:04 rhatcher Exp $
00004 #include "DatabaseUpdater/DbuDaqFileModule.h"
00005 #include "DatabaseUpdater/DbuSignalHandler.h"
00006 
00007 #include "OnlineUtil/mdBlockDefinitions.h"
00008 
00009 #include "DatabaseUpdater/DbuRunSummary.h"
00010 #include "DatabaseUpdater/DbuDaqFileSummary.h"
00011 #include "DatabaseUpdater/DbuDaqConfigFilesText.h"
00012 
00013 #include "DatabaseUpdater/DbuBits.h"
00014 #include "DatabaseUpdater/RunTypeName.h"
00015 
00016 #include <cstdio>
00017 #include <cassert>
00018 
00019 // ROOT include files
00020 #include "TObject.h"
00021 #include "TCollection.h"
00022 #include "TIterator.h"
00023 #include "TObjectTable.h"
00024 // TString for Form function
00025 #include "TString.h"  
00026 #include "TSystem.h"
00027 #include "TFile.h"
00028 #include "TMath.h"
00029 #include "TROOT.h"
00030 
00031 // MINOS include files
00032 #include "DatabaseInterface/Dbi.h"
00033 #include "DatabaseInterface/DbiCascader.h"
00034 #include "DatabaseInterface/DbiTableProxy.h"
00035 #include "DatabaseInterface/DbiTableProxyRegistry.h"
00036 #include "DatabaseInterface/DbiOutRowStream.h"
00037 #include "DatabaseInterface/DbiWriter.h"
00038 #include "DatabaseInterface/DbiCache.h"
00039 #include "DatabaseInterface/DbiResultPtr.h"
00040 #include "DatabaseInterface/DbiString.h"
00041 #include "DatabaseInterface/DbiStatement.h"
00042 
00043 #include "RawData/RawRecord.h"
00044 #include "RawData/RawDaqSnarlHeader.h"
00045 
00046 #include "RawData/RawLIAdcSummaryBlock.h"
00047 #include "RawData/RawLITimingSummaryBlock.h"
00048 
00049 #include "RawData/RawRunStartBlock.h"
00050 #include "RawData/RawRunCommentBlock.h"
00051 #include "RawData/RawRunEndBlock.h"
00052 #include "RawData/RawSubRunEndBlock.h"
00053 #include "RawData/RawRunConfigBlock.h"
00054 #include "RawData/RawConfigFilesBlock.h"
00055 #include "RawData/RawDigitDataBlock.h"
00056 
00057 #include "JobControl/JobCommand.h"
00058 #include "JobControl/JobCModuleRegistry.h"
00059 #include "MinosObjectMap/MomNavigator.h"
00060 #include "MessageService/MsgService.h"
00061 #include "Util/UtilString.h"
00062 
00063 #include <signal.h>
00064 #include "OnlineUtil/msgLogLib/msgLog.h"
00065 
00066 #include <fstream>
00067 
00068 CVSID("$Id: DbuDaqFileModule.cxx,v 1.12 2007/01/30 17:00:04 rhatcher Exp $");
00069 JOBMODULE(DbuDaqFileModule, 
00070           "DbuDaqFileModule", "Generate RunSummary entries in database.");
00071 
00072 const Int_t        gkFakeRun          = -1;
00073 const Int_t        gkFakeSubRun       = -1;
00074 const VldContext   gkFakeVldContext   = VldContext();
00075 const std::string  gkFakeFile         = "";
00076 
00077 const VldTimeStamp nullTime = VldTimeStamp((time_t)0,0);
00078 
00079 //......................................................................
00080 
00081 const Int_t sec_fivemin = 5*60;
00082 
00083 //......................................................................
00084 
00085 //
00086 // Helper functions
00087 //
00088 inline void updateMinTimeStamp(VldTimeStamp& ts, const VldTimeStamp& ts_new)
00089 {
00090   // update "ts" to the min of it's current value or the new value
00091   // (set it to the new value if it is the nullTime)
00092   if ( nullTime == ts_new ) return; // bad data
00093   if ( nullTime == ts || ts_new < ts ) ts = ts_new;
00094 }
00095 inline void updateMaxTimeStamp(VldTimeStamp& ts, const VldTimeStamp& ts_new)
00096 {
00097   // update "ts" to the max of it's current value or the new value
00098   // (set it to the new value if it is the nullTime)
00099   if ( nullTime == ts_new ) return; // bad data
00100   if ( nullTime == ts || ts_new > ts ) ts = ts_new;
00101 }
00102 inline void updateMinInt(Int_t& minInt, const Int_t curInt)
00103 {
00104   if ( curInt < 0 ) return;  // bad data
00105   if ( minInt < 0 || curInt < minInt ) minInt = curInt;
00106 }
00107 inline void updateMaxInt(Int_t& maxInt, const Int_t curInt)
00108 {
00109   if ( curInt < 0 ) return;  // bad data
00110   if ( maxInt < 0 || curInt > maxInt ) maxInt = curInt;
00111 }
00112 
00113 const char* oracleTimeStamp(VldTimeStamp& ts)
00114 {
00115   // return a string of the form "14-Oct-2004 00:14:10" (implied UTC)
00116   // use internal circular list of buffers to avoid problems
00117   // when multiple calls in a single iostream statment
00118 
00119   struct tm *ptm;
00120   time_t seconds = (time_t) ts.GetSec();
00121   ptm = gmtime(&seconds);  // returns ptr to static data
00122   const char *oracleFmt = "%d-%b-%Y %H:%M:%S";
00123 
00124   const  int nbuffers = 8;
00125   static int ibuffer  = nbuffers;
00126   ibuffer = (ibuffer+1)%nbuffers;  // each call move to next buffer
00127   static char timeString[nbuffers][64];
00128   strftime(timeString[ibuffer],sizeof(timeString[ibuffer]),oracleFmt,ptm);
00129   return timeString[ibuffer];
00130 }
00131 
00132 //......................................................................
00133 
00134 DbuDaqFileModule::DbuDaqFileModule() :
00135    fURL(""), fDbNo(0), fDbiStatement(0),
00136    fHeartbeatIntervalSec(sec_fivemin),
00137    fCurrentRunSummary(0), fCurrentDaqFileSummary(0), 
00138    fCurrentConfigFilesText(0),
00139    fCurrentRun(gkFakeRun),               fNextRun(gkFakeRun), 
00140    fCurrentSubRun(gkFakeSubRun),         fNextSubRun(gkFakeSubRun),
00141    fCurrentVldContext(gkFakeVldContext), fNextVldContext(gkFakeVldContext),
00142    fCurrentFile(gkFakeFile),             fNextFile(gkFakeFile)
00143 {}
00144 
00145 //......................................................................
00146 
00147 DbuDaqFileModule::~DbuDaqFileModule() {}
00148 
00149 //......................................................................
00150   
00151 JobCResult DbuDaqFileModule::Ana(const MomNavigator* mom)
00152 {
00153    // process the record set
00154 
00155    MSG("Dbu",Msg::kVerbose) << " DbuDaqFileModule::Ana() " << endl;
00156 
00157    ExtractRunAndFile(mom);  // fake up Begin/End Run/File
00158    DoBeginEndRunAndFile();
00159 
00160    fCurrentDaqFileSummary->fRecSets++;  // new record set
00161 
00162    JobCResult result = JobCResult::kPassed;
00163    
00164    // Get any and all raw records attached to the data record pointed 
00165    // to by "mom".  The dynamic cast from TObject is ugly but necessary
00166    TObject   *tobj   = 0;
00167    bool incNonLIRec = false;
00168    TIter reciter = const_cast<MomNavigator*>(mom)->FragmentIter();
00169    while ( (tobj = reciter() ) ) {
00170       RawRecord *rawrec = dynamic_cast<RawRecord *>(tobj);
00171       JobCResult aresult = ProcessRawRecord(rawrec);
00172       if (aresult.Failed()) result = aresult;
00173       const std::string strmname = 
00174           rawrec->GetTempTags().GetCharString("stream");
00175       if ( strmname == "DaqMonitor" || strmname == "DaqSnarl" )
00176           incNonLIRec = true;
00177    }
00178 
00179    if ( incNonLIRec ) fCurrentDaqFileSummary->fRecSetsNotLIOnly++;
00180 
00181    return result;
00182 }
00183 
00184 //......................................................................
00185 
00186 void DbuDaqFileModule::BeginJob()
00187 {
00188    // make the DbiStatement connection
00189 
00190    MSG("Dbu",Msg::kDebug) << "DbuDaqFileModule::BeginJob() start" << endl;
00191 
00192    Update_ENV_TSQL();
00193 
00194    fDbiStatement = 
00195      DbiTableProxyRegistry::Instance().GetCascader().CreateStatement(fDbNo);
00196 
00197    MSG("Dbu",Msg::kDebug) << "DbuDaqFileModule::BeginJob() end" << endl;
00198 
00199 }
00200 
00201 //......................................................................
00202 
00203 void DbuDaqFileModule::EndJob()
00204 {
00205    // this should make sure all entries are flushed
00206 
00207   fNextRun        = gkFakeRun;
00208   fNextSubRun     = gkFakeSubRun;
00209   fNextVldContext = gkFakeVldContext;
00210   fNextFile       = gkFakeFile;
00211   DoBeginEndRunAndFile();
00212 
00213   MSG("Dbu",Msg::kInfo)
00214     << "DbuDaqFileModule::EndJob() " << endl;
00215 
00216   //logInfo("DbuDaqFileModule::EndJob() processing begun");
00217 
00218   MSG("Dbu",Msg::kInfo) << "Delete DbiStatement" << endl;
00219   delete fDbiStatement;  // delete statement to release connection
00220   fDbiStatement = 0;
00221 
00222   logInfo("DbuDaqFileModule::EndJob() finished");
00223 }
00224 
00225 //......................................................................
00226 
00227 void DbuDaqFileModule::ExtractRunAndFile(const MomNavigator* mom)
00228 {
00229    // Pull out the run # and file name
00230    // Assume that any given record set comes from one-and-only-one
00231    // Run and File (true for normal Daq files)
00232    
00233    RawRecord *rawrec = dynamic_cast<RawRecord*>(mom->GetFragment("RawRecord"));
00234    if ( !rawrec ) {
00235      logWarn("ExtractRunAndFile() MomNavigator has no RawRecord");
00236      return;
00237    }
00238 
00239    const RawDaqHeader* daqHdr = 
00240      dynamic_cast<const RawDaqHeader*>(rawrec->GetRawHeader());
00241    if ( !daqHdr ) {
00242      logWarn("ExtractRunAndFile() RawRecord had no RawDaqHeader");
00243      return;
00244    }
00245 
00246    fNextVldContext   = daqHdr->GetVldContext();
00247    fNextRun          = daqHdr->GetRun();
00248    fNextSubRun       = daqHdr->GetSubRun();
00249    fNextRunType      = daqHdr->GetRunType();
00250    fNextTimeFrameNum = daqHdr->GetTimeFrameNum();
00251 
00252    const Registry& registry = rawrec->GetTempTags();
00253    const char* tmpfile = 0;
00254    registry.Get("file",tmpfile);
00255    // we only want the basename
00256    const char* basename = gSystem->BaseName(tmpfile);
00257    fNextFile   = basename;
00258 
00259    //logDebug(1,"Extract Run %d SubRun %d File %s",
00260    //         fNextRun,fNextSubRun,fNextFile.c_str());
00261 
00262 }
00263 
00264 //......................................................................
00265 
00266 void DbuDaqFileModule::DoBeginEndRunAndFile()
00267 {
00268    // Call the appropriate sequence of Begin/End Run/File
00269    // To work in the fashion that's most appropriate
00270    // we need to BeginRun before BeginFile and EndFile before EndRun.
00271    // And of course, end either before the next begin.
00272 
00273    bool newDetector  = ( fNextVldContext.GetDetector() != 
00274                          fCurrentVldContext.GetDetector() );
00275    bool newSimFlag   = ( fNextVldContext.GetSimFlag()  !=
00276                          fCurrentVldContext.GetSimFlag()  );
00277    bool newContext   = ( newDetector || newSimFlag );
00278    bool newFile      = ( fNextFile   != fCurrentFile   || newContext );
00279    bool newRun       = ( fNextRun    != fCurrentRun    || newContext );
00280    bool newSubRun    = ( fNextSubRun != fCurrentSubRun || newRun || newContext );
00281    bool newSomething = ( newFile || newRun || newSubRun );
00282 
00283    if (newSomething) {
00284      logDebug(1,"Current '%s' %d %d, Next '%s' %d %d new %c %c",
00285               fCurrentFile.c_str(),fCurrentRun,fCurrentSubRun,
00286               fNextFile.c_str(),fNextRun,fNextSubRun,
00287               (newFile?'T':'F'),(newRun?'T':'F'),(newSubRun?'T':'F'));
00288      MSG("Dbu",Msg::kDebug) 
00289          << "DoBeginEndRunAndFile status: " 
00290          << (newDetector?"new":"old") << "Detector, "
00291          << (newSimFlag ?"new":"old") << "SimFlag, "
00292          << (newFile    ?"new":"old") << "File, "
00293          << (newRun     ?"new":"old") << "Run, "
00294          << (newSubRun  ?"new":"old") << "SubRun "
00295          << endl;
00296      if (newFile) MSG("Dbu",Msg::kDebug) << "new file: " << fNextFile << endl;
00297      if (newRun)  MSG("Dbu",Msg::kDebug) << "new run:  " << fNextRun  << endl;
00298 
00299    }
00300    
00301    //MSG("Dbu",Msg::kVerbose) 
00302    //<< "DoBeginEndRunAndFile status: " 
00303    //<< (newDetector?"new":"old") << "Detector, "
00304    //<< (newSimFlag ?"new":"old") << "SimFlag, "
00305    //<< (newFile    ?"new":"old") << "File, "
00306    //<< (newRun     ?"new":"old") << "Run, "
00307    //<< (newSubRun  ?"new":"old") << "SubRun "
00308    //<< endl;
00309 
00310    if ( newFile   && fCurrentFile != gkFakeFile ) MyOwn_EndFile();
00311    if ( newRun    && fCurrentRun  != gkFakeRun  ) MyOwn_EndRun();
00312   
00313    if ( newRun    ) fCurrentRun    = fNextRun;
00314    if ( newSubRun ) fCurrentSubRun = fNextSubRun;
00315    if ( newFile   ) fCurrentFile   = fNextFile;
00316    fCurrentVldContext   = fNextVldContext;  // always moves on
00317    fCurrentRunType      = fNextRunType;
00318    fCurrentTimeFrameNum = fNextTimeFrameNum;
00319 
00320    if ( newRun    && fCurrentRun  != gkFakeRun  ) MyOwn_BeginRun();
00321    if ( newFile   && fCurrentFile != gkFakeFile ) MyOwn_BeginFile();
00322 
00323 }
00324 
00325 //......................................................................
00326 
00327 void DbuDaqFileModule::BuildExtContextAndSelect()
00328 {
00329 
00330    // construct an extended context
00331    VldTimeStamp tsStart(1995, 1, 1, 0, 0, 0); // earliest time for MINOS
00332    VldTimeStamp   tsEnd(2038, 1, 8,19,14,07); // the end of time
00333    Detector::Detector_t det     = fCurrentVldContext.GetDetector();
00334    SimFlag::SimFlag_t   simflag = fCurrentVldContext.GetSimFlag();
00335    fExtDbiSqlContext = DbiSqlContext(DbiSqlContext::kStarts,
00336                                      tsStart,tsEnd,det,simflag);
00337    
00338    Int_t seqNoMin = DbuDaqFileSummary::CalcUniqueSeqNo
00339      (det,fCurrentRun,DbuDaqFileSummary::kMinSubRun);
00340    Int_t seqNoMax = DbuDaqFileSummary::CalcUniqueSeqNo
00341      (det,fCurrentRun,DbuDaqFileSummary::kMaxSubRun);
00342 
00343    fWhereSelect = Form("SEQNO >= %d AND SEQNO <= %d",seqNoMin,seqNoMax);
00344 
00345    //MSG("Dbu",Msg::kDebug) << "WHERE " << fWhereSelect << endl;
00346 }
00347 
00348 //......................................................................
00349 
00350 void DbuDaqFileModule::CommitDbuRunSummary()
00351 {
00352 
00353    // Commit DbuRunSummary
00354 
00355   bool success = false;
00356   
00357   if ( fCurrentRunSummary ) {
00358 
00359     DbuRunSummary* drs = fCurrentRunSummary; // just a shorthand
00360 
00361     // patch up start/end times with sub run info
00362     DbiResultPtr<DbuDaqFileSummary>
00363       rsFile("DBUDAQFILESUMMARY",fExtDbiSqlContext,
00364              Dbi::kAnyTask,fWhereSelect.c_str());
00365     
00366     UInt_t nFile = rsFile.GetNumRows();
00367     for (UInt_t k=0; k < nFile; ++k) {
00368       const DbuDaqFileSummary* fs = rsFile.GetRow(k);
00369       if ( fs->fSubRun > drs->fLastSubRun ) drs->fLastSubRun = fs->fSubRun;
00370       updateMinTimeStamp(drs->fStartTime,fs->fFirstMonitorTime);
00371       updateMaxTimeStamp(drs->fEndTime,  fs->fLastMonitorTime);
00372       updateMinTimeStamp(drs->fStartTime,fs->fFirstSnarlTime);
00373       updateMaxTimeStamp(drs->fEndTime,  fs->fLastSnarlTime);
00374     }
00375 
00376     std::string cft_md5   = DbuDaqConfigFilesText::kNoMD5;
00377     int         cft_seqno = 0;
00378 
00379     // first commit the config text (if necessary)
00380     CommitDbuDaqConfigFilesText(cft_md5,cft_seqno);
00381 
00382     Int_t fmt = DbuRunSummary::GetFmtFlag();
00383     DbuRunSummary::SetFmtFlag(0);
00384     MSG("Dbu",Msg::kSynopsis)
00385       << "CommitDbuRunSummary(): " << *fCurrentRunSummary << endl;
00386     DbuRunSummary::SetFmtFlag(fmt);
00387 
00388     success = fCurrentRunSummary->Commit(fDbiStatement,cft_md5,cft_seqno);
00389   }
00390 
00391   if ( success ) {
00392     delete fCurrentRunSummary;
00393     fCurrentRunSummary = 0;
00394   }
00395 }
00396 
00397 //......................................................................
00398 
00399 void DbuDaqFileModule::CommitDbuDaqFileSummary()
00400 {
00401 
00402    // Commit DbuDaqFileSummary
00403   
00404   bool success = false;
00405   
00406   if ( fCurrentDaqFileSummary ) {
00407 
00408     MSG("Dbu",Msg::kSynopsis)
00409       << "CommitDbuDaqFileSummary(): " << *fCurrentDaqFileSummary << endl;
00410 
00411     success = fCurrentDaqFileSummary->Commit(fDbiStatement);
00412     // wrote it to the DB (maybe) generate SAM python script
00413     WritePythonFile(success);
00414   }
00415   
00416   if ( success ) {
00417     delete fCurrentDaqFileSummary;
00418     fCurrentDaqFileSummary = 0;
00419   }
00420 }
00421 
00422 //......................................................................
00423                                         
00424 void DbuDaqFileModule::CommitDbuDaqConfigFilesText(std::string& cft_md5, 
00425                                                    int& cft_seqno)
00426 {
00427 
00428    // Commit DbuDaqConfigFilesText
00429 
00430   bool success = false;
00431 
00432   if ( fCurrentConfigFilesText ) {
00433     // force the MD5 to be (re)calculated
00434     cft_md5   = fCurrentConfigFilesText->CalcMD5();
00435     // look to see if this already exists
00436     cft_seqno = fCurrentConfigFilesText->LookupSeqNo(fDbiStatement);
00437     MSG("Dbu",Msg::kDebug) << " first SEQNO lookup: " << cft_seqno << endl;
00438     if ( 0 == cft_seqno ) {
00439       // we need to write it, and get the newly added seqno
00440 
00441       MSG("Dbu",Msg::kSynopsis)
00442         << "CommitDbuDaqConfigFilesText(): " << *fCurrentConfigFilesText << endl;
00443 
00444       VldTimeStamp bot(time_t(0),0);
00445       VldTimeStamp eot(time_t(0x7fffffff),0);
00446       VldRange range(0xFF,0xFF,bot,eot,"all time and space");
00447       Int_t aggNo = -1;
00448       Dbi::Task task = 0;
00449       VldTimeStamp create;
00450       std::string dbName = GetConfig().GetCharString("dbName"); // "offline";
00451       DbiWriter<DbuDaqConfigFilesText> writer(range,aggNo,task,create,dbName);
00452       writer << *fCurrentConfigFilesText;
00453       writer.Close();
00454       cft_seqno = fCurrentConfigFilesText->LookupSeqNo(fDbiStatement);
00455       MSG("Dbu",Msg::kDebug) << " second SEQNO lookup: " << cft_seqno << endl;
00456     }
00457   }
00458   
00459   if ( success ) {
00460    delete fCurrentConfigFilesText;
00461    fCurrentConfigFilesText = 0;
00462   }
00463 }
00464 
00465 //......................................................................
00466 
00467 void DbuDaqFileModule::WritePythonFile(bool dbWriteSuccess)
00468 {
00469   // write the python file for the current DbuDaqFileSummary
00470   Registry& r = GetConfig();
00471   Int_t control      = r.GetInt("GenSAMPythonFile");
00472   if ( control == 0 || ( control == 2 && !dbWriteSuccess ) ) return;
00473 
00474   DbuRunSummary& drs = *fCurrentRunSummary;          // an alias
00475   DbuDaqFileSummary& dfs = *fCurrentDaqFileSummary;  // an alias
00476   string& refBaseName = dfs.fBaseName;
00477 
00478   string::size_type dotpos = refBaseName.find(".");
00479 
00480   const char* path = r.GetCharString("SAMPythonPath");  // unexpanded path
00481   const char* expandedPathName = 
00482     gSystem->ExpandPathName(path);  // take ownership of result
00483   string filename = expandedPathName;
00484   filename += "/";
00485   filename += refBaseName.substr(0,dotpos); // [inclusive,exclusive)
00486   filename += ".sam.py";
00487   delete [] expandedPathName;
00488 
00489   ofstream sam_py(filename.c_str());
00490 
00491   VldTimeStamp now;
00492   sam_py
00493     << "# File: " << refBaseName << endl
00494     << "# Path: " << dfs.fDirName << endl
00495     << "# Last mod: " << dfs.fModTime.AsString("sql") << endl
00496     << "# Processed At: " << now.AsString("sql") << endl
00497     << "# Processed On: " << dfs.fProcHost << endl
00498     << endl;
00499 
00500   sam_py 
00501     << "from SamFile.SamDataFile import SamDataFile" << endl
00502     << endl
00503     << "from SamFile.SamDataFile import ApplicationFamily" << endl
00504     << "from SamFile.SamDataFile import CRC" << endl
00505     << "from SamFile.SamDataFile import SamTime" << endl
00506     << "from SamFile.SamDataFile import RunDescriptorList" << endl
00507     << "from SamFile.SamDataFile import SamSize" << endl
00508     << endl
00509     << "import SAM" << endl
00510     << endl;
00511 
00512   int rvi = dfs.fRootVersion;
00513   int rvmajor = rvi/10000;
00514   int rvminor = rvi/100 - 100*rvmajor;
00515   int rvtiny  = rvi%100;
00516   string rootVersionString = Form("v%02d-%02d-%02d",rvmajor,rvminor,rvtiny);
00517   string detname = UtilString::ToLower(Detector::AsString(dfs.fDetector));
00518 
00519   VldTimeStamp startTime = dfs.fFirstMonitorTime;
00520   VldTimeStamp endTime   = dfs.fLastMonitorTime;
00521   // the above _should_ do in general ... but sometimes things are weird
00522   updateMinTimeStamp(startTime,dfs.fFirstSnarlTime);
00523   updateMaxTimeStamp(endTime,dfs.fLastSnarlTime);
00524 
00525   sam_py
00526     << "metadata = SamDataFile(" << endl
00527     << "   fileName='" << refBaseName << "'," << endl
00528     << "   fileType=SAM.DataFileType_ImportedDetector," << endl
00529     << "   fileContentStatus=SAM.DataFileContentStatus_Good," << endl
00530     << "   fileFormat=SAM.DataFileFormat_ROOT," << endl
00531     << "   fileSize=SamSize('" << dfs.fSize << "B')," << endl
00532     << "   crc=CRC(999L,SAM.CRC_Adler32Type), # to be computed later" << endl
00533     << "   group='minos'," << endl
00534     << "   applicationFamily=ApplicationFamily('online','rotorooter','" 
00535     <<                       rootVersionString << "')," << endl
00536     << "# last arg in ApplicationFamily is the ROOT version used in writing file" << endl
00537     << "   dataTier='raw-" << detname << "'," << endl
00538     << "   datastream='alldata'," << endl  // undifferentiated for raw DAQ data
00539     << "   runNumber=" << dfs.fRun << "," << endl
00540     << "   runType='" << RunTypeName(drs.fRunType,drs.fDetector,drs.fRun) << "'," << endl
00541     << "   startTime=SamTime('" << oracleTimeStamp(startTime)
00542     <<                       "(UTC)',SAM.SamTimeFormat_UTCFormat)," << endl
00543     << "   endTime=SamTime('" << oracleTimeStamp(endTime)
00544     <<                       "(UTC)',SAM.SamTimeFormat_UTCFormat)," << endl
00545     << "   eventCount=" << dfs.fRecSets << "," << endl  // # of record sets (what JobC reports)
00546     << "   firstEvent=" << dfs.fFirstSnarlNum << "," << endl
00547     << "   lastEvent=" << dfs.fLastSnarlNum  /* << "," */ << endl
00548     << ")"
00549     << endl;
00550 
00551 }
00552 
00553 //......................................................................
00554 
00555 void DbuDaqFileModule::MyOwn_BeginRun()
00556 {
00557    // Do whatever with fCurrentRun
00558    if ( fCurrentRun == gkFakeRun ) return; // never start a fake run
00559    logInfo("BeginRun %d",fCurrentRun);
00560    MSG("Dbu",Msg::kDebug) << " ########## MyOwn_BeginRun ########## " << fCurrentRun << endl;
00561 
00562    if ( fCurrentRunSummary ) {
00563      // should have been handled in EndRun
00564      DbuRunSummary* drs = fCurrentRunSummary; // just a shorthand
00565      logWarn("BeginRun still has a fCurrentRunSummary for %s run %d",
00566              Detector::AsString(drs->fDetector),drs->fRun);
00567      // well, just delete it...
00568      // ..if it's still there then probably the commit failed for
00569      // some reason (most likely write privs problem).
00570      delete fCurrentRunSummary;
00571      fCurrentRunSummary = 0;
00572    }
00573 
00574    // Check if we already have a DbuRunSummary entry in the DB for this run
00575 
00576    BuildExtContextAndSelect();
00577 
00578    DbiResultPtr<DbuRunSummary>
00579      rsPtrRun("DBURUNSUMMARY",fExtDbiSqlContext,
00580                Dbi::kAnyTask,fWhereSelect.c_str());
00581    
00582    MSG("Dbu",Msg::kDebug)
00583      << "DbiSqlContext: "
00584      << fExtDbiSqlContext.GetTimeStart() << " "
00585      << fExtDbiSqlContext.GetTimeEnd() << " "
00586      << " DetMask " << (int)fExtDbiSqlContext.GetDetector()
00587      << " SimMask " << (int)fExtDbiSqlContext.GetSimFlag()
00588      << endl
00589      << "fWhereSelect: " << fWhereSelect
00590      << endl;
00591 
00592 
00593    UInt_t nRunMatch = rsPtrRun.GetNumRows();
00594    if ( nRunMatch == 0 ) {
00595      fCurrentRunSummary = new DbuRunSummary;  // start afresh
00596 
00597      VldContext& vldc = fCurrentVldContext;   // just an alias
00598      VldTimeStamp ts  = vldc.GetTimeStamp();
00599      fCurrentRunSummary->fDetector  = vldc.GetDetector();
00600      fCurrentRunSummary->fSimFlag   = vldc.GetSimFlag();
00601      fCurrentRunSummary->fRun       = fCurrentRun;
00602      //rwh:fCurrentRunSummary->fStartTime = ts;
00603      //rwh:fCurrentRunSummary->fEndTime   = ts;
00604      fCurrentRunSummary->fRunType   = fCurrentRunType;
00605 
00606      fCurrentConfigFilesText = new DbuDaqConfigFilesText; // start afresh
00607    }
00608    else {
00609      const DbuRunSummary* dbuRunSum = rsPtrRun.GetRow(0);  // take first
00610      fCurrentRunSummary = new DbuRunSummary(*dbuRunSum);   // copy it
00611 
00612      const DbuDaqConfigFilesText* cft = dbuRunSum->fDbuDaqConfigFilesText;
00613      fCurrentConfigFilesText = new DbuDaqConfigFilesText(*cft); // copy it
00614 
00615      if ( nRunMatch > 1 ) {
00616        MSG("Dbu",Msg::kWarning) 
00617          << "BeginRun multiple DbuRunSummary entries for " 
00618          << fCurrentRun << endl;
00619        //assert(0);
00620      }
00621    }
00622 
00623   Int_t fmt = DbuRunSummary::GetFmtFlag();
00624   DbuRunSummary::SetFmtFlag(0);
00625    MSG("Dbu",Msg::kInfo)
00626      << "BeginRun Run " << fCurrentRun << " had " << nRunMatch 
00627      << " entries in DB"
00628      << endl << *fCurrentRunSummary << endl;
00629   DbuRunSummary::SetFmtFlag(fmt);
00630                           
00631 }
00632 
00633 //......................................................................
00634 
00635 void DbuDaqFileModule::MyOwn_EndRun()
00636 {
00637    // Do whatever with fCurrentRun
00638    if ( fCurrentRun == gkFakeRun ) return; // never end a fake run
00639    logInfo("EndRun %d",fCurrentRun);
00640    MSG("Dbu",Msg::kDebug) << " ########## MyOwn_EndRun ########## " << fCurrentRun << endl;
00641 
00642    CommitDbuRunSummary();
00643 }
00644 
00645 //......................................................................
00646 
00647 void DbuDaqFileModule::MyOwn_BeginFile()
00648 {
00649    // Do whatever with fCurrentFile
00650    if ( fCurrentFile == gkFakeFile ) return; // never start a fake file
00651    logInfo("BeginFile %s run %d sub %d",
00652            fCurrentFile.c_str(),fCurrentRun,fCurrentSubRun);
00653    MSG("Dbu",Msg::kDebug) << " ########## MyOwn_BeginFile ########## " << fCurrentFile << endl;
00654 
00655    if ( fCurrentDaqFileSummary ) {
00656      // should have been handled in EndFile
00657      DbuDaqFileSummary* ddfs = fCurrentDaqFileSummary; // just a shorthand
00658      logWarn("BeginFile still has a fCurrentDbuDaqFileSummary for %s run %d sub %d",
00659              Detector::AsString(ddfs->fDetector),ddfs->fRun,ddfs->fSubRun);
00660      // well, just delete it...
00661      // ..if it's still there then probably the commit failed for
00662      // some reason (most likely write privs problem).
00663      delete fCurrentDaqFileSummary;
00664      fCurrentDaqFileSummary = 0;
00665    }
00666 
00667    fCurrentDaqFileSummary = new DbuDaqFileSummary;
00668 
00669    VldContext& vldc = fCurrentVldContext; // just an alias
00670    VldTimeStamp ts  = vldc.GetTimeStamp();
00671    fCurrentDaqFileSummary->fDetector  = vldc.GetDetector();
00672    fCurrentDaqFileSummary->fSimFlag   = vldc.GetSimFlag();
00673    fCurrentDaqFileSummary->fRun       = fCurrentRun;
00674    fCurrentDaqFileSummary->fSubRun    = fCurrentSubRun;
00675    //rwh:fCurrentDaqFileSummary->fStartTime = ts;
00676    //rhw:fCurrentDaqFileSummary->fEndTime   = ts;
00677 
00678    // find the TFile for the new filename
00679    TSeqCollection* listOfFiles = gROOT->GetListOfFiles();
00680    TIter fileItr(listOfFiles);
00681    TFile* afile = 0;
00682    std::string currentBaseName = gSystem->BaseName(fCurrentFile.c_str());
00683 
00684    while ( ( afile = (TFile*)fileItr.Next() ) ) {
00685      std::string fname = afile->GetName();
00686      std::string fbasename = gSystem->BaseName(fname.c_str());
00687 
00688      if ( currentBaseName == fbasename ) {  // test without any path info
00689        // found the file, ask questions
00690        fCurrentDaqFileSummary->fBaseName       = gSystem->BaseName(fname.c_str());
00691        fCurrentDaqFileSummary->fDirName        = gSystem->DirName(fname.c_str());
00692        fCurrentDaqFileSummary->fSize           = afile->GetSize();
00693        fCurrentDaqFileSummary->fCompressLevel  = afile->GetCompressionLevel();
00694        fCurrentDaqFileSummary->fCompressFactor = afile->GetCompressionFactor();
00695        fCurrentDaqFileSummary->fRootVersion    = afile->GetVersion();
00696 
00697 #if ROOT_VERSION_CODE >= ROOT_VERSION(4,1,4)
00698        FileStat_t fileStat;
00699        gSystem->GetPathInfo(fname.c_str(),fileStat);
00700        fCurrentDaqFileSummary->fModTime        = VldTimeStamp(fileStat.fMtime,0);
00701 #else
00702        MSG("Dbu",Msg::kFatal)
00703          << "Sorry, this module will only work with "
00704          << "ROOT version v4.01.04 and beyond"
00705          << endl;
00706        assert(0);
00707 #endif
00708 
00709        fCurrentDaqFileSummary->fProcHost       = gSystem->HostName();
00710        
00711      } // the file
00712    } // loop over all files ROOT has
00713    
00714 }
00715 
00716 //......................................................................
00717 
00718 void DbuDaqFileModule::MyOwn_EndFile()
00719 {
00720    // Do whatever with fCurrentFile
00721    if ( fCurrentFile == gkFakeFile ) return; // never end a fake file
00722    logInfo("EndFile %s run %d sub %d",
00723            fCurrentFile.c_str(),fCurrentRun,fCurrentSubRun);
00724    MSG("Dbu",Msg::kDebug) << " ########## MyOwn_EndFile ########## " << fCurrentFile << endl;
00725 
00726    if ( fCurrentRunSummary ) 
00727      fCurrentRunSummary->ResetConsistencyBits(DbuBits::kInProgress);
00728    CommitDbuDaqFileSummary();
00729 }
00730 
00731 //......................................................................
00732 
00733 void DbuDaqFileModule::BeginRun()
00734 {
00735    MSG("Dbu",Msg::kDebug) << " ########## Standard BeginRun ########## " 
00736                           << GetCurrentRun()
00737                           << endl;
00738 }
00739 
00740 void DbuDaqFileModule::EndRun()
00741 {
00742    MSG("Dbu",Msg::kDebug) << " ########## Standard EndRun ########## " 
00743                           << GetCurrentRun()
00744                           << endl;
00745 }
00746 
00747 void DbuDaqFileModule::BeginFile()
00748 {
00749    MSG("Dbu",Msg::kDebug) << " ########## Standard BeginFile ########## " 
00750                           << GetCurrentFile()
00751                           << endl;
00752 }
00753 
00754 void DbuDaqFileModule::EndFile()
00755 {
00756    MSG("Dbu",Msg::kDebug) << " ########## Standard BeginFile ########## "
00757                           << GetCurrentFile()
00758                           << endl;
00759 }
00760 
00761 //......................................................................
00762 
00763 const Registry& DbuDaqFileModule::DefaultConfig() const 
00764 {
00765 //======================================================================
00766 // The default configuration for this module
00767 //======================================================================
00768   static Registry r;
00769   
00770   std::string name = this->GetName();
00771   name += ".config.default";
00772   r.SetName(name.c_str());
00773   
00774   r.UnLockValues();
00775 
00776   // comma separated list of config files that don't go into
00777   // common (shared across runs) DbuDaqConfigFilesText table
00778   r.Set("AuxConfigFileList","liStartTimes.config"); 
00779 
00780   // frequency (VldTimeStamp in the data) for outputing a heartbeat indicator
00781   r.Set("HeartbeatIntervalSec",sec_fivemin);
00782 
00783   // database into which to write
00784   r.Set("dbName","offline");
00785 
00786   // generate a SAM python file?
00787   // 0=never, 1=always, 2=only if DB write successful
00788   r.Set("GenSAMPythonFile",2);
00789   // write the SAM python file where?
00790   // set NULL to skip SAM python file generation
00791   r.Set("SAMPythonPath","."); 
00792 
00793   r.LockValues();
00794 
00795   return r;
00796 }
00797 
00798 //......................................................................
00799 
00800 void DbuDaqFileModule::Config(const Registry& r) 
00801 {
00802 //======================================================================
00803 // Configure the module using the registry r
00804 //======================================================================
00805 
00806    int tmpi;
00807    const char* tmps = 0;
00808 
00809    if (r.Get("AuxConfigFileList",tmps))    fAuxConfigFileList    = tmps;
00810    if (r.Get("HeartbeatIntervalSec",tmpi)) fHeartbeatIntervalSec = tmpi;
00811 
00812    const char* dbName     = r.GetCharString("dbName");
00813    Int_t genPython        = r.GetInt("GenSAMPythonFile");
00814    const char* pythonPath = r.GetCharString("SAMPythonPath");
00815    std::string pythonMsg;
00816    switch ( genPython ) {
00817    case 0:  pythonMsg = "No SAMPythonFile generation";   break;
00818    case 1:  pythonMsg = "Always generate SAMPythonFile"; break;
00819    case 2:  pythonMsg = "Generate SAMPythonFile if DB write okay"; break;
00820    default: pythonMsg = "<<huh?>>";
00821    }
00822    if ( genPython > 0 ) {
00823      pythonMsg += ", written in path='";
00824      pythonMsg += pythonPath;
00825      pythonMsg += "'";
00826    }
00827 
00828    MSG("Dbu",Msg::kInfo) 
00829       << "DbuDaqFileModule::Config  " << endl
00830       << " AuxConfigFileList: " << fAuxConfigFileList << endl
00831       << " HeartbeatInterval: " << fHeartbeatIntervalSec << " sec" << endl
00832       << " dbName: '" << dbName << "'" << endl
00833       << " " << pythonMsg 
00834       << endl;
00835 
00836    logInfo("DbuDaqFileModule::Config() heartbeat %d sec in %s",
00837            fHeartbeatIntervalSec, dbName);
00838 
00839 }
00840 
00841 //......................................................................
00842 
00843 void DbuDaqFileModule::Update_ENV_TSQL()
00844 {
00845 //======================================================================
00846 // copy ENV_TSQL_UPDATE_XXX to ENV_TSQL_XXX
00847 //======================================================================
00848 
00849    const char* strUser = gSystem->Getenv("ENV_TSQL_UPDATE_USER");
00850    const char* strPswd = gSystem->Getenv("ENV_TSQL_UPDATE_PSWD");
00851    const char* strUrl  = gSystem->Getenv("ENV_TSQL_UPDATE_URL");
00852 
00853    if (strUser) gSystem->Setenv("ENV_TSQL_USER",strUser);
00854    if (strPswd) gSystem->Setenv("ENV_TSQL_PSWD",strPswd);
00855    if (strUrl)  gSystem->Setenv("ENV_TSQL_URL",strUrl);
00856 
00857    fURL  = "";
00858    fDbNo = 0;
00859 
00860    // find the "offline" DB from the URL (not the "temp" one)
00861 
00862    const char* strUrlUsed = gSystem->Getenv("ENV_TSQL_URL");
00863    string urlList = (strUrlUsed) ? strUrlUsed : "";
00864    while ( urlList != "") {
00865      UInt_t maxStringPos = urlList.size();
00866      string url = urlList;
00867      UInt_t nextStringPos = urlList.find(";");
00868      if ( nextStringPos < maxStringPos ) {
00869        url = urlList.substr(0,nextStringPos);
00870        urlList.erase(0,nextStringPos+1);
00871      }
00872      else urlList = "";
00873      
00874      maxStringPos = url.size();
00875      
00876      if (url.find(GetConfig().GetCharString("dbName")) < maxStringPos) {
00877        fURL = url;
00878        break;
00879      }
00880      
00881      // if not chosen dbName ("offline") move along to next possibility
00882      ++fDbNo;
00883    }
00884 }
00885 
00886 //......................................................................
00887 
00888 JobCResult DbuDaqFileModule::ProcessRawRecord(const RawRecord* rawrec)
00889 {
00890 
00891    JobCResult result = JobCResult::kPassed;
00892 
00893    // test if the RawRecord was from the DAQ
00894    const RawDaqHeader* header = 
00895       dynamic_cast<const RawDaqHeader*>(rawrec->GetRawHeader());
00896    if (!header) {
00897       MSG("Dbu",Msg::kError)
00898          << "RawRecord lacked RawDaqHeader:" 
00899          << *(rawrec->GetRawHeader())
00900          << endl;
00901       logWarn("RawRecord lacked RawDaqHeader");
00902       return JobCResult::kFailed;
00903    }
00904 
00905    const VldContext           vldc      = header->GetVldContext();
00906    const Detector::Detector_t det       = vldc.GetDetector();
00907    const Int_t                run       = header->GetRun();
00908    const Short_t              subrun    = header->GetSubRun();
00909    const Short_t              runtype   = header->GetRunType();
00910    const VldTimeStamp         ts        = vldc.GetTimeStamp(); // ts of current record
00911 
00912    // this section is some (optional) heartbeat/debugging output
00913    const std::string strmname = rawrec->GetTempTags().GetCharString("stream");
00914    const int         strmindx = rawrec->GetTempTags().GetInt("index");
00915 
00916    Int_t this_time = vldc.GetTimeStamp().GetSec();
00917    static Int_t last_heartbeat = 0;
00918    bool pulse = ( this_time - last_heartbeat > fHeartbeatIntervalSec );
00919 
00920    if ( pulse || fHeartbeatIntervalSec < 0 ) {
00921      // send out heart beat signal
00922      const char* fmttime = vldc.GetTimeStamp().AsString("c");
00923      MSG("Dbu",Msg::kDebug) 
00924        << "heartbeat: " 
00925        << fCurrentFile << " (" << strmname << " " << strmindx << ") "
00926        << endl << " " << *header << endl;
00927 
00928      logDebug(3,"heartbeat: %c%8.8d_%4.4d %s (%s %d)",
00929               Detector::AsString(det)[0],
00930               run,subrun,fmttime,strmname.c_str(),strmindx);
00931 
00932      last_heartbeat = this_time;
00933    }
00934 
00935    // Keep track of highest subrun seen for this run
00936 
00937    if ( fCurrentRunSummary->fLastSubRun < subrun )
00938      fCurrentRunSummary->fLastSubRun = subrun;
00939 
00940    // Verify that RunType isn't different
00941 
00942    if ( fCurrentRunSummary->fRunType != runtype ) {
00943      logWarn("RunType changed in RUN %d from %d to %d",run,
00944              fCurrentRunSummary->fRunType,runtype);
00945      fCurrentRunSummary->fRunType = runtype;
00946    }
00947 
00948    // Simple accounting of # of records in each stream
00949 
00950    Int_t tf = header->GetTimeFrameNum();
00951    updateMinInt(fCurrentDaqFileSummary->fFirstTimeFrame,tf);
00952    updateMaxInt(fCurrentDaqFileSummary->fLastTimeFrame,tf);
00953 
00954    if      ( strmname == "DaqSnarl"      ) {
00955      fCurrentDaqFileSummary->fSnarlRecs++;
00956 
00957      if (fCurrentDaqFileSummary->fSnarlRecs != strmindx+1)
00958        logWarn("fSnarlRec count %d != strmindx %d+1",
00959                fCurrentDaqFileSummary->fSnarlRecs,strmindx);
00960 
00961      VldTimeStamp& refFirstSnarlTime   = fCurrentDaqFileSummary->fFirstSnarlTime;
00962      VldTimeStamp& refLastSnarlTime    = fCurrentDaqFileSummary->fLastSnarlTime;
00963      updateMinTimeStamp(refFirstSnarlTime,ts);
00964      updateMaxTimeStamp(refLastSnarlTime,ts);
00965 
00966      const RawDaqSnarlHeader* snarlHeader = 
00967        dynamic_cast<const RawDaqSnarlHeader*>(header);
00968 
00969      Int_t snarl = snarlHeader->GetSnarl();
00970      updateMinInt(fCurrentDaqFileSummary->fFirstSnarlNum,snarl);
00971      updateMaxInt(fCurrentDaqFileSummary->fLastSnarlNum,snarl);
00972 
00973      fCurrentDaqFileSummary->fTrigBitsSeen |= snarlHeader->GetTrigSrc();
00974 
00975    }
00976    else {
00977 
00978      // non DaqSnarl records ...
00979 
00980      VldTimeStamp& refFirstMonitorTime = fCurrentDaqFileSummary->fFirstMonitorTime;
00981      VldTimeStamp& refLastMonitorTime  = fCurrentDaqFileSummary->fLastMonitorTime;
00982      updateMinTimeStamp(refFirstMonitorTime,ts);
00983      updateMaxTimeStamp(refLastMonitorTime,ts);
00984 
00985      if ( strmname == "DaqMonitor"    ) {
00986        fCurrentDaqFileSummary->fMonitorRecs++;
00987        
00988        if (fCurrentDaqFileSummary->fMonitorRecs != strmindx+1)
00989          logWarn("fMonitorRec count %d != strmindx %d+1",
00990                  fCurrentDaqFileSummary->fMonitorRecs,strmindx);
00991      }
00992      else if ( strmname == "LightInjection") {
00993        fCurrentDaqFileSummary->fLightInjRecs++;
00994        
00995        if (fCurrentDaqFileSummary->fLightInjRecs != strmindx+1)
00996          logWarn("fLightInjRec count %d != strmindx %d+1",
00997                  fCurrentDaqFileSummary->fLightInjRecs,strmindx);
00998      }
00999      else {
01000        MAXMSG("Dbu",Msg::kWarning,100) 
01001          << " Saw unhandled stream='" << strmname << "'" << endl;
01002      }
01003    }
01004 
01005    //
01006 
01007    // For each RawBlock in the RawRecord extract what we can
01008    // The dynamic cast from TObject is ugly but necessary
01009    TIter itr = rawrec->GetRawBlockIter();
01010    const RawDataBlock*       rdb           = 0;
01011    const RawRunEndBlock*     runendblk     = 0;
01012    const RawSubRunEndBlock*  subrunendblk  = 0;
01013 
01014    // The dynamic cast from TObject is ugly but necessary
01015    // Careful! the itr() advances the iterator as a side effect!
01016    while ((rdb = dynamic_cast<const RawDataBlock*>(itr()))) {
01017 
01018       string blkName = rdb->GetName();
01019       fCurrentDaqFileSummary->fBlockCount[blkName]++;
01020 
01021       // runstart/runend we retain outside the loop
01022       // so we can process them after others in the same record
01023       if (!runendblk)    runendblk    = 
01024                            dynamic_cast<const RawRunEndBlock*>(rdb);
01025       if (!subrunendblk) subrunendblk = 
01026                            dynamic_cast<const RawSubRunEndBlock*>(rdb);
01027 
01028       ProcessRawBlock(rdb, run, subrun, strmname, strmindx);
01029 
01030    }
01031 
01032    // if we saw a (sub)run end block process it here after
01033    // any other blocks in the record
01034 
01035    if ( subrunendblk ) {                 
01036      // this is a SubRunEnd block
01037      VldTimeStamp startTime = subrunendblk->GetStartTime();
01038      VldTimeStamp endTime   = subrunendblk->GetEndTime();
01039      
01040      // "start time" in SubRunEnd block is start of whole run
01041      // updateMinTimeStamp(fCurrentDaqFileSummary->fFirstMonitorTime,startTime);
01042      updateMaxTimeStamp(fCurrentDaqFileSummary->fLastMonitorTime,  endTime);
01043      
01044      MSG("Dbu",Msg::kDebug) << *subrunendblk << endl;
01045      const char* fmttime = subrunendblk->GetEndTime().AsString("c");
01046      logInfo("%-16s RUN %d SUB %d @ %s (%s %d)",
01047              "SubRunEndBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01048    } // SubRunEndBlock
01049 
01050    if (runendblk) {
01051       //RawDataBlock::SetForceHexDump(true);
01052       //cout << *runendblk << endl;
01053       //RawDataBlock::SetForceHexDump(false);
01054 
01055       MSG("Dbu",Msg::kDebug) << *runendblk << endl;
01056       const char* fmttime = runendblk->GetEndTime().AsString("c");
01057       logInfo("%-16s RUN %d SUB %d @ %s (%s %d)",
01058               "RunEndBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01059 
01060       fCurrentRunSummary->ResetConsistencyBits(DbuBits::kSawNoRunEnd);
01061 
01062       //Int_t runEndSnarls  = runendblk->GetNumberOfSnarls();
01063       //Int_t runEndMonitor = runendblk->GetNumberOfNonSnarls();
01064       //if (fCurrentRunSummary->fSnarlRec   != runEndSnarls ||
01065       //    fCurrentRunSummary->fMonitorRec != runEndMonitor   ) {
01066       //   // flag that what we saw doesn't match RunEnd
01067       //   fCurrentRunSummary->SetConsistencyBits(DbuBits::kRecCountUnverified);
01068       //   MSG("Dbu",Msg::kDebug) 
01069       //     << "Counted/Expected " 
01070       //     << fCurrentRunSummary->fSnarlRec << "/" << runEndSnarls
01071       //     << " SnarlRec, "
01072       //     << fCurrentRunSummary->fMonitorRec << "/" << runEndMonitor
01073       //     << " MonitorRec "
01074       //     << endl;
01075       //}
01076       //else
01077       //  fCurrentRunSummary->ResetConsistencyBits(DbuBits::kRecCountUnverified);
01078 
01079       // no matter what, pick the larger count
01080       // (not necessarily replace them with "official" counts)
01081       // any mismatch is probably due to Dispatcher not serving all streams
01082       //if (fCurrentRunSummary->fSnarlRec   < runEndSnarls )
01083       //    fCurrentRunSummary->fSnarlRec   = runEndSnarls;
01084       //if (fCurrentRunSummary->fMonitorRec < runEndMonitor )
01085       //    fCurrentRunSummary->fMonitorRec = runEndMonitor;
01086       
01087       VldTimeStamp startTime = runendblk->GetStartTime();
01088       VldTimeStamp endTime   = runendblk->GetEndTime();
01089 
01090       bool bogus_time = false;
01091 
01092       if (startTime == nullTime) bogus_time = true;
01093       if (endTime   == nullTime) bogus_time = true;
01094 
01095       updateMinTimeStamp(fCurrentRunSummary->fStartTime,startTime);
01096       updateMaxTimeStamp(fCurrentRunSummary->fEndTime,  endTime);
01097 
01098 
01099       // last subrun (e.g. file) doesn't have separate RawSubRunEndBlock
01100       // "start time" in RunEnd block is start of whole run not particular subrun
01101       // updateMinTimeStamp(fCurrentDaqFileSummary->fFirstMonitorTime,startTime);
01102       updateMaxTimeStamp(fCurrentDaqFileSummary->fLastMonitorTime,  endTime);
01103 
01104       
01105       if (bogus_time) {
01106         MSG("Dbu",Msg::kError) 
01107           << "RunEnd block for " << fCurrentRunSummary->fRun
01108           << " had either a bad start or end time " << endl
01109           << *runendblk << endl;
01110       } 
01111       
01112       fCurrentRunSummary->fTermCode        = runendblk->GetTerminationCode();
01113       fCurrentRunSummary->fRunEndSnarls    = runendblk->GetNumberOfSnarls();
01114       fCurrentRunSummary->fRunEndNonSnarls = runendblk->GetNumberOfNonSnarls();
01115       fCurrentRunSummary->fNErrs           = runendblk->GetNumberOfErrors();
01116       fCurrentRunSummary->fTimeFrames      = runendblk->GetTotalTimeFrames();
01117       fCurrentRunSummary->fDroppedFrames   = runendblk->GetDroppedTimeFrames();
01118       
01119       // one can NOT!! assume that RunEnd is the last record 
01120       // for this run/subrun (based on empirical evidence)
01121       //
01122 
01123    } // RunEndBlock
01124 
01125    return result;
01126 }
01127 
01128 //......................................................................
01129 
01130 void DbuDaqFileModule::ProcessRawBlock(const RawDataBlock* rdb,
01131                                        const Int_t run, const Short_t subrun, 
01132                                        const std::string& strmname,
01133                                        const int strmindx)
01134 {
01135 
01136   // Actions for individual block types
01137   // Only one possible type so if/elseif/... is appropriate
01138    
01139   if ( const RawDigitDataBlock* ddblk = 
01140        dynamic_cast<const RawDigitDataBlock*>(rdb) ) { 
01141     fCurrentDaqFileSummary->fTotalDigitBlocks++;
01142     fCurrentDaqFileSummary->fTotalDigits += ddblk->GetNumberOfDigits();
01143     Int_t errDigits = ddblk->GetNumOfErrorDigits();
01144     if (errDigits > 0) {
01145       fCurrentDaqFileSummary->fErrorDigitBlocks++;
01146       fCurrentDaqFileSummary->fErrorDigits += errDigits;
01147     }
01148     MSG("Dbu",Msg::kVerbose) << *ddblk << endl;
01149     
01150 
01151   }
01152   else if ( const RawLIAdcSummaryBlock* liadcblk = 
01153        dynamic_cast<const RawLIAdcSummaryBlock*>(rdb) ) { 
01154     fCurrentDaqFileSummary->fAdcLIBlocks++;
01155     MSG("Dbu",Msg::kVerbose) << *liadcblk << endl;
01156 
01157   }
01158   else if ( const RawLITimingSummaryBlock* litimingblk = 
01159             dynamic_cast<const RawLITimingSummaryBlock*>(rdb) ) {
01160     fCurrentDaqFileSummary->fTimingLIBlocks++;
01161     MSG("Dbu",Msg::kVerbose) << *litimingblk << endl;
01162 
01163   }
01164   else if ( const RawRunStartBlock* runstartblk = 
01165             dynamic_cast<const RawRunStartBlock*>(rdb) ) {
01166     // this is a RunStart block
01167     fCurrentRunSummary->ResetConsistencyBits(DbuBits::kSawNoRunStart);
01168     VldTimeStamp startTime = runstartblk->GetStartTime();
01169     
01170     MSG("Dbu",Msg::kDebug) << *runstartblk << endl;
01171     const char* fmttime = runstartblk->GetStartTime().AsString("c");
01172     logInfo("%-16s RUN %d SUB %d @ %s (%s %d)",
01173             "RunStartBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01174   }
01175   else if ( const RawRunCommentBlock* runcommentblk = 
01176             dynamic_cast<const RawRunCommentBlock*>(rdb) ) {
01177     // this is a RunComment block
01178     fCurrentRunSummary->ResetConsistencyBits(DbuBits::kSawNoRunComment);
01179     
01180     MSG("Dbu",Msg::kDebug) << *runcommentblk << endl;
01181     const char* fmttime = runcommentblk->GetTime().AsString("c");
01182     logInfo("%-16s RUN %d SUB %d @ %s (%s %d)",
01183             "RunCommentBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01184 
01185     string runCommentString = runcommentblk->GetRunComment();
01186     if ( fCurrentRunSummary->fRunComment.find(runCommentString) == string::npos ) {
01187       // current block's text not found in current value
01188       // clear value if never yet set, otherwise prepare to append
01189       if (DbuRunSummary::kNoComment == fCurrentRunSummary->fRunComment)
01190         fCurrentRunSummary->fRunComment = runCommentString;
01191       else {
01192         logWarn("%-16s RUN %d SUB %d @ %s (%s %d) already had RunComment",
01193                 "RunCommentBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01194         fCurrentRunSummary->fRunComment += "\n";    
01195         fCurrentRunSummary->fRunComment += runCommentString;
01196       }
01197     }
01198       }
01199   else if ( const RawRunConfigBlock* runconfigblk = 
01200             dynamic_cast<const RawRunConfigBlock*>(rdb) ) {
01201     // this is a RunConfig block
01202     fCurrentRunSummary->ResetConsistencyBits(DbuBits::kSawNoRunConfig);
01203 
01204     MSG("Dbu",Msg::kDebug) << *runconfigblk << endl;
01205     const char* fmttime = runconfigblk->GetTime().AsString("c");
01206     logInfo("%-16s RUN %d SUB %d @ %s (%s %d)",
01207             "RunConfigBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01208 
01209     string runPrepareString = runconfigblk->GetRunConfig();
01210     if ( fCurrentRunSummary->fRunPrepare.find(runPrepareString) == string::npos ) {
01211       // current block's text not found in current value
01212       // clear value if never yet set, otherwise prepare to append
01213       if (DbuRunSummary::kNoRunPrepare == fCurrentRunSummary->fRunPrepare)
01214         fCurrentRunSummary->fRunPrepare = runPrepareString;
01215       else {
01216         logWarn("%-16s RUN %d SUB %d @ %s (%s %d) already had RunPrepare",
01217                 "RunConfigBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01218         fCurrentRunSummary->fRunPrepare += "\n";    
01219         fCurrentRunSummary->fRunPrepare += runPrepareString;
01220       }
01221     }
01222     
01223   }
01224   else if ( const RawConfigFilesBlock* configfilesblk = 
01225             dynamic_cast<const RawConfigFilesBlock*>(rdb) ) {
01226     // this is a ConfigFiles block
01227     fCurrentRunSummary->ResetConsistencyBits(DbuBits::kSawNoConfigFiles);
01228     
01229     HandleConfigFilesBlock(configfilesblk);
01230 
01231     //MSG("Dbu",Msg::kDebug) << *configfilesblk << endl;
01232     MSG("Dbu",Msg::kDebug) << "RawConfigFilesBlock seen" << endl;
01233     const char* fmttime = configfilesblk->GetTime().AsString("c");
01234     logInfo("%-16s RUN %d SUB %d @ %s (%s %d)",
01235           "ConfigFilesBlk",run,subrun,fmttime,strmname.c_str(),strmindx);
01236 
01237   }
01238   
01239 }
01240 
01241 //......................................................................
01242 
01243 void DbuDaqFileModule::HandleConfigFilesBlock(const RawConfigFilesBlock* configfilesblk)
01244 {
01245 
01246   // config file text info gets shunted into a separate table than
01247   // the DbuDaqRunSummary to avoid repeating the long text files
01248   // that rarely change.  the exception to this are short term
01249   // config files (e.g. liStartTimes.config) which will change often
01250   // these we won't put into that table but associate directly with
01251   // the run itself.
01252 
01253   // one could imagine using OnlineUtil/configLib to parse
01254   // these concatenated config files ... but
01255   // (1) it *really* wants to read a file from disk
01256   //     in $DAQ_CONFIG_DIR, (~) getpwuid->pw_dir or /minos/config/
01257   // (2) it can't deal with nested section (ie. our <configFileText>)
01258   // (3) it can't deal with multiple sections <tag>,/tag> 
01259   //     of the same name. <global> is in several files, 
01260   //     configLib would simply stop at the first.
01261   // (4) ?recheck? calling it again on a second section of
01262   //     the same name clears out the previously parsed data
01263   // basically configLib + kvp are half-assed parsers
01264   // kvp by itself apparently can't deal with continuation lines
01265   // which is why one needs configLib
01266   
01267   // possible solution write file parts out to /tmp
01268   // with names like  /tmp/F000RRRRRRR/dcp.config
01269   // and change $DAQ_CONFIG_DIR (save/restore before/after write/read)
01270   
01271   // new files have a defined string identifying the file
01272   // but older files one has to guess based on (hopefully) unique
01273   // strings in each type of config file.
01274   std::string guess_type = configfilesblk->GuessFileType();
01275 
01276   MSG("Dbu",Msg::kDebug) 
01277       << "HandleConfigFilesBlock guess_type '" << guess_type << "' "
01278       << " fAuxConfigFileList '" << fAuxConfigFileList << "' "
01279       << " find at " << (int)fAuxConfigFileList.find(guess_type)
01280       << " npos is " << (int)string::npos
01281       << endl;
01282 
01283   if ( fAuxConfigFileList.find(guess_type) == string::npos ) {
01284      // a config file type not in the exception list
01285 
01286      // if still the dummy default, clear it
01287      if ( fCurrentConfigFilesText->fText == DbuDaqConfigFilesText::kNoText )
01288           fCurrentConfigFilesText->fText = "";
01289 
01290      // add the text if it isn't already there
01291      const Char_t* new_text = configfilesblk->GetConfigFile();
01292      if ( fCurrentConfigFilesText->fText.find(new_text) == string::npos ) {
01293           
01294           fCurrentConfigFilesText->fText += "\n//[configFileText fileType=\"";
01295           fCurrentConfigFilesText->fText += guess_type;
01296           fCurrentConfigFilesText->fText += "\"]\n";
01297           
01298           fCurrentConfigFilesText->fText += new_text;
01299     
01300           fCurrentConfigFilesText->fText += "\n//[/configFileText fileType=\"";
01301           fCurrentConfigFilesText->fText += guess_type;
01302           fCurrentConfigFilesText->fText += "\"]\n";
01303 
01304      };
01305   
01306   }
01307   else {
01308      // a config file type in the exception list
01309      // put it in the DbuDaqRunSummary table
01310 
01311      // if still the dummy default, clear it
01312      if ( fCurrentRunSummary->fAuxConfigText == DbuRunSummary::kNoAuxConfig )
01313           fCurrentRunSummary->fAuxConfigText = "";
01314      if ( fCurrentRunSummary->fAuxConfigText == DbuRunSummary::kUnfilled )
01315           fCurrentRunSummary->fAuxConfigText = "";
01316 
01317      // add the text if it isn't already there
01318      const Char_t* new_text = configfilesblk->GetConfigFile();
01319      if ( fCurrentRunSummary->fAuxConfigText.find(new_text) == string::npos ) {
01320           
01321           fCurrentRunSummary->fAuxConfigText += "\n//[configFileText fileType=\"";
01322           fCurrentRunSummary->fAuxConfigText += guess_type;
01323           fCurrentRunSummary->fAuxConfigText += "\"]\n";
01324           
01325           fCurrentRunSummary->fAuxConfigText += new_text;
01326     
01327           fCurrentRunSummary->fAuxConfigText += "\n//[/configFileText fileType=\"";
01328           fCurrentRunSummary->fAuxConfigText += guess_type;
01329           fCurrentRunSummary->fAuxConfigText += "\"]\n";
01330 
01331      };
01332   }
01333 
01334 }
01335 
01336 //......................................................................
01337 
01338 void DbuDaqFileModule::Help()
01339 {
01340   const char* n = this->GetName();
01341 
01342   MSG("Dbu",Msg::kInfo)
01343      << "Help for module " << n << endl
01344      << endl
01345      << "  A Dbu for generating RunSummary, SubRun and ConfigFilesText entries" << endl
01346      << endl
01347      << "  /" << n << "/Record [which] ..." << endl
01348      << "  /" << n << "/Disregard [which] ..." << endl
01349      << "     controls which information to DBU" << endl
01350      << "     [which] is: " << endl
01351      << "        AtStart       - record upon seeing RunStart as well as RunEnd" << endl
01352      << endl;
01353   
01354 }
01355 

Generated on Mon Feb 15 11:06:35 2010 for loon by  doxygen 1.3.9.1