-// @(#)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 "AliRawEvent.h"
-#include "AliRawEventHeader.h"
-#include "AliStats.h"
-#include "AliMDC.h"
+#include <TBranch.h>
-#ifdef USE_HLT
-#include "AliESD.h"
-#endif
+#include "AliESDEvent.h"
+#include "AliRawEventV2.h"
+#include "AliRawDataArrayV2.h"
+#include "AliRawEventHeaderBase.h"
+#include "AliRawEquipmentHeader.h"
#include "AliRawDB.h"
ClassImp(AliRawDB)
+const char *AliRawDB::fgkAliRootTag = "$Rev$";
+
+// Split TPC into 18 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,10,1};
//______________________________________________________________________________
-AliRawDB::AliRawDB(AliRawEvent *event,
-#ifdef USE_HLT
- AliESD *esd,
-#endif
- Double_t maxsize, Int_t compress,
- Bool_t create)
+AliRawDB::AliRawDB(AliRawEventV2 *event,
+ AliESDEvent *esd,
+ Int_t compress,
+ const char* fileName,
+ Int_t basketsize) :
+ fRawDB(NULL),
+ fTree(NULL),
+ fEvent(event),
+ fESDTree(NULL),
+ fESD(esd),
+ fCompress(compress),
+ fBasketSize(basketsize),
+ fMaxSize(-1),
+ fFS1(""),
+ fFS2(""),
+ fDeleteFiles(kFALSE),
+ fStop(kFALSE)
{
- // Create a new raw DB containing at most maxsize bytes.
+ // Create a new raw DB
- fEvent = event;
-#ifdef USE_HLT
- fESD = esd;
-#endif
- 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
+ for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
+ fDetRawData[iDet] = new AliRawDataArrayV2*[fgkDetBranches[iDet]];
+ Int_t nDDLsPerBranch = AliDAQ::NumberOfDdls(iDet)/fgkDetBranches[iDet];
+ for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
+ fDetRawData[iDet][iBranch] = new AliRawDataArrayV2(nDDLsPerBranch);
+ }
+
+ fDetRawData[AliDAQ::kNDetectors] = new AliRawDataArrayV2*[fgkDetBranches[AliDAQ::kNDetectors]];
+ for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++)
+ fDetRawData[AliDAQ::kNDetectors][iBranch] = new AliRawDataArrayV2(100);
- if (create) {
- if (!Create())
+ 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
- Fatal("operator =", "assignment operator not implemented");
- return *this;
+ if(Close()==-1) Error("~AliRawDB", "cannot close output file!");
+
+ 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];
+ }
}
//______________________________________________________________________________
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();
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;
}
}
}
//______________________________________________________________________________
-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;
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...",
return kFALSE;
}
- // Create raw data TTree
- MakeTree();
-
return kTRUE;
}
+static void BranchResetBit(TBranch *b)
+{
+ // Reset MapObject on this branch and all the sub-branches
+
+ b->ResetBit( kBranchObject | kBranchAny ); // Or in newer ROOT: b->ResetBit( kMapObject )
+ TIter next( b->GetListOfBranches() );
+ TBranch *sub = 0;
+ while ( (sub = (TBranch*)next() ) ) {
+ BranchResetBit( sub );
+ }
+}
+
//______________________________________________________________________________
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
- 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);
+ fTree->BranchRef();
+
+ Int_t split = 99;
+ TBranch *b = fTree->Branch("rawevent", "AliRawEventV2", &fEvent, fBasketSize, split);
+ BranchResetBit(b);
+
+ // Make brach for each sub-detector
+ for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
+ for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++) {
+ b = fTree->Branch(Form("%s%d",AliDAQ::DetectorName(iDet),iBranch),"AliRawDataArrayV2",
+ &fDetRawData[iDet][iBranch],fBasketSize,split);
+ BranchResetBit(b);
+ }
+ }
+ // Make special branch for unrecognized raw-data payloads
+ for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++) {
+ b = fTree->Branch(Form("Common%d",iBranch),"AliRawDataArrayV2",
+ &fDetRawData[AliDAQ::kNDetectors][iBranch],fBasketSize,split);
+ BranchResetBit(b);
+ }
-#ifdef USE_HLT
// 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, fBasketSize, 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();
-#ifdef USE_HLT
- fESDTree->Write();
-#endif
+ Bool_t error = kFALSE;
+ if (fTree)
+ 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()) {
+ fTree = NULL;
+
+ 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
+
+ // Create raw data TTree if it not yet done
+ if (!fTree) MakeTree();
+
+ 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;
+
+ if (fTree) {
+ 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;
}
//______________________________________________________________________________
-void AliRawDB::WriteStats(AliStats* stats)
+Long64_t AliRawDB::AutoSave()
{
- // Write stats to raw DB, local run DB and global MySQL DB.
-
- AliRawEventHeader &header = *GetEvent()->GetHeader();
-
- // Write stats into RawDB
- TDirectory *ds = gDirectory;
- GetDB()->cd();
- stats->SetEvents(GetEvents());
- stats->SetLastId(header.GetRunNumber(), header.GetEventInRun());
- stats->SetFileSize(GetBytesWritten());
- stats->SetCompressionFactor(GetCompressionFactor());
- stats->SetEndTime();
- stats->Write("stats");
- ds->cd();
+ // Auto-save the raw-data and
+ // esd (if any) trees
+
+ Long64_t nbytes = fTree->AutoSave();
+
+ if (fESDTree) nbytes += fESDTree->AutoSave();
+
+ return nbytes;
}
//______________________________________________________________________________
-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;
}
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.
+
+ static 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;
+}
+
+
+//______________________________________________________________________________
+void AliRawDB::Reset()
+{
+ // Clear the raw-data arrays
+ // Should be done before processing the raw-data event
+
+ for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++)
+ for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
+ fDetRawData[iDet][iBranch]->ClearData();
+}
+
+//______________________________________________________________________________
+AliRawDataArrayV2 *AliRawDB::GetRawDataArray(UInt_t eqSize, UInt_t eqId) const
+{
+ // Return the corresponding raw-datra array (branch)
+ // depending on the equipment ID
+
+ Int_t iDet = AliDAQ::kNDetectors;
+ Int_t iBranch = 0; // can we split somehow the unrecognized data??? For the moment - no
+ if(eqSize) {
+ Int_t ddlIndex = -1;
+ iDet = AliDAQ::DetectorIDFromDdlID(eqId,ddlIndex);
+ if (iDet < 0 || iDet >= AliDAQ::kNDetectors)
+ iDet = AliDAQ::kNDetectors;
+ else
+ iBranch = (ddlIndex * fgkDetBranches[iDet])/AliDAQ::NumberOfDdls(iDet);
+ }
+
+ return fDetRawData[iDet][iBranch];
+}
+