]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliMDC.cxx
bug fixed
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
index 19a6d5e8e22f032c44af51aa41f871174d81fa3a..a4374b53c02129aedc183390791be61a8f19951a 100644 (file)
@@ -1,4 +1,4 @@
-// @(#)alimdc:$Name$:$Id$
+// @(#)alimdc:$Name:  $:$Id$
 // Author: Fons Rademakers  26/11/99
 // Updated: Dario Favretto  15/04/2003
 
 //                                                                      //
 // AliMDC                                                               //
 //                                                                      //
-// Set of classes defining the ALICE RAW event format. The AliRawEvent  //
+// Set of classes defining the ALICE RAW event format. The AliRawEventV2//
 // 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, themselves also being AliRawEventV2s. The number of      //
 // sub-events depends on the number of DATE LDC's.                      //
-// The AliRawEvent objects are written to a ROOT file using different   //
+// The AliRawEventV2 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.                //
 #include <TSystem.h>
 #include <TROOT.h>
 #include <TStopwatch.h>
+#include <TPluginManager.h>
+#include <TBufferFile.h>
 
 #include <sys/uio.h>
 #ifdef USE_EB
 #include "libDateEb.h"
 #endif
 
+#include "AliMDC.h"
+
 #include <AliLog.h>
-#include <AliESD.h>
+#include <AliESDEvent.h>
 
-#include "AliRawEvent.h"
-#include "AliRawEventHeader.h"
-#include "AliRawEquipment.h"
+#include "AliRawEventV2.h"
+#include "AliRawEventHeaderBase.h"
+#include "AliRawEquipmentV2.h"
 #include "AliRawEquipmentHeader.h"
+#include "AliRawDataArrayV2.h"
 #include "AliRawData.h"
-#include "AliStats.h"
 #include "AliRawDB.h"
 #include "AliRawRFIODB.h"
 #include "AliRawCastorDB.h"
 #include "AliRawRootdDB.h"
 #include "AliRawNullDB.h"
 #include "AliTagDB.h"
-#include "AliRunDB.h"
+#include "AliRawEventTag.h"
 #include "AliFilter.h"
 
-#include "AliMDC.h"
+
 
 ClassImp(AliMDC)
 
@@ -85,20 +87,24 @@ const char* const AliMDC::fgkFilterName[kNFilters] = {"AliHoughFilter"};
 
 //______________________________________________________________________________
 AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode, 
-              const char* localRunDB, Bool_t rdbmsRunDB,
-              const char* alienHostRunDB, const char* alienDirRunDB,
-              Double_t maxSizeTagDB, const char* fileNameTagDB) :
-  fEvent(new AliRawEvent),
+              Double_t maxSizeTagDB, const char* fileNameTagDB,
+              const char *guidFileFolder,
+              Int_t basketsize) :
+  fEvent(new AliRawEventV2),
   fESD(NULL),
-  fStats(NULL),
   fRawDB(NULL),
-  fRunDB(new AliRunDB(localRunDB, rdbmsRunDB, alienHostRunDB, alienDirRunDB)),
   fTagDB(NULL),
+  fEventTag(new AliRawEventTag),
   fCompress(compress),
+  fBasketSize(basketsize),
   fDeleteFiles(deleteFiles),
   fFilterMode(filterMode),
   fFilters(),
