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