]> git.uio.no Git - u/mrichter/AliRoot.git/blame - RAW/AliMDC.cxx
Coverity 22681
[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) {
b7d121f4 513 if (fd>-1) close(fd);
c92de424 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;
e10815f1 551 return 1;
94d918a7 552#endif
553
e10815f1 554 } else { // get data from a file
f2dc6b20 555 {
556 Int_t nrecv;
557 if ((nrecv = Read(fd, header.HeaderBaseBegin(), header.HeaderBaseSize())) !=
558 header.HeaderBaseSize()) {
559 if (nrecv == 0) { // eof
560 if (loop) {
561 ::lseek(fd, 0, SEEK_SET);
562 continue;
563 } else {
564 break;
565 }
566 } else {
567 Error("Run", "error reading base header");
568 Close();
569 delete[] event;
b7d121f4 570 if (fd>-1) close(fd);
f2dc6b20 571 return 1;
572 }
573 }
574 }
575 char *data = (char *)header.HeaderBaseBegin();
33314186 576 if (!hdr) {
577 hdr = AliRawEventHeaderBase::Create(data);
578 }
579 else {
580 memcpy(hdr->HeaderBaseBegin(), header.HeaderBaseBegin(), header.HeaderBaseSize());
581 }
e10815f1 582 Int_t nrecv;
f2dc6b20 583 if ((nrecv = Read(fd, hdr->HeaderBegin(), hdr->HeaderSize())) !=
584 hdr->HeaderSize()) {
e10815f1 585 if (nrecv == 0) { // eof
586 if (loop) {
587 ::lseek(fd, 0, SEEK_SET);
f2dc6b20 588 delete hdr;
e10815f1 589 continue;
590 } else {
f2dc6b20 591 delete hdr;
e10815f1 592 break;
593 }
594 } else {
595 Error("Run", "error reading header");
596 Close();
597 delete[] event;
f2dc6b20 598 delete hdr;
b7d121f4 599 if (fd>-1) close(fd);
e10815f1 600 return 1;
601 }
a197a4ce 602 }
f2dc6b20 603 if (eventSize < hdr->GetEventSize()) {
e10815f1 604 delete[] event;
f2dc6b20 605 eventSize = 2 * hdr->GetEventSize();
e10815f1 606 event = new char[eventSize];
a109e73e 607 }
e653e3e1 608 memcpy(event, header.HeaderBaseBegin(), header.HeaderBaseSize());
f2dc6b20 609 memcpy(event+hdr->HeaderBaseSize(), hdr->HeaderBegin(), hdr->HeaderSize());
610 if (hdr->GetExtendedDataSize() != 0)
611 memcpy(event+hdr->HeaderBaseSize()+hdr->HeaderSize(),
612 hdr->GetExtendedData(), hdr->GetExtendedDataSize());
613 Int_t size = hdr->GetEventSize() - hdr->GetHeadSize();
614 if (Read(fd, event + hdr->GetHeadSize(), size) != size) {
e10815f1 615 Error("Run", "error reading data");
616 Close();
617 delete[] event;
f2dc6b20 618 delete hdr;
b7d121f4 619 if (fd>-1) close(fd);
e10815f1 620 return 1;
621 }
622 }
a109e73e 623
e10815f1 624 Int_t result = ProcessEvent(event, !inputFile);
f07ec911 625 if(result < -1)
626 Error("Run", "error writing data. Error code: %d",result);
a197a4ce 627
e10815f1 628 if (result >= 0) {
629 numEvents++;
e10815f1 630 }
a197a4ce 631
e10815f1 632 if (result > 0) {
a197a4ce 633 // Filling time statistics
e10815f1 634 if (fRawDB->GetBytesWritten() > nextChunk) {
e10815f1 635 nextChunk += chunkSize;
a197a4ce 636 }
637
638 // Check size of raw db. If bigger than maxFileSize, close file
639 // and continue with new file.
e10815f1 640 if (fRawDB->GetBytesWritten() > maxFileSize) {
641
642 printf("Written raw DB at a rate of %.1f MB/s\n",
643 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
644
e10815f1 645 if (!fRawDB->NextFile()) {
646 Error("Run", "error opening next raw data file");
647 Close();
648 if (inputFile) delete[] event;
33314186 649 delete hdr;
b7d121f4 650 if (fd>-1) close(fd);
e10815f1 651 return 1;
652 }
653
654 printf("Filling raw DB %s\n", fRawDB->GetDBName());
e10815f1 655 timer.Start();
e10815f1 656 nextChunk = chunkSize;
a197a4ce 657 }
658
659 // Check size of tag db
e10815f1 660 if (fTagDB && fTagDB->FileFull()) {
661 if (!fTagDB->NextFile()) {
662 delete fTagDB;
663 fTagDB = 0;
664 } else {
665 printf("Filling tag DB %s\n", fTagDB->GetDBName());
666 }
a197a4ce 667 }
e10815f1 668 }
a197a4ce 669
e10815f1 670 // Make top event object ready for next event data
671 //printf("Event %d has %d sub-events\n", numEvents, fEvent->GetNSubEvents());
37f78e68 672 // fEvent->Reset();
e10815f1 673 // Clean up HLT ESD for the next event
37f78e68 674 // if (fESD) fESD->Reset();
e10815f1 675
676 if (!inputFile) {
a197a4ce 677#ifdef USE_EB
e10815f1 678 if (!ebReleaseEvent((iovec*)event)) {
679 Error("Run", "problem releasing event (%s)", ebGetLastError());
680 break;
a197a4ce 681 }
682#endif
e10815f1 683 }
684 }
a197a4ce 685
33314186 686 delete hdr;
687
e10815f1 688 printf("Written raw DB at a rate of %.1f MB/s\n",
689 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
a197a4ce 690
e10815f1 691 // Write stats to raw db and run db and delete stats object
692 Close();
a197a4ce 693
e10815f1 694 if (!inputFile) {
a197a4ce 695#ifdef USE_EB
e10815f1 696 // Print eor flag
697 if (eorFlag) {
a197a4ce 698 Info("Run", "event builder reported end of run (%d)", eorFlag);
e10815f1 699 }
a197a4ce 700#endif
e10815f1 701 } else {
702 // Close input source
b7d121f4 703 if (fd>-1) close(fd);
f2dc6b20 704 delete [] event;
e10815f1 705 }
a197a4ce 706
e10815f1 707 return 0;
a197a4ce 708}
709
710//______________________________________________________________________________
e10815f1 711Int_t AliMDC::Read(Int_t fd, void *buffer, Int_t length)
a197a4ce 712{
713 // Read exactly length bytes into buffer. Returns number of bytes
714 // received, returns -1 in case of error and 0 for EOF.
715
716 errno = 0;
717
e10815f1 718 if (fd < 0) return -1;
a197a4ce 719
720 Int_t n, nrecv = 0;
721 char *buf = (char *)buffer;
722
723 for (n = 0; n < length; n += nrecv) {
e10815f1 724 if ((nrecv = read(fd, buf+n, length-n)) <= 0) {
a197a4ce 725 if (nrecv == 0)
726 break; // EOF
727 if (errno != EINTR)
728 SysError("Read", "read");
729 return -1;
730 }
731 }
732 return n;
733}
734
a197a4ce 735//______________________________________________________________________________
736Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
e10815f1 737 Bool_t isSwapped, char*& data)
a197a4ce 738{
e10815f1 739 // Read equipment header info from DATE data stream. Returns bytes read
740 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
741 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
742 // and we will swap the header to host format.
743
744 memcpy(header.HeaderBegin(), data, header.HeaderSize());
745 data += header.HeaderSize();
746
747 // Swap equipment header data if needed
748 if (isSwapped)
749 header.Swap();
750
751 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
752 Error("ReadEquipmentHeader", "invalid equipment header size");
753 // try recovery... how?
754 return -1;
755 }
a197a4ce 756
e10815f1 757 return header.HeaderSize();
a197a4ce 758}
759
760//______________________________________________________________________________
e10815f1 761Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, char*& data)
a197a4ce 762{
e10815f1 763 // Read raw data from DATE data stream. Returns bytes read (i.e.
764 // size), -1 in case of error and 0 for EOF.
a197a4ce 765
e10815f1 766 raw.SetBuffer(data, size);
767 data += size;
a197a4ce 768
e10815f1 769 return size;
a197a4ce 770}
771
772//______________________________________________________________________________
e10815f1 773void AliMDC::Stop()
a197a4ce 774{
e10815f1 775 // Stop the event loop
776
777 fStop = kTRUE;
778 if (fRawDB) fRawDB->Stop();
a197a4ce 779}
780
e10815f1 781