Missing header file added
[u/mrichter/AliRoot.git] / RAW / AliRawDB.cxx
CommitLineData
a197a4ce 1// @(#)alimdc:$Name$:$Id$
2// Author: Fons Rademakers 26/11/99
3
4/**************************************************************************
5 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
6 * *
7 * Author: The ALICE Off-line Project. *
8 * Contributors are mentioned in the code where appropriate. *
9 * *
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 **************************************************************************/
18
19//////////////////////////////////////////////////////////////////////////
20// //
21// AliRawDB //
22// //
23//////////////////////////////////////////////////////////////////////////
24
25#include <errno.h>
26
27#include <TSystem.h>
28
29#ifdef ALI_DATE
30#include "event.h"
31#endif
32
52f36b9b 33#include "AliESD.h"
a197a4ce 34#include "AliRawEvent.h"
35#include "AliRawEventHeader.h"
b7d09bb3 36#include "AliStats.h"
a109e73e 37
a197a4ce 38#include "AliRawDB.h"
39
40
41ClassImp(AliRawDB)
42
43
44//______________________________________________________________________________
a109e73e 45AliRawDB::AliRawDB(AliRawEvent *event,
a109e73e 46 AliESD *esd,
e10815f1 47 Int_t compress,
48 const char* fileName) :
49 fRawDB(NULL),
50 fTree(NULL),
51 fEvent(event),
52 fESDTree(NULL),
53 fESD(esd),
54 fCompress(compress),
55 fMaxSize(-1),
56 fFS1(""),
57 fFS2(""),
58 fDeleteFiles(kFALSE),
59 fStop(kFALSE)
a197a4ce 60{
e10815f1 61 // Create a new raw DB
a197a4ce 62
63 // Consistency check with DATE header file
64#ifdef ALI_DATE
65 if (fEvent->GetHeader()->HeaderSize() != EVENT_HEAD_BASE_SIZE) {
66 Error("AliRawDB", "inconsistency between DATE and AliRawEvent headers");
67 MakeZombie();
68 return;
69 }
70#endif
71
e10815f1 72 if (fileName) {
73 if (!Create(fileName))
a197a4ce 74 MakeZombie();
75 }
76}
77
78//______________________________________________________________________________
79AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
80{
81// copy constructor
82
83 Fatal("AliRawDB", "copy constructor not implemented");
84}
85
86//______________________________________________________________________________
87AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
88{
89// assignment operator
90
91 Fatal("operator =", "assignment operator not implemented");
92 return *this;
93}
94
95//______________________________________________________________________________
96Bool_t AliRawDB::FSHasSpace(const char *fs) const
97{
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.
100
101 Long_t id, bsize, blocks, bfree;
102
103 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
104 Error("FSHasSpace", "could not stat file system %s", fs);
105 return kFALSE;
106 }
107
108 // Leave 5 percent of diskspace free
109 Double_t avail = Double_t(bfree) * 0.95;
110 if (avail*bsize > fMaxSize)
111 return kTRUE;
112
113 Warning("FSHasSpace", "no space on file system %s", fs);
114 return kFALSE;
115}
116
117//______________________________________________________________________________
118const char *AliRawDB::GetFileName() const
119{
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.
124
125 static TString fname;
126 static Bool_t fstoggle = kFALSE;
127
e10815f1 128 TString fs = fstoggle ? fFS2 : fFS1;
a197a4ce 129 TDatime dt;
130
131 TString hostname = gSystem->HostName();
132 Int_t pos;
133 if ((pos = hostname.Index(".")) != kNPOS)
134 hostname.Remove(pos);
135
136 if (!FSHasSpace(fs)) {
137 while (1) {
138 fstoggle = !fstoggle;
e10815f1 139 fs = fstoggle ? fFS2 : fFS1;
a197a4ce 140 if (FSHasSpace(fs)) break;
141 Info("GetFileName", "sleeping 30 seconds before retrying...");
142 gSystem->Sleep(30000); // sleep for 30 seconds
e10815f1 143 if (fStop) return 0;
a197a4ce 144 }
145 }
146
147 fname = fs + "/" + hostname + "_";
148 fname += dt.GetDate();
149 fname += "_";
150 fname += dt.GetTime();
151 fname += ".root";
152
153 fstoggle = !fstoggle;
154
155 return fname;
156}
157
158//______________________________________________________________________________
e10815f1 159void AliRawDB::SetFS(const char* fs1, const char* fs2)
160{
161// set the file system location
162
163 fFS1 = fs1;
164 if (fs1 && !fFS1.Contains(":")) {
165 gSystem->ResetErrno();
166 gSystem->MakeDirectory(fs1);
167 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
168 SysError("SetFS", "mkdir %s", fs1);
169 }
170 }
171
172 fFS2 = fs2;
173 if (fs2) {
174 gSystem->ResetErrno();
175 gSystem->MakeDirectory(fs2);
176 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
177 SysError("SetFS", "mkdir %s", fs2);
178 }
179 }
180}
181
182//______________________________________________________________________________
183Bool_t AliRawDB::Create(const char* fileName)
a197a4ce 184{
185 // Create a new raw DB.
186
187 const Int_t kMaxRetry = 200;
188 const Int_t kMaxSleep = 1; // seconds
189 const Int_t kMaxSleepLong = 10; // seconds
190 Int_t retry = 0;
191
192again:
e10815f1 193 if (fStop) return kFALSE;
a197a4ce 194
e10815f1 195 const char *fname = fileName;
196 if (!fname) fname = GetFileName();
a197a4ce 197 if (!fname) {
198 Error("Create", "error getting raw DB file name");
199 return kFALSE;
200 }
201
202 retry++;
203
204 fRawDB = TFile::Open(fname, GetOpenOption(),
e10815f1 205 Form("ALICE MDC%d raw DB", kMDC), fCompress,
a197a4ce 206 GetNetopt());
207 if (!fRawDB) {
208 if (retry < kMaxRetry) {
209 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
210 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
211 gSystem->Sleep(kMaxSleep*1000);
212 goto again;
213 }
214 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
215 return kFALSE;
216 }
217 if (retry > 1)
218 Warning("Create", "succeeded to open file after %d retries", retry);
219
220 if (fRawDB->IsZombie()) {
221 if (fRawDB->GetErrno() == ENOSPC ||
222 fRawDB->GetErrno() == 1018 || // SECOMERR
223 fRawDB->GetErrno() == 1027) { // SESYSERR
224 fRawDB->ResetErrno();
225 delete fRawDB;
226 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
227 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
228 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
229 goto again;
230 }
231 Error("Create", "file %s is zombie", fname);
232 fRawDB->ResetErrno();
233 delete fRawDB;
234 fRawDB = 0;
235 if (retry < kMaxRetry) {
236 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
237 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
238 gSystem->Sleep(kMaxSleep*1000);
239 goto again;
240 }
241 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
242 return kFALSE;
243 }
244
245 // Create raw data TTree
246 MakeTree();
247
248 return kTRUE;
249}
250
251//______________________________________________________________________________
252void AliRawDB::MakeTree()
253{
254 // Create ROOT Tree object container.
255
e10815f1 256 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", kMDC));
a197a4ce 257 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
258
259 Int_t bufsize = 256000;
260 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
261 //Int_t split = 1;
262 Int_t split = 0;
263 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
a109e73e 264
a109e73e 265 // Create tree which will contain the HLT ESD information
266
e10815f1 267 if (fESD) {
268 fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", kMDC));
269 fESDTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
270 split = 99;
271 fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
272 }
a109e73e 273
a197a4ce 274}
275
276//______________________________________________________________________________
277void AliRawDB::Close()
278{
279 // Close raw DB.
280
281 if (!fRawDB) return;
282
283 fRawDB->cd();
284
285 // Write the tree.
286 fTree->Write();
e10815f1 287 if (fESDTree) fESDTree->Write();
a197a4ce 288
289 // Close DB, this also deletes the fTree
290 fRawDB->Close();
291
e10815f1 292 if (fDeleteFiles) {
a197a4ce 293 gSystem->Unlink(fRawDB->GetName());
294 delete fRawDB;
295 fRawDB = 0;
296 return;
297 }
298
299 // Create semaphore to say this file is finished
300 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
301 close(tfd);
302
303 delete fRawDB;
304 fRawDB = 0;
305}
306
e10815f1 307//______________________________________________________________________________
308Int_t AliRawDB::Fill()
309{
310 // Fill the trees and return the number of written bytes
311
312 Double_t bytes = fRawDB->GetBytesWritten();
313 fTree->Fill();
314 if (fESDTree) fESDTree->Fill();
315 return Int_t(fRawDB->GetBytesWritten() - bytes);
316}
317
b7d09bb3 318//______________________________________________________________________________
319void AliRawDB::WriteStats(AliStats* stats)
320{
321 // Write stats to raw DB, local run DB and global MySQL DB.
322
323 AliRawEventHeader &header = *GetEvent()->GetHeader();
324
325 // Write stats into RawDB
326 TDirectory *ds = gDirectory;
327 GetDB()->cd();
328 stats->SetEvents(GetEvents());
329 stats->SetLastId(header.GetRunNumber(), header.GetEventInRun());
330 stats->SetFileSize(GetBytesWritten());
331 stats->SetCompressionFactor(GetCompressionFactor());
332 stats->SetEndTime();
333 stats->Write("stats");
334 ds->cd();
335}
336
a197a4ce 337//______________________________________________________________________________
e10815f1 338Bool_t AliRawDB::NextFile(const char* fileName)
a197a4ce 339{
340 // Close te current file and open a new one.
341 // Returns kFALSE in case opening failed.
342
343 Close();
344
e10815f1 345 if (!Create(fileName)) return kFALSE;
a197a4ce 346 return kTRUE;
347}
348
349//______________________________________________________________________________
350Float_t AliRawDB::GetCompressionFactor() const
351{
352 // Return compression factor.
353
354 if (fTree->GetZipBytes() == 0.)
355 return 1.0;
356 else
357 return fTree->GetTotBytes()/fTree->GetZipBytes();
358}