// Author: Fons Rademakers 26/11/99
// Updated: Dario Favretto 15/04/2003
+/**************************************************************************
+ * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
+ * *
+ * Author: The ALICE Off-line Project. *
+ * Contributors are mentioned in the code where appropriate. *
+ * *
+ * Permission to use, copy, modify and distribute this software and its *
+ * documentation strictly for non-commercial purposes is hereby granted *
+ * without fee, provided that the above copyright notice appears in all *
+ * copies and that both the copyright notice and this permission notice *
+ * appear in the supporting documentation. The authors make no claims *
+ * about the suitability of this software for any purpose. It is *
+ * provided "as is" without express or implied warranty. *
+ **************************************************************************/
+
+//////////////////////////////////////////////////////////////////////////
+// //
+// AliRawEvent //
+// //
+// Set of classes defining the ALICE RAW event format. The AliRawEvent //
+// class defines a RAW event. It consists of an AliEventHeader object //
+// an AliEquipmentHeader object, an AliRawData object and an array of //
+// sub-events, themselves also being AliRawEvents. The number of //
+// sub-events depends on the number of DATE LDC's. //
+// The AliRawEvent objects are written to a ROOT file using different //
+// technologies, i.e. to local disk via AliRawDB or via rfiod using //
+// AliRawRFIODB or via rootd using AliRawRootdDB or to CASTOR via //
+// rootd using AliRawCastorDB (and for performance testing there is //
+// also AliRawNullDB). //
+// The AliRunDB class provides the interface to the run and file //
+// catalogues (AliEn or plain MySQL). //
+// The AliStats class provides statics information that is added as //
+// a single keyed object to each raw file. //
+// The AliTagDB provides an interface to a TAG database. //
+// The AliMDC class is usid by the "alimdc" stand-alone program //
+// that reads data directly from DATE. //
+// //
+//////////////////////////////////////////////////////////////////////////
+
#include <sys/types.h>
#include <sys/stat.h>
#if defined(__DECCXX)
#include <sys/statvfs.h>
#else
+#if defined(__APPLE__)
+#include <sys/param.h>
+#include <sys/mount.h>
+#else
#include <sys/vfs.h>
#endif
+#endif
#include <unistd.h>
#include <stdlib.h>
#include <fcntl.h>
#include <errno.h>
#include <TBuffer.h>
-#include <TH1.h>
#include <TSystem.h>
#include <TError.h>
#include <TStopwatch.h>
#include <TSQLServer.h>
#include <TSQLResult.h>
+#include <TUrl.h>
+#include <TGrid.h>
+#include <TH1.h>
+#if defined(__APPLE__)
+#undef Free
+#endif
#include "AliRawEvent.h"
// Good for Linux
ClassImp(AliStats)
ClassImp(AliRawDB)
ClassImp(AliRawRFIODB)
+ClassImp(AliRawCastorDB)
ClassImp(AliRawRootdDB)
ClassImp(AliRawNullDB)
ClassImp(AliTagDB)
ClassImp(AliMDC)
// Which MDC is this...
-const Int_t kMDC = 4;
+const Int_t kMDC = 5;
// Fixed file system locations for the different DB's
#ifdef USE_RDM
-const char *kFifo = "/tmp/alimdc.fifo";
-const char *kRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
-const char *kTagDBFS = "/tmp/mdc1/tags";
-const char *kRunDBFS = "/tmp/mdc1/meta";
-const char *kRFIOFS = "rfio:/castor/cern.ch/user/r/rdm";
-const char *kRootdFS = "root://localhost//tmp/mdc1";
+const char* const kFifo = "/tmp/alimdc.fifo";
+const char* const kRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
+const char* const kTagDBFS = "/tmp/mdc1/tags";
+const char* const kRunDBFS = "/tmp/mdc1/meta";
+const char* const kRFIOFS = "rfio:/castor/cern.ch/user/r/rdm";
+const char* const kCastorFS = "castor:/castor/cern.ch/user/r/rdm";
+const char* const kRootdFS = "root://localhost//tmp/mdc1";
+const char* const kAlienHost = "alien://aliens7.cern.ch:15000/?direct";
+const char* const kAlienDir = "/alice_mdc/DC";
#else
-const char *kFifo = "/tmp/alimdc.fifo";
-const char *kRawDBFS[2] = { "/scratch/mdc1", "/scratch/mdc2" };
-const char *kTagDBFS = "/scratch/mdc1/tags";
-const char *kRunDBFS = "/scratch/mdc1/meta";
-const char *kRFIOFS = "rfio:/castor/cern.ch/lcg/alicemdc4";
-const char *kRootdFS = "root://localhost//tmp/mdc1";
+const char* const kFifo = "/tmp/alimdc.fifo";
+const char* const kRawDBFS[2] = { "/data1/mdc", "/data2/mdc" };
+const char* const kTagDBFS = "/data1/mdc/tags";
+const char* const kRunDBFS = "/data1/mdc/meta";
+const char* const kRFIOFS = "rfio:/castor/cern.ch/lcg/dc5";
+const char* const kCastorFS = "castor:/castor/cern.ch/lcg/dc5";
+const char* const kRootdFS = "root://localhost//tmp/mdc1";
+const char* const kAlienHost = "alien://aliens7.cern.ch:15000/?direct";
+const char* const kAlienDir = "/alice_mdc/DC";
#endif
// Maximum size of tag db files
// Swap equipment header data. There is no way to see if the data
// has already been swapped. This method is only called when the
// header is read from the DATE event builder (GDC).
-
+
fSize = net2host(fSize);
fEquipmentType = net2host(fEquipmentType);
fEquipmentID = net2host(fEquipmentID);
// raw data object, otherwise a private copy will be made.
fNSubEvents = 0;
- fEvtHdr = new AliRawEventHeader;
+ fEvtHdr = 0;
fEqpHdr = 0;
fRawData = 0;
fSubEvents = 0;
}
+//______________________________________________________________________________
+AliRawEventHeader *AliRawEvent::GetHeader()
+{
+ // Get event header part of AliRawEvent.
+
+ if (!fEvtHdr)
+ fEvtHdr = new AliRawEventHeader;
+
+ return fEvtHdr;
+}
+
//______________________________________________________________________________
AliRawEquipmentHeader *AliRawEvent::GetEquipmentHeader()
{
}
//______________________________________________________________________________
-AliRawEvent *AliRawEvent::GetSubEvent(Int_t index)
+AliRawEvent *AliRawEvent::GetSubEvent(Int_t index) const
{
- return (AliRawEvent *)fSubEvents->At(index);
+ // Get specified sub event. Returns 0 if sub event does not exist.
+
+ if (!fSubEvents)
+ return 0;
+
+ return (AliRawEvent *) fSubEvents->At(index);
}
//______________________________________________________________________________
ds->cd();
// Write stats also in the bookkeeping RunDB
- AliRunDB *rundb = new AliRunDB;
+ AliRunDB *rundb = new AliRunDB(kTRUE);
rundb->Update(this);
rundb->UpdateRDBMS(this);
+ rundb->UpdateAliEn(this);
delete rundb;
}
}
//______________________________________________________________________________
-Bool_t AliRawDB::FSHasSpace(const char *fs)
+Bool_t AliRawDB::FSHasSpace(const char *fs) const
{
// Check for at least fMaxSize bytes of free space on the file system.
// If the space is not available return kFALSE, kTRUE otherwise.
}
//______________________________________________________________________________
-const char *AliRawDB::GetFileName()
+const char *AliRawDB::GetFileName() const
{
// Return filename based on hostname and date and time. This will make
// each file unique. Also makes sure (via FSHasSpace()) that there is
{
// Create a new raw DB.
+ const Int_t kMaxRetry = 200;
+ const Int_t kMaxSleep = 1; // seconds
+ const Int_t kMaxSleepLong = 10; // seconds
+ Int_t retry = 0;
+
again:
+ if (gAliMDC && gAliMDC->StopLoop())
+ return kFALSE;
+
const char *fname = GetFileName();
- if (!fname) return kFALSE;
+ if (!fname) {
+ Error("Create", "error getting raw DB file name");
+ return kFALSE;
+ }
+
+ retry++;
- fRawDB = TFile::Open(fname, "RECREATE",
- Form("ALICE MDC%d raw DB", kMDC), fCompress);
+ fRawDB = TFile::Open(fname, GetOpenOption(),
+ Form("ALICE MDC%d raw DB", kMDC), fCompress,
+ GetNetopt());
if (!fRawDB) {
- Error("Create", "did not find right plugin to open file");
+ if (retry < kMaxRetry) {
+ Warning("Create", "failure to open file, sleeping %d %s before retrying...",
+ kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
+ gSystem->Sleep(kMaxSleep*1000);
+ goto again;
+ }
+ Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
return kFALSE;
}
+ if (retry > 1)
+ Warning("Create", "succeeded to open file after %d retries", retry);
+
if (fRawDB->IsZombie()) {
if (fRawDB->GetErrno() == ENOSPC ||
fRawDB->GetErrno() == 1018 || // SECOMERR
fRawDB->GetErrno() == 1027) { // SESYSERR
fRawDB->ResetErrno();
delete fRawDB;
- Warning("Create", "file is zombie, sleeping 10 seconds before retrying...");
- gSystem->Sleep(10000); // sleep 10 seconds before retrying
+ Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
+ kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
+ gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
goto again;
}
- Error("Create", "error opening raw DB");
+ Error("Create", "file %s is zombie", fname);
+ fRawDB->ResetErrno();
+ delete fRawDB;
fRawDB = 0;
+ if (retry < kMaxRetry) {
+ Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
+ kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
+ gSystem->Sleep(kMaxSleep*1000);
+ goto again;
+ }
+ Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
return kFALSE;
}
// THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP
// THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE
// WHATEVER HAS BEEN SET IN THE DATE SITE
- //gSystem->Setenv("STAGE_POOL", "mdc4");
- //gSystem->Setenv("STAGE_HOST", "lxshare003d");
+ //gSystem->Setenv("STAGE_POOL", "lcg00");
+ //gSystem->Setenv("STAGE_HOST", "stage013");
+
+ // however for sanity we check if they are really set
+ if (!gSystem->Getenv("STAGE_POOL"))
+ Error("AliRawRFIODB", "STAGE_POOL not set");
+ if (!gSystem->Getenv("STAGE_HOST"))
+ Error("AliRawRFIODB", "STAGE_HOST not set");
init = 1;
}
#endif
}
//______________________________________________________________________________
-const char *AliRawRFIODB::GetFileName()
+const char *AliRawRFIODB::GetFileName() const
{
// Return filename based on hostname and date and time. This will make
// each file unique. Also the directory will be made unique for each
// Close DB, this also deletes the fTree
fRawDB->Close();
- if (AliMDC::DeleteFiles())
- gSystem->Exec(Form("rfrm %s", fRawDB->GetName()));
+ if (AliMDC::DeleteFiles()) {
+ TUrl u(fRawDB->GetName());
+ gSystem->Exec(Form("rfrm %s", u.GetFile()));
+ }
+
+ delete fRawDB;
+ fRawDB = 0;
+}
+
+
+//______________________________________________________________________________
+AliRawCastorDB::AliRawCastorDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
+ : AliRawDB(event, maxsize, compress, kFALSE)
+{
+ // Create a new raw DB that will be accessed via CASTOR and rootd.
+
+#ifndef USE_RDM
+ static int init = 0;
+ // Set STAGE_POOL environment variable to current host
+ if (!init) {
+ // THESE ENVIRONMENT SYMBOLS ARE NOW DEFINED BY THE ALICE DATE SETUP
+ // THEREFORE WE SHALL NOT USE ANY HARDCODED VALUES BUT RATHER USE
+ // WHATEVER HAS BEEN SET IN THE DATE SITE
+ //gSystem->Setenv("STAGE_POOL", "lcg00");
+ //gSystem->Setenv("STAGE_HOST", "stage013");
+
+ // however for sanity we check if they are really set
+ if (!gSystem->Getenv("STAGE_POOL"))
+ Error("AliRawRFIODB", "STAGE_POOL not set");
+ if (!gSystem->Getenv("STAGE_HOST"))
+ Error("AliRawRFIODB", "STAGE_HOST not set");
+ init = 1;
+ }
+#endif
+
+ if (!Create())
+ MakeZombie();
+ else
+ fRawDB->UseCache(50, 0x200000); //0x100000 = 1MB)
+}
+
+//______________________________________________________________________________
+const char *AliRawCastorDB::GetFileName() const
+{
+ // Return filename based on hostname and date and time. This will make
+ // each file unique. Also the directory will be made unique for each
+ // day by adding the date to the fs. Assumes there is always enough
+ // space on the device.
+
+ static TString fname;
+
+ TString fs = kCastorFS;
+ TString fsr = kRFIOFS;
+ TDatime dt;
+
+ // make a new subdirectory for each day
+ fs += "/adc-";
+ fs += dt.GetDate();
+
+ fsr += "/adc-";
+ fsr += dt.GetDate();
+
+ Long_t id, size, flags, time;
+ if (gSystem->GetPathInfo(fsr, &id, &size, &flags, &time) == 1) {
+ // directory does not exist, create it
+ if (gSystem->mkdir(fsr, kTRUE) == -1) {
+ Error("GetFileName", "cannot create dir %s, using %s", fsr.Data(),
+ kRFIOFS);
+ fs = kCastorFS;
+ }
+ }
+ // FIXME: should check if fs is a directory
+
+ TString hostname = gSystem->HostName();
+ Int_t pos;
+ if ((pos = hostname.Index(".")) != kNPOS)
+ hostname.Remove(pos);
+
+ fname = fs + "/" + hostname + "_";
+ fname += dt.GetDate();
+ fname += "_";
+ fname += dt.GetTime();
+ fname += ".root";
+
+ return fname;
+}
+
+//______________________________________________________________________________
+void AliRawCastorDB::Close()
+{
+ // Close raw CASTOR/rootd DB.
+
+ if (!fRawDB) return;
+
+ fRawDB->cd();
+
+ // Write the tree.
+ fTree->Write();
+
+ // Close DB, this also deletes the fTree
+ fRawDB->Close();
+
+ if (AliMDC::DeleteFiles()) {
+ TUrl u(fRawDB->GetName());
+ gSystem->Exec(Form("rfrm %s", u.GetFile()));
+ }
delete fRawDB;
fRawDB = 0;
}
//______________________________________________________________________________
-const char *AliRawRootdDB::GetFileName()
+const char *AliRawRootdDB::GetFileName() const
{
// Return filename based on hostname and date and time. This will make
// each file unique. Also the directory will be made unique for each
}
//______________________________________________________________________________
-const char *AliRawNullDB::GetFileName()
+const char *AliRawNullDB::GetFileName() const
{
// Return /dev/null as filename.
}
//______________________________________________________________________________
-const char *AliTagDB::GetFileName()
+const char *AliTagDB::GetFileName() const
{
// Return filename based on hostname and date and time. This will make
// each file unique. The tags will be stored in the /data1/tags directory.
}
//______________________________________________________________________________
-const char *AliTagNullDB::GetFileName()
+const char *AliTagNullDB::GetFileName() const
{
// Return /dev/null as filename.
//______________________________________________________________________________
-AliRunDB::AliRunDB()
+AliRunDB::AliRunDB(Bool_t noLocalDB)
{
// Open run database, and get or create tree.
+ fRunDB = 0;
+
+ if (noLocalDB) return;
+
// Get hostname
char hostname[64], filename[64];
const char *fs = kRunDBFS;
{
// Add stats object to database.
+ if (!stats || !fRunDB) return;
+
TDirectory *ds = gDirectory;
fRunDB->cd();
{
// Add stats object to central MySQL DB.
+ if (!stats) return;
+
char sql[4096];
char bt[25], et[25];
delete db;
}
+//______________________________________________________________________________
+void AliRunDB::UpdateAliEn(AliStats *stats)
+{
+ // Record file in AliEn catalog.
+
+ if (!stats) return;
+
+ TGrid *g = TGrid::Connect(kAlienHost, "");
+
+ TString lfn = kAlienDir;
+ TDatime dt;
+
+ // make a subdirectory for each day
+ lfn += "/adc-";
+ lfn += dt.GetDate();
+
+ // check if directory exists, if not create it
+ Grid_ResultHandle_t res = 0;
+ if (!(res = g->OpenDir(lfn))) {
+ // directory does not exist, create it
+ if (g->Mkdir(lfn) == -1) {
+ Error("UpdateAliEn", "cannot create directory %s", lfn.Data());
+ lfn = kAlienDir;
+ }
+ }
+ if (res) g->CloseResult(res);
+
+ lfn += "/";
+ lfn += gSystem->BaseName(stats->GetFileName());
+
+ Int_t result = g->AddFile(lfn, stats->GetFileName(),
+ (int)stats->GetFileSize());
+
+ if (result == -1) {
+ Error("UpdateAliEn", "error adding file to AliEn catalog");
+ printf("AliEn: AddFile(%s, %s, %d)\n", lfn.Data(), stats->GetFileName(),
+ (int)stats->GetFileSize());
+ }
+
+ delete g;
+}
+
//______________________________________________________________________________
void AliRunDB::Close()
{
// Close run database.
- fRunDB->Close();
+ if (fRunDB) fRunDB->Close();
delete fRunDB;
}
//----------------- Use SIGUSR1 to interupt endless loop -----------------------
class AliMDCInterruptHandler : public TSignalHandler {
-private:
- AliMDC *fMDC; // alimdc to signal
public:
AliMDCInterruptHandler(AliMDC *mdc) : TSignalHandler(kSigUser1, kFALSE), fMDC(mdc) { }
- Bool_t Notify() { fMDC->SetStopLoop(); return kTRUE; }
+ Bool_t Notify() {
+ Info("Notify", "received a SIGUSR1 signal");
+ fMDC->SetStopLoop();
+ return kTRUE;
+ }
+private:
+ AliMDC *fMDC; // alimdc to signal
+
+ AliMDCInterruptHandler(const AliMDCInterruptHandler &);
+ void operator=(const AliMDCInterruptHandler &);
};
//______________________________________________________________________________
AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
- Bool_t useRFIO, Bool_t useROOTD, Bool_t useDEVNULL,
- Bool_t useLoop, Bool_t delFiles)
+ EWriteMode mode, Bool_t useLoop, Bool_t delFiles)
{
// Create MDC processor object.
fCompress = compress;
fMaxFileSize = maxFileSize;
fUseFilter = useFilter;
- fUseRFIO = useRFIO;
- fUseRootd = useROOTD;
- fUseDevNull = useDEVNULL;
+ fWriteMode = mode;
fUseLoop = useLoop;
fUseFifo = kFALSE;
fUseEb = kFALSE;
fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize,
fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress,
fgDeleteFiles ? "yes" : "no");
- if (fUseRFIO)
+ if (fWriteMode == kRFIO)
printf(", use RFIO\n");
- else if (fUseRootd)
+ else if (fWriteMode == kROOTD)
printf(", use rootd\n");
- else if (fUseDevNull)
+ else if (fWriteMode == kCASTOR)
+ printf(", use CASTOR/rootd\n");
+ else if (fWriteMode == kDEVNULL)
printf(", write raw data to /dev/null\n");
else
printf("\n");
// Create new raw DB.
AliRawDB *rawdb;
- if (fUseRFIO)
+ if (fWriteMode == kRFIO)
rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress);
- else if (fUseRootd)
+ else if (fWriteMode == kROOTD)
rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress);
- else if (fUseDevNull)
+ else if (fWriteMode == kCASTOR)
+ rawdb = new AliRawCastorDB(event, fMaxFileSize, fCompress);
+ else if (fWriteMode == kDEVNULL)
rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress);
else
rawdb = new AliRawDB(event, fMaxFileSize, fCompress);
printf("Filling raw DB %s\n", rawdb->GetDBName());
// Create new tag DB.
- AliTagDB *tagdb;
- if (fUseDevNull)
+ AliTagDB *tagdb = 0;
+#if 0
+ // no tagdb for the time being to get maximum speed
+ if (fWriteMode == kDEVNULL)
tagdb = new AliTagNullDB(event->GetHeader(), kMaxTagFileSize);
else
tagdb = new AliTagDB(event->GetHeader(), kMaxTagFileSize);
tagdb = 0;
else
printf("Filling tag DB %s\n", tagdb->GetDBName());
+#endif
// Create AliStats object
AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
// Process input stream
#ifdef USE_EB
- while (!ebEor()) {
+ Int_t eorFlag = 0;
+ while (!(eorFlag = ebEor())) {
struct iovec *ebvec;
if ((ebvec = ebGetNextEvent()) == (void *)-1) {
Error("Run", "error getting next event (%s)", ebGetLastError());
}
return 1;
}
+ ALIDEBUG(3)
+ header.Dump();
// If we were in looping mode stop directly after a SIGUSR1 signal
if (StopLoop()) {
- Info("Run", "SIGUSR1, processed %d events", fNumEvents);
+ Info("Run", "Stopping loop, processed %d events", fNumEvents);
break;
}
Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
continue;
}
- break;
default:
ALIDEBUG(1) {
Int_t s = header.GetEventSize() - header.HeaderSize();
// If there is less data for this event than the next sub-event
// header, something is wrong. Skip to next event...
if (toRead < header.HeaderSize()) {
+ ALIDEBUG(1) {
+ Warning("Run",
+ "header size (%d) exceeds number of bytes to read (%d)\n",
+ header.HeaderSize(), toRead);
+ header.Dump();
+ }
if ((status = DumpEvent(toRead)) != toRead) {
if (status == 0)
break;
}
// Loop over all sub-events... (LDCs)
+ Int_t nsub = 1;
while (toRead > 0) {
- Int_t nsub = 1;
#ifdef USE_EB
ebdata = (char *)ebvec[nsub].iov_base;
#endif
-
+
ALIDEBUG(1)
Info("Run", "reading LDC %d", nsub);
return 1;
}
+ ALIDEBUG(3)
+ subHeader.Dump();
+
toRead -= subHeader.HeaderSize();
#ifdef USE_EB
// Make sure raw data less than left over bytes for current event
if (rawSize > toRead) {
+ ALIDEBUG(1) {
+ Warning("Run", "raw data size (%d) exceeds number of bytes "
+ "to read (%d)\n", rawSize, toRead);
+ subHeader.Dump();
+ }
if ((status = DumpEvent(toRead)) != toRead) {
if (status == 0)
break;
if (rawdb->FileFull()) {
printf("Written raw DB at a rate of %.1f MB/s\n",
- Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
+ rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
- // Write stats object to raw db, run db and MySQL
+ // Write stats object to raw db, run db, MySQL and AliEn
stats->WriteToDB(rawdb);
delete stats;
- if (!rawdb->NextFile()) return 1;
+ if (!rawdb->NextFile()) {
+ Error("Run", "error opening next raw data file");
+ return 1;
+ }
printf("Filling raw DB %s\n", rawdb->GetDBName());
stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
}
// Check size of tag db
- if (tagdb->FileFull()) {
+ if (tagdb && tagdb->FileFull()) {
if (!tagdb->NextFile())
tagdb = 0;
else
}
printf("Written raw DB at a rate of %.1f MB/s\n",
- Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
+ rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
// Write stats to raw db and run db and delete stats object
stats->WriteToDB(rawdb);
}
#endif
+#ifdef USE_EB
+ // Print eor flag
+ if (eorFlag) {
+ Info("Run", "event builder reported end of run (%d)", eorFlag);
+ }
+#endif
+
return 0;
}
return nrecv;
}
-#ifdef USE_HLT
-#include <AliTPCL3Tunnel.h>
-#endif
-
//______________________________________________________________________________
Int_t AliMDC::Filter(AliRawData &raw)
{
// Call 3rd level filter for this raw data segment.
#ifdef USE_HLT
- AliTPCL3Tunnel *tunnel = 0;
- if (!tunnel) {
- // initialisation
- tunnel = new AliTPCL3Tunnel(Form("%s/TPCparams.root",
- gSystem->Getenv("ALITPC")));
- }
-
- Int_t obytes, nbytes;
- obytes = nbytes = raw.GetSize();
- char *outbuf = tunnel->EvalTrack((char *)raw.GetBuffer(), nbytes);
-
- raw.SetSize(nbytes);
- memcpy(raw.GetBuffer(), outbuf, nbytes);
- printf("Filter called for event %d: reduced from %d to %d\n", fNumEvents,
- obytes, nbytes);
+ // Add HLT code here
#else