]> git.uio.no Git - u/mrichter/AliRoot.git/blame_incremental - RAW/AliMDC.cxx
Adding MUONraw to the list of libraries
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
... / ...
CommitLineData
1// @(#)alimdc:$Name$:$Id$
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
20/* $Id$ */
21
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). //
36// The AliRunDB class provides the interface to the run and file //
37// catalogues (AliEn or plain MySQL). //
38// The AliStats class provides statics information that is added as //
39// a single keyed object to each raw file. //
40// The AliTagDB provides an interface to a TAG database. //
41// The AliMDC class is usid by the "alimdc" stand-alone program //
42// that reads data directly from DATE. //
43// //
44//////////////////////////////////////////////////////////////////////////
45
46#include <sys/types.h>
47#include <sys/stat.h>
48
49#include <errno.h>
50
51#include <TSystem.h>
52#include <TROOT.h>
53#include <TStopwatch.h>
54
55#include <sys/uio.h>
56#ifdef USE_EB
57#include "libDateEb.h"
58#endif
59
60#include <AliLog.h>
61#include <AliESD.h>
62
63#include "AliRawEvent.h"
64#include "AliRawEventHeaderBase.h"
65#include "AliRawEquipment.h"
66#include "AliRawEquipmentHeader.h"
67#include "AliRawData.h"
68#include "AliStats.h"
69#include "AliRawDB.h"
70#include "AliRawRFIODB.h"
71#include "AliRawCastorDB.h"
72#include "AliRawRootdDB.h"
73#include "AliRawNullDB.h"
74#include "AliTagDB.h"
75#include "AliRunDB.h"
76#include "AliFilter.h"
77
78#include "AliMDC.h"
79
80ClassImp(AliMDC)
81
82
83// Filter names
84const char* const AliMDC::fgkFilterName[kNFilters] = {"AliHoughFilter"};
85
86//______________________________________________________________________________
87AliMDC::AliMDC(Int_t compress, Bool_t deleteFiles, EFilterMode filterMode,
88 const char* localRunDB, Bool_t rdbmsRunDB,
89 const char* alienHostRunDB, const char* alienDirRunDB,
90 Double_t maxSizeTagDB, const char* fileNameTagDB) :
91 fEvent(new AliRawEvent),
92 fESD(NULL),
93 fStats(NULL),
94 fRawDB(NULL),
95 fRunDB(new AliRunDB(localRunDB, rdbmsRunDB, alienHostRunDB, alienDirRunDB)),
96 fTagDB(NULL),
97 fCompress(compress),
98 fDeleteFiles(deleteFiles),
99 fFilterMode(filterMode),
100 fFilters(),
101 fStop(kFALSE),
102 fIsTagDBCreated(kFALSE),
103 fMaxSizeTagDB(maxSizeTagDB),
104 fFileNameTagDB(fileNameTagDB)
105{
106 // Create MDC processor object.
107 // compress is the file compression mode.
108 // If deleteFiles is kTRUE the raw data files will be deleted after they
109 // were closed.
110 // If the filterMode if kFilterOff no filter algorithm will be, if it is
111 // kFilterTransparent the algorthims will be run but no events will be
112 // rejected, if it is kFilterOn the filters will be run and the event will
113 // be rejected if all filters return kFALSE.
114 // localRunDB is the file name of the local run DB; if NULL no local run DB
115 // will be created.
116 // The filling of a MySQL run DB can be switch on or off with rdbmsRunDB.
117 // The host and directory name of the alien run DB can be specified by
118 // alienHostRunDB and alienDirRunDB; if NULL no alien DB will be filled.
119 // If maxSizeTagDB is greater than 0 it determines the maximal size of the
120 // tag DB and then fileNameTagDB is the directory name for the tag DB.
121 // Otherwise fileNameTagDB is the file name of the tag DB. If it is NULL
122 // no tag DB will be created.
123
124
125 if (fFilterMode != kFilterOff) {
126 fESD = new AliESD;
127 }
128
129// Tag DB is now created at the point where the header version is
130// already known
131// if (fileNameTagDB) {
132// if (maxSizeTagDB > 0) {
133// fTagDB = new AliTagDB(fEvent->GetHeader(), NULL);
134// fTagDB->SetMaxSize(maxSizeTagDB);
135// fTagDB->SetFS(fileNameTagDB);
136// fTagDB->Create();
137// } else {
138// fTagDB = new AliTagDB(fEvent->GetHeader(), fileNameTagDB);
139// }
140// }
141
142 // install SIGUSR1 handler to allow clean interrupts
143 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
144
145 // create the high level filters
146 if (fFilterMode != kFilterOff) {
147 for (Int_t iFilter = 0; iFilter < kNFilters; iFilter++) {
148 TClass* filterClass = gROOT->GetClass(fgkFilterName[iFilter]);
149 if (!filterClass) {
150 Warning("AliMDC", "no filter class %s found", fgkFilterName[iFilter]);
151 continue;
152 }
153 AliFilter* filter = (AliFilter*) filterClass->New();
154 if (!filter) {
155 Warning("AliMDC", "creation of filter %s failed", fgkFilterName[iFilter]);
156 continue;
157 }
158 fFilters.Add(filter);
159 }
160 }
161}
162
163//______________________________________________________________________________
164AliMDC::~AliMDC()
165{
166// destructor
167
168 fFilters.Delete();
169 if(fTagDB) delete fTagDB;
170 delete fRunDB;
171 delete fRawDB;
172 delete fStats;
173 delete fESD;
174 delete fEvent;
175}
176
177//______________________________________________________________________________
178AliMDC::AliMDC(const AliMDC& mdc): TObject(mdc)
179{
180// copy constructor
181
182 Fatal("AliMDC", "copy constructor not implemented");
183}
184
185//______________________________________________________________________________
186AliMDC& AliMDC::operator = (const AliMDC& /*mdc*/)
187{
188// assignment operator
189
190 Fatal("operator =", "assignment operator not implemented");
191 return *this;
192}
193
194
195//______________________________________________________________________________
196Int_t AliMDC::Open(EWriteMode mode, const char* fileName)
197{
198// open a new raw DB file
199
200 if (mode == kRFIO)
201 fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, fileName);
202 else if (mode == kROOTD)
203 fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, fileName);
204 else if (mode == kCASTOR)
205 fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, fileName);
206 else if (mode == kDEVNULL)
207 fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, fileName);
208 else
209 fRawDB = new AliRawDB(fEvent, fESD, fCompress, fileName);
210 fRawDB->SetDeleteFiles(fDeleteFiles);
211
212 if (fRawDB->IsZombie()) {
213 delete fRawDB;
214 fRawDB = NULL;
215 return -1;
216 }
217 Info("Open", "Filling raw DB %s\n", fRawDB->GetDBName());
218
219 // Create AliStats object
220 fStats = new AliStats(fRawDB->GetDBName(), fCompress,
221 fFilterMode != kFilterOff);
222 return 0;
223}
224
225//______________________________________________________________________________
226Int_t AliMDC::ProcessEvent(void* event, Bool_t isIovecArray)
227{
228// Convert the DATE event to an AliRawEvent object and store it in the raw DB,
229// optionally also run the filter.
230// event is either a pointer to the streamlined event
231// or, if isIovecArray is kTRUE, a pointer to an array of iovecs with one
232// iovec per subevent (used by the event builder).
233// The return value is the number of written bytes or an error code
234 const UInt_t kFileSizeErrorLevel = 1900000000;
235
236 UInt_t currentFileSize = GetTotalSize();
237 if(currentFileSize > kFileSizeErrorLevel) {
238 Error("ProcessEvent", "file size (%u) exceeds the limit "
239 , currentFileSize);
240 return kErrFileSize;
241 }
242
243 Int_t status;
244 char* data = (char*) event;
245 if (isIovecArray) data = (char*) ((iovec*) event)[0].iov_base;
246
247 // Shortcut for easy header access
248 AliRawEventHeaderBase *header = fEvent->GetHeader(data);
249
250 // Read event header
251 if ((status = header->ReadHeader(data)) != (Int_t)header->GetHeadSize()) {
252 return kErrHeader;
253 }
254
255 if (AliDebugLevel() > 2) ToAliDebug(3, header->Dump(););
256
257 // Check event type and skip "Start of Run", "End of Run",
258 // "Start of Run Files" and "End of Run Files"
259 Int_t size = header->GetEventSize() - header->GetHeadSize();
260 switch (header->Get("Type")) {
261 case AliRawEventHeaderBase::kStartOfRun:
262 case AliRawEventHeaderBase::kEndOfRun:
263 case AliRawEventHeaderBase::kStartOfRunFiles:
264 case AliRawEventHeaderBase::kEndOfRunFiles:
265 {
266 AliDebug(1, Form("Skipping %s (%d bytes)", header->GetTypeName(), size));
267 return kErrStartEndRun;
268 }
269 default:
270 {
271 AliDebug(1, Form("Processing %s (%d bytes)", header->GetTypeName(), size));
272 }
273 }
274
275 // Amount of data left to read for this event
276 Int_t toRead = size;
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 }
286
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;
291
292 AliDebug(1, Form("reading LDC %d", nsub));
293
294 AliRawEvent *subEvent = fEvent->NextSubEvent();
295
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 }
301
302 if (AliDebugLevel() > 2) ToAliDebug(3, subHeader->Dump(););
303
304 toRead -= subHeader->GetHeadSize();
305
306 Int_t rawSize = subHeader->GetEventSize() - subHeader->GetHeadSize();
307
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 while (rawSize > 0) {
320 AliRawEquipment &equipment = *subEvent->NextEquipment();
321 AliRawEquipmentHeader &equipmentHeader =
322 *equipment.GetEquipmentHeader();
323 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
324 if ((status = ReadEquipmentHeader(equipmentHeader, header->DataIsSwapped(),
325 data)) != equipHeaderSize) {
326 return kErrEquipmentHeader;
327 }
328 toRead -= equipHeaderSize;
329 rawSize -= equipHeaderSize;
330
331 // Read equipment raw data
332 AliRawData &subRaw = *equipment.GetRawData();
333
334 Int_t eqSize = equipmentHeader.GetEquipmentSize() - equipHeaderSize;
335 if ((status = ReadRawData(subRaw, eqSize, data)) != eqSize) {
336 return kErrEquipment;
337 }
338 toRead -= eqSize;
339 rawSize -= eqSize;
340
341 }
342
343 } else { // Read only raw data but no equipment header
344 AliRawEquipment &equipment = *subEvent->NextEquipment();
345 AliRawData &subRaw = *equipment.GetRawData();
346 if ((status = ReadRawData(subRaw, rawSize, data)) != rawSize) {
347 return kErrEquipment;
348 }
349 toRead -= rawSize;
350
351 }
352
353 nsub++;
354 }
355
356 // High Level Event Filter
357 if (fFilterMode != kFilterOff) {
358 if (header->Get("Type") == AliRawEventHeaderBase::kPhysicsEvent ||
359 header->Get("Type") == AliRawEventHeaderBase::kCalibrationEvent) {
360 Bool_t result = kFALSE;
361 for (Int_t iFilter = 0; iFilter < fFilters.GetEntriesFast(); iFilter++) {
362 AliFilter* filter = (AliFilter*) fFilters[iFilter];
363 if (!filter) continue;
364 if (filter->Filter(fEvent, fESD)) result = kTRUE;
365 }
366 if ((fFilterMode == kFilterOn) && !result) return kFilterReject;
367 }
368 }
369
370 // Set stat info for first event of this file
371 if (fRawDB->GetEvents() == 0)
372 fStats->SetFirstId(header->Get("RunNb"), header->GetP("Id")[0]);
373
374 // Store raw event in tree
375 Int_t nBytes = fRawDB->Fill();
376
377 // Create Tag DB here only after the raw data header
378 // version was already identified
379 if (!fIsTagDBCreated) {
380 if (fFileNameTagDB) {
381 if (fMaxSizeTagDB > 0) {
382 fTagDB = new AliTagDB(fEvent->GetHeader(), NULL);
383 fTagDB->SetMaxSize(fMaxSizeTagDB);
384 fTagDB->SetFS(fFileNameTagDB);
385 fTagDB->Create();
386 } else {
387 fTagDB = new AliTagDB(fEvent->GetHeader(), fFileNameTagDB);
388 }
389 }
390 fIsTagDBCreated = kTRUE;
391 }
392
393 // Store header in tree
394 if (fTagDB) fTagDB->Fill();
395
396 // Make top event object ready for next event data
397 fEvent->Reset();
398 // Clean up HLT ESD for the next event
399 if (fESD) fESD->Reset();
400
401 if(nBytes >= 0)
402 return nBytes;
403 else
404 return kErrWriting;
405}
406
407//______________________________________________________________________________
408Int_t AliMDC::GetTotalSize()
409{
410// return the total current raw DB file size
411
412 if (!fRawDB) return -1;
413
414 return fRawDB->GetTotalSize();
415}
416
417//______________________________________________________________________________
418Int_t AliMDC::Close()
419{
420// close the current raw DB file
421
422 if (!fRawDB) return -1;
423
424 fRawDB->WriteStats(fStats);
425 fRunDB->Update(fStats);
426 Int_t filesize = fRawDB->Close();
427 delete fRawDB;
428 fRawDB = NULL;
429 delete fStats;
430 fStats = NULL;
431 return filesize;
432}
433
434//______________________________________________________________________________
435Int_t AliMDC::Run(const char* inputFile, Bool_t loop,
436 EWriteMode mode, Double_t maxFileSize,
437 const char* fs1, const char* fs2)
438{
439 // Run the MDC processor. Read from the input stream and only return
440 // when the input gave and EOF or a fatal error occured. On success 0
441 // is returned, 1 in case of a fatality.
442 // inputFile is the name of the DATE input file; if NULL the input will
443 // be taken from the event builder.
444 // If loop is set the same input file will be reused in an infinite loop.
445 // mode specifies the type of the raw DB.
446 // maxFileSize is the maximal size of the raw DB.
447 // fs1 and fs2 are the file system locations of the raw DB.
448
449 Info("Run", "input = %s, rawdb size = %f, filter = %s, "
450 "looping = %s, compression = %d, delete files = %s",
451 inputFile ? inputFile : "event builder", maxFileSize,
452 fFilterMode == kFilterOff ? "off" :
453 (fFilterMode == kFilterOn ? "on" : "transparent"),
454 loop ? "yes" : "no", fCompress, fDeleteFiles ? "yes" : "no");
455
456 // Open the input file
457 Int_t fd = -1;
458 if (inputFile) {
459 if ((fd = open(inputFile, O_RDONLY)) == -1) {
460 Error("Run", "cannot open input file %s", inputFile);
461 return 1;
462 }
463 }
464
465 // Used for statistics
466 TStopwatch timer;
467 timer.Start();
468 Double_t told = 0, tnew = 0;
469 Float_t chunkSize = maxFileSize/100, nextChunk = chunkSize;
470
471 // Create new raw DB.
472 if (fRawDB) Close();
473 if (mode == kRFIO) {
474 fRawDB = new AliRawRFIODB(fEvent, fESD, fCompress, NULL);
475 } else if (mode == kROOTD) {
476 fRawDB = new AliRawRootdDB(fEvent, fESD, fCompress, NULL);
477 } else if (mode == kCASTOR) {
478 fRawDB = new AliRawCastorDB(fEvent, fESD, fCompress, NULL);
479 } else if (mode == kDEVNULL) {
480 fRawDB = new AliRawNullDB(fEvent, fESD, fCompress, NULL);
481 } else {
482 fRawDB = new AliRawDB(fEvent, fESD, fCompress, NULL);
483 }
484 fRawDB->SetMaxSize(maxFileSize);
485 fRawDB->SetFS(fs1, fs2);
486 fRawDB->SetDeleteFiles(fDeleteFiles);
487 fRawDB->Create();
488
489 if (fRawDB->IsZombie()) {
490 delete fRawDB;
491 fRawDB = NULL;
492 return 1;
493 }
494 printf("Filling raw DB %s\n", fRawDB->GetDBName());
495
496 // Create AliStats object
497 fStats = new AliStats(fRawDB->GetDBName(), fCompress,
498 fFilterMode != kFilterOff);
499
500 // Process input stream
501#ifdef USE_EB
502 Int_t eorFlag = 0;
503#endif
504 char* event = NULL;
505 UInt_t eventSize = 0;
506 Int_t numEvents = 0;
507
508 AliRawEventHeaderBase header;
509
510 while (kTRUE) {
511
512 // If we were in looping mode stop directly after a SIGUSR1 signal
513 if (fStop) {
514 Info("Run", "Stopping loop, processed %d events", numEvents);
515 break;
516 }
517
518 if (!inputFile) { // get data from event builder
519#ifdef USE_EB
520 if ((eorFlag = ebEor())) break;
521 if ((event = (char*)ebGetNextEvent()) == (char*)-1) {
522 Error("Run", "error getting next event (%s)", ebGetLastError());
523 break;
524 }
525 if (event == 0) {
526 // no event, sleep for 1 second and try again
527 gSystem->Sleep(1000);
528 continue;
529 }
530#else
531 Error("Run", "AliMDC was compiled without event builder support");
532 delete fRawDB;
533 fRawDB = NULL;
534 delete fStats;
535 fStats = NULL;
536 return 1;
537#endif
538
539 } else { // get data from a file
540 {
541 Int_t nrecv;
542 if ((nrecv = Read(fd, header.HeaderBaseBegin(), header.HeaderBaseSize())) !=
543 header.HeaderBaseSize()) {
544 if (nrecv == 0) { // eof
545 if (loop) {
546 ::lseek(fd, 0, SEEK_SET);
547 continue;
548 } else {
549 break;
550 }
551 } else {
552 Error("Run", "error reading base header");
553 Close();
554 delete[] event;
555 return 1;
556 }
557 }
558 }
559 char *data = (char *)header.HeaderBaseBegin();
560 AliRawEventHeaderBase *hdr = AliRawEventHeaderBase::Create(data);
561 Int_t nrecv;
562 if ((nrecv = Read(fd, hdr->HeaderBegin(), hdr->HeaderSize())) !=
563 hdr->HeaderSize()) {
564 if (nrecv == 0) { // eof
565 if (loop) {
566 ::lseek(fd, 0, SEEK_SET);
567 delete hdr;
568 continue;
569 } else {
570 delete hdr;
571 break;
572 }
573 } else {
574 Error("Run", "error reading header");
575 Close();
576 delete[] event;
577 delete hdr;
578 return 1;
579 }
580 }
581 if (eventSize < hdr->GetEventSize()) {
582 delete[] event;
583 eventSize = 2 * hdr->GetEventSize();
584 event = new char[eventSize];
585 }
586 memcpy(event, hdr->HeaderBaseBegin(), hdr->HeaderBaseSize());
587 memcpy(event+hdr->HeaderBaseSize(), hdr->HeaderBegin(), hdr->HeaderSize());
588 if (hdr->GetExtendedDataSize() != 0)
589 memcpy(event+hdr->HeaderBaseSize()+hdr->HeaderSize(),
590 hdr->GetExtendedData(), hdr->GetExtendedDataSize());
591 Int_t size = hdr->GetEventSize() - hdr->GetHeadSize();
592 if (Read(fd, event + hdr->GetHeadSize(), size) != size) {
593 Error("Run", "error reading data");
594 Close();
595 delete[] event;
596 delete hdr;
597 return 1;
598 }
599 delete hdr;
600 }
601
602 Int_t result = ProcessEvent(event, !inputFile);
603 if(result < -1)
604 Error("Run", "error writing data. Error code: %d",result);
605
606 if (result >= 0) {
607 numEvents++;
608 if (!(numEvents%10))
609 printf("Processed event %d (%d)\n", numEvents, fRawDB->GetEvents());
610 }
611
612 if (result > 0) {
613 // Filling time statistics
614 if (fRawDB->GetBytesWritten() > nextChunk) {
615 tnew = timer.RealTime();
616 fStats->Fill(tnew-told);
617 told = tnew;
618 timer.Continue();
619 nextChunk += chunkSize;
620 }
621
622 // Check size of raw db. If bigger than maxFileSize, close file
623 // and continue with new file.
624 if (fRawDB->GetBytesWritten() > maxFileSize) {
625
626 printf("Written raw DB at a rate of %.1f MB/s\n",
627 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
628
629 // Write stats object to raw db, run db, MySQL and AliEn
630 fRawDB->WriteStats(fStats);
631 if (fRunDB) fRunDB->Update(fStats);
632 delete fStats;
633 fStats = NULL;
634
635 if (!fRawDB->NextFile()) {
636 Error("Run", "error opening next raw data file");
637 Close();
638 if (inputFile) delete[] event;
639 return 1;
640 }
641
642 printf("Filling raw DB %s\n", fRawDB->GetDBName());
643 fStats = new AliStats(fRawDB->GetDBName(), fCompress,
644 fFilterMode != kFilterOff);
645
646 timer.Start();
647 told = 0, tnew = 0;
648 nextChunk = chunkSize;
649 }
650
651 // Check size of tag db
652 if (fTagDB && fTagDB->FileFull()) {
653 if (!fTagDB->NextFile()) {
654 delete fTagDB;
655 fTagDB = 0;
656 } else {
657 printf("Filling tag DB %s\n", fTagDB->GetDBName());
658 }
659 }
660 }
661
662 // Make top event object ready for next event data
663 //printf("Event %d has %d sub-events\n", numEvents, fEvent->GetNSubEvents());
664 // fEvent->Reset();
665 // Clean up HLT ESD for the next event
666 // if (fESD) fESD->Reset();
667
668 if (!inputFile) {
669#ifdef USE_EB
670 if (!ebReleaseEvent((iovec*)event)) {
671 Error("Run", "problem releasing event (%s)", ebGetLastError());
672 break;
673 }
674#endif
675 }
676 }
677
678 printf("Written raw DB at a rate of %.1f MB/s\n",
679 fRawDB->GetBytesWritten() / timer.RealTime() / 1000000.);
680
681 // Write stats to raw db and run db and delete stats object
682 Close();
683
684 if (!inputFile) {
685#ifdef USE_EB
686 // Print eor flag
687 if (eorFlag) {
688 Info("Run", "event builder reported end of run (%d)", eorFlag);
689 }
690#endif
691 } else {
692 // Close input source
693 close(fd);
694 delete [] event;
695 }
696
697 return 0;
698}
699
700//______________________________________________________________________________
701Int_t AliMDC::Read(Int_t fd, void *buffer, Int_t length)
702{
703 // Read exactly length bytes into buffer. Returns number of bytes
704 // received, returns -1 in case of error and 0 for EOF.
705
706 errno = 0;
707
708 if (fd < 0) return -1;
709
710 Int_t n, nrecv = 0;
711 char *buf = (char *)buffer;
712
713 for (n = 0; n < length; n += nrecv) {
714 if ((nrecv = read(fd, buf+n, length-n)) <= 0) {
715 if (nrecv == 0)
716 break; // EOF
717 if (errno != EINTR)
718 SysError("Read", "read");
719 return -1;
720 }
721 }
722 return n;
723}
724
725//______________________________________________________________________________
726Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
727 Bool_t isSwapped, char*& data)
728{
729 // Read equipment header info from DATE data stream. Returns bytes read
730 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
731 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
732 // and we will swap the header to host format.
733
734 memcpy(header.HeaderBegin(), data, header.HeaderSize());
735 data += header.HeaderSize();
736
737 // Swap equipment header data if needed
738 if (isSwapped)
739 header.Swap();
740
741 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
742 Error("ReadEquipmentHeader", "invalid equipment header size");
743 // try recovery... how?
744 return -1;
745 }
746
747 return header.HeaderSize();
748}
749
750//______________________________________________________________________________
751Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, char*& data)
752{
753 // Read raw data from DATE data stream. Returns bytes read (i.e.
754 // size), -1 in case of error and 0 for EOF.
755
756 raw.SetBuffer(data, size);
757 data += size;
758
759 return size;
760}
761
762//______________________________________________________________________________
763void AliMDC::Stop()
764{
765 // Stop the event loop
766
767 fStop = kTRUE;
768 if (fRawDB) fRawDB->Stop();
769}
770
771
772//______________________________________________________________________________
773AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const
774 AliMDCInterruptHandler&
775 handler):
776 TSignalHandler(handler)
777{
778// copy constructor
779
780 Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
781}
782
783//______________________________________________________________________________
784AliMDC::AliMDCInterruptHandler&
785 AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler&
786 /*handler*/)
787{
788// assignment operator
789
790 Fatal("operator =", "assignment operator not implemented");
791 return *this;
792}