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