PREAN/TFndPreanScalers.cxx

00001 // @(#)fROOT/PREAN:$Name:  $:$Id: TFndPreanScalers.cxx,v 1.3 2007/09/05 10:15:21 Diego_Faso Exp $
00002 // Author: H. So , 2006/05/29
00003 
00004 #include "TFndPreanScalers.h"
00005 
00006 //______________________________________________________________________________
00007 // TFndPreanScalers
00008 //
00009 // Preanalyzer for scaler data.  It is a fROOT version of readscaler daemon.
00010 //
00011 // Technical note: this class is a non-copyable singleton class.  Default
00012 // constructor is hidden from users, and copy constructor / assignment
00013 // operator are not implemented on purpose.  All accesses to the singleton
00014 // instance should be done via Instance() static method.  A global pointer
00015 // like gFndPreanScalers could have been added for users' convinience, but
00016 // this idea was discarded due to thread-safety and efficiency.  It is
00017 // recommended for users to save the pointer returned by Instance() for
00018 // repetead use.
00019 //
00020 // The comment below, copied from the original source, shows the raw event
00021 // structure relevant to scalers analysis.
00022 //
00024 //                                                                                       //
00025 //      Original code: readscaler: a daemon to read the FINUDA scaler values             //
00026 //                     written by S. Piano, F. Pompili, G. Simonetti on Aug. 2003        //
00027 //                                                                                       //
00029 //
00030 //            GLOBAL EVENT HEADER
00031 //
00032 //      RawEvent[0] -----> GLOBAL EVENT LENGTH
00033 //      RawEvent[1] -----> EVENT NUMBER (Hardware)
00034 //      RawEvent[2] -----> EVENT NUMBER (Software)
00035 //      RawEvent[3] -----> RUN TYPE
00036 //      RawEvent[4] -----> RUN NUMBER
00037 //      RawEvent[5] -----> Run starting time (unix format)
00038 //      RawEvent[6] -----> elapsed time from run start
00039 //      RawEvent[7] -----> GTS pointer == 16
00040 //      RawEvent[8] -----> TOF pointer
00041 //      RawEvent[9] -----> ISI pointer
00042 //      RawEvent[10] ----> OSI pointer
00043 //      RawEvent[11] ----> LMD pointer
00044 //      RawEvent[12] ----> STB pointer
00045 //       ... ...         ... ... ... ...
00046 //      RawEvent[15] ----> 0 END OF GLOBAL EVENT HEADER
00047 //
00048 //            GTS EVENT BUFFER
00049 //
00050 //     RawEvent[16+0 =16] -----> EVENT LENGTH = HEADER LENGTH + k (k = number of read data)
00051 //     RawEvent[16+1 =17] -----> EVENT NUMBER (Hardware)
00052 //     RawEvent[16+2 =18] -----> DETECTOR IDENTIFIER (GTS)
00053 //     RawEvent[16+3 =19] -----> RUN NUMBER
00054 //     RawEvent[16+4 =20] -----> EVENT NUMBER (Software)
00055 //     RawEvent[16+5 =21] -----> HEADER LENGTH (36)
00056 //
00057 //     RawEvent[16+6 =22] -----> EQUIPMENT  1 POINTER: CORBO
00058 //     RawEvent[16+8 =24] -----> EQUIPMENT  3 POINTER: VME TRIGGER SELECTOR
00059 //     RawEvent[16+9 =25] -----> EQUIPMENT  4 POINTER: VME PATTERN UNIT
00060 //     RawEvent[16+10=26] -----> EQUIPMENT  5 POINTER: VME SCALER
00061 //     RawEvent[16+31=47] -----> EQUIPMENT 26 POINTER: CAMAC TDC (LECROY 2229)
00062 //     RawEvent[16+36=52] -----> FIRST DATUM
00063 //
00064 //     scp=RawEvent[26]+16
00065 //
00066 //     (5) VME SCALER
00067 //      RawEvent[scp+0] ----> length
00068 //      RawEvent[scp+1] ----> scaler V1 config. (cascading)
00069 //      RawEvent[scp+2] ----> MULT 2-7 (HYP)
00070 //      RawEvent[scp+3] ----> MULT 2-7 (BHA)
00071 //      RawEvent[scp+4] ----> BTB-MB
00072 //      RawEvent[scp+5] ----> BTB-EL
00073 //      RawEvent[scp+6] ----> PC (Prompt Coincidence)
00074 //      RawEvent[scp+7] ----> Presc BTB-MB
00075 //      RawEvent[scp+8] ----> OR-MB
00076 //      RawEvent[scp+9] ----> OR-EL
00077 //      RawEvent[scp+10] ---> HYP
00078 //      RawEvent[scp+11] ---> BHA
00079 //      RawEvent[scp+12] ---> Presc BHA
00080 //      RawEvent[scp+13] ---> Presc BTB-EL
00081 //      RawEvent[scp+14] ---> OR-TOFONE
00082 //      RawEvent[scp+15] ---> Presc OR-MB
00083 //      RawEvent[scp+16] ---> Total Triggers
00084 //      RawEvent[scp+17] ---> TIME (100 Hz)
00085 //
00086 //      RawEvent[scp+18] ---> scaler V2 config. (cascading)
00087 //      RawEvent[scp+19] ---> MULT 2-7 (HYP)
00088 //      RawEvent[scp+20] ---> MULT 2-7 (BHA)
00089 //      RawEvent[scp+21] ---> BTB-MB
00090 //      RawEvent[scp+22] ---> BTB-EL
00091 //      RawEvent[scp+23] ---> PC (Prompt Coincidence)
00092 //      RawEvent[scp+24] ---> Presc BTB-MB
00093 //      RawEvent[scp+25] ---> OR-MB
00094 //      RawEvent[scp+26] ---> OR-EL
00095 //      RawEvent[scp+27] ---> HYP
00096 //      RawEvent[scp+28] ---> BHA
00097 //      RawEvent[scp+29] ---> Presc BHA
00098 //      RawEvent[scp+30] ---> Presc BTB-EL
00099 //      RawEvent[scp+31] ---> OR-TOFONE
00100 //      RawEvent[scp+32] ---> Presc OR-MB
00101 //      RawEvent[scp+33] ---> Total Triggers
00102 //      RawEvent[scp+34] ---> TIME (100 Hz)
00103 //
00104 //      RawEvent[scp+35] ---> scaler V3 config (cascading)
00105 //      RawEvent[scp+36] ---> HYP
00106 //      RawEvent[scp+37] ---> BHA
00107 //      RawEvent[scp+38] ---> Presc OR-EL
00108 //      RawEvent[scp+39] ---> BTB-EL
00109 //      RawEvent[scp+40] ---> OR TOFONE
00110 //      RawEvent[scp+41] ---> LASER photodiode
00111 //      RawEvent[scp+42] ---> OR TOFINO
00112 //      RawEvent[scp+43] ---> SC (Slow Coincidence)
00113 //      RawEvent[scp+44] ---> void
00114 //      RawEvent[scp+45] ---> ORTofino*ORTofone
00115 //      RawEvent[scp+46] ---> void
00116 //      RawEvent[scp+47] ---> void
00117 //      RawEvent[scp+48] --->      |canali
00118 //      RawEvent[scp+49] ---> RF/4 |in cascata
00119 //      RawEvent[scp+50] ---> trigger*busy
00120 //      RawEvent[scp+51] ---> TIME (100 Hz)
00121 //
00122 //      RawEvent[scp+52] ---> scaler V4 config (cascading)
00123 //      RawEvent[scp+53] ---> HYP
00124 //      RawEvent[scp+54] ---> BHA
00125 //      RawEvent[scp+55] ---> Presc OR-EL
00126 //      RawEvent[scp+56] ---> BTB-EL
00127 //      RawEvent[scp+57] ---> OR TOFONE
00128 //      RawEvent[scp+58] ---> LASER photodiode
00129 //      RawEvent[scp+59] ---> OR TOFINO
00130 //      RawEvent[scp+60] ---> SC (Slow Coincidence)
00131 //      RawEvent[scp+61] ---> void
00132 //      RawEvent[scp+62] ---> ORTofino*ORTofone
00133 //      RawEvent[scp+63] ---> void
00134 //      RawEvent[scp+64] ---> void
00135 //      RawEvent[scp+65] --->      |canali
00136 //      RawEvent[scp+66] ---> RF/4 |in cascata
00137 //      RawEvent[scp+67] ---> trigger*busy
00138 //      RawEvent[scp+68] ---> TIME (100 Hz)
00139 //
00140 //      RawEvent[scp+69] ---> Scaler TOFINO config (cascading)
00141 //      RawEvent[scp+70] ---> Tofino MT 1
00142 //      RawEvent[scp+71] ---> Tofino MT 2
00143 //      RawEvent[scp+72] ---> Tofino MT 3
00144 //      RawEvent[scp+73] ---> Tofino MT 4
00145 //      RawEvent[scp+74] ---> Tofino MT 5
00146 //      RawEvent[scp+75] ---> Tofino MT 6
00147 //      RawEvent[scp+76] ---> Tofino MT 7
00148 //      RawEvent[scp+77] ---> Tofino MT 8
00149 //      RawEvent[scp+78] ---> Tofino MT 9
00150 //      RawEvent[scp+79] ---> Tofino MT 10
00151 //      RawEvent[scp+80] ---> Tofino MT 11
00152 //      RawEvent[scp+81] ---> Tofino MT 12
00153 
00154 #include <cerrno>
00155 #include <stdexcept>
00156 #include <sstream>
00157 #include <TMutex.h>
00158 
00159 #include "TFndPrean.h"
00160 #include "TFndEnv.h"
00161 
00162 using namespace std;
00163 
00164 ClassImp(TFndPreanScalers)
00165 
00166 static TVirtualMutex *fgMutex = NULL;
00167 
00168 //______________________________________________________________________________
00169 TFndPreanScalers *TFndPreanScalers::Instance()
00170 {
00171   // Returns a pointer to the global instance of this class.  The instance is
00172   // created when this function is called for the first time.
00173 
00174   R__LOCKGUARD2(fgMutex);
00175   static TFndPreanScalers instance;
00176   return &instance;
00177 }
00178 
00179 //______________________________________________________________________________
00180 TFndPreanScalers::Data::Data(const UInt_t rawEvent[])
00181 {
00182   const UInt_t *pEvh = rawEvent;        // pointer to Global Event Header
00183   const UInt_t *pGts = pEvh + kEvhLen;  // pointer to GTS buffer
00184   const UInt_t *pScb = pGts + pGts[10]; // pointer to VME scalers buffer
00185   memcpy(evh, pEvh, sizeof(evh));
00186   memcpy(gts, pGts, sizeof(gts));
00187   memcpy(scb, pScb, sizeof(scb));
00188 }
00189 
00190 //______________________________________________________________________________
00191 TFndPreanScalers::TFndPreanScalers()
00192   : fDatime(), fSavedTime(), fSavedDay(), fSavedFif(),
00193     fV0(), fBhaInt(), fBhaInt0(), fHypInt(), fHypInt0(), fSavedEvNum()
00194 {
00195   // Default constructor.
00196   //
00197   // Throws std::runtime_error if it is not possible to open the fast files.
00198 
00199   fCurTime = fDatime.Convert();
00200   fSavedDay = fCurTime / kSecondsPerDay ;
00201   fSavedFif = fCurTime / kScalerInterval ;
00202 
00203   TFndEnv *env = TFndEnv::Instance();
00204   const char *pathDafne = env->GetValue("froot.PreAnalysis.PathDafne", "/data02/fnddafne", "FND_PREAN_SHR");
00205   fPath[0] = FROOT::ConcatFileName(pathDafne, env->GetValue("froot.PreAnalysis.DirReadScaler", "readscaler"));
00206   fPath[1] = FROOT::ConcatFileName(pathDafne, env->GetValue("froot.PreAnalysis.DirRunInfo", "runinfo"));
00207 
00208   fFastFd[0] = fFastFd[1] = -1;
00209 
00210   if (RecreateFastFiles() < 0)
00211     throw std::runtime_error("Cannot proceed scalers preanalysis");
00212 }
00213 
00214 //______________________________________________________________________________
00215 TFndPreanScalers::~TFndPreanScalers()
00216 {
00217   // Destroys the object.  Raw files and fast files are closed.  Since the
00218   // class is a singleton class this method will be called only when the
00219   // program is stopped or the library is unloaded.
00220 
00221   CloseRawFiles();
00222   CloseFastFiles();
00223 }
00224 
00225 //______________________________________________________________________________
00226 Int_t TFndPreanScalers::RecreateFastFiles()
00227 {
00228   // Creates or recreates fast files.
00229   //
00230   // Returns 0 on success, -1 on error.
00231 
00232   TString readScalerFastFileName, runInfoFastFileName;
00233   readScalerFastFileName.Form("%s/finuda_stat.fast", fPath[0].Data());
00234   runInfoFastFileName.Form("%s/runinfo_stat.fast", fPath[1].Data());
00235 
00236   if (fFastFd[0] >= 0 && TEMP_FAILURE_RETRY(close(fFastFd[0])) < 0)
00237     Warning("RecreateFastFiles", "Cannot close previous readscaler fast file: %s", strerror(errno));
00238   if (fFastFd[1] >= 0 && TEMP_FAILURE_RETRY(close(fFastFd[1])) < 0)
00239     Warning("RecreateFastFiles", "Cannot close previous runinfo fast file: %s", strerror(errno));
00240 
00241   int ret = 0;
00242   if ((fFastFd[0] = TEMP_FAILURE_RETRY(creat(readScalerFastFileName.Data(), 0644))) < 0) {
00243     Error("RecreateFastFiles", "Cannot create readscaler fast file: %s", strerror(errno));
00244     ret = -1;
00245   }
00246   if ((fFastFd[1] = TEMP_FAILURE_RETRY(creat(runInfoFastFileName.Data(), 0644))) < 0) {
00247     Error("RecreateFastFiles", "Cannot create runinfo fast file: %s", strerror(errno));
00248     ret = -1;
00249   }
00250   return ret;
00251 }
00252 
00253 //______________________________________________________________________________
00254 Int_t TFndPreanScalers::WriteFastFiles(const string &readScalerText, const string &runInfoText)
00255 {
00256   // Writes pre-generated text in fast files.
00257   //
00258   // Returns 0 on success, -1 on error.
00259 
00260   int ret = 0;
00261   if (lseek(fFastFd[0], 0, SEEK_SET) < 0 ||
00262       TEMP_FAILURE_RETRY(ftruncate(fFastFd[0], 0)) < 0 ||
00263       TEMP_FAILURE_RETRY(write(fFastFd[0], readScalerText.c_str(), readScalerText.size())) < 0) {
00264     Error("WriteFastFiles", "Cannot update readscaler fast file: %s", strerror(errno));
00265     ret = -1;
00266   }
00267   if (lseek(fFastFd[1], 0, SEEK_SET) < 0 ||
00268       TEMP_FAILURE_RETRY(ftruncate(fFastFd[1], 0)) < 0 ||
00269       TEMP_FAILURE_RETRY(write(fFastFd[1], runInfoText.c_str(), runInfoText.size())) < 0) {
00270     Error("WriteFastFiles", "Cannot update runinfo fast file: %s", strerror(errno));
00271     ret = -1;
00272   }
00273   return ret;
00274 }
00275 
00276 //______________________________________________________________________________
00277 Int_t TFndPreanScalers::CloseFastFiles()
00278 {
00279   // Closes fast files.
00280   //
00281   // Returns 0 on success, -1 on error.
00282 
00283   int ret = 0;
00284   if (fFastFd[0] >= 0 && TEMP_FAILURE_RETRY(close(fFastFd[0])) < 0) {
00285     Error("CloseFastFiles", "Cannot close readscaler fast file: %s", strerror(errno));
00286     ret = -1;
00287   }
00288   fFastFd[0] = -1;
00289   if (fFastFd[1] >= 0 && TEMP_FAILURE_RETRY(close(fFastFd[1])) < 0) {
00290     Error("CloseFastFiles", "Cannot close readscaler fast file: %s", strerror(errno));
00291     ret = -1;
00292   }
00293   fFastFd[1] = -1;
00294   return ret;
00295 }
00296 
00297 //______________________________________________________________________________
00298 Int_t TFndPreanScalers::OpenRawFiles()
00299 {
00300   // Opens raw files based on date.  Note that the date is specified by
00301   // fDatime and may be different from the current date.
00302   //
00303   // Returns 0 on success, -1 on error.
00304 
00305   int ret = 0;
00306   if (!fRawFile[0].is_open()) {
00307     TString str;
00308     str.Form("%s/%04d%02d%02d.raw", fPath[0].Data(), fDatime.GetYear(), fDatime.GetMonth(), fDatime.GetDay());
00309     fRawFile[0].clear();
00310     fRawFile[0].open(str, ofstream::app);
00311     if (!fRawFile[0]) {
00312       Error("OpenRawFiles", "%s: %s", str.Data(), strerror(errno));
00313       ret = -1;
00314     }
00315   }
00316   if (!fRawFile[1].is_open()) {
00317     TString str;
00318     str.Form("%s/%04d%02d%02d.raw", fPath[1].Data(), fDatime.GetYear(), fDatime.GetMonth(), fDatime.GetDay());
00319     fRawFile[1].clear();
00320     fRawFile[1].open(str, ofstream::app);
00321     if (!fRawFile[1]) {
00322       Error("OpenRawFiles", "%s: %s", str.Data(), strerror(errno));
00323       ret = -1;
00324     }
00325   }
00326   return ret;
00327 }
00328 
00329 //______________________________________________________________________________
00330 Int_t TFndPreanScalers::CloseRawFiles()
00331 {
00332   // Closes raw files currently open.
00333   //
00334   // Returns 0 on success, -1 on error.
00335 
00336   int ret = 0;
00337   if (fRawFile[0].is_open()) {
00338     fRawFile[0].clear();
00339     fRawFile[0].close();
00340     if (!fRawFile[0]) {
00341       Error("CloseRawFiles", "Cannot close readscaler file: %s", strerror(errno));
00342       ret = -1;
00343     }
00344   }
00345   if (fRawFile[1].is_open()) {
00346     fRawFile[1].clear();
00347     fRawFile[1].close();
00348     if (!fRawFile[1]) {
00349       Error("CloseRawFiles", "Cannot close runinfo file: %s", strerror(errno));
00350       ret = -1;
00351     }
00352   }
00353   return ret;
00354 }
00355 
00356 //______________________________________________________________________________
00357 Int_t TFndPreanScalers::WriteRawFiles(const string &scalerText, const string &scalerInfoText)
00358 {
00359   // Writes pre-generated text in raw files.
00360   //
00361   // Returns 0 on success, -1 on error.
00362 
00363   int ret = 0;
00364   if (!(fRawFile[0] << scalerText << flush)) {
00365     Error("WriteRawFiles", "Cannot write to readscaler file: %s", strerror(errno));
00366     ret = -1;
00367   }
00368   if (!(fRawFile[1] << scalerInfoText << flush)) {
00369     Error("WriteRawFiles", "Cannot write to runinfo file: %s", strerror(errno));
00370     ret = -1;
00371   }
00372   return ret;
00373 }
00374 
00375 //______________________________________________________________________________
00376 void TFndPreanScalers::CalculateRate(const UInt_t v[], const UInt_t v0[], Float_t vr[])
00377 {
00378   // Calcluates event rates and save them in vr.
00379 
00380   Float_t tempo = (v[17] - v0[17]) / 100.;
00381   memset(vr, 0, sizeof(vr));
00382   for (Int_t i = 2; i < 18; i++)
00383     vr[i] = (v[i] - v0[i]) / tempo;
00384   for (Int_t i = 19; i < 35; i++)
00385     vr[i] = (v[i] - v0[i]) / tempo;
00386   for (Int_t i = 36; i < 52; i++) {
00387     switch (i) {
00388     case 44: case 46: case 47: break; // void: nothing to do
00389     case 48: break;                   // high word of RF/4: cannot be used alone
00390     case 49:                          // 64bit calculation - don't forget that UInt_t is usually 32bit.
00391       vr[i] = (FROOT::Convert64(v[48], v[49]) - FROOT::Convert64(v0[48], v0[49])) / tempo;
00392       break;
00393     default:
00394       vr[i] = (v[i] - v0[i]) / tempo;
00395     }
00396   }
00397   for (Int_t i = 53; i < 69; i++) {
00398     switch (i) {
00399     case 61: case 63: case 64: break; // void: nothing to do
00400     case 65: break;                   // high word of RF/4: cannot be used alone
00401     case 66:                          // 64bit calculation - don't forget that UInt_t is usually 32bit.
00402       vr[i] = (FROOT::Convert64(v[65], v[66]) - FROOT::Convert64(v0[65], v0[66])) / tempo;
00403       break;
00404     default:
00405       vr[i] = (v[i] - v0[i]) / tempo;
00406     }
00407   }
00408   for (Int_t i = 70; i < 82; i++)
00409     vr[i] = (v[i] - v0[i]) / tempo;
00410 }
00411 
00412 //______________________________________________________________________________
00413 string TFndPreanScalers::GenerateReadScalerText(const UInt_t evh[], const Float_t vr[], UInt_t daqStatus)
00414 {
00415   // Generate text for writing readscaler raw/fast files.
00416   //
00417   // Returns generated std::string.
00418 
00419   ostringstream ss;
00420   ss << fCurTime
00421      << " " << evh[1] << " " << evh[2] << " " << evh[3] << " " << evh[4]
00422      << " " << vr[4] << " " << vr[5] << " " << vr[8] << " " << vr[9]
00423      << " " << vr[11] << " " << vr[14] << " " << vr[16] << " " << vr[17]
00424      << " " << vr[70] << " " << vr[71] << " " << vr[72] << " " << vr[73]
00425      << " " << vr[74] << " " << vr[75] << " " << vr[76] << " " << vr[77]
00426      << " " << vr[78] << " " << vr[79] << " " << vr[80] << " " << vr[81]
00427      << " " << daqStatus << " " << fBhaInt0 << " " << fHypInt0 << " " << endl;
00428   if (!ss)
00429     Warning("GenerateReadScalerText", "Failed");
00430   return ss.str();
00431 }
00432 
00433 //______________________________________________________________________________
00434 string TFndPreanScalers::GenerateRunInfoText(const UInt_t evh[], const UInt_t gts[], const Float_t vr[], UInt_t daqStatus)
00435 {
00436   // Generate text for writing runinfo raw/fast files.
00437   //
00438   // Returns generated std::string.
00439 
00440   ostringstream ss;
00441   ss << fCurTime
00442      << " " << evh[1] << " " << evh[2] << " " << evh[3] << " " << evh[4]
00443      << " " << evh[5] << " " << evh[6] << " " << evh[7] << " " << evh[8]
00444      << " " << evh[9] << " " << evh[10] << " " << evh[11] << " " << evh[12]
00445      << " " << gts[10]
00446      << " " << vr[2] << " " << vr[3] << " " << vr[4] << " " << vr[5]
00447      << " " << vr[6] << " " << vr[7] << " " << vr[8] << " " << vr[9]
00448      << " " << vr[10] << " " << vr[11] << " " << vr[12] << " " << vr[13]
00449      << " " << vr[14] << " " << vr[15] << " " << vr[16] << " " << vr[17]
00450      << " " << vr[19] << " " << vr[20] << " " << vr[21] << " " << vr[22]
00451      << " " << vr[23] << " " << vr[24] << " " << vr[25] << " " << vr[26]
00452      << " " << vr[27] << " " << vr[28] << " " << vr[29] << " " << vr[30]
00453      << " " << vr[31] << " " << vr[32] << " " << vr[33] << " " << vr[34]
00454      << " " << vr[36] << " " << vr[37] << " " << vr[38] << " " << vr[39]
00455      << " " << vr[40] << " " << vr[41] << " " << vr[42] << " " << vr[43]
00456      << " " << vr[45] << " " << "0" << " " << vr[49] << " " << vr[50]
00457      << " " << vr[51] << " " << vr[53] << " " << vr[54] << " " << vr[55]
00458      << " " << vr[56] << " " << vr[57] << " " << vr[58] << " " << vr[59]
00459      << " " << vr[60] << " " << vr[62] << " " << "0" << " " << vr[66]
00460      << " " << vr[67] << " " << vr[68] << " " << vr[70] << " " << vr[71]
00461      << " " << vr[72] << " " << vr[73] << " " << vr[74] << " " << vr[75]
00462      << " " << vr[76] << " " << vr[77] << " " << vr[78] << " " << vr[79]
00463      << " " << vr[80] << " " << vr[81] << " " << daqStatus << " " << endl;
00464   if (!ss)
00465     Warning("GenerateRunInfoText", "Failed");
00466   return ss.str();
00467 }
00468 
00469 //______________________________________________________________________________
00470 Int_t TFndPreanScalers::Write(const Data &data)
00471 {
00472   // Writes data in files and save information for later use.  Destination raw
00473   // files are decided based on the current date.
00474   //
00475   // Returns 0 on success, -1 on error.
00476 
00477   int ret = 0;
00478 
00479   // event number (hardware)
00480   UInt_t evNum = data.evh[1];
00481 
00482   // DAQ status: kStopped in offline mode, one of EDaqStatus in online mode.
00483   Int_t daqStatus = data.evh[15];
00484   if (evNum == fSavedEvNum && daqStatus == kActive)
00485     daqStatus = kCrashed;
00486 
00487   fDatime.Set();
00488   if (OpenRawFiles() < 0) {
00489     Error("Write", "cannot open scaler files");
00490     return -1;
00491   }
00492 
00493   fCurTime = fDatime.Convert();
00494   UInt_t curDay  = fCurTime / kSecondsPerDay;
00495   if (curDay > fSavedDay) {
00496     // new day - close old file and open new one
00497     fSavedDay = curDay;
00498 
00499     if (CloseRawFiles() < 0) {
00500       Error("Write", "cannot close old scaler files");
00501       return -1;
00502     }
00503     if (OpenRawFiles() < 0) {
00504       Error("Write", "cannot open new scaler files");
00505       return -1;
00506     }
00507   }
00508 
00509   Float_t vr[kScbLen];
00510   CalculateRate(data.scb, fV0, vr);
00511   fBhaInt += data.scb[11] - fV0[11];
00512   fHypInt += data.scb[10] - fV0[10];
00513 
00514   UInt_t curFif  = fCurTime / kScalerInterval;
00515   if (curFif > fSavedFif) {
00516     fSavedFif = curFif;
00517     fBhaInt0  = fBhaInt;
00518     fBhaInt   = 0;
00519     fHypInt0  = fHypInt;
00520     fHypInt   = 0;
00521   }
00522 
00523   const string &readScalerText = GenerateReadScalerText(data.evh, vr, daqStatus);
00524   const string &runInfoText    = GenerateRunInfoText(data.evh, data.gts, vr, daqStatus);
00525 
00526   if (WriteFastFiles(readScalerText, runInfoText) < 0)
00527     ret = -1;
00528 
00529   if ((fCurTime % kScalerInterval == 0 && fCurTime != fSavedTime) || daqStatus == kStopped) {
00530     fSavedTime = fCurTime;
00531     if (WriteRawFiles(readScalerText, runInfoText) < 0)
00532       ret = -1;
00533   }
00534 
00535   memcpy(fV0, data.scb, sizeof(fV0));
00536   fSavedEvNum = evNum;
00537 
00538   return ret;
00539 }

Generated on Tue Oct 16 15:40:47 2007 by  doxygen 1.5.2