]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliMDC.cxx
Coverity 18409
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
CommitLineData
60838f24 1// @(#)alimdc:$Name: $:$Id$
a197a4ce 2// Author: Fons Rademakers 26/11/99
3// Updated: Dario Favretto 15/04/2003
4
5/**************************************************************************
6 * Copyright(c) 1998-2003, ALICE Experiment at CERN, All rights reserved. *
7 * *
8 * Author: The ALICE Off-line Project. *
9 * Contributors are mentioned in the code where appropriate. *
10 * *
11 * Permission to use, copy, modify and distribute this software and its *
12 * documentation strictly for non-commercial purposes is hereby granted *
13 * without fee, provided that the above copyright notice appears in all *
14 * copies and that both the copyright notice and this permission notice *
15 * appear in the supporting documentation. The authors make no claims *
16 * about the suitability of this software for any purpose. It is *
17 * provided "as is" without express or implied warranty. *
18 **************************************************************************/
19
8c49c5a5 20/* $Id$ */
21
a197a4ce 22//////////////////////////////////////////////////////////////////////////
23// //
24// AliMDC //
25// //
33314186 26// Set of classes defining the ALICE RAW event format. The AliRawEventV2//
a197a4ce 27// class defines a RAW event. It consists of an AliEventHeader object //
28// an AliEquipmentHeader object, an AliRawData object and an array of //
33314186 29// sub-events, themselves also being AliRawEventV2s. The number of //
a197a4ce 30// sub-events depends on the number of DATE LDC's. //
33314186 31// The AliRawEventV2 objects are written to a ROOT file using different //
a197a4ce 32// technologies, i.e. to local disk via AliRawDB or via rfiod using //
33// AliRawRFIODB or via rootd using AliRawRootdDB or to CASTOR via //
34// rootd using AliRawCastorDB (and for performance testing there is //
35// also AliRawNullDB). //
a197a4ce 36// The AliStats class provides statics information that is added as //
37// a single keyed object to each raw file. //
38// The AliTagDB provides an interface to a TAG database. //
39// The AliMDC class is usid by the "alimdc" stand-alone program //
40// that reads data directly from DATE. //
41// //
42//////////////////////////////////////////////////////////////////////////
43
8c49c5a5 44#include <sys/types.h>
45#include <sys/stat.h>
46
a197a4ce 47#include <errno.h>
48
49#include <TSystem.h>
e10815f1 50#include <TROOT.h>
a197a4ce 51#include <TStopwatch.h>
5cc4c1fe 52#include <TPluginManager.h>
936875a4 53#include <TBufferFile.h>
a197a4ce 54
e10815f1 55#include <sys/uio.h>
a197a4ce 56#ifdef USE_EB
57#include "libDateEb.h"
58#endif
59
af885e0f 60#include "AliMDC.h"
61
e10815f1 62#include <AliLog.h>
af885e0f 63#include <AliESDEvent.h>
a109e73e 64
33314186 65#include "AliRawEventV2.h"
f2dc6b20 66#include "AliRawEventHeaderBase.h"
33314186 67#include "AliRawEquipmentV2.h"
a197a4ce 68#include "AliRawEquipmentHeader.h"
33314186 69#include "AliRawDataArrayV2.h"
a197a4ce 70#include "AliRawData.h"
a197a4ce 71#include "AliRawDB.h"
72#include "AliRawRFIODB.h"
73#include "AliRawCastorDB.h"
74#include "AliRawRootdDB.h"
75#include "AliRawNullDB.h"
76#include "AliTagDB.h"
54dd2271 77#include "AliRawEventTag.h"
e10815f1 78#include "AliFilter.h"
a197a4ce 79
af885e0f 80
a197a4ce 81
a197a4ce 82ClassImp(AliMDC)
83
84
e10815f1 85// Filter names
86const char* const AliMDC::fgkFilterName[kNFilters] = {"AliHoughFilter"};
a197a4ce 87
e10815f1 88//______________________________________________________________________________
89AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode,
5d315e4d 90 Double_t maxSizeTagDB, const char* fileNameTagDB,
a8b0468f 91 const char *guidFileFolder,
92 Int_t basketsize) :
33314186 93 fEvent(new AliRawEventV2),
e10815f1 94 fESD(NULL),
e10815f1 95 fRawDB(NULL),
e10815f1 96 fTagDB(NULL),
54dd2271 97 fEventTag(new AliRawEventTag),
e10815f1 98 fCompress(compress),
a8b0468f 99 fBasketSize(basketsize),
e10815f1 100 fDeleteFiles(deleteFiles),
101 fFilterMode(filterMode),
102 fFilters(),
f2dc6b20 103 fStop(kFALSE),
104 fIsTagDBCreated(kFALSE),
105 fMaxSizeTagDB(maxSizeTagDB),
5d315e4d 106 fFileNameTagDB(fileNameTagDB),
107 fGuidFileFolder(guidFileFolder)
e10815f1 108{
109 // Create MDC processor object.
110 // compress is the file compression mode.
111 // If deleteFiles is kTRUE the raw data files will be deleted after they
112 // were closed.
113 // If the filterMode if kFilterOff no filter algorithm will be, if it is
114 // kFilterTransparent the algorthims will be run but no events will be
115 // rejected, if it is kFilterOn the filters will be run and the event will
116 // be rejected if all filters return kFALSE.
e10815f1 117 // If maxSizeTagDB is greater than 0 it determines the maximal size of the
118 // tag DB and then fileNameTagDB is the directory name for the tag DB.
119 // Otherwise fileNameTagDB is the file name of the tag DB. If it is NULL
120 // no tag DB will be created.
5d315e4d 121 // Optional 'guidFileFolder' specifies the folder in which *.guid files
122 // will be stored. In case this option is not given, the *.guid files
123 // will be written to the same folder as the raw-data files.
60838f24 124
125 // Set the maximum tree size to 19GB
126 // in order to allow big raw data files
127 TTree::SetMaxTreeSize(20000000000LL);
936875a4 128
33314186 129 AliRawEquipmentHeader::Class()->IgnoreTObjectStreamer();
130 AliRawEquipmentV2::Class()->IgnoreTObjectStreamer();
131 AliRawEventV2::Class()->IgnoreTObjectStreamer();
132 AliRawDataArrayV2::Class()->IgnoreTObjectStreamer();
133
936875a4 134 TBufferFile::SetGlobalReadParam(5);
e10815f1 135
5cc4c1fe 136 // This line is needed in case of a stand-alone application w/o
137 // $ROOTSYS/etc/system.rootrc file
138 gROOT->GetPluginManager()->AddHandler("TVirtualStreamerInfo",
139 "*",
140 "TStreamerInfo",
141 "RIO",
142 "TStreamerInfo()");
e10815f1 143
144 if (fFilterMode != kFilterOff) {
af885e0f 145 fESD = new AliESDEvent();
e10815f1 146 }
a197a4ce 147
5d315e4d 148 // Create the guid files folder if it does not exist
581835ab 149 if (!fGuidFileFolder.IsNull()) {
5d315e4d 150 gSystem->ResetErrno();
581835ab 151 gSystem->MakeDirectory(fGuidFileFolder.Data());
5d315e4d 152 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
581835ab 153 SysError("AliMDC", "mkdir %s", fGuidFileFolder.Data());
5d315e4d 154 }
155 }
156
e10815f1 157 // install SIGUSR1 handler to allow clean interrupts
158 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
a197a4ce 159
e10815f1 160 // create the high level filters
161 if (fFilterMode != kFilterOff) {
162 for (Int_t iFilter = 0; iFilter < kNFilters; iFilter++) {
163 TClass* filterClass = gROOT->GetClass(fgkFilterName[iFilter]);
164 if (!filterClass) {
165 Warning("AliMDC", "no filter class %s found", fgkFilterName[iFilter]);
166 continue;
a197a4ce 167 }
e10815f1 168 AliFilter* filter = (AliFilter*) filterClass->New();
169 if (!filter) {
170 Warning("AliMDC", "creation of filter %s failed", fgkFilterName[iFilter]);
171 continue;
a197a4ce 172 }
e10815f1 173 fFilters.Add(filter);
174 }
175 }
a197a4ce 176}
177
e10815f1 178//______________________________________________________________________________
179AliMDC::~AliMDC()
180{
181// destructor
182
183 fFilters.Delete();
f2dc6b20 184 if(fTagDB) delete fTagDB;
e10815f1 185 delete fRawDB;
e10815f1 186 delete fESD;
187 delete fEvent;
54dd2271 188 delete fEventTag;
e10815f1 189}
190
a197a4ce 191//______________________________________________________________________________
4fbf7315 192Int_t AliMDC::Open(EWriteMode mode, const char* fileName,
193 Double_t maxFileSize,
194 const char* fs1, const char* fs2)
a197a4ce 195{
e10815f1 196// open a new raw DB file
197
198 if (mode == kRFIO)
8ec37122 199 fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName, fBasketSize);
e10815f1 200 else if (mode == kROOTD)
8ec37122 201 fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName, fBasketSize);
e10815f1 202 else if (mode == kCASTOR)
8ec37122 203 fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName, fBasketSize);
e10815f1 204 else if (mode == kDEVNULL)
8ec37122 205 fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName, fBasketSize);
e10815f1 206 else
8ec37122 207 fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName, fBasketSize);
e10815f1 208 fRawDB->SetDeleteFiles(fDeleteFiles);
209
19359f9c 210 if (fRawDB->IsZombie()) {
211 delete fRawDB;
212 fRawDB = NULL;
213 return -1;
214 }
215
4fbf7315 216 if (fileName == NULL) {
217 fRawDB->SetMaxSize(maxFileSize);
218 fRawDB->SetFS(fs1, fs2);
19359f9c 219 if (!fRawDB->Create()) {
220 delete fRawDB;
221 fRawDB = NULL;
222 return -1;
223 }
4fbf7315 224 }
225
19359f9c 226 if (!fRawDB->WriteGuidFile(fGuidFileFolder)) {
e10815f1 227 delete fRawDB;
228 fRawDB = NULL;
19359f9c 229 return -2;
e10815f1 230 }
19359f9c 231
e10815f1 232 Info("Open", "Filling raw DB %s\n", fRawDB->GetDBName());
a197a4ce 233
e10815f1 234 return 0;
235}
a109e73e 236
e10815f1 237//______________________________________________________________________________
238Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
239{
33314186 240// Convert the DATE event to an AliRawEventV2 object and store it in the raw DB,
e10815f1 241// optionally also run the filter.
242// event is either a pointer to the streamlined event
243// or, if isIovecArray is kTRUE, a pointer to an array of iovecs with one
244// iovec per subevent (used by the event builder).
245// The return value is the number of written bytes or an error code
60838f24 246 const Long64_t kFileSizeErrorLevel = 19000000000LL;
d21e9888 247
60838f24 248 Long64_t currentFileSize = GetTotalSize();
33314186 249 // AliDebug(1,Form("current file size is %lld bytes",currentFileSize));
d21e9888 250 if(currentFileSize > kFileSizeErrorLevel) {
6c12d59f 251 Error("ProcessEvent", "file size (%lld) exceeds the limit "
d21e9888 252 , currentFileSize);
253 return kErrFileSize;
254 }
e10815f1 255
256 Int_t status;
257 char* data = (char*) event;
258 if (isIovecArray) data = (char*) ((iovec*) event)[0].iov_base;
259
260 // Shortcut for easy header access
f2dc6b20 261 AliRawEventHeaderBase *header = fEvent->GetHeader(data);
e10815f1 262
263 // Read event header
f2dc6b20 264 if ((status = header->ReadHeader(data)) != (Int_t)header->GetHeadSize()) {
33314186 265 Error("ProcessEvent","Wrong event header format (%d != %d)",
266 status,(Int_t)header->GetHeadSize());
e10815f1 267 return kErrHeader;
268 }
a197a4ce 269
33314186 270 // if (AliDebugLevel() > 2) ToAliDebug(3, header->Dump(););
e10815f1 271
272 // Check event type and skip "Start of Run", "End of Run",
273 // "Start of Run Files" and "End of Run Files"
f2dc6b20 274 Int_t size = header->GetEventSize() - header->GetHeadSize();
33314186 275 UInt_t eventType = header->Get("Type");
276
277 // AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size));
a197a4ce 278
e10815f1 279 // Amount of data left to read for this event
280 Int_t toRead = size;
a197a4ce 281
cce65444 282 // StartOfRun, EndOfRun etc. events have no payload
283 // Nevertheless, store the event headers in the tree
284 if (toRead > 0) {
285
286 // If there is less data for this event than the next sub-event
287 // header, something is wrong. Skip to next event...
288 if (toRead < (Int_t)header->GetHeadSize()) {
289 Error("ProcessEvent", "header size (%d) exceeds number of bytes "
290 "to read (%d)", header->GetHeadSize(), toRead);
291 if (AliDebugLevel() > 0) ToAliDebug(1, header->Dump(););
292 return kErrHeaderSize;
293 }
e10815f1 294
cce65444 295 // Loop over all sub-events... (LDCs)
296 Int_t nsub = 1;
297 while (toRead > 0) {
298 if (isIovecArray) data = (char*) ((iovec*) event)[nsub].iov_base;
e10815f1 299
33314186 300 // AliDebug(1, Form("reading LDC %d", nsub));
e10815f1 301
33314186 302 AliRawEventV2 *subEvent = fEvent->NextSubEvent();
e10815f1 303
cce65444 304 // Read sub-event header
305 AliRawEventHeaderBase *subHeader = subEvent->GetHeader(data);
306 if ((status = subHeader->ReadHeader(data)) != (Int_t)subHeader->GetHeadSize()) {
307 return kErrSubHeader;
308 }
e10815f1 309
33314186 310 // if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump(););
e10815f1 311
cce65444 312 toRead -= subHeader->GetHeadSize();
e10815f1 313
cce65444 314 Int_t rawSize = subHeader->GetEventSize() - subHeader->GetHeadSize();
e10815f1 315
cce65444 316 // Make sure raw data less than left over bytes for current event
317 if (rawSize > toRead) {
318 Warning("ProcessEvent", "raw data size (%d) exceeds number of "
319 "bytes to read (%d)\n", rawSize, toRead);
320 if (AliDebugLevel() > 0) ToAliDebug(1, subHeader->Dump(););
321 return kErrDataSize;
322 }
323
324 // Read Equipment Headers (in case of physics or calibration event)
33314186 325 if (eventType == AliRawEventHeaderBase::kPhysicsEvent ||
326 eventType == AliRawEventHeaderBase::kCalibrationEvent ||
327 eventType == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent ||
328 eventType == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent ||
329 eventType == AliRawEventHeaderBase::kStartOfData ||
330 eventType == AliRawEventHeaderBase::kEndOfData) {
cce65444 331 while (rawSize > 0) {
33314186 332 AliRawEquipmentV2 &equipment = *subEvent->NextEquipment();
cce65444 333 AliRawEquipmentHeader &equipmentHeader =
334 *equipment.GetEquipmentHeader();
335 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
336 if ((status = ReadEquipmentHeader(equipmentHeader, header->DataIsSwapped(),
337 data)) != equipHeaderSize) {
338 return kErrEquipmentHeader;
339 }
340
33314186 341 // if (AliDebugLevel() > 2) ToAliDebug(3, equipmentHeader.Dump(););
cce65444 342
343 toRead -= equipHeaderSize;
344 rawSize -= equipHeaderSize;
345
346 // Read equipment raw data
33314186 347 AliRawDataArrayV2 *arr = fRawDB->GetRawDataArray(equipmentHeader.GetEquipmentSize(),
348 equipmentHeader.GetId());
349 AliRawData &subRaw = *equipment.NextRawData(arr);
cce65444 350
351 Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize;
352 if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) {
353 return kErrEquipment;
354 }
355 toRead -= eqSize;
356 rawSize -= eqSize;
e10815f1 357
e10815f1 358 }
e10815f1 359
cce65444 360 } else { // Read only raw data but no equipment header
42127dba 361 if (rawSize) {
33314186 362 AliRawEquipmentV2 &equipment = *subEvent->NextEquipment();
363 AliRawEquipmentHeader &equipmentHeader =
364 *equipment.GetEquipmentHeader();
365 equipmentHeader.Reset();
366 AliRawDataArrayV2 *arr = fRawDB->GetRawDataArray(equipmentHeader.GetEquipmentSize(),
367 equipmentHeader.GetId());
368 AliRawData &subRaw = *equipment.NextRawData(arr);
42127dba 369 if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) {
370 return kErrEquipment;
371 }
372 toRead -= rawSize;
e10815f1 373 }
a197a4ce 374 }
a197a4ce 375
cce65444 376 nsub++;
e10815f1 377 }
e10815f1 378 }
a197a4ce 379
e10815f1 380 // High Level Event Filter
381 if (fFilterMode != kFilterOff) {
33314186 382 if (eventType == AliRawEventHeaderBase::kPhysicsEvent ||
383 eventType == AliRawEventHeaderBase::kCalibrationEvent ||
384 eventType == AliRawEventHeaderBase::kSystemSoftwareTriggerEvent ||
385 eventType == AliRawEventHeaderBase::kDetectorSoftwareTriggerEvent ||
386 eventType == AliRawEventHeaderBase::kStartOfData ||
387 eventType == AliRawEventHeaderBase::kEndOfData) {
e10815f1 388 Bool_t result = kFALSE;
389 for (Int_t iFilter = 0; iFilter < fFilters.GetEntriesFast(); iFilter++) {
390 AliFilter* filter = (AliFilter*) fFilters[iFilter];
391 if (!filter) continue;
392 if (filter->Filter(fEvent, fESD)) result = kTRUE;
a197a4ce 393 }
e10815f1 394 if ((fFilterMode == kFilterOn) && !result) return kFilterReject;
395 }
396 }
a197a4ce 397
e10815f1 398 // Store raw event in tree
399 Int_t nBytes = fRawDB->Fill();
a197a4ce 400
54dd2271 401 // Fill the event tag object
33314186 402 fEventTag->SetHeader(header);
54dd2271 403 fEventTag->SetGUID(fRawDB->GetDB()->GetUUID().AsString());
404 fEventTag->SetEventNumber(fRawDB->GetEvents()-1);
405
f2dc6b20 406 // Create Tag DB here only after the raw data header
407 // version was already identified
408 if (!fIsTagDBCreated) {
581835ab 409 if (!fFileNameTagDB.IsNull()) {
f2dc6b20 410 if (fMaxSizeTagDB > 0) {
54dd2271 411 fTagDB = new AliTagDB(fEventTag, NULL);
f2dc6b20 412 fTagDB->SetMaxSize(fMaxSizeTagDB);
581835ab 413 fTagDB->SetFS(fFileNameTagDB.Data());
19359f9c 414 if (!fTagDB->Create()) return kErrTagFile;
f2dc6b20 415 } else {
581835ab 416 fTagDB = new AliTagDB(fEventTag, fFileNameTagDB.Data());
19359f9c 417 if (fTagDB->IsZombie()) return kErrTagFile;
f2dc6b20 418 }
419 }
420 fIsTagDBCreated = kTRUE;
421 }
422
54dd2271 423 // Store event tag in tree
e10815f1 424 if (fTagDB) fTagDB->Fill();
a197a4ce 425
37f78e68 426 // Make top event object ready for next event data
427 fEvent->Reset();
33314186 428 fRawDB->Reset();
429
37f78e68 430 // Clean up HLT ESD for the next event
431 if (fESD) fESD->Reset();
432
f07ec911 433 if(nBytes >= 0)
434 return nBytes;
435 else
436 return kErrWriting;
e10815f1 437}
438
d21e9888 439//______________________________________________________________________________
60838f24 440Long64_t AliMDC::GetTotalSize()
d21e9888 441{
442// return the total current raw DB file size
443
444 if (!fRawDB) return -1;
445
446 return fRawDB->GetTotalSize();
447}
448
e10815f1 449//______________________________________________________________________________
d2450633 450Long64_t AliMDC::Close()
e10815f1 451{
452// close the current raw DB file
453
f07ec911 454 if (!fRawDB) return -1;
e10815f1 455
d2450633 456 Long64_t filesize = fRawDB->Close();
e10815f1 457 delete fRawDB;
458 fRawDB = NULL;
f07ec911 459 return filesize;
e10815f1 460}
a197a4ce 461
0cd3f979 462//______________________________________________________________________________
463Long64_t AliMDC::AutoSave()
464{
465 // Auto-save the raw-data
466 // and esd (if any) trees
467
468 if (!fRawDB) return -1;
469
470 return fRawDB->AutoSave();
471}
472
e10815f1 473//______________________________________________________________________________
474Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
475 EWriteMode mode, Double_t maxFileSize,
476 const char* fs1, const char* fs2)
477{
478 // Run the MDC processor. Read from the input stream and only return
479 // when the input gave and EOF or a fatal error occured. On success 0
480 // is returned, 1 in case of a fatality.
481 // inputFile is the name of the DATE input file; if NULL the input will
482 // be taken from the event builder.
483 // If loop is set the same input file will be reused in an infinite loop.
484 // mode specifies the type of the raw DB.
485 // maxFileSize is the maximal size of the raw DB.
486 // fs1 and fs2 are the file system locations of the raw DB.
487
488 Info("Run", "input = %s, rawdb size = %f, filter = %s, "
489 "looping = %s, compression = %d, delete files = %s",
490 inputFile ? inputFile : "event builder", maxFileSize,
491 fFilterMode == kFilterOff ? "off" :
492 (fFilterMode == kFilterOn ? "on" : "transparent"),
493 loop ? "yes" : "no", fCompress, fDeleteFiles ? "yes" : "no");
494
495 // Open the input file
496 Int_t fd = -1;
497 if (inputFile) {
498 if ((fd = open(inputFile, O_RDONLY)) == -1) {
499 Error("Run", "cannot open input file %s", inputFile);
500 return 1;
501 }
502 }
a197a4ce 503
e10815f1 504 // Used for statistics
505 TStopwatch timer;
506 timer.Start();
e10815f1 507 Float_t chunkSize = maxFileSize/100, nextChunk = chunkSize;
508
509 // Create new raw DB.
510 if (fRawDB) Close();
a197a4ce 511
c92de424 512 if (Open(mode,NULL,maxFileSize,fs1,fs2) < 0) {
513 close(fd);
514 return 1;
515 }
e10815f1 516 // Process input stream
a197a4ce 517#ifdef USE_EB
e10815f1 518 Int_t eorFlag = 0;
a197a4ce 519#endif
e10815f1 520 char* event = NULL;
521 UInt_t eventSize = 0;
522 Int_t numEvents = 0;
523
f2dc6b20 524 AliRawEventHeaderBase header;
33314186 525 AliRawEventHeaderBase *hdr = NULL;
f2dc6b20 526
e10815f1 527 while (kTRUE) {
528
529 // If we were in looping mode stop directly after a SIGUSR1 signal
530 if (fStop) {
531 Info("Run", "Stopping loop, processed %d events", numEvents);
532 break;
533 }
a197a4ce 534
e10815f1 535 if (!inputFile) { // get data from event builder
94d918a7 536#ifdef USE_EB
e10815f1 537 if ((eorFlag = ebEor())) break;
538 if ((event = (char*)ebGetNextEvent()) == (char*)-1) {
539 Error("Run", "error getting next event (%s)", ebGetLastError());
540 break;
541 }
542 if (event == 0) {
543 // no event, sleep for 1 second and try again
544 gSystem->Sleep(1000);
545 continue;
546 }
547#else
548 Error("Run", "AliMDC was compiled without event builder support");
549 delete fRawDB;
550 fRawDB = NULL;
c92de424 551 close(fd);
e10815f1 552 return 1;
94d918a7 553#endif
554
e10815f1 555 } else { // get data from a file
f2dc6b20 556 {
557 Int_t nrecv;
558 if ((nrecv = Read(fd, header.HeaderBaseBegin(), header.HeaderBaseSize())) !=
559 header.HeaderBaseSize()) {
560 if (nrecv == 0) { // eof
561 if (loop) {
562 ::lseek(fd, 0, SEEK_SET);
563 continue;
564 } else {
565 break;
566 }
567 } else {
568 Error("Run", "error reading base header");
569 Close();
570 delete[] event;
c92de424 571 close(fd);
f2dc6b20 572 return 1;
573 }
574 }
575 }
576 char *data = (char *)header.HeaderBaseBegin();
33314186 577 if (!hdr) {
578 hdr = AliRawEventHeaderBase::Create(data);
579 }
580 else {
581 memcpy(hdr->HeaderBaseBegin(), header.HeaderBaseBegin(), header.HeaderBaseSize());
582 }
e10815f1 583 Int_t nrecv;
f2dc6b20 584 if ((nrecv = Read(fd, hdr->HeaderBegin(), hdr->HeaderSize())) !=
585 hdr->HeaderSize()) {
e10815f1 586 if (nrecv == 0) { // eof
587 if (loop) {
588 ::lseek(fd, 0, SEEK_SET);
f2dc6b20 589 delete hdr;
e10815f1 590 continue;
591 } else {
f2dc6b20 592 delete hdr;
e10815f1 593 break;
594 }
595 } else {
596 Error("Run", "error reading header");
597 Close();
598 delete[] event;
f2dc6b20 599 delete hdr;
c92de424 600 close(fd);
e10815f1 601 return 1;
602 }
a197a4ce 603 }
f2dc6b20 604 if (eventSize < hdr->GetEventSize()) {
e10815f1 605 delete[] event;
f2dc6b20 606 eventSize = 2 * hdr->GetEventSize();
e10815f1 607 event = new char[eventSize];
a109e73e 608 }
e653e3e1 609 memcpy(event, header.HeaderBaseBegin(), header.HeaderBaseSize());
f2dc6b20 610 memcpy(event+hdr->HeaderBaseSize(), hdr->HeaderBegin(), hdr->HeaderSize());
611 if (hdr->GetExtendedDataSize() != 0)
612 memcpy(event+hdr->HeaderBaseSize()+hdr->HeaderSize(),
613 hdr->GetExtendedData(), hdr->GetExtendedDataSize());
614 Int_t size = hdr->GetEventSize() - hdr->GetHeadSize();
615 if (Read(fd, event + hdr->GetHeadSize(), size) != size) {
e10815f1 616 Error("Run", "error reading data");
617 Close();
618 delete[] event;
f2dc6b20 619 delete hdr;
c92de424 620 close(fd);
e10815f1 621 return 1;
622 }
623 }
a109e73e 624
e10815f1 625 Int_t result = ProcessEvent(event, !inputFile);
f07ec911 626 if(result < -1)
627 Error("Run", "error writing data. Error code: %d",result);
a197a4ce 628
e10815f1 629 if (result >= 0) {
630 numEvents++;
e10815f1 631 }
a197a4ce 632
e10815f1 633 if (result > 0) {
a197a4ce 634 // Filling time statistics
e10815f1 635 if (fRawDB->GetBytesWritten() > nextChunk) {
e10815f1 636 nextChunk += chunkSize;
a197a4ce 637 }
638
639 // Check size of raw db. If bigger than maxFileSize, close file
640 // and continue with new file.
e10815f1 641 if (fRawDB->GetBytesWritten() > maxFileSize) {
642
643 printf("Written raw DB at a rate of %.1f MB/s\n",
644 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
645
e10815f1 646 if (!fRawDB->NextFile()) {
647 Error("Run", "error opening next raw data file");
648 Close();
649 if (inputFile) delete[] event;
33314186 650 delete hdr;
c92de424 651 close(fd);
e10815f1 652 return 1;
653 }
654
655 printf("Filling raw DB %s\n", fRawDB->GetDBName());
e10815f1 656 timer.Start();
e10815f1 657 nextChunk = chunkSize;
a197a4ce 658 }
659
660 // Check size of tag db
e10815f1 661 if (fTagDB && fTagDB->FileFull()) {
662 if (!fTagDB->NextFile()) {
663 delete fTagDB;
664 fTagDB = 0;
665 } else {
666 printf("Filling tag DB %s\n", fTagDB->GetDBName());
667 }
a197a4ce 668 }
e10815f1 669 }
a197a4ce 670
e10815f1 671 // Make top event object ready for next event data
672 //printf("Event %d has %d sub-events\n", numEvents, fEvent->GetNSubEvents());
37f78e68 673 // fEvent->Reset();
e10815f1 674 // Clean up HLT ESD for the next event
37f78e68 675 // if (fESD) fESD->Reset();
e10815f1 676
677 if (!inputFile) {
a197a4ce 678#ifdef USE_EB
e10815f1 679 if (!ebReleaseEvent((iovec*)event)) {
680 Error("Run", "problem releasing event (%s)", ebGetLastError());
681 break;
a197a4ce 682 }
683#endif
e10815f1 684 }
685 }
a197a4ce 686
33314186 687 delete hdr;
688
e10815f1 689 printf("Written raw DB at a rate of %.1f MB/s\n",
690 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
a197a4ce 691
e10815f1 692 // Write stats to raw db and run db and delete stats object
693 Close();
a197a4ce 694
e10815f1 695 if (!inputFile) {
a197a4ce 696#ifdef USE_EB
e10815f1 697 // Print eor flag
698 if (eorFlag) {
a197a4ce 699 Info("Run", "event builder reported end of run (%d)", eorFlag);
e10815f1 700 }
a197a4ce 701#endif
e10815f1 702 } else {
703 // Close input source
704 close(fd);
f2dc6b20 705 delete [] event;
e10815f1 706 }
a197a4ce 707
e10815f1 708 return 0;
a197a4ce 709}
710
711//______________________________________________________________________________
e10815f1 712Int_t AliMDC::Read(Int_t fd, void *buffer, Int_t length)
a197a4ce 713{
714 // Read exactly length bytes into buffer. Returns number of bytes
715 // received, returns -1 in case of error and 0 for EOF.
716
717 errno = 0;
718
e10815f1 719 if (fd < 0) return -1;
a197a4ce 720
721 Int_t n, nrecv = 0;
722 char *buf = (char *)buffer;
723
724 for (n = 0; n < length; n += nrecv) {
e10815f1 725 if ((nrecv = read(fd, buf+n, length-n)) <= 0) {
a197a4ce 726 if (nrecv == 0)
727 break; // EOF
728 if (errno != EINTR)
729 SysError("Read", "read");
730 return -1;
731 }
732 }
733 return n;
734}
735
a197a4ce 736//______________________________________________________________________________
737Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
e10815f1 738 Bool_t isSwapped, char*& data)
a197a4ce 739{
e10815f1 740 // Read equipment header info from DATE data stream. Returns bytes read
741 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
742 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
743 // and we will swap the header to host format.
744
745 memcpy(header.HeaderBegin(), data, header.HeaderSize());
746 data += header.HeaderSize();
747
748 // Swap equipment header data if needed
749 if (isSwapped)
750 header.Swap();
751
752 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
753 Error("ReadEquipmentHeader", "invalid equipment header size");
754 // try recovery... how?
755 return -1;
756 }
a197a4ce 757
e10815f1 758 return header.HeaderSize();
a197a4ce 759}
760
761//______________________________________________________________________________
e10815f1 762Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, char*& data)
a197a4ce 763{
e10815f1 764 // Read raw data from DATE data stream. Returns bytes read (i.e.
765 // size), -1 in case of error and 0 for EOF.
a197a4ce 766
e10815f1 767 raw.SetBuffer(data, size);
768 data += size;
a197a4ce 769
e10815f1 770 return size;
a197a4ce 771}
772
773//______________________________________________________________________________
e10815f1 774void AliMDC::Stop()
a197a4ce 775{
e10815f1 776 // Stop the event loop
777
778 fStop = kTRUE;
779 if (fRawDB) fRawDB->Stop();
a197a4ce 780}
781
e10815f1 782