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