]> git.uio.no Git - u/mrichter/AliRoot.git/blobdiff - RAW/AliRawDB.cxx
Moving from 32-bit to 64-bit return value of the file close method. Last modification...
[u/mrichter/AliRoot.git] / RAW / AliRawDB.cxx
index 28a128e5adfc010c244c1c8badb9c3a1cc56cc20..22515f0efde6d9705b317b9d967b7dbd4982736d 100644 (file)
@@ -1,4 +1,4 @@
-// @(#)alimdc:$Name$:$Id$
+// @(#)alimdc:$Name:  $:$Id$
 // Author: Fons Rademakers  26/11/99
 
 /**************************************************************************
 //////////////////////////////////////////////////////////////////////////
 
 #include <errno.h>
+#include <Riostream.h>
+
+#if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
+#include <TBufferFile.h>
+#else
+#include <TBuffer.h>
+#endif
 
 #include <TSystem.h>
+#include <TKey.h>
 
-#ifdef ALI_DATE
-#include "event.h"
-#endif
+#include <TObjString.h>
 
+#include "AliESDEvent.h"
 #include "AliRawEvent.h"
-#include "AliRawEventHeader.h"
+#include "AliRawDataArray.h"
+#include "AliRawEventHeaderBase.h"
+#include "AliRawEquipment.h"
+#include "AliRawEquipmentHeader.h"
 #include "AliStats.h"
-#include "AliMDC.h"
-
-#ifdef USE_HLT
-#include "AliESD.h"
-#endif
 
 #include "AliRawDB.h"
 
 
 ClassImp(AliRawDB)
 
+const char *AliRawDB::fgkAliRootTag = "$Rev$";
+
+// Split TPC into 9 branches in order to avoid problems with big memory
+// consumption in case of TPC events w/o zero-suppression
+Int_t AliRawDB::fgkDetBranches[AliDAQ::kNDetectors+1] = {1,1,1,18,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1};
 
 //______________________________________________________________________________
 AliRawDB::AliRawDB(AliRawEvent *event,
-#ifdef USE_HLT
-                  AliESD *esd, 
-#endif
-                  Double_t maxsize, Int_t compress,
-                   Bool_t create)
+                  AliESDEvent *esd, 
+                  Int_t compress,
+                   const char* fileName) :
+  fRawDB(NULL),
+  fTree(NULL),
+  fEvent(event),
+  fESDTree(NULL),
+  fESD(esd),
+  fCompress(compress),
+  fMaxSize(-1),
+  fFS1(""),
+  fFS2(""),
+  fDeleteFiles(kFALSE),
+  fStop(kFALSE)
 {
-   // Create a new raw DB containing at most maxsize bytes.
-
-   fEvent    = event;
-   fESD      = esd;
-   fMaxSize  = maxsize;
-   fCompress = compress;
-
-   // Consistency check with DATE header file
-#ifdef ALI_DATE
-   if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
-      Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
-      MakeZombie();
-      return;
-   }
-#endif
+   // Create a new raw DB
+
+  for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
+    fDetRawData[iDet] = new AliRawDataArray*[fgkDetBranches[iDet]];
+    Int_t nDDLsPerBranch = AliDAQ::NumberOfDdls(iDet)/fgkDetBranches[iDet];
+    for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
+      fDetRawData[iDet][iBranch] = new AliRawDataArray(nDDLsPerBranch);
+  }
 
-   if (create) {
-      if (!Create())
+  fDetRawData[AliDAQ::kNDetectors] = new AliRawDataArray*[fgkDetBranches[AliDAQ::kNDetectors]];
+  for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++)
+    fDetRawData[AliDAQ::kNDetectors][iBranch] = new AliRawDataArray(100);
+
+   if (fileName) {
+      if (!Create(fileName))
          MakeZombie();
    }
 }
 
-//______________________________________________________________________________
-AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
-{
-// copy constructor
-
-  Fatal("AliRawDB", "copy constructor not implemented");
-}
 
 //______________________________________________________________________________
-AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
-{
-// assignment operator
+AliRawDB::~AliRawDB() {
+  // Destructor
+
+  if(Close()==-1) Error("~AliRawDB", "cannot close output file!");
 
-  Fatal("operator =", "assignment operator not implemented");
-  return *this;
+  for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++) {
+    for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
+      delete fDetRawData[iDet][iBranch];
+    delete [] fDetRawData[iDet];
+  }
 }
 
 //______________________________________________________________________________
@@ -125,7 +138,7 @@ const char *AliRawDB::GetFileName() const
    static TString fname;
    static Bool_t  fstoggle = kFALSE;
 
-   TString fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
+   TString fs = fstoggle ? fFS2 : fFS1;
    TDatime dt;
 
    TString hostname = gSystem->HostName();
@@ -136,12 +149,11 @@ const char *AliRawDB::GetFileName() const
    if (!FSHasSpace(fs)) {
       while (1) {
          fstoggle = !fstoggle;
-         fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
+         fs = fstoggle ? fFS2 : fFS1;
          if (FSHasSpace(fs)) break;
          Info("GetFileName", "sleeping 30 seconds before retrying...");
          gSystem->Sleep(30000);   // sleep for 30 seconds
-         if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
-            return 0;
+         if (fStop) return 0;
       }
    }
 
@@ -157,20 +169,44 @@ const char *AliRawDB::GetFileName() const
 }
 
 //______________________________________________________________________________
-Bool_t AliRawDB::Create()
+void AliRawDB::SetFS(const char* fs1, const char* fs2)
+{
+// set the file system location
+
+  fFS1 = fs1;
+  if (fs1 && !fFS1.Contains(":")) {
+    gSystem->ResetErrno();
+    gSystem->MakeDirectory(fs1);
+    if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
+      SysError("SetFS", "mkdir %s", fs1);
+    }
+  }
+
+  fFS2 = fs2;
+  if (fs2) {
+    gSystem->ResetErrno();
+    gSystem->MakeDirectory(fs2);
+    if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
+      SysError("SetFS", "mkdir %s", fs2);
+    }
+  }
+}
+
+//______________________________________________________________________________
+Bool_t AliRawDB::Create(const char* fileName)
 {
    // Create a new raw DB.
 
-   const Int_t kMaxRetry = 200;
+   const Int_t kMaxRetry = 1;
    const Int_t kMaxSleep = 1;      // seconds
    const Int_t kMaxSleepLong = 10; // seconds
    Int_t retry = 0;
 
 again:
-   if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
-      return kFALSE;
+   if (fStop) return kFALSE;
 
-   const char *fname = GetFileName();
+   const char *fname = fileName;
+   if (!fname) fname = GetFileName();
    if (!fname) {
       Error("Create", "error getting raw DB file name");
       return kFALSE;
@@ -179,8 +215,8 @@ again:
    retry++;
 
    fRawDB = TFile::Open(fname, GetOpenOption(),
-                        Form("ALICE MDC%d raw DB", AliMDC::kMDC), fCompress,
-                        GetNetopt());
+                       Form("ALICE raw-data file (%s)", GetAliRootTag()), fCompress,
+                       GetNetopt());
    if (!fRawDB) {
       if (retry < kMaxRetry) {
          Warning("Create", "failure to open file, sleeping %d %s before retrying...",
@@ -230,8 +266,10 @@ void AliRawDB::MakeTree()
 {
    // Create ROOT Tree object container.
 
-   fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", AliMDC::kMDC));
-   fTree->SetAutoSave(2000000000);  // autosave when 2 Gbyte written
+   fTree = new TTree("RAW", Form("ALICE raw-data tree (%s)", GetAliRootTag()));
+   fTree->SetAutoSave(21000000000LL);  // autosave when 21 Gbyte written
+
+   fTree->BranchRef();
 
    Int_t bufsize = 256000;
    // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
@@ -239,46 +277,139 @@ void AliRawDB::MakeTree()
    Int_t split   = 0;
    fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
 
-#ifdef USE_HLT
+   // Make brach for each sub-detector
+   for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
+     for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
+       fTree->Branch(Form("%s%d",AliDAQ::DetectorName(iDet),iBranch),"AliRawDataArray",
+                    &fDetRawData[iDet][iBranch],bufsize,split);
+   }
+   // Make special branch for unrecognized raw-data payloads
+   for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++)
+     fTree->Branch(Form("Common%d",iBranch),"AliRawDataArray",
+                  &fDetRawData[AliDAQ::kNDetectors][iBranch],bufsize,split);
+
    // Create tree which will contain the HLT ESD information
 
-   fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", AliMDC::kMDC));
-   fESDTree->SetAutoSave(2000000000);  // autosave when 2 Gbyte written
-   split   = 99;
-   fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
-#endif
+   if (fESD) {
+     fESDTree = new TTree("esdTree", Form("ALICE HLT ESD tree (%s)", GetAliRootTag()));
+     fESDTree->SetAutoSave(21000000000LL);  // autosave when 21 Gbyte written
+     split   = 0;
+     fESDTree->Branch("ESD", "AliESDEvent", &fESD, bufsize, split);
+   }
 
 }
 
 //______________________________________________________________________________
-void AliRawDB::Close()
+Long64_t AliRawDB::Close()
 {
    // Close raw DB.
+   if (!fRawDB) return 0;
 
-   if (!fRawDB) return;
+   if (!fRawDB->IsOpen()) return 0;
 
    fRawDB->cd();
 
    // Write the tree.
-   fTree->Write();
-   fESDTree->Write();
+   Bool_t error = kFALSE;
+   if (fTree->Write() == 0)
+     error = kTRUE;
+   if (fESDTree)
+     if (fESDTree->Write() == 0)
+       error = kTRUE;
 
    // Close DB, this also deletes the fTree
    fRawDB->Close();
 
-   if (AliMDC::DeleteFiles()) {
+   Long64_t filesize = fRawDB->GetEND();
+
+   if (fDeleteFiles) {
       gSystem->Unlink(fRawDB->GetName());
       delete fRawDB;
       fRawDB = 0;
-      return;
+      if(!error)
+       return filesize;
+      else
+       return -1;
    }
 
-   // Create semaphore to say this file is finished
-   Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
-   close(tfd);
-
    delete fRawDB;
    fRawDB = 0;
+   if(!error)
+     return filesize;
+   else
+     return -1;
+}
+
+//______________________________________________________________________________
+Int_t AliRawDB::Fill()
+{
+   // Fill the trees and return the number of written bytes
+
+  for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++)
+    for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
+      fDetRawData[iDet][iBranch]->ClearData();
+
+   // Move the raw-data payloads to the corresponding branches
+  for(Int_t iSubEvent = 0; iSubEvent < fEvent->GetNSubEvents(); iSubEvent++) {
+    AliRawEvent *subEvent = fEvent->GetSubEvent(iSubEvent);
+    for(Int_t iEquipment = 0; iEquipment < subEvent->GetNEquipments(); iEquipment++) {
+      AliRawEquipment *equipment = subEvent->GetEquipment(iEquipment);
+      UInt_t eqId = equipment->GetEquipmentHeader()->GetId();
+      Int_t ddlIndex;
+      Int_t iDet = AliDAQ::DetectorIDFromDdlID(eqId,ddlIndex);
+      Int_t iBranch;
+      if (iDet < 0 || iDet > AliDAQ::kNDetectors) {
+       iDet = AliDAQ::kNDetectors;
+       iBranch = 0; // can we split somehow the unrecognized data??? For the moment - no
+      }
+      else {
+       iBranch = (ddlIndex * fgkDetBranches[iDet])/AliDAQ::NumberOfDdls(iDet);
+      }
+      equipment->SetRawDataRef(fDetRawData[iDet][iBranch]);
+    }
+  }
+
+   Double_t bytes = fRawDB->GetBytesWritten();
+   Bool_t error = kFALSE;
+   if (fTree->Fill() == -1)
+     error = kTRUE;
+   if (fESDTree) 
+     if (fESDTree->Fill() == -1)
+       error = kTRUE;
+   if(!error)
+     return Int_t(fRawDB->GetBytesWritten() - bytes);
+   else
+     return -1;
+}
+
+//______________________________________________________________________________
+Long64_t AliRawDB::GetTotalSize()
+{
+   // Return the total size of the trees
+  Long64_t total = 0;
+
+  {
+    Int_t skey = 0;
+    TDirectory *dir = fTree->GetDirectory();
+    if (dir) {
+      TKey *key = dir->GetKey(fTree->GetName());
+      if (key) skey = key->GetKeylen();
+    }
+    total += (Long64_t)skey + fTree->GetZipBytes();
+  }
+
+  if(fESDTree)
+    {
+      Int_t skey = 0;
+      TDirectory *dir = fESDTree->GetDirectory();
+      if (dir) {
+       TKey *key = dir->GetKey(fESDTree->GetName());
+       if (key) skey = key->GetKeylen();
+      }
+      total += (Long64_t)skey + fESDTree->GetZipBytes();
+    }
+
+  return total;
 }
 
 //______________________________________________________________________________
@@ -286,13 +417,13 @@ void AliRawDB::WriteStats(AliStats* stats)
 {
    // Write stats to raw DB, local run DB and global MySQL DB.
 
-   AliRawEventHeader &header = *GetEvent()->GetHeader();
+   AliRawEventHeaderBase &header = *GetEvent()->GetHeader();
 
    // Write stats into RawDB
    TDirectory *ds = gDirectory;
    GetDB()->cd();
    stats->SetEvents(GetEvents());
-   stats->SetLastId(header.GetRunNumber(), header.GetEventInRun());
+   stats->SetLastId(header.GetP("Id")[0]);
    stats->SetFileSize(GetBytesWritten());
    stats->SetCompressionFactor(GetCompressionFactor());
    stats->SetEndTime();
@@ -301,14 +432,14 @@ void AliRawDB::WriteStats(AliStats* stats)
 }
 
 //______________________________________________________________________________
-Bool_t AliRawDB::NextFile()
+Bool_t AliRawDB::NextFile(const char* fileName)
 {
    // Close te current file and open a new one.
    // Returns kFALSE in case opening failed.
 
    Close();
 
-   if (!Create()) return kFALSE;
+   if (!Create(fileName)) return kFALSE;
    return kTRUE;
 }
 
@@ -322,3 +453,53 @@ Float_t AliRawDB::GetCompressionFactor() const
    else
       return fTree->GetTotBytes()/fTree->GetZipBytes();
 }
+
+//______________________________________________________________________________
+const char *AliRawDB::GetAliRootTag()
+{
+  // Return the aliroot tag (version)
+  // used to generate the raw data file.
+  // Stored in the raw-data file title.
+
+  TString version = fgkAliRootTag;
+  version.Remove(TString::kBoth,'$');
+  version.ReplaceAll("Rev","AliRoot version");
+
+  return version.Data();
+}
+
+//______________________________________________________________________________
+Bool_t AliRawDB::WriteGuidFile(TString &guidFileFolder)
+{
+  // Write the guid file
+  // in the specified folder or
+  // in the folder where the raw data
+  // file is.
+
+   TString guidFileName;
+   if (!guidFileFolder.IsNull()) {
+     guidFileName = guidFileFolder;
+
+     TString pathStr = fRawDB->GetName();
+     TObjArray *pathArr = pathStr.Tokenize('/');
+     guidFileName.Append("/");
+     guidFileName.Append(((TObjString *)pathArr->Last())->String());
+     pathArr->Delete();
+     delete pathArr;
+   }
+   else
+     guidFileName = fRawDB->GetName();
+
+   guidFileName += ".guid";
+
+   ofstream fguid(guidFileName.Data());
+   if (!fguid.is_open()) {
+     Error("WriteGuidFile", "failure to open guid file %s", guidFileName.Data());
+     return kFALSE;
+   }
+   TString guid = fRawDB->GetUUID().AsString();
+   fguid << "guid: \t" << guid.Data();
+   fguid.close();
+
+   return kTRUE;
+}