]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliRawEvent.cxx
fix some coding violations.
[u/mrichter/AliRoot.git] / RAW / AliRawEvent.cxx
index 7b21d5403bd67520744c9562ff06c8983ce57126..31b5282b98da4fb8ed35e1b140235b819c9a0c5f 100644 (file)
@@ -2,26 +2,75 @@
 // 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
@@ -40,6 +89,7 @@ ClassImp(AliRawData)
 ClassImp(AliStats)
 ClassImp(AliRawDB)
 ClassImp(AliRawRFIODB)
+ClassImp(AliRawCastorDB)
 ClassImp(AliRawRootdDB)
 ClassImp(AliRawNullDB)
 ClassImp(AliTagDB)
@@ -48,23 +98,29 @@ ClassImp(AliRunDB)
 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
@@ -168,7 +224,7 @@ void AliRawEquipmentHeader::Swap()
    // 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);
@@ -185,12 +241,23 @@ AliRawEvent::AliRawEvent()
    // 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()
 {
@@ -239,9 +306,14 @@ AliRawEvent *AliRawEvent::NextSubEvent()
 }
 
 //______________________________________________________________________________
-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);
 }
 
 //______________________________________________________________________________
@@ -356,9 +428,10 @@ void AliStats::WriteToDB(AliRawDB *rawdb)
    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;
 }
 
@@ -386,7 +459,7 @@ AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress,
 }
 
 //______________________________________________________________________________
-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.
@@ -408,7 +481,7 @@ Bool_t AliRawDB::FSHasSpace(const char *fs)
 }
 
 //______________________________________________________________________________
-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
@@ -454,28 +527,61 @@ Bool_t AliRawDB::Create()
 {
    // 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;
    }
 
@@ -567,8 +673,14 @@ AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress)
       // 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
@@ -580,7 +692,7 @@ AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress)
 }
 
 //______________________________________________________________________________
-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
@@ -636,8 +748,112 @@ void AliRawRFIODB::Close()
    // 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;
@@ -657,7 +873,7 @@ AliRawRootdDB::AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compres
 }
 
 //______________________________________________________________________________
-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
@@ -737,7 +953,7 @@ AliRawNullDB::AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
 }
 
 //______________________________________________________________________________
-const char *AliRawNullDB::GetFileName()
+const char *AliRawNullDB::GetFileName() const
 {
    // Return /dev/null as filename.
 
@@ -848,7 +1064,7 @@ Float_t AliTagDB::GetCompressionFactor() const
 }
 
 //______________________________________________________________________________
-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.
@@ -886,7 +1102,7 @@ AliTagNullDB::AliTagNullDB(AliRawEventHeader *header, Double_t maxsize) :
 }
 
 //______________________________________________________________________________
-const char *AliTagNullDB::GetFileName()
+const char *AliTagNullDB::GetFileName() const
 {
    // Return /dev/null as filename.
 
@@ -914,10 +1130,14 @@ void AliTagNullDB::Close()
 
 
 //______________________________________________________________________________
-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;
@@ -944,6 +1164,8 @@ void AliRunDB::Update(AliStats *stats)
 {
    // Add stats object to database.
 
+   if (!stats || !fRunDB) return;
+
    TDirectory *ds = gDirectory;
    fRunDB->cd();
 
@@ -967,6 +1189,8 @@ void AliRunDB::UpdateRDBMS(AliStats *stats)
 {
    // Add stats object to central MySQL DB.
 
+   if (!stats) return;
+
    char sql[4096];
    char bt[25], et[25];
 
@@ -1002,28 +1226,76 @@ void AliRunDB::UpdateRDBMS(AliStats *stats)
    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.
 
@@ -1031,9 +1303,7 @@ AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
    fCompress     = compress;
    fMaxFileSize  = maxFileSize;
    fUseFilter    = useFilter;
-   fUseRFIO      = useRFIO;
-   fUseRootd     = useROOTD;
-   fUseDevNull   = useDEVNULL;
+   fWriteMode    = mode;
    fUseLoop      = useLoop;
    fUseFifo      = kFALSE;
    fUseEb        = kFALSE;
@@ -1073,11 +1343,13 @@ AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
           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");
@@ -1123,11 +1395,13 @@ Int_t AliMDC::Run()
 
    // 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);
@@ -1136,8 +1410,10 @@ Int_t AliMDC::Run()
    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);
@@ -1145,6 +1421,7 @@ Int_t AliMDC::Run()
       tagdb = 0;
    else
       printf("Filling tag DB %s\n", tagdb->GetDBName());
+#endif
 
    // Create AliStats object
    AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
@@ -1154,7 +1431,8 @@ Int_t AliMDC::Run()
 
    // 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());
@@ -1185,10 +1463,12 @@ Int_t AliMDC::Run()
          }
          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;
       }
 
@@ -1214,7 +1494,6 @@ Int_t AliMDC::Run()
                   Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
                continue;
             }
-            break;
          default:
             ALIDEBUG(1) {
                Int_t s = header.GetEventSize() - header.HeaderSize();
@@ -1228,6 +1507,12 @@ Int_t AliMDC::Run()
       // 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;
@@ -1238,12 +1523,12 @@ Int_t AliMDC::Run()
       }
 
       // 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);
 
@@ -1259,6 +1544,9 @@ Int_t AliMDC::Run()
             return 1;
          }
 
+         ALIDEBUG(3)
+            subHeader.Dump();
+
          toRead -= subHeader.HeaderSize();
 
 #ifdef USE_EB
@@ -1290,6 +1578,11 @@ Int_t AliMDC::Run()
 
          // 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;
@@ -1351,13 +1644,16 @@ Int_t AliMDC::Run()
       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);
@@ -1368,7 +1664,7 @@ Int_t AliMDC::Run()
       }
 
       // Check size of tag db
-      if (tagdb->FileFull()) {
+      if (tagdb && tagdb->FileFull()) {
          if (!tagdb->NextFile())
             tagdb = 0;
          else
@@ -1388,7 +1684,7 @@ Int_t AliMDC::Run()
    }
 
    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);
@@ -1411,6 +1707,13 @@ Int_t AliMDC::Run()
    }
 #endif
 
+#ifdef USE_EB
+   // Print eor flag
+   if (eorFlag) {
+      Info("Run", "event builder reported end of run (%d)", eorFlag);
+   }
+#endif
+
    return 0;
 }
 
@@ -1568,32 +1871,14 @@ Int_t AliMDC::DumpEvent(Int_t toRead)
    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