1 // @(#)alimdc:$Name: $:$Id$
2 // Author: Fons Rademakers 26/11/99
4 /**************************************************************************
5 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
7 * Author: The ALICE Off-line Project. *
8 * Contributors are mentioned in the code where appropriate. *
10 * Permission to use, copy, modify and distribute this software and its *
11 * documentation strictly for non-commercial purposes is hereby granted *
12 * without fee, provided that the above copyright notice appears in all *
13 * copies and that both the copyright notice and this permission notice *
14 * appear in the supporting documentation. The authors make no claims *
15 * about the suitability of this software for any purpose. It is *
16 * provided "as is" without express or implied warranty. *
17 **************************************************************************/
19 //////////////////////////////////////////////////////////////////////////
23 //////////////////////////////////////////////////////////////////////////
26 #include <Riostream.h>
29 #if ROOT_VERSION_CODE >= ROOT_VERSION(5,15,0)
30 #include <TBufferFile.h>
38 #include <TObjString.h>
42 #include "AliESDEvent.h"
43 #include "AliRawEventV2.h"
44 #include "AliRawDataArrayV2.h"
45 #include "AliRawEventHeaderBase.h"
46 #include "AliRawEquipmentHeader.h"
54 const char *AliRawDB::fgkAliRootTag = "$Rev$";
56 // Split TPC into 18 branches in order to avoid problems with big memory
57 // consumption in case of TPC events w/o zero-suppression
58 Int_t AliRawDB::fgkDetBranches[AliDAQ::kNDetectors+1] = {
85 //______________________________________________________________________________
86 AliRawDB::AliRawDB(AliRawEventV2 *event,
97 fBasketSize(basketsize),
101 fDeleteFiles(kFALSE),
104 // Create a new raw DB
106 for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
107 fDetRawData[iDet] = new AliRawDataArrayV2*[fgkDetBranches[iDet]];
108 Int_t nDDLsPerBranch = AliDAQ::NumberOfDdls(iDet)/fgkDetBranches[iDet];
109 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
110 fDetRawData[iDet][iBranch] = new AliRawDataArrayV2(nDDLsPerBranch);
113 fDetRawData[AliDAQ::kNDetectors] = new AliRawDataArrayV2*[fgkDetBranches[AliDAQ::kNDetectors]];
114 for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++)
115 fDetRawData[AliDAQ::kNDetectors][iBranch] = new AliRawDataArrayV2(100);
118 if (!Create(fileName))
124 //______________________________________________________________________________
125 AliRawDB::~AliRawDB() {
128 if(Close()==-1) Error("~AliRawDB", "cannot close output file!");
130 for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++) {
131 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
132 delete fDetRawData[iDet][iBranch];
133 delete [] fDetRawData[iDet];
137 //______________________________________________________________________________
138 Bool_t AliRawDB::FSHasSpace(const char *fs) const
140 // Check for at least fMaxSize bytes of free space on the file system.
141 // If the space is not available return kFALSE, kTRUE otherwise.
143 Long_t id, bsize, blocks, bfree;
145 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
146 Error("FSHasSpace", "could not stat file system %s", fs);
150 // Leave 5 percent of diskspace free
151 Double_t avail = Double_t(bfree) * 0.95;
152 if (avail*bsize > fMaxSize)
155 Warning("FSHasSpace", "no space on file system %s", fs);
159 //______________________________________________________________________________
160 const char *AliRawDB::GetFileName() const
162 // Return filename based on hostname and date and time. This will make
163 // each file unique. Also makes sure (via FSHasSpace()) that there is
164 // enough space on the file system to store the file. Returns 0 in
165 // case of error or interrupt signal.
167 static TString fname;
168 static Bool_t fstoggle = kFALSE;
170 TString fs = fstoggle ? fFS2 : fFS1;
173 TString hostname = gSystem->HostName();
175 if ((pos = hostname.Index(".")) != kNPOS)
176 hostname.Remove(pos);
178 if (!FSHasSpace(fs)) {
180 fstoggle = !fstoggle;
181 fs = fstoggle ? fFS2 : fFS1;
182 if (FSHasSpace(fs)) break;
183 Info("GetFileName", "sleeping 30 seconds before retrying...");
184 gSystem->Sleep(30000); // sleep for 30 seconds
189 fname = fs + "/" + hostname + "_";
190 fname += dt.GetDate();
192 fname += dt.GetTime();
195 fstoggle = !fstoggle;
200 //______________________________________________________________________________
201 void AliRawDB::SetFS(const char* fs1, const char* fs2)
203 // set the file system location
206 if (fs1 && !fFS1.Contains(":")) {
207 gSystem->ResetErrno();
208 gSystem->MakeDirectory(fs1);
209 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
210 SysError("SetFS", "mkdir %s", fs1);
216 gSystem->ResetErrno();
217 gSystem->MakeDirectory(fs2);
218 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
219 SysError("SetFS", "mkdir %s", fs2);
224 //______________________________________________________________________________
225 Bool_t AliRawDB::Create(const char* fileName)
227 // Create a new raw DB.
229 const Int_t kMaxRetry = 1;
230 const Int_t kMaxSleep = 1; // seconds
231 const Int_t kMaxSleepLong = 10; // seconds
235 if (fStop) return kFALSE;
237 const char *fname = fileName;
238 if (!fname) fname = GetFileName();
240 Error("Create", "error getting raw DB file name");
246 fRawDB = TFile::Open(fname, GetOpenOption(),
247 Form("ALICE raw-data file (%s)", GetAliRootTag()), fCompress,
250 if (retry < kMaxRetry) {
251 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
252 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
253 gSystem->Sleep(kMaxSleep*1000);
256 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
260 Warning("Create", "succeeded to open file after %d retries", retry);
262 if (fRawDB->IsZombie()) {
263 if (fRawDB->GetErrno() == ENOSPC ||
264 fRawDB->GetErrno() == 1018 || // SECOMERR
265 fRawDB->GetErrno() == 1027) { // SESYSERR
266 fRawDB->ResetErrno();
268 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
269 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
270 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
273 Error("Create", "file %s is zombie", fname);
274 fRawDB->ResetErrno();
277 if (retry < kMaxRetry) {
278 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
279 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
280 gSystem->Sleep(kMaxSleep*1000);
283 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
290 static void BranchResetBit(TBranch *b)
292 // Reset MapObject on this branch and all the sub-branches
294 b->ResetBit( kBranchObject | kBranchAny ); // Or in newer ROOT: b->ResetBit( kMapObject )
295 TIter next( b->GetListOfBranches() );
297 while ( (sub = (TBranch*)next() ) ) {
298 BranchResetBit( sub );
302 //______________________________________________________________________________
303 void AliRawDB::MakeTree()
305 // Create ROOT Tree object container.
307 fTree = new TTree("RAW", Form("ALICE raw-data tree (%s)", GetAliRootTag()));
308 fTree->SetAutoSave(21000000000LL); // autosave when 21 Gbyte written
313 TBranch *b = fTree->Branch("rawevent", "AliRawEventV2", &fEvent, fBasketSize, split);
316 // Make brach for each sub-detector
317 for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
318 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++) {
319 b = fTree->Branch(Form("%s%d",AliDAQ::DetectorName(iDet),iBranch),"AliRawDataArrayV2",
320 &fDetRawData[iDet][iBranch],fBasketSize,split);
324 // Make special branch for unrecognized raw-data payloads
325 for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++) {
326 b = fTree->Branch(Form("Common%d",iBranch),"AliRawDataArrayV2",
327 &fDetRawData[AliDAQ::kNDetectors][iBranch],fBasketSize,split);
331 // Create tree which will contain the HLT ESD information
334 fESDTree = new TTree("esdTree", Form("ALICE HLT ESD tree (%s)", GetAliRootTag()));
335 fESDTree->SetAutoSave(21000000000LL); // autosave when 21 Gbyte written
337 fESDTree->Branch("ESD", "AliESDEvent", &fESD, fBasketSize, split);
342 //______________________________________________________________________________
343 Long64_t AliRawDB::Close()
346 if (!fRawDB) return 0;
348 if (!fRawDB->IsOpen()) return 0;
353 Bool_t error = kFALSE;
355 if (fTree->Write() == 0)
358 if (fESDTree->Write() == 0)
361 // Close DB, this also deletes the fTree
366 Long64_t filesize = fRawDB->GetEND();
369 gSystem->Unlink(fRawDB->GetName());
386 //______________________________________________________________________________
387 Int_t AliRawDB::Fill()
389 // Fill the trees and return the number of written bytes
391 // Create raw data TTree if it not yet done
392 if (!fTree) MakeTree();
394 Double_t bytes = fRawDB->GetBytesWritten();
395 Bool_t error = kFALSE;
396 if (fTree->Fill() == -1)
399 if (fESDTree->Fill() == -1)
402 return Int_t(fRawDB->GetBytesWritten() - bytes);
407 //______________________________________________________________________________
408 Long64_t AliRawDB::GetTotalSize()
410 // Return the total size of the trees
415 TDirectory *dir = fTree->GetDirectory();
417 TKey *key = dir->GetKey(fTree->GetName());
418 if (key) skey = key->GetKeylen();
420 total += (Long64_t)skey + fTree->GetZipBytes();
426 TDirectory *dir = fESDTree->GetDirectory();
428 TKey *key = dir->GetKey(fESDTree->GetName());
429 if (key) skey = key->GetKeylen();
431 total += (Long64_t)skey + fESDTree->GetZipBytes();
437 //______________________________________________________________________________
438 Long64_t AliRawDB::AutoSave()
440 // Auto-save the raw-data and
441 // esd (if any) trees
443 Long64_t nbytes = fTree->AutoSave();
445 if (fESDTree) nbytes += fESDTree->AutoSave();
450 //______________________________________________________________________________
451 Bool_t AliRawDB::NextFile(const char* fileName)
453 // Close te current file and open a new one.
454 // Returns kFALSE in case opening failed.
458 if (!Create(fileName)) return kFALSE;
462 //______________________________________________________________________________
463 Float_t AliRawDB::GetCompressionFactor() const
465 // Return compression factor.
467 if (fTree->GetZipBytes() == 0.)
470 return fTree->GetTotBytes()/fTree->GetZipBytes();
473 //______________________________________________________________________________
474 const char *AliRawDB::GetAliRootTag()
476 // Return the aliroot tag (version)
477 // used to generate the raw data file.
478 // Stored in the raw-data file title.
480 static TString version = fgkAliRootTag;
481 version.Remove(TString::kBoth,'$');
482 version.ReplaceAll("Rev","AliRoot version");
484 return version.Data();
487 //______________________________________________________________________________
488 Bool_t AliRawDB::WriteGuidFile(TString &guidFileFolder)
490 // Write the guid file
491 // in the specified folder or
492 // in the folder where the raw data
495 TString guidFileName;
496 if (!guidFileFolder.IsNull()) {
497 guidFileName = guidFileFolder;
499 TString pathStr = fRawDB->GetName();
500 TObjArray *pathArr = pathStr.Tokenize('/');
501 guidFileName.Append("/");
502 guidFileName.Append(((TObjString *)pathArr->Last())->String());
507 guidFileName = fRawDB->GetName();
509 guidFileName += ".guid";
511 ofstream fguid(guidFileName.Data());
512 if (!fguid.is_open()) {
513 Error("WriteGuidFile", "failure to open guid file %s", guidFileName.Data());
516 TString guid = fRawDB->GetUUID().AsString();
517 fguid << "guid: \t" << guid.Data();
524 //______________________________________________________________________________
525 void AliRawDB::Reset()
527 // Clear the raw-data arrays
528 // Should be done before processing the raw-data event
530 for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++)
531 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
532 fDetRawData[iDet][iBranch]->ClearData();
535 //______________________________________________________________________________
536 AliRawDataArrayV2 *AliRawDB::GetRawDataArray(UInt_t eqSize, UInt_t eqId) const
538 // Return the corresponding raw-datra array (branch)
539 // depending on the equipment ID
541 Int_t iDet = AliDAQ::kNDetectors;
542 Int_t iBranch = 0; // can we split somehow the unrecognized data??? For the moment - no
545 iDet = AliDAQ::DetectorIDFromDdlID(eqId,ddlIndex);
546 if (iDet < 0 || iDet >= AliDAQ::kNDetectors)
547 iDet = AliDAQ::kNDetectors;
549 iBranch = (ddlIndex * fgkDetBranches[iDet])/AliDAQ::NumberOfDdls(iDet);
552 return fDetRawData[iDet][iBranch];