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"
48 //______________________________________________________________________________
49 AliRawDB::AliRawDB(AliRawEvent *event,
53 Double_t maxsize, Int_t compress,
56 // Create a new raw DB containing at most maxsize bytes.
63 // Consistency check with DATE header file
65 if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
66 Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
78 //______________________________________________________________________________
79 AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
83 Fatal("AliRawDB", "copy constructor not implemented");
86 //______________________________________________________________________________
87 AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
89 // assignment operator
91 Fatal("operator =", "assignment operator not implemented");
95 //______________________________________________________________________________
96 Bool_t AliRawDB::FSHasSpace(const char *fs) const
98 // Check for at least fMaxSize bytes of free space on the file system.
99 // If the space is not available return kFALSE, kTRUE otherwise.
101 Long_t id, bsize, blocks, bfree;
103 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
104 Error("FSHasSpace", "could not stat file system %s", fs);
108 // Leave 5 percent of diskspace free
109 Double_t avail = Double_t(bfree) * 0.95;
110 if (avail*bsize > fMaxSize)
113 Warning("FSHasSpace", "no space on file system %s", fs);
117 //______________________________________________________________________________
118 const char *AliRawDB::GetFileName() const
120 // Return filename based on hostname and date and time. This will make
121 // each file unique. Also makes sure (via FSHasSpace()) that there is
122 // enough space on the file system to store the file. Returns 0 in
123 // case of error or interrupt signal.
125 static TString fname;
126 static Bool_t fstoggle = kFALSE;
128 TString fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
131 TString hostname = gSystem->HostName();
133 if ((pos = hostname.Index(".")) != kNPOS)
134 hostname.Remove(pos);
136 if (!FSHasSpace(fs)) {
138 fstoggle = !fstoggle;
139 fs = fstoggle ? AliMDC::RawDBFS(1) : AliMDC::RawDBFS(0);
140 if (FSHasSpace(fs)) break;
141 Info("GetFileName", "sleeping 30 seconds before retrying...");
142 gSystem->Sleep(30000); // sleep for 30 seconds
143 if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
148 fname = fs + "/" + hostname + "_";
149 fname += dt.GetDate();
151 fname += dt.GetTime();
154 fstoggle = !fstoggle;
159 //______________________________________________________________________________
160 Bool_t AliRawDB::Create()
162 // Create a new raw DB.
164 const Int_t kMaxRetry = 200;
165 const Int_t kMaxSleep = 1; // seconds
166 const Int_t kMaxSleepLong = 10; // seconds
170 if (AliMDC::Instance() && AliMDC::Instance()->StopLoop())
173 const char *fname = GetFileName();
175 Error("Create", "error getting raw DB file name");
181 fRawDB = TFile::Open(fname, GetOpenOption(),
182 Form("ALICE MDC%d raw DB", AliMDC::kMDC), fCompress,
185 if (retry < kMaxRetry) {
186 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
187 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
188 gSystem->Sleep(kMaxSleep*1000);
191 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
195 Warning("Create", "succeeded to open file after %d retries", retry);
197 if (fRawDB->IsZombie()) {
198 if (fRawDB->GetErrno() == ENOSPC ||
199 fRawDB->GetErrno() == 1018 || // SECOMERR
200 fRawDB->GetErrno() == 1027) { // SESYSERR
201 fRawDB->ResetErrno();
203 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
204 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
205 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
208 Error("Create", "file %s is zombie", fname);
209 fRawDB->ResetErrno();
212 if (retry < kMaxRetry) {
213 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
214 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
215 gSystem->Sleep(kMaxSleep*1000);
218 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
222 // Create raw data TTree
228 //______________________________________________________________________________
229 void AliRawDB::MakeTree()
231 // Create ROOT Tree object container.
233 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", AliMDC::kMDC));
234 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
236 Int_t bufsize = 256000;
237 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
240 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
243 // Create tree which will contain the HLT ESD information
245 fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", AliMDC::kMDC));
246 fESDTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
248 fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
253 //______________________________________________________________________________
254 void AliRawDB::Close()
266 // Close DB, this also deletes the fTree
269 if (AliMDC::DeleteFiles()) {
270 gSystem->Unlink(fRawDB->GetName());
276 // Create semaphore to say this file is finished
277 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
284 //______________________________________________________________________________
285 void AliRawDB::WriteStats(AliStats* stats)
287 // Write stats to raw DB, local run DB and global MySQL DB.
289 AliRawEventHeader &header = *GetEvent()->GetHeader();
291 // Write stats into RawDB
292 TDirectory *ds = gDirectory;
294 stats->SetEvents(GetEvents());
295 stats->SetLastId(header.GetRunNumber(), header.GetEventInRun());
296 stats->SetFileSize(GetBytesWritten());
297 stats->SetCompressionFactor(GetCompressionFactor());
299 stats->Write("stats");
303 //______________________________________________________________________________
304 Bool_t AliRawDB::NextFile()
306 // Close te current file and open a new one.
307 // Returns kFALSE in case opening failed.
311 if (!Create()) return kFALSE;
315 //______________________________________________________________________________
316 Float_t AliRawDB::GetCompressionFactor() const
318 // Return compression factor.
320 if (fTree->GetZipBytes() == 0.)
323 return fTree->GetTotBytes()/fTree->GetZipBytes();