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