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 //////////////////////////////////////////////////////////////////////////
33 #include "AliRawEvent.h"
34 #include "AliRawEventHeader.h"
43 //______________________________________________________________________________
44 AliRawDB::AliRawDB(AliRawEvent *event,
47 const char* fileName) :
60 // Create a new raw DB
62 // Consistency check with DATE header file
64 if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
65 Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
72 if (!Create(fileName))
77 //______________________________________________________________________________
78 AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
82 Fatal("AliRawDB", "copy constructor not implemented");
85 //______________________________________________________________________________
86 AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
88 // assignment operator
90 Fatal("operator =", "assignment operator not implemented");
94 //______________________________________________________________________________
95 Bool_t AliRawDB::FSHasSpace(const char *fs) const
97 // Check for at least fMaxSize bytes of free space on the file system.
98 // If the space is not available return kFALSE, kTRUE otherwise.
100 Long_t id, bsize, blocks, bfree;
102 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
103 Error("FSHasSpace", "could not stat file system %s", fs);
107 // Leave 5 percent of diskspace free
108 Double_t avail = Double_t(bfree) * 0.95;
109 if (avail*bsize > fMaxSize)
112 Warning("FSHasSpace", "no space on file system %s", fs);
116 //______________________________________________________________________________
117 const char *AliRawDB::GetFileName() const
119 // Return filename based on hostname and date and time. This will make
120 // each file unique. Also makes sure (via FSHasSpace()) that there is
121 // enough space on the file system to store the file. Returns 0 in
122 // case of error or interrupt signal.
124 static TString fname;
125 static Bool_t fstoggle = kFALSE;
127 TString fs = fstoggle ? fFS2 : fFS1;
130 TString hostname = gSystem->HostName();
132 if ((pos = hostname.Index(".")) != kNPOS)
133 hostname.Remove(pos);
135 if (!FSHasSpace(fs)) {
137 fstoggle = !fstoggle;
138 fs = fstoggle ? fFS2 : fFS1;
139 if (FSHasSpace(fs)) break;
140 Info("GetFileName", "sleeping 30 seconds before retrying...");
141 gSystem->Sleep(30000); // sleep for 30 seconds
146 fname = fs + "/" + hostname + "_";
147 fname += dt.GetDate();
149 fname += dt.GetTime();
152 fstoggle = !fstoggle;
157 //______________________________________________________________________________
158 void AliRawDB::SetFS(const char* fs1, const char* fs2)
160 // set the file system location
163 if (fs1 && !fFS1.Contains(":")) {
164 gSystem->ResetErrno();
165 gSystem->MakeDirectory(fs1);
166 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
167 SysError("SetFS", "mkdir %s", fs1);
173 gSystem->ResetErrno();
174 gSystem->MakeDirectory(fs2);
175 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
176 SysError("SetFS", "mkdir %s", fs2);
181 //______________________________________________________________________________
182 Bool_t AliRawDB::Create(const char* fileName)
184 // Create a new raw DB.
186 const Int_t kMaxRetry = 200;
187 const Int_t kMaxSleep = 1; // seconds
188 const Int_t kMaxSleepLong = 10; // seconds
192 if (fStop) return kFALSE;
194 const char *fname = fileName;
195 if (!fname) fname = GetFileName();
197 Error("Create", "error getting raw DB file name");
203 fRawDB = TFile::Open(fname, GetOpenOption(),
204 Form("ALICE MDC%d raw DB", kMDC), fCompress,
207 if (retry < kMaxRetry) {
208 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
209 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
210 gSystem->Sleep(kMaxSleep*1000);
213 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
217 Warning("Create", "succeeded to open file after %d retries", retry);
219 if (fRawDB->IsZombie()) {
220 if (fRawDB->GetErrno() == ENOSPC ||
221 fRawDB->GetErrno() == 1018 || // SECOMERR
222 fRawDB->GetErrno() == 1027) { // SESYSERR
223 fRawDB->ResetErrno();
225 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
226 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
227 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
230 Error("Create", "file %s is zombie", fname);
231 fRawDB->ResetErrno();
234 if (retry < kMaxRetry) {
235 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
236 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
237 gSystem->Sleep(kMaxSleep*1000);
240 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
244 // Create raw data TTree
250 //______________________________________________________________________________
251 void AliRawDB::MakeTree()
253 // Create ROOT Tree object container.
255 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", kMDC));
256 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
258 Int_t bufsize = 256000;
259 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
262 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
264 // Create tree which will contain the HLT ESD information
267 fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", kMDC));
268 fESDTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
270 fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
275 //______________________________________________________________________________
276 void AliRawDB::Close()
286 if (fESDTree) fESDTree->Write();
288 // Close DB, this also deletes the fTree
292 gSystem->Unlink(fRawDB->GetName());
298 // Create semaphore to say this file is finished
299 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
306 //______________________________________________________________________________
307 Int_t AliRawDB::Fill()
309 // Fill the trees and return the number of written bytes
311 Double_t bytes = fRawDB->GetBytesWritten();
313 if (fESDTree) fESDTree->Fill();
314 return Int_t(fRawDB->GetBytesWritten() - bytes);
317 //______________________________________________________________________________
318 void AliRawDB::WriteStats(AliStats* stats)
320 // Write stats to raw DB, local run DB and global MySQL DB.
322 AliRawEventHeader &header = *GetEvent()->GetHeader();
324 // Write stats into RawDB
325 TDirectory *ds = gDirectory;
327 stats->SetEvents(GetEvents());
328 stats->SetLastId(header.GetRunNumber(), header.GetEventInRun());
329 stats->SetFileSize(GetBytesWritten());
330 stats->SetCompressionFactor(GetCompressionFactor());
332 stats->Write("stats");
336 //______________________________________________________________________________
337 Bool_t AliRawDB::NextFile(const char* fileName)
339 // Close te current file and open a new one.
340 // Returns kFALSE in case opening failed.
344 if (!Create(fileName)) return kFALSE;
348 //______________________________________________________________________________
349 Float_t AliRawDB::GetCompressionFactor() const
351 // Return compression factor.
353 if (fTree->GetZipBytes() == 0.)
356 return fTree->GetTotBytes()/fTree->GetZipBytes();