-  fStop(kFALSE)
+  fStop(kFALSE),
+  fIsTagDBCreated(kFALSE),
+  fMaxSizeTagDB(maxSizeTagDB),
+  fFileNameTagDB(fileNameTagDB),
+  fGuidFileFolder(guidFileFolder)
 {
   // Create MDC processor object.
   // compress is the file compression mode.
@@ -108,29 +114,43 @@ AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode,
   // kFilterTransparent the algorthims will be run but no events will be
   // rejected, if it is kFilterOn the filters will be run and the event will
   // be rejected if all filters return kFALSE.
-  // localRunDB is the file name of the local run DB; if NULL no local run DB
-  // will be created.
-  // The filling of a MySQL run DB can be switch on or off with rdbmsRunDB.
-  // The host and directory name of the alien run DB can be specified by
-  // alienHostRunDB and alienDirRunDB; if NULL no alien DB will be filled.
   // If maxSizeTagDB is greater than 0 it determines the maximal size of the
   // tag DB and then fileNameTagDB is the directory name for the tag DB.
   // Otherwise fileNameTagDB is the file name of the tag DB. If it is NULL
   // no tag DB will be created.
+  // Optional 'guidFileFolder' specifies the folder in which *.guid files
+  // will be stored. In case this option is not given, the *.guid files
+  // will be written to the same folder as the raw-data files.
+
+  // Set the maximum tree size to 19GB
+  // in order to allow big raw data files
+  TTree::SetMaxTreeSize(20000000000LL);
+
+  AliRawEquipmentHeader::Class()->IgnoreTObjectStreamer();
+  AliRawEquipmentV2::Class()->IgnoreTObjectStreamer();
+  AliRawEventV2::Class()->IgnoreTObjectStreamer();
+  AliRawDataArrayV2::Class()->IgnoreTObjectStreamer();
+
+  TBufferFile::SetGlobalReadParam(5);
  
+  // This line is needed in case of a stand-alone application w/o
+  // $ROOTSYS/etc/system.rootrc file
+  gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
+                                       "*",
+                                       "TStreamerInfo",
+                                       "RIO",
+                                       "TStreamerInfo()");
 
   if (fFilterMode != kFilterOff) {
-    fESD = new AliESD;
+    fESD = new AliESDEvent();
   }
 
-  if (fileNameTagDB) {
-    if (maxSizeTagDB > 0) {
-      fTagDB = new AliTagDB(fEvent->GetHeader(), NULL);
-      fTagDB->SetMaxSize(maxSizeTagDB);
-      fTagDB->SetFS(fileNameTagDB);
-      fTagDB->Create();
-    } else {
-      fTagDB = new AliTagDB(fEvent->GetHeader(), fileNameTagDB);
+  // Create the guid files folder if it does not exist
+  if (!fGuidFileFolder.IsNull()) {
+    gSystem->ResetErrno();
+    gSystem->MakeDirectory(fGuidFileFolder.Data());
+    if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
+      SysError("AliMDC", "mkdir %s", fGuidFileFolder.Data());
     }
   }
 
@@ -161,47 +181,30 @@ AliMDC::~AliMDC()
 // destructor
 
   fFilters.Delete();
-  delete fTagDB;
-  delete fRunDB;
+  if(fTagDB) delete fTagDB;
   delete fRawDB;
-  delete fStats;
   delete fESD;
   delete fEvent;
+  delete fEventTag;
 }
  
 //______________________________________________________________________________
-AliMDC::AliMDC(const AliMDC& mdc): TObject(mdc)
-{
-// copy constructor
-
-  Fatal("AliMDC", "copy constructor not implemented");
-}
-
-//______________________________________________________________________________
-AliMDC& AliMDC::operator = (const AliMDC& /*mdc*/)
-{
-// assignment operator
-
-  Fatal("operator =", "assignment operator not implemented");
-  return *this;
-}
-
-
-//______________________________________________________________________________
-Int_t AliMDC::Open(EWriteMode mode, const char* fileName)
+Int_t AliMDC::Open(EWriteMode mode, const char* fileName,
+                  Double_t maxFileSize,
+                  const char* fs1, const char* fs2)
 {
 // open a new raw DB file
 
   if (mode == kRFIO)
-    fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName);
+    fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName, fBasketSize);
   else if (mode == kROOTD)
-    fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName);
+    fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName, fBasketSize);
   else if (mode == kCASTOR)
-    fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName);
+    fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName, fBasketSize);
   else if (mode == kDEVNULL)
-    fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName);
+    fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName, fBasketSize);
   else
-    fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName);
+    fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName, fBasketSize);
   fRawDB->SetDeleteFiles(fDeleteFiles);
 
   if (fRawDB->IsZombie()) {
@@ -209,28 +212,43 @@ Int_t AliMDC::Open(EWriteMode mode, const char* fileName)
     fRawDB = NULL;
     return -1;
   }
+
+  if (fileName == NULL) {
+    fRawDB->SetMaxSize(maxFileSize);
+    fRawDB->SetFS(fs1, fs2);
+    if (!fRawDB->Create()) {
+      delete fRawDB;
+      fRawDB = NULL;
+      return -1;
+    }
+  }
+
+  if (!fRawDB->WriteGuidFile(fGuidFileFolder)) {
+    delete fRawDB;
+    fRawDB = NULL;
+    return -2;
+  }
+
   Info("Open", "Filling raw DB %s\n", fRawDB->GetDBName());
 
