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