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