-  // Create AliStats object
-  fStats = new AliStats(fRawDB->GetDBName(), fCompress, 
-                       fFilterMode != kFilterOff);
   return 0;
 }
 
 //______________________________________________________________________________
 Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
 {
-// Convert the DATE event to an AliRawEvent object and store it in the raw DB,
+// Convert the DATE event to an AliRawEventV2 object and store it in the raw DB,
 // optionally also run the filter.
 // event is either a pointer to the streamlined event 
 // or, if isIovecArray is kTRUE, a pointer to an array of iovecs with one
 // iovec per subevent (used by the event builder).
 // The return value is the number of written bytes or an error code
-  const UInt_t kFileSizeErrorLevel   = 1900000000;
+  const Long64_t kFileSizeErrorLevel   = 19000000000LL;
 
-  UInt_t currentFileSize = GetTotalSize();
+  Long64_t currentFileSize = GetTotalSize();
+  //  AliDebug(1,Form("current file size is %lld bytes",currentFileSize));
   if(currentFileSize > kFileSizeErrorLevel) {
-    Error("ProcessEvent", "file size (%u) exceeds the limit "
+    Error("ProcessEvent", "file size (%lld) exceeds the limit "
          , currentFileSize);
     return kErrFileSize;
   }
@@ -240,118 +258,133 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
   if (isIovecArray) data = (char*) ((iovec*) event)[0].iov_base;
 
   // Shortcut for easy header access
-  AliRawEventHeader &header = *fEvent->GetHeader();
+  AliRawEventHeaderBase *header = fEvent->GetHeader(data);
 
   // Read event header
-  if ((status = ReadHeader(header, data)) != header.HeaderSize()) {
+  if ((status = header->ReadHeader(data)) != (Int_t)header->GetHeadSize()) {
+    Error("ProcessEvent","Wrong event header format (%d != %d)",
+         status,(Int_t)header->GetHeadSize());
     return kErrHeader;
   }
 
-  if (AliDebugLevel() > 2) ToAliDebug(3, header.Dump(););
+  //  if (AliDebugLevel() > 2) ToAliDebug(3, header->Dump(););
 
   // Check event type and skip "Start of Run", "End of Run",
   // "Start of Run Files" and "End of Run Files"
-  Int_t size = header.GetEventSize() - header.HeaderSize();
-  switch (header.GetType()) {
-  case AliRawEventHeader::kStartOfRun:
-  case AliRawEventHeader::kEndOfRun:
-  case AliRawEventHeader::kStartOfRunFiles:
-  case AliRawEventHeader::kEndOfRunFiles:
-    {
-      AliDebug(1, Form("Skipping %s (%d bytes)", header.GetTypeName(), size));
-      return kErrStartEndRun;
-    }
-  default:
-    {
-      AliDebug(1, Form("Processing %s (%d bytes)", header.GetTypeName(), size));
-    }
-  }
+  Int_t size = header->GetEventSize() - header->GetHeadSize();
+  UInt_t eventType = header->Get("Type");  
+
+  //  AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size));
 
   // Amount of data left to read for this event
   Int_t toRead = size;
 
-  // 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()) {
-    Error("ProcessEvent", "header size (%d) exceeds number of bytes "
-         "to read (%d)", header.HeaderSize(), toRead);
-    if (AliDebugLevel() > 0) ToAliDebug(1, header.Dump(););
-    return kErrHeaderSize;
-  }
+  // StartOfRun, EndOfRun etc. events have no payload
+  // Nevertheless, store the event headers in the tree
+  if (toRead > 0) {
+
+    // If there is less data for this event than the next sub-event
+    // header, something is wrong. Skip to next event...
+    if (toRead < (Int_t)header->GetHeadSize()) {
+      Error("ProcessEvent", "header size (%d) exceeds number of bytes "
+           "to read (%d)", header->GetHeadSize(), toRead);
+      if (AliDebugLevel() > 0) ToAliDebug(1, header->Dump(););
+      return kErrHeaderSize;
+    }
   
-  // Loop over all sub-events... (LDCs)
-  Int_t nsub = 1;
-  while (toRead > 0) {
-    if (isIovecArray) data = (char*) ((iovec*) event)[nsub].iov_base;
+    // Loop over all sub-events... (LDCs)
+    Int_t nsub = 1;
+    while (toRead > 0) {
+      if (isIovecArray) data = (char*) ((iovec*) event)[nsub].iov_base;
 
-    AliDebug(1, Form("reading LDC %d", nsub));
+      //      AliDebug(1, Form("reading LDC %d", nsub));
 
-    AliRawEvent *subEvent = fEvent->NextSubEvent();
+      AliRawEventV2 *subEvent = fEvent->NextSubEvent();
 
-    // Read sub-event header
-    AliRawEventHeader &subHeader = *subEvent->GetHeader();
-    if ((status = ReadHeader(subHeader, data)) != subHeader.HeaderSize()) {
-      return kErrSubHeader;
-    }
+      // Read sub-event header
+      AliRawEventHeaderBase *subHeader = subEvent->GetHeader(data);
+      if ((status = subHeader->ReadHeader(data)) != (Int_t)subHeader->GetHeadSize()) {
+       return kErrSubHeader;
+      }
 
-    if (AliDebugLevel() > 2) ToAliDebug(3, subHeader.Dump(););
+      //      if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump(););
 
-    toRead -= subHeader.HeaderSize();
+      toRead -= subHeader->GetHeadSize();
 
-    Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
+      Int_t rawSize = subHeader->GetEventSize() - subHeader->GetHeadSize();
 
-    // Make sure raw data less than left over bytes for current event
-    if (rawSize > toRead) {
-      Warning("ProcessEvent", "raw data size (%d) exceeds number of "
-             "bytes to read (%d)\n", rawSize, toRead);
-      if (AliDebugLevel() > 0) ToAliDebug(1, subHeader.Dump(););
-      return kErrDataSize;
-    }
+      // Make sure raw data less than left over bytes for current event
+      if (rawSize > toRead) {
+       Warning("ProcessEvent", "raw data size (%d) exceeds number of "
+               "bytes to read (%d)\n", rawSize, toRead);
+       if (AliDebugLevel() > 0) ToAliDebug(1, subHeader->Dump(););
+       return kErrDataSize;
+      }
 
-    // Read Equipment Headers (in case of physics or calibration event)
-    if (header.GetType() == AliRawEventHeader::kPhysicsEvent ||
-       header.GetType() == AliRawEventHeader::kCalibrationEvent) {
-      while (rawSize > 0) {
-       AliRawEquipment &equipment = *subEvent->NextEquipment();
-       AliRawEquipmentHeader &equipmentHeader = 
-         *equipment.GetEquipmentHeader();
-       Int_t equipHeaderSize = equipmentHeader.HeaderSize();
-       if ((status = ReadEquipmentHeader(equipmentHeader, header.DataIsSwapped(),
-                                         data)) != equipHeaderSize) {
-         return kErrEquipmentHeader;
-       }
-       toRead  -= equipHeaderSize;
-       rawSize -= equipHeaderSize;
+      // Read Equipment Headers (in case of physics or calibration event)
+      if (eventType == AliRawEventHeaderBase::kPhysicsEvent ||
+         eventType == AliRawEventHeaderBase::kCalibrationEvent ||
+         eventType == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent ||
+         eventType == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent ||
+         eventType == AliRawEventHeaderBase::kStartOfData ||
+         eventType == AliRawEventHeaderBase::kEndOfData) {
+       while (rawSize > 0) {
+         AliRawEquipmentV2 &equipment = *subEvent->NextEquipment();
+         AliRawEquipmentHeader &equipmentHeader = 
+           *equipment.GetEquipmentHeader();
+         Int_t equipHeaderSize = equipmentHeader.HeaderSize();
+         if ((status = ReadEquipmentHeader(equipmentHeader, header->DataIsSwapped(),
+                                           data)) != equipHeaderSize) {
+           return kErrEquipmentHeader;
+         }
 
-       // Read equipment raw data
-       AliRawData &subRaw = *equipment.GetRawData();
+         //      if (AliDebugLevel() > 2) ToAliDebug(3, equipmentHeader.Dump(););
 
-       Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize;
-       if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) {
-         return kErrEquipment;
-       }
-       toRead  -= eqSize;
-       rawSize -= eqSize;
+         toRead  -= equipHeaderSize;
+         rawSize -= equipHeaderSize;
 
-      }
+         // Read equipment raw data
+         AliRawDataArrayV2 *arr = fRawDB->GetRawDataArray(equipmentHeader.GetEquipmentSize(),
+                                                          equipmentHeader.GetId());
+         AliRawData &subRaw = *equipment.NextRawData(arr);
+
+         Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize;
+         if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) {
+           return kErrEquipment;
+         }
+         toRead  -= eqSize;
+         rawSize -= eqSize;
 
-    } else {  // Read only raw data but no equipment header
-      AliRawEquipment &equipment = *subEvent->NextEquipment();
-      AliRawData &subRaw = *equipment.GetRawData();
-      if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) {
-       return kErrEquipment;
+       }
+
+      } else {  // Read only raw data but no equipment header
+       if (rawSize) {
+         AliRawEquipmentV2 &equipment = *subEvent->NextEquipment();
+         AliRawEquipmentHeader &equipmentHeader = 
+           *equipment.GetEquipmentHeader();
+         equipmentHeader.Reset();
+         AliRawDataArrayV2 *arr = fRawDB->GetRawDataArray(equipmentHeader.GetEquipmentSize(),
+                                                          equipmentHeader.GetId());
+         AliRawData &subRaw = *equipment.NextRawData(arr);
+         if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) {
+           return kErrEquipment;
+         }
+         toRead  -= rawSize;
+       }
       }
-      toRead  -= rawSize;
 
+      nsub++;
     }
-
-    nsub++;
   }
 
   // High Level Event Filter
   if (fFilterMode != kFilterOff) {
-    if (header.GetType() == AliRawEventHeader::kPhysicsEvent ||
-       header.GetType() == AliRawEventHeader::kCalibrationEvent) {
+    if (eventType == AliRawEventHeaderBase::kPhysicsEvent ||
+       eventType == AliRawEventHeaderBase::kCalibrationEvent ||
+       eventType == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent ||
+       eventType == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent ||
+       eventType == AliRawEventHeaderBase::kStartOfData ||
+       eventType == AliRawEventHeaderBase::kEndOfData) {
       Bool_t result = kFALSE;
       for (Int_t iFilter = 0; iFilter < fFilters.GetEntriesFast(); iFilter++) {
        AliFilter* filter = (AliFilter*) fFilters[iFilter];
@@ -362,18 +395,38 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
     }
   }
 
-  // Set stat info for first event of this file
-  if (fRawDB->GetEvents() == 0)
-    fStats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
-
   // Store raw event in tree
   Int_t nBytes = fRawDB->Fill();
 
-  // Store header in tree
+  // Fill the event tag object
+  fEventTag->SetHeader(header);
+  fEventTag->SetGUID(fRawDB->GetDB()->GetUUID().AsString());
+  fEventTag->SetEventNumber(fRawDB->GetEvents()-1);
+
+  // Create Tag DB here only after the raw data header
+  // version was already identified
+  if (!fIsTagDBCreated) {
+    if (!fFileNameTagDB.IsNull()) {
+      if (fMaxSizeTagDB > 0) {
+       fTagDB = new AliTagDB(fEventTag, NULL);
+       fTagDB->SetMaxSize(fMaxSizeTagDB);
+       fTagDB->SetFS(fFileNameTagDB.Data());
+       if (!fTagDB->Create()) return kErrTagFile;
+      } else {
+       fTagDB = new AliTagDB(fEventTag, fFileNameTagDB.Data());
+       if (fTagDB->IsZombie()) return kErrTagFile;
+      }
+    }
+    fIsTagDBCreated = kTRUE;
+  }
+
+  // Store event tag in tree
   if (fTagDB) fTagDB->Fill();
 
   // Make top event object ready for next event data
   fEvent->Reset();
+  fRawDB->Reset();
+
   // Clean up HLT ESD for the next event
   if (fESD) fESD->Reset();
 
@@ -384,7 +437,7 @@ Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
 }
 
 //______________________________________________________________________________
-Int_t AliMDC::GetTotalSize()
+Long64_t AliMDC::GetTotalSize()
 {
 // return the total current raw DB file size
 
@@ -394,22 +447,29 @@ Int_t AliMDC::GetTotalSize()
 }
 
 //______________________________________________________________________________
-Int_t AliMDC::Close()
+Long64_t AliMDC::Close()
 {
 // close the current raw DB file
 
   if (!fRawDB) return -1;
 
-  fRawDB->WriteStats(fStats);
-  fRunDB->Update(fStats);
-  Int_t filesize = fRawDB->Close();
+  Long64_t filesize = fRawDB->Close();
   delete fRawDB;
   fRawDB = NULL;
-  delete fStats;
-  fStats = NULL;
   return filesize;
 }
 
+//______________________________________________________________________________
+Long64_t AliMDC::AutoSave()
+{
+  // Auto-save the raw-data
+  // and esd (if any) trees
+
+  if (!fRawDB) return -1;
+
+  return fRawDB->AutoSave();
+}
+
 //______________________________________________________________________________
 Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
                  EWriteMode mode, Double_t maxFileSize, 
@@ -444,37 +504,12 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
   // Used for statistics
   TStopwatch timer;
   timer.Start();
-  Double_t told = 0, tnew = 0;
   Float_t  chunkSize = maxFileSize/100, nextChunk = chunkSize;
 
   // Create new raw DB.
   if (fRawDB) Close();
-  if (mode == kRFIO) {
-    fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, NULL);
-  } else if (mode == kROOTD) {
-    fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, NULL);
-  } else if (mode == kCASTOR) {
-    fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, NULL);
-  } else if (mode == kDEVNULL) {
-    fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, NULL);
-  } else {
-    fRawDB = new AliRawDB(fEvent, fESD, fCompress, NULL);
-  }
-  fRawDB->SetMaxSize(maxFileSize);
-  fRawDB->SetFS(fs1, fs2);
-  fRawDB->SetDeleteFiles(fDeleteFiles);
-  fRawDB->Create();
 
