TOF QA Task (F. Bellini)
[u/mrichter/AliRoot.git] / RAW / AliRawDB.cxx
CommitLineData
60838f24 1// @(#)alimdc:$Name: $:$Id$
a197a4ce 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
936875a4 39#include <TBranch.h>
40
af885e0f 41#include "AliESDEvent.h"
33314186 42#include "AliRawEventV2.h"
43#include "AliRawDataArrayV2.h"
f2dc6b20 44#include "AliRawEventHeaderBase.h"
6605cb7a 45#include "AliRawEquipmentHeader.h"
a109e73e 46
a197a4ce 47#include "AliRawDB.h"
48
49
50ClassImp(AliRawDB)
51
60838f24 52const char *AliRawDB::fgkAliRootTag = "$Rev$";
a197a4ce 53
33314186 54// Split TPC into 18 branches in order to avoid problems with big memory
30d59ac8 55// consumption in case of TPC events w/o zero-suppression
7034c7a7 56Int_t AliRawDB::fgkDetBranches[AliDAQ::kNDetectors+1] = {1,1,1,18,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,1,10,1};
30d59ac8 57
a197a4ce 58//______________________________________________________________________________
33314186 59AliRawDB::AliRawDB(AliRawEventV2 *event,
af885e0f 60 AliESDEvent *esd,
e10815f1 61 Int_t compress,
a8b0468f 62 const char* fileName,
63 Int_t basketsize) :
e10815f1 64 fRawDB(NULL),
65 fTree(NULL),
66 fEvent(event),
67 fESDTree(NULL),
68 fESD(esd),
69 fCompress(compress),
a8b0468f 70 fBasketSize(basketsize),
e10815f1 71 fMaxSize(-1),
72 fFS1(""),
73 fFS2(""),
74 fDeleteFiles(kFALSE),
19359f9c 75 fStop(kFALSE)
a197a4ce 76{
e10815f1 77 // Create a new raw DB
a197a4ce 78
30d59ac8 79 for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
33314186 80 fDetRawData[iDet] = new AliRawDataArrayV2*[fgkDetBranches[iDet]];
30d59ac8 81 Int_t nDDLsPerBranch = AliDAQ::NumberOfDdls(iDet)/fgkDetBranches[iDet];
82 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
33314186 83 fDetRawData[iDet][iBranch] = new AliRawDataArrayV2(nDDLsPerBranch);
30d59ac8 84 }
6605cb7a 85
33314186 86 fDetRawData[AliDAQ::kNDetectors] = new AliRawDataArrayV2*[fgkDetBranches[AliDAQ::kNDetectors]];
30d59ac8 87 for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++)
33314186 88 fDetRawData[AliDAQ::kNDetectors][iBranch] = new AliRawDataArrayV2(100);
6605cb7a 89
e10815f1 90 if (fileName) {
91 if (!Create(fileName))
a197a4ce 92 MakeZombie();
93 }
94}
95
6605cb7a 96
97//______________________________________________________________________________
98AliRawDB::~AliRawDB() {
99 // Destructor
100
101 if(Close()==-1) Error("~AliRawDB", "cannot close output file!");
102
30d59ac8 103 for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++) {
104 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
105 delete fDetRawData[iDet][iBranch];
106 delete [] fDetRawData[iDet];
107 }
6605cb7a 108}
109
a197a4ce 110//______________________________________________________________________________
a197a4ce 111Bool_t AliRawDB::FSHasSpace(const char *fs) const
112{
113 // Check for at least fMaxSize bytes of free space on the file system.
114 // If the space is not available return kFALSE, kTRUE otherwise.
115
116 Long_t id, bsize, blocks, bfree;
117
118 if (gSystem->GetFsInfo(fs, &id, &bsize, &blocks, &bfree) == 1) {
119 Error("FSHasSpace", "could not stat file system %s", fs);
120 return kFALSE;
121 }
122
123 // Leave 5 percent of diskspace free
124 Double_t avail = Double_t(bfree) * 0.95;
125 if (avail*bsize > fMaxSize)
126 return kTRUE;
127
128 Warning("FSHasSpace", "no space on file system %s", fs);
129 return kFALSE;
130}
131
132//______________________________________________________________________________
133const char *AliRawDB::GetFileName() const
134{
135 // Return filename based on hostname and date and time. This will make
136 // each file unique. Also makes sure (via FSHasSpace()) that there is
137 // enough space on the file system to store the file. Returns 0 in
138 // case of error or interrupt signal.
139
140 static TString fname;
141 static Bool_t fstoggle = kFALSE;
142
e10815f1 143 TString fs = fstoggle ? fFS2 : fFS1;
a197a4ce 144 TDatime dt;
145
146 TString hostname = gSystem->HostName();
147 Int_t pos;
148 if ((pos = hostname.Index(".")) != kNPOS)
149 hostname.Remove(pos);
150
151 if (!FSHasSpace(fs)) {
152 while (1) {
153 fstoggle = !fstoggle;
e10815f1 154 fs = fstoggle ? fFS2 : fFS1;
a197a4ce 155 if (FSHasSpace(fs)) break;
156 Info("GetFileName", "sleeping 30 seconds before retrying...");
157 gSystem->Sleep(30000); // sleep for 30 seconds
e10815f1 158 if (fStop) return 0;
a197a4ce 159 }
160 }
161
162 fname = fs + "/" + hostname + "_";
163 fname += dt.GetDate();
164 fname += "_";
165 fname += dt.GetTime();
166 fname += ".root";
167
168 fstoggle = !fstoggle;
169
170 return fname;
171}
172
173//______________________________________________________________________________
e10815f1 174void AliRawDB::SetFS(const char* fs1, const char* fs2)
175{
176// set the file system location
177
178 fFS1 = fs1;
179 if (fs1 && !fFS1.Contains(":")) {
180 gSystem->ResetErrno();
181 gSystem->MakeDirectory(fs1);
182 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
183 SysError("SetFS", "mkdir %s", fs1);
184 }
185 }
186
187 fFS2 = fs2;
188 if (fs2) {
189 gSystem->ResetErrno();
190 gSystem->MakeDirectory(fs2);
191 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
192 SysError("SetFS", "mkdir %s", fs2);
193 }
194 }
195}
196
197//______________________________________________________________________________
198Bool_t AliRawDB::Create(const char* fileName)
a197a4ce 199{
200 // Create a new raw DB.
201
f07ec911 202 const Int_t kMaxRetry = 1;
a197a4ce 203 const Int_t kMaxSleep = 1; // seconds
204 const Int_t kMaxSleepLong = 10; // seconds
205 Int_t retry = 0;
206
207again:
e10815f1 208 if (fStop) return kFALSE;
a197a4ce 209
e10815f1 210 const char *fname = fileName;
211 if (!fname) fname = GetFileName();
a197a4ce 212 if (!fname) {
213 Error("Create", "error getting raw DB file name");
214 return kFALSE;
215 }
216
217 retry++;
218
219 fRawDB = TFile::Open(fname, GetOpenOption(),
ee8f2a6c 220 Form("ALICE raw-data file (%s)", GetAliRootTag()), fCompress,
f07ec911 221 GetNetopt());
a197a4ce 222 if (!fRawDB) {
223 if (retry < kMaxRetry) {
224 Warning("Create", "failure to open file, 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 if (retry > 1)
233 Warning("Create", "succeeded to open file after %d retries", retry);
234
235 if (fRawDB->IsZombie()) {
236 if (fRawDB->GetErrno() == ENOSPC ||
237 fRawDB->GetErrno() == 1018 || // SECOMERR
238 fRawDB->GetErrno() == 1027) { // SESYSERR
239 fRawDB->ResetErrno();
240 delete fRawDB;
241 Warning("Create", "file is a zombie (no space), sleeping %d %s before retrying...",
242 kMaxSleepLong, kMaxSleepLong==1 ? "second" : "seconds");
243 gSystem->Sleep(kMaxSleepLong*1000); // sleep 10 seconds before retrying
244 goto again;
245 }
246 Error("Create", "file %s is zombie", fname);
247 fRawDB->ResetErrno();
248 delete fRawDB;
249 fRawDB = 0;
250 if (retry < kMaxRetry) {
251 Warning("Create", "file is a zombie, sleeping %d %s before retrying...",
252 kMaxSleep, kMaxSleep==1 ? "second" : "seconds");
253 gSystem->Sleep(kMaxSleep*1000);
254 goto again;
255 }
256 Error("Create", "failure to open file %s after %d tries", fname, kMaxRetry);
257 return kFALSE;
258 }
259
a197a4ce 260 return kTRUE;
261}
262
936875a4 263static void BranchResetBit(TBranch *b)
264{
265 // Reset MapObject on this branch and all the sub-branches
266
267 b->ResetBit( kBranchObject | kBranchAny ); // Or in newer ROOT: b->ResetBit( kMapObject )
268 TIter next( b->GetListOfBranches() );
269 TBranch *sub = 0;
270 while ( (sub = (TBranch*)next() ) ) {
271 BranchResetBit( sub );
272 }
273}
274
a197a4ce 275//______________________________________________________________________________
276void AliRawDB::MakeTree()
277{
278 // Create ROOT Tree object container.
279
ee8f2a6c 280 fTree = new TTree("RAW", Form("ALICE raw-data tree (%s)", GetAliRootTag()));
60838f24 281 fTree->SetAutoSave(21000000000LL); // autosave when 21 Gbyte written
a197a4ce 282
6605cb7a 283 fTree->BranchRef();
284
33314186 285 Int_t split = 99;
286 TBranch *b = fTree->Branch("rawevent", "AliRawEventV2", &fEvent, fBasketSize, split);
936875a4 287 BranchResetBit(b);
a109e73e 288
6605cb7a 289 // Make brach for each sub-detector
290 for (Int_t iDet = 0; iDet < AliDAQ::kNDetectors; iDet++) {
936875a4 291 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++) {
33314186 292 b = fTree->Branch(Form("%s%d",AliDAQ::DetectorName(iDet),iBranch),"AliRawDataArrayV2",
936875a4 293 &fDetRawData[iDet][iBranch],fBasketSize,split);
294 BranchResetBit(b);
295 }
6605cb7a 296 }
297 // Make special branch for unrecognized raw-data payloads
936875a4 298 for (Int_t iBranch = 0; iBranch < fgkDetBranches[AliDAQ::kNDetectors]; iBranch++) {
33314186 299 b = fTree->Branch(Form("Common%d",iBranch),"AliRawDataArrayV2",
936875a4 300 &fDetRawData[AliDAQ::kNDetectors][iBranch],fBasketSize,split);
301 BranchResetBit(b);
302 }
6605cb7a 303
a109e73e 304 // Create tree which will contain the HLT ESD information
305
e10815f1 306 if (fESD) {
ee8f2a6c 307 fESDTree = new TTree("esdTree", Form("ALICE HLT ESD tree (%s)", GetAliRootTag()));
60838f24 308 fESDTree->SetAutoSave(21000000000LL); // autosave when 21 Gbyte written
5f42007f 309 split = 0;
a8b0468f 310 fESDTree->Branch("ESD", "AliESDEvent", &fESD, fBasketSize, split);
e10815f1 311 }
a109e73e 312
a197a4ce 313}
314
315//______________________________________________________________________________
d2450633 316Long64_t AliRawDB::Close()
a197a4ce 317{
318 // Close raw DB.
f07ec911 319 if (!fRawDB) return 0;
a197a4ce 320
f07ec911 321 if (!fRawDB->IsOpen()) return 0;
a197a4ce 322
323 fRawDB->cd();
324
325 // Write the tree.
f07ec911 326 Bool_t error = kFALSE;
33314186 327 if (fTree)
328 if (fTree->Write() == 0)
329 error = kTRUE;
f07ec911 330 if (fESDTree)
331 if (fESDTree->Write() == 0)
332 error = kTRUE;
a197a4ce 333
334 // Close DB, this also deletes the fTree
335 fRawDB->Close();
336
33314186 337 fTree = NULL;
338
d2450633 339 Long64_t filesize = fRawDB->GetEND();
f07ec911 340
e10815f1 341 if (fDeleteFiles) {
a197a4ce 342 gSystem->Unlink(fRawDB->GetName());
343 delete fRawDB;
344 fRawDB = 0;
f07ec911 345 if(!error)
346 return filesize;
347 else
348 return -1;
a197a4ce 349 }
350
a197a4ce 351 delete fRawDB;
352 fRawDB = 0;
f07ec911 353 if(!error)
354 return filesize;
355 else
356 return -1;
a197a4ce 357}
358
359//______________________________________________________________________________
e10815f1 360Int_t AliRawDB::Fill()
361{
33314186 362 // Fill the trees and return the number of written bytes
6605cb7a 363
33314186 364 // Create raw data TTree if it not yet done
365 if (!fTree) MakeTree();
6605cb7a 366
e10815f1 367 Double_t bytes = fRawDB->GetBytesWritten();
f07ec911 368 Bool_t error = kFALSE;
369 if (fTree->Fill() == -1)
370 error = kTRUE;
371 if (fESDTree)
372 if (fESDTree->Fill() == -1)
373 error = kTRUE;
374 if(!error)
375 return Int_t(fRawDB->GetBytesWritten() - bytes);
376 else
377 return -1;
e10815f1 378}
379
380//______________________________________________________________________________
60838f24 381Long64_t AliRawDB::GetTotalSize()
d21e9888 382{
383 // Return the total size of the trees
60838f24 384 Long64_t total = 0;
d21e9888 385
33314186 386 if (fTree) {
d21e9888 387 Int_t skey = 0;
388 TDirectory *dir = fTree->GetDirectory();
389 if (dir) {
390 TKey *key = dir->GetKey(fTree->GetName());
391 if (key) skey = key->GetKeylen();
392 }
60838f24 393 total += (Long64_t)skey + fTree->GetZipBytes();
d21e9888 394 }
395
396 if(fESDTree)
397 {
398 Int_t skey = 0;
399 TDirectory *dir = fESDTree->GetDirectory();
400 if (dir) {
401 TKey *key = dir->GetKey(fESDTree->GetName());
402 if (key) skey = key->GetKeylen();
403 }
60838f24 404 total += (Long64_t)skey + fESDTree->GetZipBytes();
d21e9888 405 }
406
407 return total;
408}
409
410//______________________________________________________________________________
0cd3f979 411Long64_t AliRawDB::AutoSave()
412{
413 // Auto-save the raw-data and
414 // esd (if any) trees
415
416 Long64_t nbytes = fTree->AutoSave();
417
418 if (fESDTree) nbytes += fESDTree->AutoSave();
419
420 return nbytes;
421}
422
423//______________________________________________________________________________
e10815f1 424Bool_t AliRawDB::NextFile(const char* fileName)
a197a4ce 425{
426 // Close te current file and open a new one.
427 // Returns kFALSE in case opening failed.
428
429 Close();
430
e10815f1 431 if (!Create(fileName)) return kFALSE;
a197a4ce 432 return kTRUE;
433}
434
435//______________________________________________________________________________
436Float_t AliRawDB::GetCompressionFactor() const
437{
438 // Return compression factor.
439
440 if (fTree->GetZipBytes() == 0.)
441 return 1.0;
442 else
443 return fTree->GetTotBytes()/fTree->GetZipBytes();
444}
ee8f2a6c 445
446//______________________________________________________________________________
447const char *AliRawDB::GetAliRootTag()
448{
449 // Return the aliroot tag (version)
450 // used to generate the raw data file.
451 // Stored in the raw-data file title.
452
544dec61 453 static TString version = fgkAliRootTag;
ee8f2a6c 454 version.Remove(TString::kBoth,'$');
ff5606a9 455 version.ReplaceAll("Rev","AliRoot version");
ee8f2a6c 456
457 return version.Data();
458}
5d315e4d 459
460//______________________________________________________________________________
581835ab 461Bool_t AliRawDB::WriteGuidFile(TString &guidFileFolder)
5d315e4d 462{
463 // Write the guid file
19359f9c 464 // in the specified folder or
465 // in the folder where the raw data
466 // file is.
5d315e4d 467
468 TString guidFileName;
581835ab 469 if (!guidFileFolder.IsNull()) {
19359f9c 470 guidFileName = guidFileFolder;
5d315e4d 471
472 TString pathStr = fRawDB->GetName();
473 TObjArray *pathArr = pathStr.Tokenize('/');
474 guidFileName.Append("/");
475 guidFileName.Append(((TObjString *)pathArr->Last())->String());
476 pathArr->Delete();
477 delete pathArr;
478 }
479 else
480 guidFileName = fRawDB->GetName();
481
482 guidFileName += ".guid";
483
484 ofstream fguid(guidFileName.Data());
19359f9c 485 if (!fguid.is_open()) {
486 Error("WriteGuidFile", "failure to open guid file %s", guidFileName.Data());
487 return kFALSE;
488 }
5d315e4d 489 TString guid = fRawDB->GetUUID().AsString();
490 fguid << "guid: \t" << guid.Data();
491 fguid.close();
19359f9c 492
493 return kTRUE;
5d315e4d 494}
33314186 495
496
497//______________________________________________________________________________
498void AliRawDB::Reset()
499{
500 // Clear the raw-data arrays
501 // Should be done before processing the raw-data event
502
503 for (Int_t iDet = 0; iDet < (AliDAQ::kNDetectors + 1); iDet++)
504 for (Int_t iBranch = 0; iBranch < fgkDetBranches[iDet]; iBranch++)
505 fDetRawData[iDet][iBranch]->ClearData();
506}
507
508//______________________________________________________________________________
509AliRawDataArrayV2 *AliRawDB::GetRawDataArray(UInt_t eqSize, UInt_t eqId) const
510{
511 // Return the corresponding raw-datra array (branch)
512 // depending on the equipment ID
513
514 Int_t iDet = AliDAQ::kNDetectors;
515 Int_t iBranch = 0; // can we split somehow the unrecognized data??? For the moment - no
516 if(eqSize) {
517 Int_t ddlIndex = -1;
518 iDet = AliDAQ::DetectorIDFromDdlID(eqId,ddlIndex);
519 if (iDet < 0 || iDet >= AliDAQ::kNDetectors)
520 iDet = AliDAQ::kNDetectors;
521 else
522 iBranch = (ddlIndex * fgkDetBranches[iDet])/AliDAQ::NumberOfDdls(iDet);
523 }
524
525 return fDetRawData[iDet][iBranch];
526}
527