Export AliDAQ header file into include
[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>
d21e9888 28#include <TKey.h>
a197a4ce 29
52f36b9b 30#include "AliESD.h"
a197a4ce 31#include "AliRawEvent.h"
f2dc6b20 32#include "AliRawEventHeaderBase.h"
b7d09bb3 33#include "AliStats.h"
a109e73e 34
a197a4ce 35#include "AliRawDB.h"
36
37
38ClassImp(AliRawDB)
39
40
41//______________________________________________________________________________
a109e73e 42AliRawDB::AliRawDB(AliRawEvent *event,
a109e73e 43 AliESD *esd,
e10815f1 44 Int_t compress,
45 const char* fileName) :
46 fRawDB(NULL),
47 fTree(NULL),
48 fEvent(event),
49 fESDTree(NULL),
50 fESD(esd),
51 fCompress(compress),
52 fMaxSize(-1),
53 fFS1(""),
54 fFS2(""),
55 fDeleteFiles(kFALSE),
56 fStop(kFALSE)
a197a4ce 57{
e10815f1 58 // Create a new raw DB
a197a4ce 59
e10815f1 60 if (fileName) {
61 if (!Create(fileName))
a197a4ce 62 MakeZombie();
63 }
64}
65
66//______________________________________________________________________________
67AliRawDB::AliRawDB(const AliRawDB& rawDB): TObject(rawDB)
68{
69// copy constructor
70
71 Fatal("AliRawDB", "copy constructor not implemented");
72}
73
74//______________________________________________________________________________
75AliRawDB& AliRawDB::operator = (const AliRawDB& /*rawDB*/)
76{
77// assignment operator
78
79 Fatal("operator =", "assignment operator not implemented");
80 return *this;
81}
82
83//______________________________________________________________________________
84Bool_t AliRawDB::FSHasSpace(const char *fs) const
85{
86 // Check for at least fMaxSize bytes of free space on the file system.
87 // If the space is not available return kFALSE, kTRUE otherwise.
88
89 Long_t id, bsize, blocks, bfree;
90
91 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
92 Error("FSHasSpace", "could not stat file system %s", fs);
93 return kFALSE;
94 }
95
96 // Leave 5 percent of diskspace free
97 Double_t avail = Double_t(bfree) * 0.95;
98 if (avail*bsize > fMaxSize)
99 return kTRUE;
100
101 Warning("FSHasSpace", "no space on file system %s", fs);
102 return kFALSE;
103}
104
105//______________________________________________________________________________
106const char *AliRawDB::GetFileName() const
107{
108 // Return filename based on hostname and date and time. This will make
109 // each file unique. Also makes sure (via FSHasSpace()) that there is
110 // enough space on the file system to store the file. Returns 0 in
111 // case of error or interrupt signal.
112
113 static TString fname;
114 static Bool_t fstoggle = kFALSE;
115
e10815f1 116 TString fs = fstoggle ? fFS2 : fFS1;
a197a4ce 117 TDatime dt;
118
119 TString hostname = gSystem->HostName();
120 Int_t pos;
121 if ((pos = hostname.Index(".")) != kNPOS)
122 hostname.Remove(pos);
123
124 if (!FSHasSpace(fs)) {
125 while (1) {
126 fstoggle = !fstoggle;
e10815f1 127 fs = fstoggle ? fFS2 : fFS1;
a197a4ce 128 if (FSHasSpace(fs)) break;
129 Info("GetFileName", "sleeping 30 seconds before retrying...");
130 gSystem->Sleep(30000); // sleep for 30 seconds
e10815f1 131 if (fStop) return 0;
a197a4ce 132 }
133 }
134
135 fname = fs + "/" + hostname + "_";
136 fname += dt.GetDate();
137 fname += "_";
138 fname += dt.GetTime();
139 fname += ".root";
140
141 fstoggle = !fstoggle;
142
143 return fname;
144}
145
146//______________________________________________________________________________
e10815f1 147void AliRawDB::SetFS(const char* fs1, const char* fs2)
148{
149// set the file system location
150
151 fFS1 = fs1;
152 if (fs1 && !fFS1.Contains(":")) {
153 gSystem->ResetErrno();
154 gSystem->MakeDirectory(fs1);
155 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
156 SysError("SetFS", "mkdir %s", fs1);
157 }
158 }
159
160 fFS2 = fs2;
161 if (fs2) {
162 gSystem->ResetErrno();
163 gSystem->MakeDirectory(fs2);
164 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
165 SysError("SetFS", "mkdir %s", fs2);
166 }
167 }
168}
169
170//______________________________________________________________________________
171Bool_t AliRawDB::Create(const char* fileName)
a197a4ce 172{
173 // Create a new raw DB.
174
f07ec911 175 const Int_t kMaxRetry = 1;
a197a4ce 176 const Int_t kMaxSleep = 1; // seconds
177 const Int_t kMaxSleepLong = 10; // seconds
178 Int_t retry = 0;
179
180again:
e10815f1 181 if (fStop) return kFALSE;
a197a4ce 182
e10815f1 183 const char *fname = fileName;
184 if (!fname) fname = GetFileName();
a197a4ce 185 if (!fname) {
186 Error("Create", "error getting raw DB file name");
187 return kFALSE;
188 }
189
190 retry++;
191
192 fRawDB = TFile::Open(fname, GetOpenOption(),
f07ec911 193 Form("ALICE MDC%d raw DB", kMDC), fCompress,
194 GetNetopt());
a197a4ce 195 if (!fRawDB) {
196 if (retry < kMaxRetry) {
197 Warning("Create", "failure to open file, sleeping %d %s before retrying...",
198 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
199 gSystem->Sleep(kMaxSleep*1000);
200 goto again;
201 }
202 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
203 return kFALSE;
204 }
205 if (retry > 1)
206 Warning("Create", "succeeded to open file after %d retries", retry);
207
208 if (fRawDB->IsZombie()) {
209 if (fRawDB->GetErrno() == ENOSPC ||
210 fRawDB->GetErrno() == 1018 || // SECOMERR
211 fRawDB->GetErrno() == 1027) { // SESYSERR
212 fRawDB->ResetErrno();
213 delete fRawDB;
214 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
215 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
216 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
217 goto again;
218 }
219 Error("Create", "file %s is zombie", fname);
220 fRawDB->ResetErrno();
221 delete fRawDB;
222 fRawDB = 0;
223 if (retry < kMaxRetry) {
224 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
225 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
226 gSystem->Sleep(kMaxSleep*1000);
227 goto again;
228 }
229 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
230 return kFALSE;
231 }
232
233 // Create raw data TTree
234 MakeTree();
235
236 return kTRUE;
237}
238
239//______________________________________________________________________________
240void AliRawDB::MakeTree()
241{
242 // Create ROOT Tree object container.
243
e10815f1 244 fTree = new TTree("RAW", Form("ALICE MDC%d raw data tree", kMDC));
a197a4ce 245 fTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
246
247 Int_t bufsize = 256000;
248 // splitting 29.6 MB/s, no splitting 35.3 MB/s on P4 2GHz 15k SCSI
249 //Int_t split = 1;
250 Int_t split = 0;
251 fTree->Branch("rawevent", "AliRawEvent", &fEvent, bufsize, split);
a109e73e 252
a109e73e 253 // Create tree which will contain the HLT ESD information
254
e10815f1 255 if (fESD) {
256 fESDTree = new TTree("esdTree", Form("ALICE MDC%d HLT ESD tree", kMDC));
257 fESDTree->SetAutoSave(2000000000); // autosave when 2 Gbyte written
5f42007f 258 split = 0;
e10815f1 259 fESDTree->Branch("ESD", "AliESD", &fESD, bufsize, split);
260 }
a109e73e 261
a197a4ce 262}
263
264//______________________________________________________________________________
f07ec911 265Int_t AliRawDB::Close()
a197a4ce 266{
267 // Close raw DB.
f07ec911 268 if (!fRawDB) return 0;
a197a4ce 269
f07ec911 270 if (!fRawDB->IsOpen()) return 0;
a197a4ce 271
272 fRawDB->cd();
273
274 // Write the tree.
f07ec911 275 Bool_t error = kFALSE;
276 if (fTree->Write() == 0)
277 error = kTRUE;
278 if (fESDTree)
279 if (fESDTree->Write() == 0)
280 error = kTRUE;
a197a4ce 281
282 // Close DB, this also deletes the fTree
283 fRawDB->Close();
284
f07ec911 285 Int_t filesize = fRawDB->GetEND();
286
e10815f1 287 if (fDeleteFiles) {
a197a4ce 288 gSystem->Unlink(fRawDB->GetName());
289 delete fRawDB;
290 fRawDB = 0;
f07ec911 291 if(!error)
292 return filesize;
293 else
294 return -1;
a197a4ce 295 }
296
297 // Create semaphore to say this file is finished
298 Int_t tfd = ::creat(Form("%s.done", fRawDB->GetName()), 0644);
299 close(tfd);
300
301 delete fRawDB;
302 fRawDB = 0;
f07ec911 303 if(!error)
304 return filesize;
305 else
306 return -1;
a197a4ce 307}
308
309//______________________________________________________________________________
e10815f1 310Int_t AliRawDB::Fill()
311{
312 // Fill the trees and return the number of written bytes
313
314 Double_t bytes = fRawDB->GetBytesWritten();
f07ec911 315 Bool_t error = kFALSE;
316 if (fTree->Fill() == -1)
317 error = kTRUE;
318 if (fESDTree)
319 if (fESDTree->Fill() == -1)
320 error = kTRUE;
321 if(!error)
322 return Int_t(fRawDB->GetBytesWritten() - bytes);
323 else
324 return -1;
e10815f1 325}
326
327//______________________________________________________________________________
d21e9888 328Int_t AliRawDB::GetTotalSize()
329{
330 // Return the total size of the trees
331 Int_t total = 0;
332
333 {
334 Int_t skey = 0;
335 TDirectory *dir = fTree->GetDirectory();
336 if (dir) {
337 TKey *key = dir->GetKey(fTree->GetName());
338 if (key) skey = key->GetKeylen();
339 }
340 total += skey;
341 if (fTree->GetZipBytes() > 0) total += fTree->GetTotBytes();
342 TBuffer b(TBuffer::kWrite,10000);
343 TTree::Class()->WriteBuffer(b,fTree);
344 total += b.Length();
345 }
346
347 if(fESDTree)
348 {
349 Int_t skey = 0;
350 TDirectory *dir = fESDTree->GetDirectory();
351 if (dir) {
352 TKey *key = dir->GetKey(fESDTree->GetName());
353 if (key) skey = key->GetKeylen();
354 }
355 total += skey;
356 if (fESDTree->GetZipBytes() > 0) total += fESDTree->GetTotBytes();
357 TBuffer b(TBuffer::kWrite,10000);
358 TTree::Class()->WriteBuffer(b,fESDTree);
359 total += b.Length();
360 }
361
362 return total;
363}
364
365//______________________________________________________________________________
b7d09bb3 366void AliRawDB::WriteStats(AliStats* stats)
367{
368 // Write stats to raw DB, local run DB and global MySQL DB.
369
f2dc6b20 370 AliRawEventHeaderBase &header = *GetEvent()->GetHeader();
b7d09bb3 371
372 // Write stats into RawDB
373 TDirectory *ds = gDirectory;
374 GetDB()->cd();
375 stats->SetEvents(GetEvents());
f2dc6b20 376 stats->SetLastId(header.Get("RunNb"), header.GetP("Id")[0]);
b7d09bb3 377 stats->SetFileSize(GetBytesWritten());
378 stats->SetCompressionFactor(GetCompressionFactor());
379 stats->SetEndTime();
380 stats->Write("stats");
381 ds->cd();
382}
383
384//______________________________________________________________________________
e10815f1 385Bool_t AliRawDB::NextFile(const char* fileName)
a197a4ce 386{
387 // Close te current file and open a new one.
388 // Returns kFALSE in case opening failed.
389
390 Close();
391
e10815f1 392 if (!Create(fileName)) return kFALSE;
a197a4ce 393 return kTRUE;
394}
395
396//______________________________________________________________________________
397Float_t AliRawDB::GetCompressionFactor() const
398{
399 // Return compression factor.
400
401 if (fTree->GetZipBytes() == 0.)
402 return 1.0;
403 else
404 return fTree->GetTotBytes()/fTree->GetZipBytes();
405}