AliRawEvent classes used in the data challenges and stand-alone alimdc
authorrdm <rdm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 11 Sep 2003 14:57:05 +0000 (14:57 +0000)
committerrdm <rdm@f7af4fe6-9843-0410-8265-dc069ae4e863>
Thu, 11 Sep 2003 14:57:05 +0000 (14:57 +0000)
program used to read from DATE and create ALICE RAW ROOT files.

RAW/.cvsignore [new file with mode: 0644]
RAW/AAREADME [new file with mode: 0644]
RAW/AARUN [new file with mode: 0644]
RAW/AliRawEvent.cxx [new file with mode: 0644]
RAW/AliRawEvent.h [new file with mode: 0644]
RAW/DateEvent.h [new file with mode: 0644]
RAW/LinkDef.h [new file with mode: 0644]
RAW/Make-macros [new file with mode: 0644]
RAW/Makefile [new file with mode: 0644]
RAW/alimdc.cxx [new file with mode: 0644]

diff --git a/RAW/.cvsignore b/RAW/.cvsignore
new file mode 100644 (file)
index 0000000..12c5e03
--- /dev/null
@@ -0,0 +1,3 @@
+AliRawDict.cxx
+AliRawDict.h
+alimdc
diff --git a/RAW/AAREADME b/RAW/AAREADME
new file mode 100644 (file)
index 0000000..94c45b9
--- /dev/null
@@ -0,0 +1,23 @@
+Build alimdc using one of the following targets:
+
+depend           # generate dependencies
+
+rdm              # for local running uses /tmp/mdc1 and /tmp/mdc2
+                 # and rfio:/castor/cern.ch/user/r/rdm
+
+<default>        # for running in ADC environment but started by hand (not via
+                 # SMI). Uses /pool/mdc and /tmp/mdc and 
+                 # rfio:/castor/cern.ch/alice/mdc4
+
+smi              # idem as above but for running under control of SMI/DIM.
+
+evb              # access eventbuilder via shared memory segment
+
+debug            # enable debug outout
+
+
+typical use:
+
+make rdm          # for local testing
+make rdm debug    # idem with some debug output
+make evb smi      # for running in data challenge under control of DATE
diff --git a/RAW/AARUN b/RAW/AARUN
new file mode 100644 (file)
index 0000000..a2e73a3
--- /dev/null
+++ b/RAW/AARUN
@@ -0,0 +1,4 @@
+./alimdc 1000000000 0 -0 -datebig.raw     # endless loop to RFIO
+./alimdc 1000000000 0 +0 -datebig.raw     # endless loop to rootd
+./alimdc 1000000000 0  0 -datebig.raw     # endless loop to local file in /tmp
+./alimdc 1000000000 0 @0 -datebig.raw     # endless loop to /dev/null
diff --git a/RAW/AliRawEvent.cxx b/RAW/AliRawEvent.cxx
new file mode 100644 (file)
index 0000000..84cf520
--- /dev/null
@@ -0,0 +1,1595 @@
+// @(#)alimdc:$Name$:$Id$
+// Author: Fons Rademakers  26/11/99
+// Updated: Dario Favretto  15/04/2003
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <sys/vfs.h>
+#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 "AliRawEvent.h"
+
+// Good for Linux
+#define long32 int
+#include "DateEvent.h"
+
+#ifdef USE_EB
+#include "libDateEb.h"
+#endif
+
+
+ClassImp(AliRawEvent)
+ClassImp(AliRawEventHeader)
+ClassImp(AliRawEquipmentHeader)
+ClassImp(AliRawData)
+ClassImp(AliStats)
+ClassImp(AliRawDB)
+ClassImp(AliRawRFIODB)
+ClassImp(AliRawRootdDB)
+ClassImp(AliRawNullDB)
+ClassImp(AliTagDB)
+ClassImp(AliTagNullDB)
+ClassImp(AliRunDB)
+ClassImp(AliMDC)
+
+// Which MDC is this...
+const Int_t kMDC = 4;
+
+// 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";
+#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";
+#endif
+
+// Maximum size of tag db files
+const Double_t kMaxTagFileSize = 2.5e8;    // 250MB
+
+Bool_t AliMDC::fgDeleteFiles = kFALSE;
+
+AliMDC *gAliMDC = 0;
+
+
+//______________________________________________________________________________
+Bool_t AliRawEventHeader::DataIsSwapped() const
+{
+   // Returns true if event data is swapped.
+
+   if (TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_EVENT_SWAPPED))
+      return kTRUE;
+   return kFALSE;
+}
+
+//______________________________________________________________________________
+void AliRawEventHeader::Swap()
+{
+   // Swap header data.
+
+   if (IsSwapped()) {
+      fSize         = net2host(fSize);
+      fMagic        = net2host(fMagic);
+      fHeadLen      = net2host(fHeadLen);
+      fVersion      = net2host(fVersion);
+      fType         = net2host(fType);
+      fRunNb        = net2host(fRunNb);
+      for (int i = 0; i < kIdWords; i++)
+         fId[i] = net2host(fId[i]);
+      for (int i = 0; i < kTriggerWords; i++)
+         fTriggerPattern[i] = net2host(fTriggerPattern[i]);
+      for (int i = 0; i < kDetectorWords; i++)
+         fDetectorPattern[i] = net2host(fDetectorPattern[i]);
+      for (int i = 0; i < kAttributeWords; i++)
+         fTypeAttribute[i] = net2host(fTypeAttribute[i]);
+      fLDCId        = net2host(fLDCId);
+      fGDCId        = net2host(fGDCId);
+   }
+}
+
+//______________________________________________________________________________
+UInt_t AliRawEventHeader::GetEventInRun() const
+{
+   // Get event number in run. Correct for fixed target mode which is used
+   // in the Data Challenge Setup.
+
+   if (!TEST_SYSTEM_ATTRIBUTE(fTypeAttribute, ATTR_ORBIT_BC)) {
+      return EVENT_ID_GET_NB_IN_RUN(fId);
+   }
+   return 0;
+}
+
+//______________________________________________________________________________
+const char *AliRawEventHeader::GetTypeName() const
+{
+   // Get event type as a string.
+
+   switch (GetType()) {
+      case kStartOfRun:
+         return "START_OF_RUN";
+         break;
+      case kEndOfRun:
+         return "END_OF_RUN";
+         break;
+      case kStartOfRunFiles:
+         return "START_OF_RUN_FILES";
+         break;
+      case kEndOfRunFiles:
+         return "END_OF_RUN_FILES";
+         break;
+      case kStartOfBurst:
+         return "START_OF_BURST";
+         break;
+      case kEndOfBurst:
+         return "END_OF_BURST";
+         break;
+      case kPhysicsEvent:
+         return "PHYSICS_EVENT";
+         break;
+      case kCalibrationEvent:
+         return "CALIBRATION_EVENT";
+         break;
+      case kFormatError:
+         return "EVENT_FORMAT_ERROR";
+         break;
+      default:
+         return "*** UNKNOWN EVENT TYPE ***";
+         break;
+   }
+}
+
+
+//______________________________________________________________________________
+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);
+   fBasicElementSizeType = net2host(fBasicElementSizeType);
+   for (int i = 0; i < kAttributeWords; i++)
+      fTypeAttribute[i] = net2host(fTypeAttribute[i]);
+}
+
+
+//______________________________________________________________________________
+AliRawEvent::AliRawEvent()
+{
+   // Create ALICE event object. If ownData is kFALSE we will use a static
+   // raw data object, otherwise a private copy will be made.
+
+   fNSubEvents = 0;
+   fEvtHdr     = new AliRawEventHeader;
+   fEqpHdr     = 0;
+   fRawData    = 0;
+   fSubEvents  = 0;
+}
+
+//______________________________________________________________________________
+AliRawEquipmentHeader *AliRawEvent::GetEquipmentHeader()
+{
+   // Get equipment header part of AliRawEvent.
+
+   if (!fEqpHdr)
+      fEqpHdr = new AliRawEquipmentHeader;
+
+   return fEqpHdr;
+}
+
+//______________________________________________________________________________
+AliRawData *AliRawEvent::GetRawData()
+{
+   // Get raw data part of AliRawEvent.
+
+   if (!fRawData)
+      fRawData = new AliRawData;
+
+   return fRawData;
+}
+
+//______________________________________________________________________________
+AliRawEvent *AliRawEvent::NextSubEvent()
+{
+   // Returns next sub-event object.
+
+   if (!fSubEvents)
+      fSubEvents = new TObjArray(100); // arbitrary, probably enough to prevent resizing
+
+   if (fSubEvents->GetSize() <= fNSubEvents) {
+      fSubEvents->Expand(fNSubEvents+10);
+      Warning("NextSubEvent", "expanded fSubEvents by 10 to %d",
+              fSubEvents->GetSize());
+   }
+
+   AliRawEvent *ev;
+   if (!(ev = (AliRawEvent *)fSubEvents->At(fNSubEvents))) {
+      ev = new AliRawEvent;
+      fSubEvents->AddAt(ev, fNSubEvents);
+   }
+
+   fNSubEvents++;
+
+   return ev;
+}
+
+//______________________________________________________________________________
+void AliRawEvent::Reset()
+{
+   // Reset the event in case it needs to be re-used (avoiding costly
+   // new/delete cycle). We reset the size marker for the AliRawData
+   // objects and the sub event counter.
+
+   for (int i = 0; i < fNSubEvents; i++) {
+      AliRawEvent *ev = (AliRawEvent *)fSubEvents->At(i);
+      ev->GetRawData()->SetSize(0);
+   }
+   fNSubEvents = 0;
+}
+
+//______________________________________________________________________________
+AliRawEvent::~AliRawEvent()
+{
+   // Clean up event object. Delete also, possible, private raw data.
+
+   delete fEvtHdr;
+   delete fEqpHdr;
+   delete fRawData;
+   if (fSubEvents)
+      fSubEvents->Delete();
+   delete fSubEvents;
+}
+
+//______________________________________________________________________________
+AliStats::AliStats(const char *filename, Int_t compmode, Bool_t filter)
+{
+   // Create statistics object.
+
+   fEvents     = 0;
+   fFirstRun   = 0;
+   fFirstEvent = 0;
+   fLastRun    = 0;
+   fLastEvent  = 0;
+   fChunk      = -0.5;
+   fFileName   = filename;
+   fCompMode   = compmode;
+   fFilter     = filter;
+   fRTHist     = 0;
+}
+
+//______________________________________________________________________________
+AliStats::~AliStats()
+{
+   // Cleanup stats object.
+
+   delete fRTHist;
+}
+
+//______________________________________________________________________________
+AliStats &AliStats::operator=(const AliStats &rhs)
+{
+   // AliStats assignment operator.
+
+   if (this != &rhs) {
+      TObject::operator=(rhs);
+      fEvents     = rhs.fEvents;
+      fFirstRun   = rhs.fFirstRun;
+      fFirstEvent = rhs.fFirstEvent;
+      fLastRun    = rhs.fLastRun;
+      fLastEvent  = rhs.fLastEvent;
+      fBegin      = rhs.fBegin;
+      fEnd        = rhs.fEnd;
+      fFileName   = rhs.fFileName;
+      fFileSize   = rhs.fFileSize;
+      fCompFactor = rhs.fCompFactor;
+      fCompMode   = rhs.fCompMode;
+      fFilter     = rhs.fFilter;
+      fRTHist     = rhs.fRTHist ? (TH1F*) rhs.fRTHist->Clone() : 0;
+      fChunk      = rhs.fChunk;
+   }
+   return *this;
+}
+
+//______________________________________________________________________________
+void AliStats::Fill(Float_t time)
+{
+   // Fill histogram. This histogram shows the (hopefully constant) time
+   // it takes to fill the ROOT DB.
+   // Expects to be called 100 times for each file.
+
+   if (!fRTHist) {
+      fRTHist = new TH1F("rtime","Real-time to write data chunk", 100, 0, 100);
+      fRTHist->SetDirectory(0);
+   }
+
+   fRTHist->Fill(fChunk, time);
+   fChunk += 1.0;
+}
+
+//______________________________________________________________________________
+void AliStats::WriteToDB(AliRawDB *rawdb)
+{
+   // Write stats to raw DB, local run DB and global MySQL DB.
+
+   AliRawEventHeader &header = *rawdb->GetEvent()->GetHeader();
+
+   // Write stats into RawDB
+   TDirectory *ds = gDirectory;
+   rawdb->GetDB()->cd();
+   SetEvents(rawdb->GetEvents());
+   SetLastId(header.GetRunNumber(), header.GetEventInRun());
+   SetFileSize(rawdb->GetBytesWritten());
+   SetCompressionFactor(rawdb->GetCompressionFactor());
+   SetEndTime();
+   Write("stats");
+   ds->cd();
+
+   // Write stats also in the bookkeeping RunDB
+   AliRunDB *rundb = new AliRunDB;
+   rundb->Update(this);
+   rundb->UpdateRDBMS(this);
+   delete rundb;
+}
+
+//______________________________________________________________________________
+AliRawDB::AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress,
+                   Bool_t create)
+{
+   // Create a new raw DB containing at most maxsize bytes.
+
+   fEvent    = event;
+   fMaxSize  = maxsize;
+   fCompress = compress;
+
+   // Consistency check with DATE header file
+   if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
+      Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
+      MakeZombie();
+      return;
+   }
+
+   if (create) {
+      if (!Create())
+         MakeZombie();
+   }
+}
+
+//______________________________________________________________________________
+Bool_t AliRawDB::FSHasSpace(const char *fs)
+{
+   // Check for at least fMaxSize bytes of free space on the file system.
+   // If the space is not available return kFALSE, kTRUE otherwise.
+
+   Long_t id, bsize, blocks, bfree;
+
+   if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
+      Error("FSHasSpace", "could not stat file system %s", fs);
+      return kFALSE;
+   }
+
+   // Leave 5 percent of diskspace free
+   Double_t avail = Double_t(bfree) * 0.95;
+   if (avail*bsize > fMaxSize)
+      return kTRUE;
+
+   Warning("FSHasSpace", "no space on file system %s", fs);
+   return kFALSE;
+}
+
+//______________________________________________________________________________
+const char *AliRawDB::GetFileName()
+{
+   // Return filename based on hostname and date and time. This will make
+   // each file unique. Also makes sure (via FSHasSpace()) that there is
+   // enough space on the file system to store the file. Returns 0 in
+   // case of error or interrupt signal.
+
+   static TString fname;
+   static Bool_t  fstoggle = kFALSE;
+
+   TString fs = fstoggle ? kRawDBFS[1] : kRawDBFS[0];
+   TDatime dt;
+
+   TString hostname = gSystem->HostName();
+   Int_t pos;
+   if ((pos = hostname.Index(".")) != kNPOS)
+      hostname.Remove(pos);
+
+   if (!FSHasSpace(fs)) {
+      while (1) {
+         fstoggle = !fstoggle;
+         fs = fstoggle ? kRawDBFS[1] : kRawDBFS[0];
+         if (FSHasSpace(fs)) break;
+         Info("GetFileName", "sleeping 30 seconds before retrying...");
+         gSystem->Sleep(30000);   // sleep for 30 seconds
+         if (gAliMDC && gAliMDC->StopLoop())
+            return 0;
+      }
+   }
+
+   fname = fs + "/" + hostname + "_";
+   fname += dt.GetDate();
+   fname += "_";
+   fname += dt.GetTime();
+   fname += ".root";
+
+   fstoggle = !fstoggle;
+
+   return fname;
+}
+
+//______________________________________________________________________________
+Bool_t AliRawDB::Create()
+{
+   // Create a new raw DB.
+
+again:
+   const char *fname = GetFileName();
+   if (!fname) return kFALSE;
+
+   fRawDB = TFile::Open(fname, "RECREATE",
+                        Form("ALICE MDC%d raw DB", kMDC), fCompress);
+   if (!fRawDB) {
+      Error("Create", "did not find right plugin to open file");
+      return kFALSE;
+   }
+   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
+         goto again;
+      }
+      Error("Create", "error opening raw DB");
+      fRawDB = 0;
+      return kFALSE;
+   }
+
+   // Create raw data TTree
+   MakeTree();
+
+   return kTRUE;
+}
+
+//______________________________________________________________________________
+void AliRawDB::MakeTree()
+{
+   // Create ROOT Tree object container.
+
+   fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", kMDC));
+   fTree->SetAutoSave(2000000000);  // autosave when 2 Gbyte written
+
+   Int_t bufsize = 256000;
+   // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
+   //Int_t split   = 1;
+   Int_t split   = 0;
+   fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
+}
+
+//______________________________________________________________________________
+void AliRawDB::Close()
+{
+   // Close raw DB.
+
+   if (!fRawDB) return;
+
+   fRawDB->cd();
+
+   // Write the tree.
+   fTree->Write();
+
+   // Close DB, this also deletes the fTree
+   fRawDB->Close();
+
+   if (AliMDC::DeleteFiles()) {
+      gSystem->Unlink(fRawDB->GetName());
+      delete fRawDB;
+      fRawDB = 0;
+      return;
+   }
+
+   // Create semaphore to say this file is finished
+   Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
+   close(tfd);
+
+   delete fRawDB;
+   fRawDB = 0;
+}
+
+//______________________________________________________________________________
+Bool_t AliRawDB::NextFile()
+{
+   // Close te current file and open a new one.
+   // Returns kFALSE in case opening failed.
+
+   Close();
+
+   if (!Create()) return kFALSE;
+   return kTRUE;
+}
+
+//______________________________________________________________________________
+Float_t AliRawDB::GetCompressionFactor() const
+{
+   // Return compression factor.
+
+   if (fTree->GetZipBytes() == 0.)
+      return 1.0;
+   else
+      return fTree->GetTotBytes()/fTree->GetZipBytes();
+}
+
+
+//______________________________________________________________________________
+AliRawRFIODB::AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress)
+   : AliRawDB(event, maxsize, compress, kFALSE)
+{
+   // Create a new raw DB that will be accessed via RFIO.
+
+#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", "mdc4");
+      //gSystem->Setenv("STAGE_HOST", "lxshare003d");
+      init = 1;
+   }
+#endif
+
+   if (!Create())
+      MakeZombie();
+   else
+      fRawDB->UseCache(50, 0x200000);  //0x100000 = 1MB)
+}
+
+//______________________________________________________________________________
+const char *AliRawRFIODB::GetFileName()
+{
+   // 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 = kRFIOFS;
+   TDatime dt;
+
+   // make a new subdirectory for each day
+   fs += "/adc-";
+   fs += dt.GetDate();
+
+   Long_t id, size, flags, time;
+   if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) {
+      // directory does not exist, create it
+      if (gSystem->mkdir(fs, kTRUE) == -1) {
+         Error("GetFileName", "cannot create dir %s, using %s", fs.Data(),
+               kRFIOFS);
+         fs = kRFIOFS;
+      }
+   }
+   // 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 AliRawRFIODB::Close()
+{
+   // Close raw RFIO DB.
+
+   if (!fRawDB) return;
+
+   fRawDB->cd();
+
+   // Write the tree.
+   fTree->Write();
+
+   // Close DB, this also deletes the fTree
+   fRawDB->Close();
+
+   if (AliMDC::DeleteFiles())
+      gSystem->Exec(Form("rfrm %s", fRawDB->GetName()));
+
+   delete fRawDB;
+   fRawDB = 0;
+}
+
+
+//______________________________________________________________________________
+AliRawRootdDB::AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
+   : AliRawDB(event, maxsize, compress, kFALSE)
+{
+   // Create a new raw DB that will be accessed via rootd daemon.
+
+   if (!Create())
+      MakeZombie();
+   else
+      fRawDB->UseCache(50, 0x200000);  //0x100000 = 1MB)
+}
+
+//______________________________________________________________________________
+const char *AliRawRootdDB::GetFileName()
+{
+   // 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 = kRootdFS;
+   TDatime dt;
+
+#if 0
+   // make a new subdirectory for each day
+   fs += "/adc-";
+   fs += dt.GetDate();
+
+   Long_t id, size, flags, time;
+   if (gSystem->GetPathInfo(fs, &id, &size, &flags, &time) == 1) {
+      // directory does not exist, create it
+      if (gSystem->mkdir(fs, kTRUE) == -1) {
+         Error("GetFileName", "cannot create dir %s, using %s", fs.Data(),
+               kRootdFS);
+         fs = kRootdFS;
+      }
+   }
+   // FIXME: should check if fs is a directory
+#endif
+
+   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 AliRawRootdDB::Close()
+{
+   // Close raw rootd DB.
+
+   if (!fRawDB) return;
+
+   fRawDB->cd();
+
+   // Write the tree.
+   fTree->Write();
+
+   // Close DB, this also deletes the fTree
+   fRawDB->Close();
+
+#if 0
+   // can use services of TFTP
+   if (AliMDC::DeleteFiles())
+      gSystem->Exec(Form("rfrm %s", fRawDB->GetName()));
+#endif
+
+   delete fRawDB;
+   fRawDB = 0;
+}
+
+
+//______________________________________________________________________________
+AliRawNullDB::AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress)
+   : AliRawDB(event, maxsize, compress, kFALSE)
+{
+   // Create a new raw DB that will wrtie to /dev/null.
+
+   if (!Create())
+      MakeZombie();
+}
+
+//______________________________________________________________________________
+const char *AliRawNullDB::GetFileName()
+{
+   // Return /dev/null as filename.
+
+   return "/dev/null";
+}
+
+//______________________________________________________________________________
+void AliRawNullDB::Close()
+{
+   // Close raw RFIO DB.
+
+   if (!fRawDB) return;
+
+   fRawDB->cd();
+
+   // Write the tree.
+   fTree->Write();
+
+   // Close DB, this also deletes the fTree
+   fRawDB->Close();
+
+   delete fRawDB;
+   fRawDB = 0;
+}
+
+
+//______________________________________________________________________________
+AliTagDB::AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create)
+{
+   // Create tag DB.
+
+   fHeader   = header;
+   fMaxSize  = maxsize;
+
+   if (create) {
+      if (!Create())
+         MakeZombie();
+   }
+}
+
+//______________________________________________________________________________
+Bool_t AliTagDB::Create()
+{
+   // Create a new tag DB.
+
+   fTagDB = new TFile(GetFileName(), "RECREATE",
+                      Form("ALICE MDC%d tag DB", kMDC), 1);
+   if (fTagDB->IsZombie()) {
+      Error("Create", "error opening tag DB");
+      fTagDB = 0;
+      return kFALSE;
+   }
+
+   // Create ROOT Tree object container
+   fTree = new TTree("TAG", Form("ALICE MDC%d header data tree", kMDC));
+   fTree->SetAutoSave(100000000);  // autosave when 100 Mbyte written
+
+   Int_t bufsize = 32000;
+   Int_t split   = 1;
+   fTree->Branch("header", "AliRawEventHeader", &fHeader, bufsize, split);
+
+   return kTRUE;
+}
+
+//______________________________________________________________________________
+void AliTagDB::Close()
+{
+   // Close tag DB.
+
+   if (!fTagDB) return;
+
+   fTagDB->cd();
+
+   // Write the tree.
+   fTree->Write();
+
+   // Close DB, this also deletes the fTree
+   fTagDB->Close();
+
+   if (AliMDC::DeleteFiles())
+      gSystem->Unlink(fTagDB->GetName());
+
+   delete fTagDB;
+   fTagDB = 0;
+}
+
+//______________________________________________________________________________
+Bool_t AliTagDB::NextFile()
+{
+   // Close te current file and open a new one.
+   // Returns kFALSE in case opening failed.
+
+   Close();
+
+   if (!Create()) return kFALSE;
+   return kTRUE;
+}
+
+//______________________________________________________________________________
+Float_t AliTagDB::GetCompressionFactor() const
+{
+   // Return compression factor.
+
+   if (fTree->GetZipBytes() == 0.)
+      return 1.0;
+   else
+      return fTree->GetTotBytes()/fTree->GetZipBytes();
+}
+
+//______________________________________________________________________________
+const char *AliTagDB::GetFileName()
+{
+   // 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.
+
+   static char fname[64];
+   const char *fs = kTagDBFS;
+
+   // check that fs exists (crude check fails if fs is a file)
+   gSystem->MakeDirectory(fs);
+
+   char hostname[64];
+
+   strcpy(hostname, gSystem->HostName());
+
+   char *s;
+   if ((s = strchr(hostname, '.')))
+      *s = 0;
+
+   TDatime dt;
+
+   sprintf(fname, "%s/%s_%d_%d.root", fs, hostname, dt.GetDate(), dt.GetTime());
+
+   return fname;
+}
+
+
+//______________________________________________________________________________
+AliTagNullDB::AliTagNullDB(AliRawEventHeader *header, Double_t maxsize) :
+   AliTagDB(header, maxsize, kFALSE)
+{
+   // Create tag db writing to /dev/null.
+
+   if (!Create())
+      MakeZombie();
+}
+
+//______________________________________________________________________________
+const char *AliTagNullDB::GetFileName()
+{
+   // Return /dev/null as filename.
+
+   return "/dev/null";
+}
+
+//______________________________________________________________________________
+void AliTagNullDB::Close()
+{
+   // Close null tag DB.
+
+   if (!fTagDB) return;
+
+   fTagDB->cd();
+
+   // Write the tree.
+   fTree->Write();
+
+   // Close DB, this also deletes the fTree
+   fTagDB->Close();
+
+   delete fTagDB;
+   fTagDB = 0;
+}
+
+
+//______________________________________________________________________________
+AliRunDB::AliRunDB()
+{
+   // Open run database, and get or create tree.
+
+   // Get hostname
+   char hostname[64], filename[64];
+   const char *fs = kRunDBFS;
+
+   // check that fs exists (crude check fails if fs is a file)
+   gSystem->MakeDirectory(fs);
+
+   strcpy(hostname, gSystem->HostName());
+
+   char *s;
+   if ((s = strchr(hostname, '.')))
+      *s = 0;
+
+   sprintf(filename, "%s/%s_rundb.root", fs, hostname);
+
+   if (!gSystem->AccessPathName(filename, kFileExists))
+      fRunDB = new TFile(filename, "UPDATE");
+   else
+      fRunDB = new TFile(filename, "CREATE", Form("ALICE MDC%d Run DB", kMDC));
+}
+
+//______________________________________________________________________________
+void AliRunDB::Update(AliStats *stats)
+{
+   // Add stats object to database.
+
+   TDirectory *ds = gDirectory;
+   fRunDB->cd();
+
+   char sname[64];
+   char *s = strrchr(stats->GetFileName(), '/');
+   if (s) {
+      s++;
+      strcpy(sname, s);
+   } else
+      strcpy(sname, stats->GetFileName());
+   s = strchr(sname, '.');
+   if (s) *s = 0;
+
+   stats->Write(sname);
+
+   ds->cd();
+}
+
+//______________________________________________________________________________
+void AliRunDB::UpdateRDBMS(AliStats *stats)
+{
+   // Add stats object to central MySQL DB.
+
+   char sql[4096];
+   char bt[25], et[25];
+
+   strcpy(bt, stats->GetBeginTime().AsSQLString());
+   strcpy(et, stats->GetEndTime().AsSQLString());
+
+   sprintf(sql, "INSERT INTO mdc%dcatalog VALUES (0, '%s', %d, "
+           "%d, %d, %d, %d, %d, %d, %.2f, '%s', '%s', '%s')", kMDC,
+           stats->GetFileName(), (int)stats->GetFileSize(), stats->GetEvents(),
+           stats->GetFirstRun(), stats->GetFirstEvent(), stats->GetLastRun(),
+           stats->GetLastEvent(), stats->GetCompressionMode(),
+           stats->GetCompressionFactor(), stats->GetFilterState() ? "on" : "off",
+           bt, et);
+
+   // open connection to MySQL server on pcsalo
+   TSQLServer *db = TSQLServer::Connect("mysql://pcsalo.cern.ch/mdc", "alice", "amdc");
+
+   if (!db || db->IsZombie()) {
+      Error("UpdateRDBMS", "failed to connect to MySQL server on pcsalo");
+      printf("%s\n", sql);
+      delete db;
+      return;
+   }
+
+   TSQLResult *res = db->Query(sql);
+
+   if (!res) {
+      Error("UpdateRDBMS", Form("insert into mdc%dcatalog failed", kMDC));
+      printf("%s\n", sql);
+   }
+
+   delete res;
+   delete db;
+}
+
+//______________________________________________________________________________
+void AliRunDB::Close()
+{
+   // Close run database.
+
+   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; }
+};
+
+//______________________________________________________________________________
+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)
+{
+   // Create MDC processor object.
+
+   fFd           = fd;
+   fCompress     = compress;
+   fMaxFileSize  = maxFileSize;
+   fUseFilter    = useFilter;
+   fUseRFIO      = useRFIO;
+   fUseRootd     = useROOTD;
+   fUseDevNull   = useDEVNULL;
+   fUseLoop      = useLoop;
+   fUseFifo      = kFALSE;
+   fUseEb        = kFALSE;
+   fStopLoop     = kFALSE;
+   fNumEvents    = 0;
+   fDebugLevel   = 0;
+   fgDeleteFiles = delFiles;
+
+   if (fFd == -1) {
+#ifdef USE_EB
+     if (!ebRegister()) {
+        Error("AliMDC", "cannot register with the event builder (%s)",
+              ebGetLastError());
+        return;
+     }
+     fUseEb = kTRUE;
+#else
+     if ((mkfifo(kFifo, 0644) < 0) && (errno != EEXIST)) {
+         Error("AliMDC", "cannot create fifo %s", kFifo);
+         return;
+      }
+      if ((chmod(kFifo, 0666) == -1) && (errno != EPERM)) {
+         Error("AliMDC", "cannot change permission of fifo %s", kFifo);
+         return;
+      }
+      if ((fFd = open(kFifo, O_RDONLY)) == -1) {
+         Error("AliMDC", "cannot open input file %s", kFifo);
+         return;
+      }
+      fUseFifo = kTRUE;
+#endif
+      fUseLoop = kFALSE;
+   }
+
+   printf("<AliMDC::AliMDC>: input = %s, rawdb size = %f, filter = %s, "
+          "looping = %s, compression = %d, delete files = %s",
+          fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize,
+          fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress,
+          fgDeleteFiles ? "yes" : "no");
+   if (fUseRFIO)
+      printf(", use RFIO\n");
+   else if (fUseRootd)
+      printf(", use rootd\n");
+   else if (fUseDevNull)
+      printf(", write raw data to /dev/null\n");
+   else
+      printf("\n");
+
+   // install SIGUSR1 handler to allow clean interrupts
+   gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
+
+   gAliMDC = this;
+}
+
+//______________________________________________________________________________
+Int_t AliMDC::Run()
+{
+   // Run the MDC processor. Read from the input stream and only return
+   // when the input gave and EOF or a fatal error occured. On success 0
+   // is returned, 1 in case of a fatality.
+
+   TStopwatch timer;
+   Int_t status;
+
+   // Make sure needed directories exist
+   const char *dirs[4];
+   dirs[0] = kRawDBFS[0];
+   dirs[1] = kRawDBFS[1];
+   dirs[2] = kTagDBFS;
+   dirs[3] = kRunDBFS;
+   for (int idir = 0; idir < 4; idir++) {
+      gSystem->ResetErrno();
+      gSystem->MakeDirectory(dirs[idir]);
+      if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
+         SysError("Run", "mkdir %s", dirs[idir]);
+         return 1;
+      }
+   }
+
+   // Used for statistics
+   timer.Start();
+   Double_t told = 0, tnew = 0;
+   Float_t  chunkSize = fMaxFileSize/100, nextChunk = chunkSize;
+
+   // Event object used to store event data.
+   AliRawEvent *event = new AliRawEvent;
+
+   // Create new raw DB.
+   AliRawDB *rawdb;
+   if (fUseRFIO)
+      rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress);
+   else if (fUseRootd)
+      rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress);
+   else if (fUseDevNull)
+      rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress);
+   else
+      rawdb = new AliRawDB(event, fMaxFileSize, fCompress);
+
+   if (rawdb->IsZombie()) return 1;
+   printf("Filling raw DB %s\n", rawdb->GetDBName());
+
+   // Create new tag DB.
+   AliTagDB *tagdb;
+   if (fUseDevNull)
+      tagdb = new AliTagNullDB(event->GetHeader(), kMaxTagFileSize);
+   else
+      tagdb = new AliTagDB(event->GetHeader(), kMaxTagFileSize);
+   if (tagdb->IsZombie())
+      tagdb = 0;
+   else
+      printf("Filling tag DB %s\n", tagdb->GetDBName());
+
+   // Create AliStats object
+   AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
+
+   // Shortcut for easy header access
+   AliRawEventHeader &header = *event->GetHeader();
+
+   // Process input stream
+#ifdef USE_EB
+   while (!ebEor()) {
+      struct iovec *ebvec;
+      if ((ebvec = ebGetNextEvent()) == (void *)-1) {
+         Error("Run", "error getting next event (%s)", ebGetLastError());
+         break;
+      }
+      if (ebvec == 0) {
+         // no event, sleep for 1 second and try again
+         gSystem->Sleep(1000);
+         continue;
+      }
+      char *ebdata = (char *) ebvec[0].iov_base;
+#else
+   while (1) {
+      char *ebdata = 0;
+#endif
+
+      // Read event header
+      if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) {
+         if (status == 0) {
+            if (fUseLoop) {
+#ifndef USE_EB
+               ::lseek(fFd, 0, SEEK_SET);
+#endif
+               continue;
+            }
+            printf("<AliMDC::Run>: EOF, processed %d events\n", fNumEvents);
+            break;
+         }
+         return 1;
+      }
+
+      // If we were in looping mode stop directly after a SIGUSR1 signal
+      if (StopLoop()) {
+         Info("Run", "SIGUSR1, processed %d events", fNumEvents);
+         break;
+      }
+
+      // Check if event has any hard track flagged
+      Bool_t callFilter = kFALSE;
+      // This needs to be re-engineered for the next ADC...
+      //if (fUseFilter && TEST_USER_ATTRIBUTE(header.GetTypeAttribute(), 0))
+      //   callFilter = kTRUE;
+
+      // Check event type and skip "Start of Run", "End of Run",
+      // "Start of Run Files" and "End of Run Files"
+      switch (header.GetType()) {
+         case kStartOfRun:
+         case kEndOfRun:
+         case kStartOfRunFiles:
+         case kEndOfRunFiles:
+            {
+               Int_t skip = header.GetEventSize() - header.HeaderSize();
+#ifndef USE_EB
+               ::lseek(fFd, skip, SEEK_CUR);
+#endif
+               ALIDEBUG(1)
+                  Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
+               continue;
+            }
+            break;
+         default:
+            ALIDEBUG(1) {
+               Int_t s = header.GetEventSize() - header.HeaderSize();
+               Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s);
+            }
+      }
+
+      // Amount of data left to read for this event
+      Int_t toRead = 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()) {
+         if ((status = DumpEvent(toRead)) != toRead) {
+            if (status == 0)
+               break;
+            return 1;
+         }
+         Error("Run", "discarding event %d (too little data for header)", fNumEvents);
+         continue;
+      }
+
+      // Loop over all sub-events... (LDCs)
+      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);
+
+         AliRawEvent *subEvent = event->NextSubEvent();
+
+         // Read sub-event header
+         AliRawEventHeader &subHeader = *subEvent->GetHeader();
+         if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) {
+            if (status == 0) {
+               Error("Run", "unexpected EOF reading sub-event header");
+               break;
+            }
+            return 1;
+         }
+
+         toRead -= subHeader.HeaderSize();
+
+#ifdef USE_EB
+         ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize();
+#endif
+
+         Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
+
+         // Read Equipment Header (in case of physics or calibration event)
+         if (header.GetType() == kPhysicsEvent ||
+             header.GetType() == kCalibrationEvent) {
+            AliRawEquipmentHeader &equipment = *subEvent->GetEquipmentHeader();
+            Int_t equipHeaderSize = equipment.HeaderSize();
+            if ((status = ReadEquipmentHeader(equipment, header.DataIsSwapped(),
+                                              ebdata)) != equipHeaderSize) {
+               if (status == 0) {
+                  Error("Run", "unexpected EOF reading equipment-header");
+                  break;
+               }
+               return 1;
+            }
+            toRead  -= equipHeaderSize;
+            rawSize -= equipHeaderSize;
+#ifdef USE_EB
+            ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize() +
+                     equipHeaderSize;
+#endif
+         }
+
+         // Make sure raw data less than left over bytes for current event
+         if (rawSize > toRead) {
+            if ((status = DumpEvent(toRead)) != toRead) {
+               if (status == 0)
+                  break;
+               return 1;
+            }
+            Error("Run", "discarding event %d (too much data)", fNumEvents);
+            continue;
+         }
+
+         // Read sub-event raw data
+         AliRawData &subRaw = *subEvent->GetRawData();
+         if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) {
+            if (status == 0) {
+               Error("Run", "unexpected EOF reading sub-event raw data");
+               break;
+            }
+            return 1;
+         }
+
+         if (callFilter) {
+            if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0))
+               Filter(subRaw);
+            else {
+               // set size of all sectors without hard track flag to 0
+               subRaw.SetSize(0);
+            }
+         }
+
+         toRead -= rawSize;
+         nsub++;
+      }
+
+      // Set stat info for first event of this file
+      if (rawdb->GetEvents() == 0)
+         stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
+
+      // Store raw event in tree
+      rawdb->Fill();
+
+      // Store header in tree
+      if (tagdb) tagdb->Fill();
+
+      fNumEvents++;
+
+      if (!(fNumEvents%10))
+         printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents());
+
+      // Filling time statistics
+      if (rawdb->GetBytesWritten() > nextChunk) {
+         tnew = timer.RealTime();
+         stats->Fill(tnew-told);
+         told = tnew;
+         timer.Continue();
+         nextChunk += chunkSize;
+      }
+
+      // Check size of raw db. If bigger than maxFileSize, close file
+      // and continue with new file.
+      if (rawdb->FileFull()) {
+
+         printf("Written raw DB at a rate of %.1f MB/s\n",
+                Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
+
+         // Write stats object to raw db, run db and MySQL
+         stats->WriteToDB(rawdb);
+         delete stats;
+
+         if (!rawdb->NextFile()) return 1;
+
+         printf("Filling raw DB %s\n", rawdb->GetDBName());
+         stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
+
+         timer.Start();
+         told = 0, tnew = 0;
+         nextChunk = chunkSize;
+      }
+
+      // Check size of tag db
+      if (tagdb->FileFull()) {
+         if (!tagdb->NextFile())
+            tagdb = 0;
+         else
+            printf("Filling tag DB %s\n", tagdb->GetDBName());
+      }
+
+      // Make top event object ready for next event data
+      //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents());
+      event->Reset();
+
+#ifdef USE_EB
+      if (!ebReleaseEvent(ebvec)) {
+         Error("Run", "problem releasing event (%s)", ebGetLastError());
+         break;
+      }
+#endif
+   }
+
+   printf("Written raw DB at a rate of %.1f MB/s\n",
+          Float_t(fMaxFileSize / timer.RealTime() / 1000000.));
+
+   // Write stats to raw db and run db and delete stats object
+   stats->WriteToDB(rawdb);
+   delete stats;
+
+   // Close the raw DB
+   delete rawdb;
+
+   // Close the tag DB
+   delete tagdb;
+
+   // Close input source
+   close(fFd);
+
+#if 0
+   // Cleanup fifo
+   if (fUseFifo && ::unlink(kFifo) == -1) {
+      SysError("Run", "unlink");
+      return 1;
+   }
+#endif
+
+   return 0;
+}
+
+//______________________________________________________________________________
+Int_t AliMDC::Read(void *buffer, Int_t length)
+{
+   // Read exactly length bytes into buffer. Returns number of bytes
+   // received, returns -1 in case of error and 0 for EOF.
+
+   errno = 0;
+
+   if (fFd < 0) return -1;
+
+   Int_t n, nrecv = 0;
+   char *buf = (char *)buffer;
+
+   for (n = 0; n < length; n += nrecv) {
+      if ((nrecv = read(fFd, buf+n, length-n)) <= 0) {
+         if (nrecv == 0)
+            break;        // EOF
+         if (errno != EINTR)
+            SysError("Read", "read");
+         return -1;
+      }
+   }
+   return n;
+}
+
+//______________________________________________________________________________
+Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb)
+{
+   // Read header info from DATE data stream. Returns bytes read (i.e.
+   // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
+
+   Int_t nrecv;
+
+   if (eb) {
+      // read from event builder memory area
+      memcpy(header.HeaderBegin(), eb, header.HeaderSize());
+      nrecv = header.HeaderSize();
+   } else {
+      // read from fifo or file
+      if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
+           header.HeaderSize()) {
+         if (nrecv == 0)
+            return 0;
+         return -1;
+      }
+   }
+
+   // 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 nrecv;
+}
+
+//______________________________________________________________________________
+Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
+                                  Bool_t isSwapped, void *eb)
+{
+   // Read equipment header info from DATE data stream. Returns bytes read
+   // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
+   // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
+   // and we will swap the header to host format.
+
+   Int_t nrecv;
+
+   if (eb) {
+      // read from event builder memory area
+      memcpy(header.HeaderBegin(), eb, header.HeaderSize());
+      nrecv = header.HeaderSize();
+   } else {
+      // read from fifo or file
+      if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
+           header.HeaderSize()) {
+         if (nrecv == 0)
+            return 0;
+         return -1;
+      }
+   }
+
+   // Swap equipment header data if needed
+   if (isSwapped)
+      header.Swap();
+
+   if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
+      Error("ReadEquipmentHeader", "invalid equipment header size");
+      // try recovery... how?
+      return -1;
+   }
+
+   return nrecv;
+}
+
+//______________________________________________________________________________
+Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb)
+{
+   // Read raw data from DATE data stream. Returns bytes read (i.e.
+   // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
+
+   Int_t nrecv;
+
+   if (eb) {
+      // read from event builder memory area
+      raw.SetBuffer(eb, size);
+      nrecv = size;
+   } else {
+      // read from fifo or file
+      raw.SetSize(size);
+      if ((nrecv = Read(raw.GetBuffer(), size)) != size) {
+         if (nrecv == 0) {
+            Error("ReadRawData", "unexpected EOF");
+            return 0;
+         }
+         return -1;
+      }
+   }
+
+   return nrecv;
+}
+
+//______________________________________________________________________________
+Int_t AliMDC::DumpEvent(Int_t toRead)
+{
+   // This case should not happen, but if it does try to handle it
+   // gracefully by reading the rest of the event and discarding it.
+   // Returns bytes read, -1 in case of fatal error and 0 for EOF.
+
+   Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents);
+
+   Int_t nrecv;
+   char *tbuf = new char[toRead];
+   if ((nrecv = Read(tbuf, toRead)) != toRead) {
+      if (nrecv == 0) {
+         Error("DumpEvent", "unexpected EOF");
+         return 0;
+      }
+      return -1;
+   }
+   delete [] tbuf;
+
+   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);
+
+#else
+
+   raw.GetSize();
+   printf("Filter called for event %d\n", fNumEvents);
+
+#endif
+
+   return 0;
+}
diff --git a/RAW/AliRawEvent.h b/RAW/AliRawEvent.h
new file mode 100644 (file)
index 0000000..e1f0784
--- /dev/null
@@ -0,0 +1,447 @@
+// @(#)alimdc:$Name$:$Id$
+// Author: Fons Rademakers  26/11/99
+// Updated: Dario Favretto  15/04/2003
+
+#ifndef ALIRAWEVENT_H
+#define ALIRAWEVENT_H
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+
+#ifndef ROOT_Bytes
+#include <Bytes.h>
+#endif
+
+#ifndef ROOT_TDatime
+#include <TDatime.h>
+#endif
+
+#ifndef ROOT_TString
+#include <TString.h>
+#endif
+
+#ifndef ROOT_TFile
+#include <TFile.h>
+#endif
+
+#ifndef ROOT_TTree
+#include <TTree.h>
+#endif
+
+
+// Forward class declarations
+class TH1F;
+class AliRawDB;
+
+
+// The following enumeration can be used once the kEventTypeMask has been
+// applied to the raw event type
+enum EAliRawEventType {
+   kStartOfRun =       1,    // START_OF_RUN
+   kEndOfRun =         2,    // END_OF_RUN
+   kStartOfRunFiles =  3,    // START_OF_RUN_FILES
+   kEndOfRunFiles =    4,    // END_OF_RUN_FILES
+   kStartOfBurst =     5,    // START_OF_BURST
+   kEndOfBurst =       6,    // END_OF_BURST
+   kPhysicsEvent =     7,    // PHYSICS_EVENT
+   kCalibrationEvent = 8,    // CALIBRATION_EVENT
+   kFormatError =      9     // EVENT_FORMAT_ERROR
+};
+
+const Int_t kEventTypeMin = kStartOfRun;
+const Int_t kEventTypeMax = kFormatError;
+
+const UInt_t kEventMagicNumber        = 0xDA1E5AFE;
+const UInt_t kEventMagicNumberSwapped = 0xFE5A1EDA;
+
+// Type sizes
+const Int_t kIdWords        = 2;
+const Int_t kTriggerWords   = 2;
+const Int_t kDetectorWords  = 1;
+const Int_t kAttributeWords = 3;
+
+
+class AliRawEventHeader : public TObject {
+
+private:
+   UInt_t fSize;          // size of event in bytes
+   UInt_t fMagic;         // magic number used for consistency check
+   UInt_t fHeadLen;       // size of header in bytes
+   UInt_t fVersion;       // unique version identifier
+   UInt_t fType;          // event type
+   UInt_t fRunNb;         // run number
+   UInt_t fId[kIdWords];  // id field
+   UInt_t fTriggerPattern[kTriggerWords];   // trigger pattern
+   UInt_t fDetectorPattern[kDetectorWords]; // detector pattern
+   UInt_t fTypeAttribute[kAttributeWords];  // system (0,1) and user (2) attributes
+   UInt_t fLDCId;         // LDC id
+   UInt_t fGDCId;         // GDC id
+
+public:
+   AliRawEventHeader() { fSize = 0; }
+   virtual ~AliRawEventHeader() { }
+
+   void         *HeaderBegin() { return (void *) &fSize; }
+   Int_t         HeaderSize() const { return (Long_t) &fGDCId - (Long_t) &fSize + sizeof(fGDCId); }
+   Bool_t        DataIsSwapped() const;
+   Bool_t        IsSwapped() const { return (fMagic == kEventMagicNumberSwapped) ? kTRUE : kFALSE; }
+   Bool_t        IsValid() const { return IsSwapped() ? kTRUE : ((fMagic == kEventMagicNumber) ? kTRUE : kFALSE); }
+   void          Swap();
+
+   UInt_t        GetEventSize() const { return fSize; }
+   UInt_t        GetMagic() const { return fMagic; }
+   UInt_t        GetHeaderLength() const { return fHeadLen; }
+   UInt_t        GetVersion() const { return fVersion; }
+   UInt_t        GetType() const { return fType; }
+   const char   *GetTypeName() const;
+   UInt_t        GetRunNumber() const { return fRunNb; }
+   UInt_t        GetEventInRun() const;
+   const UInt_t *GetId() const { return fId; }
+   const UInt_t *GetTriggerPattern() const { return fTriggerPattern; }
+   const UInt_t *GetDetectorPattern() const { return fDetectorPattern; }
+   const UInt_t *GetTypeAttribute() const { return fTypeAttribute; }
+   UInt_t        GetLDCId() const { return fLDCId; }
+   UInt_t        GetGDCId() const { return fGDCId; }
+
+   ClassDef(AliRawEventHeader,1)  // Alice raw event header
+};
+
+
+class AliRawEquipmentHeader : public TObject {
+
+private:
+   UInt_t fSize;                            // number of raw data bytes
+   UInt_t fEquipmentType;                   // equipment type
+   UInt_t fEquipmentID;                     // equipment ID
+   UInt_t fTypeAttribute[kAttributeWords];  // system (0,1) and user (2) attributes
+   UInt_t fBasicElementSizeType;            // basic element size type
+
+public:
+   AliRawEquipmentHeader() { fSize = 0; }
+   ~AliRawEquipmentHeader() { }
+
+   void         *HeaderBegin() { return (void *) &fSize; }
+   Int_t         HeaderSize() const { return (Long_t) &fBasicElementSizeType - (Long_t) &fSize + sizeof(fBasicElementSizeType); }
+   void          Swap();
+
+   UInt_t        GetEquipmentSize() const { return fSize; }
+   UInt_t        GetEquipmentType() const { return fEquipmentType; }
+   UInt_t        GetId() const { return fEquipmentID; }
+   const UInt_t *GetTypeAttribute() const { return fTypeAttribute; }
+   UInt_t        GetBasicSizeType() const { return fBasicElementSizeType; }
+
+   ClassDef(AliRawEquipmentHeader,1) //Alice equipment header
+};
+
+
+class AliRawData : public TObject {
+
+private:
+   Int_t   fSize;         // number of raw data bytes
+   Int_t   fBufSize;      //!actual size of fRawData
+   char   *fRawData;      //[fSize] raw event data
+   Bool_t  fOwner;        //!if true object owns fRawData buffer
+
+public:
+   AliRawData() { fSize = fBufSize = 0; fRawData = 0; fOwner = kFALSE; }
+   virtual ~AliRawData() { if (fOwner) delete [] fRawData; }
+
+   void  SetSize(Int_t size) {
+      if (size > fBufSize) {
+         if (fOwner) delete [] fRawData;
+         fRawData = new char [size];
+         fBufSize = size;
+         fOwner   = kTRUE;
+      }
+      fSize = size;
+   }
+   void  SetBuffer(void *buf, Int_t size) {
+      if (fOwner) delete [] fRawData;
+      fRawData = (char *) buf;
+      fBufSize = size;
+      fSize    = size;
+      fOwner   = kFALSE;
+   }
+   Int_t    GetSize() const { return fSize; }
+   void    *GetBuffer() { return fRawData; }
+
+   ClassDef(AliRawData,1)  // Alice raw event buffer
+};
+
+
+class AliRawEvent : public TObject {
+
+private:
+   Int_t                  fNSubEvents;  // number of valid sub-events
+   AliRawEventHeader     *fEvtHdr;      // event header object
+   AliRawEquipmentHeader *fEqpHdr;      // equipment header
+   AliRawData            *fRawData;     // raw data container
+   TObjArray             *fSubEvents;   // sub AliRawEvent's
+
+public:
+   AliRawEvent();
+   virtual ~AliRawEvent();
+
+   AliRawEventHeader     *GetHeader() const { return fEvtHdr; }
+   AliRawEquipmentHeader *GetEquipmentHeader();
+   AliRawData            *GetRawData();
+   Int_t                  GetNSubEvents() const { return fNSubEvents; }
+   AliRawEvent           *NextSubEvent();
+   void                   Reset();
+
+   ClassDef(AliRawEvent,1)  // ALICE raw event object
+};
+
+
+class AliStats : public TObject {
+
+private:
+   Int_t    fEvents;     // number of events in this file
+   Int_t    fFirstRun;   // run number of first event in file
+   Int_t    fFirstEvent; // event number of first event in file
+   Int_t    fLastRun;    // run number of last event in file
+   Int_t    fLastEvent;  // event number of last event in file
+   TDatime  fBegin;      // begin of filling time
+   TDatime  fEnd;        // end of filling time
+   TString  fFileName;   // name of file containing this data
+   Double_t fFileSize;   // size of file
+   Float_t  fCompFactor; // tree compression factor
+   Int_t    fCompMode;   // compression mode
+   Bool_t   fFilter;     // 3rd level filter on/off
+   TH1F    *fRTHist;     // histogram of real-time to process chunck of data
+   Float_t  fChunk;      //!chunk to be histogrammed
+
+public:
+   AliStats(const char *filename = "", Int_t compmode = 0, Bool_t filter = kFALSE);
+   virtual ~AliStats();
+   AliStats &operator=(const AliStats &rhs);
+
+   void SetEvents(Int_t events) { fEvents = events; }
+   void SetFirstId(Int_t run, Int_t event) { fFirstRun = run; fFirstEvent = event; }
+   void SetLastId(Int_t run, Int_t event) { fLastRun = run; fLastEvent = event; }
+   void SetBeginTime() { fBegin.Set(); }
+   void SetEndTime() { fEnd.Set(); }
+   void SetFileSize(Double_t size) { fFileSize = size; }
+   void SetCompressionFactor(Float_t comp) { fCompFactor = comp; }
+   void Fill(Float_t time);
+   void WriteToDB(AliRawDB *rawdb);
+
+   Int_t       GetEvents() const { return fEvents; }
+   Int_t       GetFirstRun() const { return fFirstRun; }
+   Int_t       GetFirstEvent() const { return fFirstEvent; }
+   Int_t       GetLastRun() const { return fLastRun; }
+   Int_t       GetLastEvent() const { return fLastEvent; }
+   TDatime    &GetBeginTime() { return fBegin; }
+   TDatime    &GetEndTime() { return fEnd; }
+   Double_t    GetFileSize() const { return fFileSize; }
+   Int_t       GetCompressionMode() const { return fCompMode; }
+   Float_t     GetCompressionFactor() const { return fCompFactor; }
+   Bool_t      GetFilterState() const { return fFilter; }
+   const char *GetFileName() const { return fFileName; }
+   TH1F       *GetRTHist() const { return fRTHist; }
+
+   ClassDef(AliStats,1)  // Statistics object
+};
+
+
+class AliRawDB : public TObject {
+
+protected:
+   TFile         *fRawDB;         // DB to store raw data
+   TTree         *fTree;          // tree used to store raw data
+   AliRawEvent   *fEvent;         // AliRawEvent via which data is stored
+   Int_t          fCompress;      // compression mode (1 default)
+   Double_t       fMaxSize;       // maximum size in bytes of the raw DB
+
+   virtual const char *GetFileName();
+   virtual Bool_t      FSHasSpace(const char *fs);
+   virtual void        MakeTree();
+
+public:
+   AliRawDB(AliRawEvent *event, Double_t maxsize, Int_t compress,
+            Bool_t create = kTRUE);
+   ~AliRawDB() { Close(); }
+
+   virtual Bool_t Create();
+   virtual void   Close();
+   void           Fill() { fTree->Fill(); }
+   Bool_t         FileFull() { return (fRawDB->GetBytesWritten() > fMaxSize) ?
+                               kTRUE : kFALSE; }
+
+   Bool_t      NextFile();
+
+   Double_t     GetBytesWritten() const { return fRawDB->GetBytesWritten(); }
+   TFile       *GetDB() const { return fRawDB; }
+   const char  *GetDBName() const { return fRawDB->GetName(); }
+   Int_t        GetEvents() const { return (Int_t) fTree->GetEntries(); }
+   AliRawEvent *GetEvent() const { return fEvent; }
+   Float_t      GetCompressionFactor() const;
+   Int_t        GetCompressionMode() const { return fRawDB->GetCompressionLevel(); }
+
+   ClassDef(AliRawDB,0)  // Raw DB
+};
+
+
+class AliRawRFIODB : public AliRawDB {
+
+private:
+   const char *GetFileName();
+
+public:
+   AliRawRFIODB(AliRawEvent *event, Double_t maxsize, Int_t compress);
+   ~AliRawRFIODB() { Close(); }
+
+   void Close();
+
+   ClassDef(AliRawRFIODB,0)  // Raw DB via RFIO
+};
+
+
+class AliRawRootdDB : public AliRawDB {
+
+private:
+   const char *GetFileName();
+
+public:
+   AliRawRootdDB(AliRawEvent *event, Double_t maxsize, Int_t compress);
+   ~AliRawRootdDB() { Close(); }
+
+   void Close();
+
+   ClassDef(AliRawRootdDB,0)  // Raw DB via rootd
+};
+
+
+class AliRawNullDB : public AliRawDB {
+
+private:
+   const char *GetFileName();
+
+public:
+   AliRawNullDB(AliRawEvent *event, Double_t maxsize, Int_t compress);
+   ~AliRawNullDB() { Close(); }
+
+   void Close();
+
+   ClassDef(AliRawNullDB,0)  // Raw DB to /dev/null
+};
+
+
+class AliTagDB : public TObject {
+
+protected:
+   TFile             *fTagDB;     // DB to store header information only (tag)
+   TTree             *fTree;      // tree use to store header
+   AliRawEventHeader *fHeader;    // header via which data is stored
+   Double_t           fMaxSize;   // maximum size in bytes of tag DB
+
+   virtual const char *GetFileName();
+
+public:
+   AliTagDB(AliRawEventHeader *header, Double_t maxsize, Bool_t create = kTRUE);
+   ~AliTagDB() { Close(); }
+
+   Bool_t          Create();
+   virtual void    Close();
+   void            Fill() { fTree->Fill(); }
+   Bool_t          FileFull()
+            { return (fTagDB->GetBytesWritten() > fMaxSize) ? kTRUE : kFALSE; }
+
+   Bool_t          NextFile();
+
+   Double_t           GetBytesWritten() const { return fTagDB->GetBytesWritten(); }
+   TFile             *GetDB() const { return fTagDB; }
+   const char        *GetDBName() const { return fTagDB->GetName(); }
+   AliRawEventHeader *GetHeader() const { return fHeader; }
+   Int_t              GetEvents() const { return (Int_t) fTree->GetEntries(); }
+   Float_t            GetCompressionFactor() const;
+
+   ClassDef(AliTagDB,0)  // Tag DB
+};
+
+
+class AliTagNullDB : public AliTagDB {
+
+private:
+   const char *GetFileName();
+
+public:
+   AliTagNullDB(AliRawEventHeader *header, Double_t maxsize);
+   ~AliTagNullDB() { Close(); }
+
+   void Close();
+
+   ClassDef(AliTagNullDB,0)   // Tag DB to /dev/null
+};
+
+
+class AliRunDB : public TObject {
+
+private:
+   TFile  *fRunDB;     // run database
+
+public:
+   AliRunDB();
+   ~AliRunDB() { Close(); }
+
+   void Update(AliStats *stats);
+   void UpdateRDBMS(AliStats *stats);
+   void Close();
+
+   ClassDef(AliRunDB,0)  // Run (bookkeeping) DB
+};
+
+
+class AliMDC : public TObject {
+
+private:
+   Int_t     fFd;          // DATE input stream
+   Int_t     fCompress;    // compression factor used for raw output DB
+   Int_t     fNumEvents;   // number of events processed
+   Int_t     fDebugLevel;  // controls debug print-out
+   Double_t  fMaxFileSize; // maximum size of raw output DB
+   Bool_t    fUseFifo;     // read from fifo, file otherwise
+   Bool_t    fUseEb;       // use event builder API instead of fifo
+   Bool_t    fUseFilter;   // use 3rd level trigger filter
+   Bool_t    fUseRFIO;     // write directly to RFIO file
+   Bool_t    fUseRootd;    // write directly to rootd file
+   Bool_t    fUseDevNull;  // write to /dev/null
+   Bool_t    fUseLoop;     // loop on input source (must be file)
+   Bool_t    fStopLoop;    // break from endless loop (triggered by SIGUSR1)
+
+   static Bool_t fgDeleteFiles;
+
+   Int_t     Read(const char *name) { return TObject::Read(name); }
+   Int_t     Read(void *buffer, Int_t length);
+   Int_t     ReadHeader(AliRawEventHeader &header, void *eb = 0);
+   Int_t     ReadEquipmentHeader(AliRawEquipmentHeader &header,
+                                 Bool_t isSwapped, void *eb = 0);
+   Int_t     ReadRawData(AliRawData &raw, Int_t size, void *eb = 0);
+   Int_t     DumpEvent(Int_t toRead);
+   Int_t     Filter(AliRawData &raw);
+
+public:
+   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);
+   ~AliMDC() { }
+
+   Int_t  Run();
+   void   SetStopLoop() { fStopLoop = kTRUE; }
+   Bool_t StopLoop() const { return fStopLoop; }
+
+   void   SetDebugLevel(Int_t level) { fDebugLevel = level; }
+   Bool_t GetDebugLevel() const { return fDebugLevel; }
+
+   static Bool_t DeleteFiles() { return fgDeleteFiles; }
+
+   ClassDef(AliMDC,0)  // MDC processor
+};
+
+R__EXTERN AliMDC *gAliMDC;
+
+#define ALIDEBUG(level) \
+   if (gAliMDC && gAliMDC->GetDebugLevel() >= (level))
+
+#endif
diff --git a/RAW/DateEvent.h b/RAW/DateEvent.h
new file mode 100644 (file)
index 0000000..7f33930
--- /dev/null
@@ -0,0 +1,377 @@
+/****************************************************************************
+ *
+ * event.h: DATE event data format
+ *
+ * Revision History:
+ *    V01.00  RD PVV    09-Jan-97 Initial version
+ *    V01.01  AV        24-Feb-97 Added START_OF_RUN_FILES and triggerNb
+ *    V02.02  RD        13-Mar-97 Detector ID mask type added
+ *    V02.03  PVV       20-Mar-97 Detector ID on 128 bits
+ *    V02.03  RD PVV    20-Mar-97 Added EVENT_DATA_TRUNCATED
+ *    V02.04  PVV       06-May-97 Added EVENT_TYPE_MASK
+ *    V02.05  RD PVV    09-May-97 Increase EVENT_DATA_MAX_SIZE to 50 K
+ *    V02.06  WB MG     22-May-97 Added END_OF_RUN_FILES
+ *    V02.07  WB        23-May-97 Added errorCode, deadTime, deadTimeusec
+ *                                EVENT_DATA_MAX_SIZE set to 100 * 1024
+ *                                MAX_DETECTORS set to 126
+ *    V02.08  PVV       02-Jun-97 Modify the encoding of types
+ *    V02.09  WB RD PVV 28-Jul-98 Add fileSeqNb in the header.
+ *                                Reduce detector mask to 3 long
+ *    V02.10  RD        31-Jul-98 (start|end)OfRunFiles added to eventType
+ *    V02.11  PVV RD    02-Sep-98 Event type re-numbered
+ *                                Equipment bit added to event type
+ *    V02.12  AV PVV RD 03-Sep-98 FileSeqNo moved before detectorId
+ *    V02.13  RD        08-Oct-98 32 bits fields defined as long32
+ *    V02.13  RD        19-Feb-99 Endianness/swap definitions added
+ *    V02.14  WB PVV RD 21-Jun-99 typeAttribute added
+ *    V02.15  RD        27-Jul-99 Macros for typeAttribute handling added
+ *    V02.16  RD        19-Nov-99 Bug in Attributes test/set fixed
+ *    V02.17  WB PVV RD 08-May-00 System attributes for SOR and EOR added
+ *    V02.18  RD        18-May-00 EVENT_H_ID added
+ *    V02.19  RD        10-Aug-00 Macros for detectorId handling added
+ *    V03.00  RD        23-Nov-00 Version for DATE V4
+ *
+ * Preprocessor definitions:
+ *  NDEBUG  Define BEFORE including this file to disable run-time checks on
+ *          various parameters
+ *
+ * Related facilities:
+ *  validateEvent.c  Validation program, should be run after EACH change to
+ *                   the definitions given here below
+ ***************************************************************************/
+#ifndef __event_h__
+#define __event_h__
+
+#define EVENT_MAJOR_VERSION_NUMBER 0x0003
+#define EVENT_MINOR_VERSION_NUMBER 0x0000
+
+/* ========== System includes ========= */
+#include <string.h> /* Needed by: memset, memcpy */
+#include <assert.h> /* Needed by: assert */
+
+/* ========== Definitions for the event header ========== */
+
+/* ---------- Header base size ---------- */
+/* This value must be updated for each change in the eventHeaderStruct */
+#define EVENT_HEAD_BASE_SIZE 64
+
+/* ---------- Event size ---------- */
+typedef unsigned long32 eventSizeType;
+
+/* ---------- Magic signature and its byte-swapped version ---------- */
+#define EVENT_MAGIC_NUMBER         ((eventMagicType)0xDA1E5AFE)
+#define EVENT_MAGIC_NUMBER_SWAPPED ((eventMagicType)0xFE5A1EDA)
+typedef unsigned long32 eventMagicType;
+
+/* ---------- Header size ---------- */
+typedef unsigned long32 eventHeadSizeType;
+
+/* ---------- Unique version identifier ---------- */
+#define EVENT_CURRENT_VERSION \
+  (((EVENT_MAJOR_VERSION_NUMBER<<16)&0xffff0000)|\
+   (EVENT_MINOR_VERSION_NUMBER&0x0000ffff))
+typedef unsigned long32 eventVersionType;
+
+/* ---------- Event type ---------- */
+typedef unsigned long32 eventTypeType;
+#define START_OF_RUN         ((eventTypeType)1)
+#define END_OF_RUN           ((eventTypeType)2)
+#define START_OF_RUN_FILES   ((eventTypeType)3)
+#define END_OF_RUN_FILES     ((eventTypeType)4)
+#define START_OF_BURST       ((eventTypeType)5)
+#define END_OF_BURST         ((eventTypeType)6)
+#define PHYSICS_EVENT        ((eventTypeType)7)
+#define CALIBRATION_EVENT    ((eventTypeType)8)
+#define EVENT_FORMAT_ERROR   ((eventTypeType)9)
+#define EVENT_TYPE_MIN       1
+#define EVENT_TYPE_MAX       9
+enum eventTypeEnum {
+  startOfRun =       START_OF_RUN,
+  endOfRun =         END_OF_RUN,
+  startOfRunFiles =  START_OF_RUN_FILES,
+  endOfRunFiles =    END_OF_RUN_FILES,
+  startOfBurst =     START_OF_BURST,
+  endOfBurst =       END_OF_BURST,
+  physicsEvent =     PHYSICS_EVENT,
+  calibrationEvent = CALIBRATION_EVENT,
+  formatError =      EVENT_FORMAT_ERROR
+};
+#define EVENT_TYPE_OK(t) (((t) >= EVENT_TYPE_MIN) && (((t) <= EVENT_TYPE_MAX)))
+
+/* ---------- Run number ---------- */
+typedef unsigned long32 eventRunNbType;
+
+/* ---------- The eventId field ---------- */
+#define EVENT_ID_BYTES 8
+#define EVENT_ID_WORDS ((EVENT_ID_BYTES) >> 2)
+typedef unsigned long32 eventIdType[EVENT_ID_WORDS];
+
+   /* PERIOD - ORBIT - BUNCH crossing type events */
+#define EVENT_ID_MAX_PERIOD         0x0fffffff
+#define EVENT_ID_MAX_ORBIT          0x00ffffff
+#define EVENT_ID_MAX_BUNCH_CROSSING 0x00000fff
+#define LOAD_EVENT_ID(id,s,o,bc)       \
+  (EVENT_ID_SET_PERIOD(id,s),          \
+   EVENT_ID_SET_ORBIT(id,o),           \
+   EVENT_ID_SET_BUNCH_CROSSING(id,bc))
+#define EVENT_ID_GET_BUNCH_CROSSING(id) ((id)[1]&0x00000fff)
+#define EVENT_ID_GET_ORBIT(id) \
+                     ((((id)[0]<<20)&0xf00000)|(((id)[1]>>12)&0xfffff))
+#define EVENT_ID_GET_PERIOD(id) (((id)[0]>>4)&0x0fffffff)
+
+#define EVENT_ID_SET_BUNCH_CROSSING(id,v)                \
+  (assert(((v)>=0)&&((v)<=EVENT_ID_MAX_BUNCH_CROSSING)), \
+   (id)[1]=((id)[1]&0xfffff000)|((v)&0xfff))
+#define EVENT_ID_SET_ORBIT(id,v) \
+  (assert(((v)>=0)&&((v)<=EVENT_ID_MAX_ORBIT)),           \
+   (id)[0]=(((id)[0])&0xfffffff0)|(((v)&0x00f00000)>>20), \
+   (id)[1]=(((id)[1])&0x00000fff)|(((v)&0x000fffff)<<12))
+#define EVENT_ID_SET_PERIOD(id,v)                         \
+  (assert(((v)>=0)&&((v)<=EVENT_ID_MAX_PERIOD)),          \
+   (id)[0]=(((id)[0])&0x0000000f)|(((v)&0x0fffffff)<<4))
+
+   /* RAW type event */
+#define EVENT_ID_MAX_NB_IN_RUN   0xffffffff
+#define EVENT_ID_MAX_BURST_NB    0x00000fff
+#define EVENT_ID_MAX_NB_IN_BURST 0x000fffff
+#define LOAD_RAW_EVENT_ID(id,nir,bn,nib)                     \
+  (assert(((nir)>=0) && ((nir) <= EVENT_ID_MAX_NB_IN_RUN) && \
+          ((bn)>=0)  && ((bn)<=EVENT_ID_MAX_BURST_NB) &&     \
+         ((nib)>=0) && ((nib)<=EVENT_ID_MAX_NB_IN_BURST)),  \
+   (id)[0]=nir,                                              \
+   (id)[1]=((bn<<20)&0xfff00000)|(nib&0x000fffff))
+#define EVENT_ID_SET_NB_IN_RUN(id,nir)                  \
+  (assert(((nir)>=0)&&((nir)<=EVENT_ID_MAX_NB_IN_RUN)), \
+   (id)[0]=(nir))
+#define EVENT_ID_SET_BURST_NB(id,bn)                    \
+  (assert(((bn)>=0)&&((bn)<=EVENT_ID_MAX_BURST_NB)),    \
+   (id)[1]=((id)[1]&0x000fffff)|(((bn)<<20)&0xfff00000))
+#define EVENT_ID_SET_NB_IN_BURST(id,nib)                  \
+  (assert(((nib)>=0)&&((nib)<=EVENT_ID_MAX_NB_IN_BURST)), \
+   (id)[1]=((id)[1]&0xfff00000)|((nib)&0x000fffff))
+#define EVENT_ID_GET_NB_IN_RUN(id)   ((id)[0])
+#define EVENT_ID_GET_BURST_NB(id)    (((id)[1]>>20)&0x00000fff)
+#define EVENT_ID_GET_NB_IN_BURST(id) ((id)[1]&0x000fffff)
+
+   /* All events */
+#define EQ_EVENT_ID(a,b) ((((a)[0])==((b)[0]))&&(((a)[1])==((b)[1])))
+#define GT_EVENT_ID(a,b) \
+    (((((a)[0])>((b)[0])))||((((a)[0])==((b)[0]))&&(((a)[1])>((b)[1]))))
+#define LT_EVENT_ID(a,b) \
+    ((((a)[0])<((b)[0])) || ((((a)[0])==((b)[0]))&&(((a)[1])<((b)[1]))))
+#define GE_EVENT_ID(a,b) (!LT_EVENT_ID(a,b))
+#define LE_EVENT_ID(a,b) (!GT_EVENT_ID(a,b))
+#define COPY_EVENT_ID(from,to) \
+                      memcpy((void*)to,(const void*)from,EVENT_ID_BYTES)
+#define ADD_EVENT_ID(a,b) ((a)[1]+=(b)[1],(a)[0]+=(b)[0])
+#define SUB_EVENT_ID(a,b) ((a)[1]-=(b)[1],(a)[0]-=(b)[0])
+#define ZERO_EVENT_ID(id) memset(id,0,EVENT_ID_BYTES)
+
+/* ---------- Trigger pattern (and relative masks) ---------- */
+#define EVENT_TRIGGER_PATTERN_BYTES    8
+#define EVENT_TRIGGER_PATTERN_WORDS    ((EVENT_TRIGGER_PATTERN_BYTES)>>2)
+typedef unsigned long32 eventTriggerPatternType[EVENT_TRIGGER_PATTERN_WORDS];
+#define EVENT_TRIGGER_ID_MIN           1
+#define EVENT_TRIGGER_ID_MAX           50
+#define CHECK_TRIGGER(t)               (assert(((t)>=EVENT_TRIGGER_ID_MIN) && \
+                                               ((t)<=EVENT_TRIGGER_ID_MAX)))
+#define TRIGGER_TO_BIT(t)              (1<<((t)&0x1f))
+#define TRIGGER_TO_WORD(t)             (CHECK_TRIGGER(t), (t)>>5)
+#define ZERO_TRIGGER_PATTERN(p)        memset(p,0,EVENT_TRIGGER_PATTERN_BYTES)
+#define SET_TRIGGER_IN_PATTERN(p,id)   (p)[TRIGGER_TO_WORD(id)] |= \
+                                                            TRIGGER_TO_BIT(id)
+#define CLEAR_TRIGGER_IN_PATTERN(p,id) (p)[TRIGGER_TO_WORD(id)] &= \
+                                                         ~(TRIGGER_TO_BIT(id))
+#define FLIP_TRIGGER_IN_PATTERN(p,id)  (p)[TRIGGER_TO_WORD(id)] ^= \
+                                                            TRIGGER_TO_BIT(id)
+#define TEST_TRIGGER_IN_PATTERN(p,id)  (((p)[TRIGGER_TO_WORD(id)] & \
+                                                     TRIGGER_TO_BIT(id)) != 0)
+#define TRIGGER_PATTERN_INVALID(p)     (((p)[0] & 1) == 0)
+#define TRIGGER_PATTERN_VALID(p)       (((p)[0] & 1) != 0)
+#define VALIDATE_TRIGGER_PATTERN(p)    ((p)[0] |= 1)
+#define INVALIDATE_TRIGGER_PATTERN(p)  ((p)[0] &= 0xfffffffe)
+#define COPY_TRIGGER_PATTERN(f,t)      memcpy(t,f,EVENT_TRIGGER_PATTERN_BYTES)
+#define TRIGGER_PATTERN_OK(p)          (((p)[1] & 0xfff80000) == 0)
+
+/* ---------- Detectors cluster (and relative masks) ---------- */
+#define EVENT_DETECTOR_PATTERN_BYTES 4
+#define EVENT_DETECTOR_PATTERN_WORDS (EVENT_DETECTOR_PATTERN_BYTES>>2)
+typedef unsigned long32 eventDetectorPatternType[EVENT_DETECTOR_PATTERN_WORDS];
+#define EVENT_DETECTOR_ID_MIN  1
+#define EVENT_DETECTOR_ID_MAX 24
+#define CHECK_DETECTOR(d) (assert(((d) >= EVENT_DETECTOR_ID_MIN) &&\
+                                  ((d) <= EVENT_DETECTOR_ID_MAX)))
+#define DETECTOR_TO_BIT(d)              (CHECK_DETECTOR(d), 1<<(d))
+#define ZERO_DETECTOR_PATTERN(p)        ((p)[0] = 0)
+#define SET_DETECTOR_IN_PATTERN(p,d)    ((p)[0] |= DETECTOR_TO_BIT(d))
+#define CLEAR_DETECTOR_IN_PATTERN(p,d)  ((p)[0] &= ~(DETECTOR_TO_BIT(d)))
+#define FLIP_DETECTOR_IN_PATTERN(p,d)   ((p)[0] ^= DETECTOR_TO_BIT(d))
+#define TEST_DETECTOR_IN_PATTERN(p,d)   (((p)[0] & DETECTOR_TO_BIT(d))!=0)
+#define DETECTOR_PATTERN_INVALID(p)     (((p)[0] & 1) == 0)
+#define DETECTOR_PATTERN_VALID(p)       (((p)[0] & 1) != 0)
+#define VALIDATE_DETECTOR_PATTERN(p)    ((p)[0] |= 1)
+#define INVALIDATE_DETECTOR_PATTERN(p)  ((p)[0] &= 0xfffffffe)
+#define COPY_DETECTOR_PATTERN(f,t)      ((t)[0] = (f)[0])
+#define DETECTOR_PATTERN_OK(p)          (((p)[0] & 0xfe000000) == 0)
+
+/* ---------- The sizes and positions of the typeAttribute field ---------- */
+#define ALL_ATTRIBUTE_WORDS    3
+#define ALL_ATTRIBUTE_BYTES    (ALL_ATTRIBUTE_WORDS * 4)
+#define ALL_ATTRIBUTE_BITS     (ALL_ATTRIBUTE_BYTES * 8)
+#define USER_ATTRIBUTE_WORDS   2
+#define USER_ATTRIBUTE_BYTES   (USER_ATTRIBUTE_WORDS * 4)
+#define USER_ATTRIBUTE_BITS    (USER_ATTRIBUTE_BYTES * 8)
+#define FIRST_USER_ATTRIBUTE   0
+#define LAST_USER_ATTRIBUTE    (USER_ATTRIBUTE_BITS - 1)
+#define SYSTEM_ATTRIBUTE_WORDS 1
+#define SYSTEM_ATTRIBUTE_BYTES (SYSTEM_ATTRIBUTE_WORDS * 4)
+#define SYSTEM_ATTRIBUTE_BITS  (SYSTEM_ATTRIBUTE_BYTES * 8)
+#define FIRST_SYSTEM_ATTRIBUTE USER_ATTRIBUTE_BITS
+#define LAST_SYSTEM_ATTRIBUTE  (USER_ATTRIBUTE_BITS + \
+                                 SYSTEM_ATTRIBUTE_BITS - 1)
+typedef unsigned long32 eventTypeAttributeType[ALL_ATTRIBUTE_WORDS];
+
+   /* Word and bit definitions */
+#define SYS_ATTR_2_W(b) (assert(((b)>=64)&&((b)<=95)),2)
+#define USR_ATTR_2_W(b) (assert(((b)>= 0)&&((b)<=63)),(b)>>5)
+#define ATTR_2_W(b)     (assert(((b)>= 0)&&((b)<=95)),(b)>>5)
+#define ATTR_2_B(b)     (1<<((b)&0x1f))
+
+   /* Macros to handle all attributes without distinction */
+#define RESET_ATTRIBUTES(m)      ((m)[2] = (m)[1] = (m)[0] = 0)
+#define SET_ANY_ATTRIBUTE(m,b)   (m)[ATTR_2_W(b)] |=  ATTR_2_B(b)
+#define CLEAR_ANY_ATTRIBUTE(m,b) (m)[ATTR_2_W(b)] &= ~(ATTR_2_B(b))
+#define FLIP_ANY_ATTRIBUTE(m,b)  (m)[ATTR_2_W(b)] ^=  ATTR_2_B(b)
+#define TEST_ANY_ATTRIBUTE(m,b)  (((m)[ATTR_2_W(b)] & ATTR_2_B(b))!= 0)
+#define COPY_ALL_ATTRIBUTES( from, to )\
+      memcpy((void *)&to[0], (const void *)&from[0], ALL_ATTRIBUTE_BYTES)
+
+   /* Macros to handle SYSTEM attributes */
+#define RESET_SYSTEM_ATTRIBUTES(m)  ((m)[2] = 0)
+#define SET_SYSTEM_ATTRIBUTE(m,b)   (m)[SYS_ATTR_2_W(b)] |= ATTR_2_B(b)
+#define CLEAR_SYSTEM_ATTRIBUTE(m,b) (m)[SYS_ATTR_2_W(b)] &= ~(ATTR_2_B(b))
+#define FLIP_SYSTEM_ATTRIBUTE(m,b)  (m)[SYS_ATTR_2_W(b)] ^= ATTR_2_B(b)
+#define TEST_SYSTEM_ATTRIBUTE(m,b)  (((m)[SYS_ATTR_2_W(b)] & ATTR_2_B(b)) != 0)
+#define COPY_SYSTEM_ATTRIBUTES( from, to ) \
+   memcpy((void *)&to[2], (const void *)&from[2], SYSTEM_ATTRIBUTE_BYTES)
+
+   /* Macros to handle USER attributes */
+#define RESET_USER_ATTRIBUTES(m)  ((m)[0] = (m)[1] = 0)
+#define SET_USER_ATTRIBUTE(m,b)   (m)[USR_ATTR_2_W(b)] |= ATTR_2_B(b)
+#define CLEAR_USER_ATTRIBUTE(m,b) (m)[USR_ATTR_2_W(b)] &= ~(ATTR_2_B(b))
+#define FLIP_USER_ATTRIBUTE(m,b)  (m)[USR_ATTR_2_W(b)] ^= ATTR_2_B(b)
+#define TEST_USER_ATTRIBUTE(m,b)  (((m)[USR_ATTR_2_W(b)] & ATTR_2_B(b)) != 0)
+#define COPY_USER_ATTRIBUTES( from, to ) \
+     memcpy((void *)&to[0], (const void *)&from[0], USER_ATTRIBUTE_BYTES)
+
+   /* System attributes assignment */
+#define ATTR_P_START              64          /* Start of a phase          */
+#define ATTR_P_END                65          /* End of a phase            */
+#define ATTR_START_OF_RUN_START   ATTR_P_START/* Start of SOR phase        */
+#define ATTR_START_OF_RUN_END     ATTR_P_END  /* End of SOR phase          */
+#define ATTR_END_OF_RUN_START     ATTR_P_START/* Start of EOR phase        */
+#define ATTR_END_OF_RUN_END       ATTR_P_END  /* End of SOR phase          */
+#define ATTR_EVENT_SWAPPED        66          /* Swapped event header      */
+#define ATTR_EVENT_PAGED         67          /* Paged event               */
+#define ATTR_SUPER_EVENT          68          /* Super event               */
+#define ATTR_ORBIT_BC             69          /* Orbit/bunch crossing in ID*/
+
+#define ATTR_EVENT_DATA_TRUNCATED 94          /* Truncated payload         */
+#define ATTR_EVENT_ERROR          95          /* Invalid event content     */
+
+#define SYSTEM_ATTRIBUTES_OK(m) \
+  ((((m)[2]) & ~(ATTR_2_B(ATTR_P_START)              | \
+                 ATTR_2_B(ATTR_P_END)                | \
+                 ATTR_2_B(ATTR_EVENT_SWAPPED)        | \
+                 ATTR_2_B(ATTR_EVENT_PAGED)          | \
+                 ATTR_2_B(ATTR_SUPER_EVENT)          | \
+                 ATTR_2_B(ATTR_ORBIT_BC)             | \
+                 ATTR_2_B(ATTR_EVENT_DATA_TRUNCATED) | \
+                 ATTR_2_B(ATTR_EVENT_ERROR))) == 0)
+
+/* ---------- LDC and GDC identifier ---------- */
+typedef unsigned long32 eventHostIdType;
+typedef eventHostIdType eventLdcIdType;
+typedef eventHostIdType eventGdcIdType;
+#define HOST_ID_MIN ((eventHostIdType)0)         /* The minimum allowed ID */
+#define HOST_ID_MAX ((eventHostIdType)511)       /* The maximum allowed ID */
+#define VOID_ID     ((eventHostIdType)-1)        /* Unloaded ID            */
+
+/* ---------- The event header structure (with + without data) ---------- */
+struct eventHeaderStruct { 
+  eventSizeType             eventSize;
+  eventMagicType            eventMagic;
+  eventHeadSizeType         eventHeadSize;
+  eventVersionType          eventVersion;
+  eventTypeType             eventType;
+  eventRunNbType            eventRunNb;
+  eventIdType               eventId;
+  eventTriggerPatternType   eventTriggerPattern;
+  eventDetectorPatternType  eventDetectorPattern;
+  eventTypeAttributeType    eventTypeAttribute;
+  eventLdcIdType            eventLdcId;
+  eventGdcIdType            eventGdcId;
+};
+
+struct eventStruct {
+    struct eventHeaderStruct eventHeader;
+           unsigned short    eventRawData[1];
+};
+
+/* ========== Definitions for the Vector ========== */
+typedef short        eventVectorBankIdType;
+typedef unsigned int eventVectorSizeType;
+typedef unsigned int eventVectorOffsetType;
+
+struct eventVectorStruct {
+  eventVectorBankIdType eventVectorBankId;
+  unsigned              eventVectorPointsToVector : 1;
+  eventVectorSizeType   eventVectorSize;
+  eventVectorOffsetType eventVectorStartOffset;
+};
+
+/* ========== Definitions for the payload descriptor ========== */
+typedef        unsigned long32   eventNumEquipmentsType;
+typedef struct eventVectorStruct eventExtensionVectorType;
+
+struct vectorPayloadDescriptorStruct {
+  eventNumEquipmentsType   eventNumEquipments;
+  eventExtensionVectorType eventExtensionVector;
+};
+
+/* ========== Definitions for the equipment header ========== */
+typedef long32                 equipmentSizeType;
+typedef long32                 equipmentTypeType;
+typedef long32                 equipmentIdType;
+typedef eventTypeAttributeType equipmentTypeAttributeType;
+typedef long32                 equipmentBasicElementSizeType;
+
+struct equipmentHeaderStruct {
+  equipmentSizeType             equipmentSize;
+  equipmentTypeType             equipmentType;
+  equipmentIdType               equipmentId;
+  equipmentTypeAttributeType    equipmentTypeAttribute;
+  equipmentBasicElementSizeType equipmentBasicElementSize;
+};
+
+struct equipmentDescriptorStruct {
+  struct equipmentHeaderStruct equipmentHeader;
+  struct eventVectorStruct     equipmentVector;
+};
+
+struct equipmentStruct {
+  struct equipmentHeaderStruct equipmentHeader;
+         unsigned short        equipmentRawData[1];
+};
+
+/* ========== Global macros ========== */
+
+/* The macro PAGED_EVENT_SIZE receives in input the ADDRESS of a paged
+   event and returns the size (in bytes) of the first page of the
+   event */
+#define PAGED_EVENT_SIZE( event ) \
+  (EVENT_HEAD_BASE_SIZE +sizeof( struct vectorPayloadDescriptorStruct ) + \
+   ((*(eventNumEquipmentsType *)((void*)event+EVENT_HEAD_BASE_SIZE))* \
+     (sizeof( struct equipmentDescriptorStruct ))))
+
+#endif
diff --git a/RAW/LinkDef.h b/RAW/LinkDef.h
new file mode 100644 (file)
index 0000000..e64c85d
--- /dev/null
@@ -0,0 +1,23 @@
+#ifdef __CINT__
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ enum EAliRawEventType;
+
+#pragma link C++ class AliRawEvent;
+#pragma link C++ class AliRawEventHeader;
+#pragma link C++ class AliRawEquipmentHeader;
+#pragma link C++ class AliRawData;
+#pragma link C++ class AliStats;
+#pragma link C++ class AliRawDB;
+#pragma link C++ class AliRawRFIODB;
+#pragma link C++ class AliRawRootdDB;
+#pragma link C++ class AliRawNullDB;
+#pragma link C++ class AliTagDB;
+#pragma link C++ class AliTagNullDB;
+#pragma link C++ class AliRunDB;
+#pragma link C++ class AliMDC;
+
+#endif
diff --git a/RAW/Make-macros b/RAW/Make-macros
new file mode 100644 (file)
index 0000000..8900b55
--- /dev/null
@@ -0,0 +1,96 @@
+##### MACROS #####
+
+ROOTH         = TH1.h
+
+SRCS          = AliRawEvent.cxx
+
+HDRS          = AliRawEvent.h LinkDef.h
+
+DICT          = AliRawDict.cxx
+DICTH         = $(DICT:.cxx=.h)
+DICTO         = $(DICT:.cxx=.o)
+
+MAIN          = alimdc.cxx
+MAINO         = $(MAIN:.cxx=.o)
+
+OBJS          = $(SRCS:.cxx=.o) $(DICTO)
+
+ALLDICT       = $(DICT) $(DICTH)
+ALLSRCS       = $(SRCS) $(HDRS) $(MAIN) DateEvent.h
+ALLOBJS       = $(OBJS) $(MAINO)
+
+ALIRAW        = libAliRaw.so
+ALIMDC        = alimdc
+
+
+
+##### RULES #####
+
+.SUFFIXES: .cxx
+.PHONY: all rdm smi evb hlt debug
+
+.cxx.o:
+       $(CXX) $(OPT) $(CXXFLAGS) -c $<
+
+
+##### TARGETS #####
+
+all:            $(ALIRAW) $(ALIMDC)
+
+rdm:            $(ALIRAW) $(ALIMDC)
+
+smi:            $(ALIRAW) $(ALIMDC)
+
+evb:            $(ALIRAW) $(ALIMDC)
+
+hlt:            $(ALIRAW) $(ALIMDC)
+
+$(ALIRAW):      $(DICT) $(OBJS)
+               rm -f $(ALIRAW)
+                ifeq ($(PLATFORM),aix)
+                  $(SHLD) -o $(ALIRAW) $(LIBS) -p 0 $(OBJS)
+                else
+                   ifeq ($(PLATFORM),alpha)
+                     $(SHLD) -o $(ALIRAW) $(OBJS) -lcxxstd -lcxx -lexc -lots -lc
+                   else
+                     $(LD) $(SOFLAGS) $(LDFLAGS) $(OBJS) -o $(ALIRAW)
+                   endif
+                endif
+               chmod 555 $(ALIRAW)
+               @echo "$(ALIRAW) done"
+
+
+$(ALIMDC):      $(MAINO) $(ALIRAW)
+                ifeq ($(PLATFORM),aix)
+                  ln -fs $(ALILRAW) libAliRaw.a
+                  $(LD) $(LDFLAGS) $(MAINO) libAliRaw.a \
+                  $(LIBS) -o $(ALIMDC)
+                else
+                  $(LD) $(LDFLAGS) $(MAINO) $(ALIRAW) \
+                  $(LIBS) -o $(ALIMDC)
+                endif
+               @if [ `id -u -n` = "alicemdc" ]; then \
+                  chmod 6755 alimdc; \
+               fi
+
+$(DICT):        $(HDRS)
+               @echo "Generating dictionary ..."
+               rootcint -f $(DICT) -c $(ROOTH) $(HDRS)
+
+$(DICTO):       $(DICT)
+               $(CXX) $(NOOPT) $(CXXFLAGS) -c $(DICT)
+
+depend:
+               rmkdepend -fMake-depend -- $(CXXFLAGS) -- $(SRCS) $(MAIN) \
+               > /dev/null 2>&1
+
+dist:
+               rm -f alimdc.tar.gz ; \
+               tar cvf alimdc.tar AA* $(ALLSRCS) .rootrc *.C Make* ; \
+               gzip alimdc.tar
+
+clean:
+               @rm -f $(ALLOBJS) $(ALLDICT)
+
+distclean:      clean
+               @rm -f $(ALIMDC) $(ALIRAW)
diff --git a/RAW/Makefile b/RAW/Makefile
new file mode 100644 (file)
index 0000000..afc2a67
--- /dev/null
@@ -0,0 +1,62 @@
+# Makefile for ALICE MDC program for Linux
+
+include $(ROOTSYS)/test/Makefile.arch
+
+LDFLAGS      += -Wl,-rpath,/ROOT/Linux/CurrentRelease/root/lib \
+                -Wl,-rpath,/date/smi/linux \
+                -Wl,-rpath,/date/dim/linux \
+                -Wl,-rpath,/adcRoot/alimdc4
+
+ifneq ($(findstring rdm,$(MAKECMDGOALS)),)
+CXXFLAGS += -DUSE_RDM
+endif
+
+ifneq ($(findstring debug,$(MAKECMDGOALS)),)
+CXXFLAGS += -DUSE_DEBUG -g
+endif
+
+ifneq ($(findstring smi,$(MAKECMDGOALS)),)
+#SMIDIR    = ./smi
+#DIMDIR    = ./dim
+SMIDIR    = ../date/smi
+DIMDIR    = ../date/dim
+CXXFLAGS += -DUSE_SMI -I$(SMIDIR)/smixx -I$(DIMDIR)/dim
+LIBS     += -L$(SMIDIR)/linux -lsmiui -lsmi -L$(DIMDIR)/linux -ldim
+endif
+
+ifneq ($(findstring evb,$(MAKECMDGOALS)),)
+ifneq ($(findstring rdm,$(MAKECMDGOALS)),)
+EBDIR     = ./eb
+BMDIR     = ./eb
+DBMDIR    = ./eb
+DBDIR     = ./eb
+FIFODIR   = ./eb
+INFODIR   = ./eb
+else
+EBDIR     = ../date/eventBuilder
+BMDIR     = ../date/banksManager
+DBMDIR    = ../date/bufferManager
+DBDIR     = ../date/db
+FIFODIR   = ../date/simpleFifo
+INFODIR   = ../date/infoLogger
+endif
+CXXFLAGS += -DUSE_EB -I$(EBDIR)
+LIBS     += -L$(EBDIR)/Linux -L$(BMDIR)/Linux -L$(DBMDIR)/Linux \
+            -L$(DBDIR)/Linux -L$(FIFODIR)/Linux -L$(INFODIR)/Linux \
+            -lDateEb -lBanksManager -lDateBufferManager \
+            -lDb -lFifo -lInfo
+endif
+
+ifneq ($(findstring hlt,$(MAKECMDGOALS)),)
+CXXFLAGS += -DUSE_HLT -I$(ALITPC)
+LIBS     += -L$(ALITPC) -lSTEER -lTPC
+endif
+
+##### MACROS and TARGETS #####
+
+include Make-macros
+
+
+##### DEPENDENCIES #####
+
+include Make-depend
diff --git a/RAW/alimdc.cxx b/RAW/alimdc.cxx
new file mode 100644 (file)
index 0000000..3b63123
--- /dev/null
@@ -0,0 +1,175 @@
+// @(#)alimdc:$Name$:$Id$
+// Author: Fons Rademakers  26/11/99
+
+//////////////////////////////////////////////////////////////////////////
+//                                                                      //
+// alimdc                                                               //
+//                                                                      //
+// Main program used to create application that reads a data stream     //
+// from the DATE DAQ system and that creates a ROOT database.           //
+//                                                                      //
+// Written by: Fons Rademakers, 1/4/99.                                 //
+//                                                                      //
+//////////////////////////////////////////////////////////////////////////
+
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <fcntl.h>
+#include <errno.h>
+
+#include <TROOT.h>
+#include <TSystem.h>
+#include <TError.h>
+
+#ifdef USE_SMI
+extern "C" {
+   #include <smirtl.h>
+}
+#endif
+
+#include "AliRawEvent.h"
+
+
+#ifdef USE_SMI
+void SMI_handle_command()
+{
+   // Handle SMI commands
+
+   char action[64], param[64];
+   int n_params;
+
+   smi_get_action(action, &n_params);
+   if (n_params >= 1) {
+      smi_get_par_value("PARAM", param);
+   } else {
+      strcpy(param, "");
+   }
+   if (strcmp(action, "STOP") == 0) {
+      gAliMDC->StopLoop();
+   }
+   smi_set_state("RUNNING");
+}
+#endif
+
+//______________________________________________________________________________
+static void Usage(const char *prognam)
+{
+#ifdef USE_SMI
+      fprintf(stderr, "Usage: %s <sminame> <dbsize> <filter> <compmode> [date_file]\n",
+              prognam);
+      fprintf(stderr, " <sminame> = name used by SMI\n");
+#else
+      fprintf(stderr, "Usage: %s <dbsize> <filter> <compmode> [date_file]\n",
+              prognam);
+#endif
+      fprintf(stderr, " <dbsize> = maximum raw DB size (in bytes)\n");
+      fprintf(stderr, "    (precede by - to delete raw and tag databases on close)\n");
+      fprintf(stderr, " <filter> = state of 3rd level filter (0 or 1)\n");
+      fprintf(stderr, " <compmode> = compression level (see TFile)\n");
+      fprintf(stderr, "    (precede by - to use RFIO, -0 is RFIO and 0 compression)\n");
+      fprintf(stderr, "    (precede by + to use rootd, -0 is rootd and 0 compression)\n");
+      fprintf(stderr, "    (precede by @ to use /dev/null as sink)\n");
+#ifdef USE_EB
+      fprintf(stderr, " [date_file] = optional input file (default reads from DATE EventBuffer)\n");
+#else
+      fprintf(stderr, " [date_file] = optional input file (default reads from pipe /tmp/alimdc.fifo)\n");
+#endif
+      fprintf(stderr, "    (precede with - for endless loop on same file (use SIGUSR1 to stop)\n");
+}
+
+//______________________________________________________________________________
+int main(int argc, char **argv)
+{
+   // Convert a DATE data stream to a ROOT DB.
+
+   // Set ROOT in batch mode
+   gROOT->SetBatch();
+
+#ifdef USE_SMI
+    // Handle command line arguments
+   if ((argc == 2 && (!strcmp(argv[1], "-?") || !strcmp(argv[1], "-help"))) ||
+       argc > 6 || argc < 5) {
+      Usage(argv[0]);
+      return 1;
+   }
+
+   char smiobj[128];
+   strcpy(smiobj, argv[1]);
+   smi_attach(smiobj, SMI_handle_command);
+   smi_volatile();
+   smi_set_state("RUNNING");
+
+   for (int i = 1; i < argc-1; i++)
+      argv[i] = argv[i+1];
+   argc--;
+
+#else
+   // Handle command line arguments
+   if ((argc == 2 && (!strcmp(argv[1], "-?") || !strcmp(argv[1], "-help"))) ||
+       argc > 5 || argc < 4) {
+      Usage(argv[0]);
+      return 1;
+   }
+#endif
+
+   Bool_t   useRFIO = kFALSE, useROOTD = kFALSE, useDEVNULL = kFALSE;
+   Bool_t   useFilter = kFALSE, useLoop = kFALSE;
+   Bool_t   delFiles = kFALSE;
+   Int_t    fd = -1, compress;
+   Double_t maxFileSize;
+
+   // no special arg checking so don't make errors
+   if (argv[1][0] == '-') {
+      delFiles = kTRUE;
+      maxFileSize = atoi(argv[1]+1);
+   } else
+      maxFileSize = atoi(argv[1]);
+   if (maxFileSize < 1000 || maxFileSize > 2.e9) {
+      Error(argv[0], "unreasonable file size %f\n", maxFileSize);
+      return 1;
+   }
+
+   int filter = atoi(argv[2]);
+   if (filter != 0)
+      useFilter = kTRUE;
+
+   if (argv[3][0] == '-') {
+      useRFIO = kTRUE;
+      compress = atoi(argv[3]+1);
+   } else if (argv[3][0] == '+') {
+      useROOTD = kTRUE;
+      compress = atoi(argv[3]+1);
+   } else if (argv[3][0] == '@') {
+      useDEVNULL = kTRUE;
+      compress = atoi(argv[3]+1);
+   } else
+      compress = atoi(argv[3]);
+   if (compress > 9) {
+      Error(argv[0], "unreasonable compression mode %d\n", compress);
+      return 1;
+   }
+
+   if (argc == 5) {
+      char *file = argv[4];
+      if (argv[4][0] == '-') {
+         useLoop = kTRUE;
+         file = argv[4]+1;
+      }
+      if ((fd = open(file, O_RDONLY)) == -1) {
+         Error(argv[0], "cannot open input file %s", argv[4]);
+         return 1;
+      }
+   }
+
+   // Create MDC processor object and process input stream
+   AliMDC mdcproc(fd, compress, maxFileSize, useFilter, useRFIO, useROOTD,
+                  useDEVNULL, useLoop, delFiles);
+
+#ifdef USE_DEBUG
+   mdcproc.SetDebugLevel(3);
+#endif
+
+   return mdcproc.Run();
+}