-  if (fRawDB->IsZombie()) {
-    delete fRawDB;
-    fRawDB = NULL;
-    return 1;
-  }
-  printf("Filling raw DB %s\n", fRawDB->GetDBName());
-
-  // Create AliStats object
-  fStats = new AliStats(fRawDB->GetDBName(), fCompress, 
-                       fFilterMode != kFilterOff);
+  if (Open(mode,NULL,maxFileSize,fs1,fs2) < 0) return 1;
 
   // Process input stream
 #ifdef USE_EB
@@ -484,6 +519,9 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
   UInt_t eventSize = 0;
   Int_t numEvents = 0;
 
+  AliRawEventHeaderBase header;
+  AliRawEventHeaderBase *hdr = NULL;
+
   while (kTRUE) {
 
     // If we were in looping mode stop directly after a SIGUSR1 signal
@@ -508,41 +546,72 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
       Error("Run", "AliMDC was compiled without event builder support");
       delete fRawDB;
       fRawDB = NULL;
-      delete fStats;
-      fStats = NULL;
       return 1;
 #endif
 
     } else {  // get data from a file
-      AliRawEventHeader header;
+      {
+       Int_t nrecv;
+       if ((nrecv = Read(fd, header.HeaderBaseBegin(), header.HeaderBaseSize())) !=
+           header.HeaderBaseSize()) {
+         if (nrecv == 0) {  // eof
+           if (loop) {
+             ::lseek(fd, 0, SEEK_SET);
+             continue;
+           } else {
+             break;
+           }
+         } else {
+           Error("Run", "error reading base header");
+           Close();
+           delete[] event;
+           return 1;
+         }
+       }
+      }
+      char *data = (char *)header.HeaderBaseBegin();
+      if (!hdr) {
+       hdr = AliRawEventHeaderBase::Create(data);
+      }
+      else {
+       memcpy(hdr->HeaderBaseBegin(), header.HeaderBaseBegin(), header.HeaderBaseSize());
+      }
       Int_t nrecv;
-      if ((nrecv = Read(fd, header.HeaderBegin(), header.HeaderSize())) !=
-         header.HeaderSize()) {
+      if ((nrecv = Read(fd, hdr->HeaderBegin(), hdr->HeaderSize())) !=
+         hdr->HeaderSize()) {
        if (nrecv == 0) {  // eof
          if (loop) {
            ::lseek(fd, 0, SEEK_SET);
+           delete hdr;
            continue;
          } else {
+           delete hdr;
            break;
          }
        } else {
          Error("Run", "error reading header");
          Close();
          delete[] event;
+         delete hdr;
          return 1;
        }
       }
-      if (eventSize < header.GetEventSize()) {
+      if (eventSize < hdr->GetEventSize()) {
        delete[] event;
-       eventSize = 2 * header.GetEventSize();
+       eventSize = 2 * hdr->GetEventSize();
        event = new char[eventSize];
       }
-      memcpy(event, header.HeaderBegin(), header.HeaderSize());
-      Int_t size = header.GetEventSize() - header.HeaderSize();
-      if (Read(fd, event + header.HeaderSize(), size) != size) {
+      memcpy(event, header.HeaderBaseBegin(), header.HeaderBaseSize());
+      memcpy(event+hdr->HeaderBaseSize(), hdr->HeaderBegin(), hdr->HeaderSize());
+      if (hdr->GetExtendedDataSize() != 0)
+       memcpy(event+hdr->HeaderBaseSize()+hdr->HeaderSize(),
+              hdr->GetExtendedData(), hdr->GetExtendedDataSize());
+      Int_t size = hdr->GetEventSize() - hdr->GetHeadSize();
+      if (Read(fd, event + hdr->GetHeadSize(), size) != size) {
        Error("Run", "error reading data");
        Close();
        delete[] event;
+       delete hdr;
        return 1;
       }
     }
@@ -553,17 +622,11 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
 
     if (result >= 0) {
       numEvents++;
-      if (!(numEvents%10))
-       printf("Processed event %d (%d)\n", numEvents, fRawDB->GetEvents());
     }
 
     if (result > 0) {
       // Filling time statistics
       if (fRawDB->GetBytesWritten() > nextChunk) {
-       tnew = timer.RealTime();
-       fStats->Fill(tnew-told);
-       told = tnew;
-       timer.Continue();
        nextChunk += chunkSize;
       }
 
@@ -574,25 +637,16 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
        printf("Written raw DB at a rate of %.1f MB/s\n",
               fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
 
-       // Write stats object to raw db, run db, MySQL and AliEn
-       fRawDB->WriteStats(fStats);
-       if (fRunDB) fRunDB->Update(fStats);
-       delete fStats;
-       fStats = NULL;
-
        if (!fRawDB->NextFile()) {
          Error("Run", "error opening next raw data file");
          Close();
          if (inputFile) delete[] event;
+         delete hdr;
          return 1;
        }
 
        printf("Filling raw DB %s\n", fRawDB->GetDBName());
-       fStats = new AliStats(fRawDB->GetDBName(), fCompress, 
-                             fFilterMode != kFilterOff);
-
        timer.Start();
-       told = 0, tnew = 0;
        nextChunk = chunkSize;
       }
 
@@ -623,6 +677,8 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
     }
   }
 
+  delete hdr;
+
   printf("Written raw DB at a rate of %.1f MB/s\n",
         fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
 
@@ -639,6 +695,7 @@ Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
   } else {
     // Close input source
     close(fd);
+    delete [] event;
   }
 
   return 0;
@@ -669,34 +726,6 @@ Int_t AliMDC::Read(Int_t fd, void *buffer, Int_t length)
    return n;
 }
 
-//______________________________________________________________________________
-Int_t AliMDC::ReadHeader(AliRawEventHeader &header, char*& data)
-{
-  // Read header info from DATE data stream. Returns bytes read (i.e.
-  // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
-
-  memcpy(header.HeaderBegin(), data, header.HeaderSize());
-  data += header.HeaderSize();
-
-  // Swap header data if needed
-  if (header.IsSwapped())
-    header.Swap();
-
-  // Is header valid...
-  if (!header.IsValid()) {
-    Error("ReadHeader", "invalid header format");
-    // try recovery... how?
-    return -1;
-  }
-  if (header.GetEventSize() < (UInt_t)header.HeaderSize()) {
-    Error("ReadHeader", "invalid header size");
-    // try recovery... how?
-    return -1;
-  }
-
-  return header.HeaderSize();
-}
-
 //______________________________________________________________________________
 Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
                                   Bool_t isSwapped, char*& data)
@@ -744,24 +773,3 @@ void AliMDC::Stop()
 }
 
 
-//______________________________________________________________________________
-AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const 
-                                                      AliMDCInterruptHandler&
-                                                      handler): 
-  TSignalHandler(handler) 
-{
-// copy constructor
-
-  Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
-}
-
-//______________________________________________________________________________
-AliMDC::AliMDCInterruptHandler& 
-  AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler& 
-                                             /*handler*/)
-{
-// assignment operator
-
-  Fatal("operator =", "assignment operator not implemented");
-  return *this;
-}