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