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