Alice dependencies removed.
[u/mrichter/AliRoot.git] / RAW / AliMDC.cxx
CommitLineData
a197a4ce 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
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). //
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
8c49c5a5 46#include <sys/types.h>
47#include <sys/stat.h>
48
a197a4ce 49#include <errno.h>
50
51#include <TSystem.h>
52#include <TError.h>
53#include <TStopwatch.h>
54
55#ifdef ALI_DATE
56#include "event.h"
57#endif
58#ifdef USE_EB
59#include "libDateEb.h"
60#endif
61
62#include "AliRawEvent.h"
63#include "AliRawEventHeader.h"
94d918a7 64#include "AliRawEquipment.h"
a197a4ce 65#include "AliRawEquipmentHeader.h"
66#include "AliRawData.h"
67#include "AliStats.h"
68#include "AliRawDB.h"
69#include "AliRawRFIODB.h"
70#include "AliRawCastorDB.h"
71#include "AliRawRootdDB.h"
72#include "AliRawNullDB.h"
73#include "AliTagDB.h"
74
75#include "AliMDC.h"
76
77
78ClassImp(AliMDC)
79
80
81#define ALIDEBUG(level) \
82 if (AliMDC::Instance() && (AliMDC::Instance()->GetDebugLevel() >= (level)))
83
84
85// Fixed file system locations for the different DB's
86#ifdef USE_RDM
87const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo";
88const char* const AliMDC::fgkRawDBFS[2] = { "/tmp/mdc1", "/tmp/mdc2" };
89const char* const AliMDC::fgkTagDBFS = "/tmp/mdc1/tags";
90const char* const AliMDC::fgkRunDBFS = "/tmp/mdc1/meta";
91const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/user/r/rdm";
92const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/user/r/rdm";
93const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1";
94const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct";
95const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC";
96#else
97const char* const AliMDC::fgkFifo = "/tmp/alimdc.fifo";
98const char* const AliMDC::fgkRawDBFS[2] = { "/data1/mdc", "/data2/mdc" };
99const char* const AliMDC::fgkTagDBFS = "/data1/mdc/tags";
100const char* const AliMDC::fgkRunDBFS = "/data1/mdc/meta";
101const char* const AliMDC::fgkRFIOFS = "rfio:/castor/cern.ch/lcg/dc5";
102const char* const AliMDC::fgkCastorFS = "castor:/castor/cern.ch/lcg/dc5";
103const char* const AliMDC::fgkRootdFS = "root://localhost//tmp/mdc1";
104const char* const AliMDC::fgkAlienHost = "alien://aliens7.cern.ch:15000/?direct";
105const char* const AliMDC::fgkAlienDir = "/alice_mdc/DC";
106#endif
107
108// Maximum size of tag db files
109const Double_t AliMDC::fgkMaxTagFileSize = 2.5e8; // 250MB
110
111Bool_t AliMDC::fgDeleteFiles = kFALSE;
112AliMDC* AliMDC::fgInstance = NULL;
113
114
115//______________________________________________________________________________
116AliMDC::AliMDC(Int_t fd, Int_t compress, Double_t maxFileSize, Bool_t useFilter,
117 EWriteMode mode, Bool_t useLoop, Bool_t delFiles)
118{
119 // Create MDC processor object.
120
121 fFd = fd;
122 fCompress = compress;
123 fMaxFileSize = maxFileSize;
124 fUseFilter = useFilter;
125 fWriteMode = mode;
126 fUseLoop = useLoop;
127 fUseFifo = kFALSE;
128 fUseEb = kFALSE;
129 fStopLoop = kFALSE;
130 fNumEvents = 0;
131 fDebugLevel = 0;
132 fgDeleteFiles = delFiles;
133
134 if (fFd == -1) {
135#ifdef USE_EB
136 if (!ebRegister()) {
137 Error("AliMDC", "cannot register with the event builder (%s)",
138 ebGetLastError());
139 return;
140 }
141 fUseEb = kTRUE;
142#else
143 if ((mkfifo(fgkFifo, 0644) < 0) && (errno != EEXIST)) {
144 Error("AliMDC", "cannot create fifo %s", fgkFifo);
145 return;
146 }
147 if ((chmod(fgkFifo, 0666) == -1) && (errno != EPERM)) {
148 Error("AliMDC", "cannot change permission of fifo %s", fgkFifo);
149 return;
150 }
151 if ((fFd = open(fgkFifo, O_RDONLY)) == -1) {
152 Error("AliMDC", "cannot open input file %s", fgkFifo);
153 return;
154 }
155 fUseFifo = kTRUE;
156#endif
157 fUseLoop = kFALSE;
158 }
159
160 printf("<AliMDC::AliMDC>: input = %s, rawdb size = %f, filter = %s, "
161 "looping = %s, compression = %d, delete files = %s",
162 fUseFifo ? "fifo" : (fUseEb ? "eb" : "file"), fMaxFileSize,
163 fUseFilter ? "on" : "off", fUseLoop ? "yes" : "no", fCompress,
164 fgDeleteFiles ? "yes" : "no");
165 if (fWriteMode == kRFIO)
166 printf(", use RFIO\n");
167 else if (fWriteMode == kROOTD)
168 printf(", use rootd\n");
169 else if (fWriteMode == kCASTOR)
170 printf(", use CASTOR/rootd\n");
171 else if (fWriteMode == kDEVNULL)
172 printf(", write raw data to /dev/null\n");
173 else
174 printf("\n");
175
176 // install SIGUSR1 handler to allow clean interrupts
177 gSystem->AddSignalHandler(new AliMDCInterruptHandler(this));
178
179 fgInstance = this;
180}
181
182//______________________________________________________________________________
183AliMDC::AliMDC(const AliMDC& mdc): TObject(mdc)
184{
185// copy constructor
186
187 Fatal("AliMDC", "copy constructor not implemented");
188}
189
190//______________________________________________________________________________
191AliMDC& AliMDC::operator = (const AliMDC& /*mdc*/)
192{
193// assignment operator
194
195 Fatal("operator =", "assignment operator not implemented");
196 return *this;
197}
198
199//______________________________________________________________________________
200Int_t AliMDC::Run()
201{
202 // Run the MDC processor. Read from the input stream and only return
203 // when the input gave and EOF or a fatal error occured. On success 0
204 // is returned, 1 in case of a fatality.
205
206 TStopwatch timer;
207 Int_t status;
208
209 // Make sure needed directories exist
210 const char *dirs[4];
211 dirs[0] = fgkRawDBFS[0];
212 dirs[1] = fgkRawDBFS[1];
213 dirs[2] = fgkTagDBFS;
214 dirs[3] = fgkRunDBFS;
215 for (int idir = 0; idir < 4; idir++) {
216 gSystem->ResetErrno();
217 gSystem->MakeDirectory(dirs[idir]);
218 if (gSystem->GetErrno() && gSystem->GetErrno() != EEXIST) {
219 SysError("Run", "mkdir %s", dirs[idir]);
220 return 1;
221 }
222 }
223
224 // Used for statistics
225 timer.Start();
226 Double_t told = 0, tnew = 0;
227 Float_t chunkSize = fMaxFileSize/100, nextChunk = chunkSize;
228
229 // Event object used to store event data.
230 AliRawEvent *event = new AliRawEvent;
231
232 // Create new raw DB.
233 AliRawDB *rawdb;
234 if (fWriteMode == kRFIO)
235 rawdb = new AliRawRFIODB(event, fMaxFileSize, fCompress);
236 else if (fWriteMode == kROOTD)
237 rawdb = new AliRawRootdDB(event, fMaxFileSize, fCompress);
238 else if (fWriteMode == kCASTOR)
239 rawdb = new AliRawCastorDB(event, fMaxFileSize, fCompress);
240 else if (fWriteMode == kDEVNULL)
241 rawdb = new AliRawNullDB(event, fMaxFileSize, fCompress);
242 else
243 rawdb = new AliRawDB(event, fMaxFileSize, fCompress);
244
245 if (rawdb->IsZombie()) return 1;
246 printf("Filling raw DB %s\n", rawdb->GetDBName());
247
248 // Create new tag DB.
249 AliTagDB *tagdb = 0;
250#if 0
251 // no tagdb for the time being to get maximum speed
252 if (fWriteMode == fgkDEVNULL)
253 tagdb = new AliTagNullDB(event->GetHeader(), fgkMaxTagFileSize);
254 else
255 tagdb = new AliTagDB(event->GetHeader(), fgkMaxTagFileSize);
256 if (tagdb->IsZombie())
257 tagdb = 0;
258 else
259 printf("Filling tag DB %s\n", tagdb->GetDBName());
260#endif
261
262 // Create AliStats object
263 AliStats *stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
264
265 // Shortcut for easy header access
266 AliRawEventHeader &header = *event->GetHeader();
267
268 // Process input stream
269#ifdef USE_EB
270 Int_t eorFlag = 0;
271 while (!(eorFlag = ebEor())) {
272 struct iovec *ebvec;
273 if ((ebvec = ebGetNextEvent()) == (void *)-1) {
274 Error("Run", "error getting next event (%s)", ebGetLastError());
275 break;
276 }
277 if (ebvec == 0) {
278 // no event, sleep for 1 second and try again
279 gSystem->Sleep(1000);
280 continue;
281 }
282 char *ebdata = (char *) ebvec[0].iov_base;
283#else
284 while (1) {
285 char *ebdata = 0;
286#endif
287
288 // Read event header
289 if ((status = ReadHeader(header, ebdata)) != header.HeaderSize()) {
290 if (status == 0) {
291 if (fUseLoop) {
292#ifndef USE_EB
293 ::lseek(fFd, 0, SEEK_SET);
294#endif
295 continue;
296 }
297 printf("<AliMDC::Run>: EOF, processed %d events\n", fNumEvents);
298 break;
299 }
300 return 1;
301 }
302 ALIDEBUG(3)
303 header.Dump();
304
305 // If we were in looping mode stop directly after a SIGUSR1 signal
306 if (StopLoop()) {
307 Info("Run", "Stopping loop, processed %d events", fNumEvents);
308 break;
309 }
310
311 // Check if event has any hard track flagged
312 Bool_t callFilter = kFALSE;
313 // This needs to be re-engineered for the next ADC...
314 //if (fUseFilter && TEST_USER_ATTRIBUTE(header.GetTypeAttribute(), 0))
315 // callFilter = kTRUE;
316
317 // Check event type and skip "Start of Run", "End of Run",
318 // "Start of Run Files" and "End of Run Files"
319 switch (header.GetType()) {
320 case AliRawEventHeader::kStartOfRun:
321 case AliRawEventHeader::kEndOfRun:
322 case AliRawEventHeader::kStartOfRunFiles:
323 case AliRawEventHeader::kEndOfRunFiles:
324 {
325 Int_t skip = header.GetEventSize() - header.HeaderSize();
326#ifndef USE_EB
327 ::lseek(fFd, skip, SEEK_CUR);
328#endif
329 ALIDEBUG(1)
330 Info("Run", "Skipping %s (%d bytes)", header.GetTypeName(), skip);
331 continue;
332 }
333 default:
334 ALIDEBUG(1) {
335 Int_t s = header.GetEventSize() - header.HeaderSize();
336 Info("Run", "Processing %s (%d bytes)", header.GetTypeName(), s);
337 }
338 }
339
340 // Amount of data left to read for this event
341 Int_t toRead = header.GetEventSize() - header.HeaderSize();
342
343 // If there is less data for this event than the next sub-event
344 // header, something is wrong. Skip to next event...
345 if (toRead < header.HeaderSize()) {
346 ALIDEBUG(1) {
347 Warning("Run",
348 "header size (%d) exceeds number of bytes to read (%d)\n",
349 header.HeaderSize(), toRead);
350 header.Dump();
351 }
352 if ((status = DumpEvent(toRead)) != toRead) {
353 if (status == 0)
354 break;
355 return 1;
356 }
357 Error("Run", "discarding event %d (too little data for header)", fNumEvents);
358 continue;
359 }
360
361 // Loop over all sub-events... (LDCs)
362 Int_t nsub = 1;
363 while (toRead > 0) {
364#ifdef USE_EB
365 ebdata = (char *)ebvec[nsub].iov_base;
366#endif
367
368 ALIDEBUG(1)
369 Info("Run", "reading LDC %d", nsub);
370
371 AliRawEvent *subEvent = event->NextSubEvent();
372
373 // Read sub-event header
374 AliRawEventHeader &subHeader = *subEvent->GetHeader();
375 if ((status = ReadHeader(subHeader, ebdata)) != subHeader.HeaderSize()) {
376 if (status == 0) {
377 Error("Run", "unexpected EOF reading sub-event header");
378 break;
379 }
380 return 1;
381 }
382
383 ALIDEBUG(3)
384 subHeader.Dump();
385
386 toRead -= subHeader.HeaderSize();
387
388#ifdef USE_EB
389 ebdata = (char *)(ebvec[nsub].iov_base) + subHeader.HeaderSize();
390#endif
391
392 Int_t rawSize = subHeader.GetEventSize() - subHeader.HeaderSize();
393
a197a4ce 394 // Make sure raw data less than left over bytes for current event
395 if (rawSize > toRead) {
396 ALIDEBUG(1) {
94d918a7 397 Warning("Run", "raw data size (%d) exceeds number of "
398 "bytes to read (%d)\n", rawSize, toRead);
399 subHeader.Dump();
a197a4ce 400 }
401 if ((status = DumpEvent(toRead)) != toRead) {
402 if (status == 0)
403 break;
404 return 1;
405 }
406 Error("Run", "discarding event %d (too much data)", fNumEvents);
407 continue;
408 }
409
94d918a7 410 // Read Equipment Headers (in case of physics or calibration event)
411 if (header.GetType() == AliRawEventHeader::kPhysicsEvent ||
412 header.GetType() == AliRawEventHeader::kCalibrationEvent) {
413 while (rawSize > 0) {
414 AliRawEquipment &equipment = *subEvent->NextEquipment();
415 AliRawEquipmentHeader &equipmentHeader =
416 *equipment.GetEquipmentHeader();
417 Int_t equipHeaderSize = equipmentHeader.HeaderSize();
418 if ((status = ReadEquipmentHeader(equipmentHeader, header.DataIsSwapped(),
419 ebdata)) != equipHeaderSize) {
420 if (status == 0) {
421 Error("Run", "unexpected EOF reading equipment-header");
422 break;
423 }
424 return 1;
425 }
426 toRead -= equipHeaderSize;
427 rawSize -= equipHeaderSize;
428#ifdef USE_EB
429 ebdata = (char *)(ebvec[nsub].iov_base) +
430 subHeader.HeaderSize() + equipHeaderSize;
431#endif
432
433 // Read equipment raw data
434 AliRawData &subRaw = *equipment.GetRawData();
435 Int_t eqSize = equipmentHeader.GetEquipmentSize() -
436 equipHeaderSize;
437 if ((status = ReadRawData(subRaw, eqSize, ebdata)) != eqSize) {
438 if (status == 0) {
439 Error("Run", "unexpected EOF reading sub-event raw data");
440 break;
441 }
442 return 1;
443 }
444 toRead -= eqSize;
445 rawSize -= eqSize;
a197a4ce 446
94d918a7 447 if (callFilter) {
a197a4ce 448#ifdef ALI_DATE
94d918a7 449 if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0))
450 Filter(subRaw);
451 else {
452 // set size of all sectors without hard track flag to 0
453 subRaw.SetSize(0);
454 }
455#endif
456 }
457 }
458
459 } else { // Read only raw data but no equipment header
460 AliRawEquipment &equipment = *subEvent->NextEquipment();
461 AliRawData &subRaw = *equipment.GetRawData();
462 if ((status = ReadRawData(subRaw, rawSize, ebdata)) != rawSize) {
463 if (status == 0) {
464 Error("Run", "unexpected EOF reading sub-event raw data");
465 break;
466 }
467 return 1;
a197a4ce 468 }
94d918a7 469 toRead -= rawSize;
470
471 if (callFilter) {
472#ifdef ALI_DATE
473 if (TEST_USER_ATTRIBUTE(subHeader.GetTypeAttribute(), 0))
474 Filter(subRaw);
475 else {
476 // set size of all sectors without hard track flag to 0
477 subRaw.SetSize(0);
478 }
a197a4ce 479#endif
94d918a7 480 }
481 }
a197a4ce 482
a197a4ce 483 nsub++;
484 }
485
486 // Set stat info for first event of this file
487 if (rawdb->GetEvents() == 0)
488 stats->SetFirstId(header.GetRunNumber(), header.GetEventInRun());
489
490 // Store raw event in tree
491 rawdb->Fill();
492
493 // Store header in tree
494 if (tagdb) tagdb->Fill();
495
496 fNumEvents++;
497
498 if (!(fNumEvents%10))
499 printf("Processed event %d (%d)\n", fNumEvents, rawdb->GetEvents());
500
501 // Filling time statistics
502 if (rawdb->GetBytesWritten() > nextChunk) {
503 tnew = timer.RealTime();
504 stats->Fill(tnew-told);
505 told = tnew;
506 timer.Continue();
507 nextChunk += chunkSize;
508 }
509
510 // Check size of raw db. If bigger than maxFileSize, close file
511 // and continue with new file.
512 if (rawdb->FileFull()) {
513
514 printf("Written raw DB at a rate of %.1f MB/s\n",
515 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
516
517 // Write stats object to raw db, run db, MySQL and AliEn
518 stats->WriteToDB(rawdb);
519 delete stats;
520
521 if (!rawdb->NextFile()) {
522 Error("Run", "error opening next raw data file");
523 return 1;
524 }
525
526 printf("Filling raw DB %s\n", rawdb->GetDBName());
527 stats = new AliStats(rawdb->GetDBName(), fCompress, fUseFilter);
528
529 timer.Start();
530 told = 0, tnew = 0;
531 nextChunk = chunkSize;
532 }
533
534 // Check size of tag db
535 if (tagdb && tagdb->FileFull()) {
536 if (!tagdb->NextFile())
537 tagdb = 0;
538 else
539 printf("Filling tag DB %s\n", tagdb->GetDBName());
540 }
541
542 // Make top event object ready for next event data
543 //printf("Event %d has %d sub-events\n", fNumEvents, event->GetNSubEvents());
544 event->Reset();
545
546#ifdef USE_EB
547 if (!ebReleaseEvent(ebvec)) {
548 Error("Run", "problem releasing event (%s)", ebGetLastError());
549 break;
550 }
551#endif
552 }
553
554 printf("Written raw DB at a rate of %.1f MB/s\n",
555 rawdb->GetBytesWritten() / timer.RealTime() / 1000000.);
556
557 // Write stats to raw db and run db and delete stats object
558 stats->WriteToDB(rawdb);
559 delete stats;
560
561 // Close the raw DB
562 delete rawdb;
563
564 // Close the tag DB
565 delete tagdb;
566
567 // Close input source
568 close(fFd);
569
570#if 0
571 // Cleanup fifo
572 if (fUseFifo && ::unlink(fgkFifo) == -1) {
573 SysError("Run", "unlink");
574 return 1;
575 }
576#endif
577
578#ifdef USE_EB
579 // Print eor flag
580 if (eorFlag) {
581 Info("Run", "event builder reported end of run (%d)", eorFlag);
582 }
583#endif
584
585 return 0;
586}
587
588//______________________________________________________________________________
589Int_t AliMDC::Read(void *buffer, Int_t length)
590{
591 // Read exactly length bytes into buffer. Returns number of bytes
592 // received, returns -1 in case of error and 0 for EOF.
593
594 errno = 0;
595
596 if (fFd < 0) return -1;
597
598 Int_t n, nrecv = 0;
599 char *buf = (char *)buffer;
600
601 for (n = 0; n < length; n += nrecv) {
602 if ((nrecv = read(fFd, buf+n, length-n)) <= 0) {
603 if (nrecv == 0)
604 break; // EOF
605 if (errno != EINTR)
606 SysError("Read", "read");
607 return -1;
608 }
609 }
610 return n;
611}
612
613//______________________________________________________________________________
614Int_t AliMDC::ReadHeader(AliRawEventHeader &header, void *eb)
615{
616 // Read header info from DATE data stream. Returns bytes read (i.e.
617 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
618
619 Int_t nrecv;
620
621 if (eb) {
622 // read from event builder memory area
623 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
624 nrecv = header.HeaderSize();
625 } else {
626 // read from fifo or file
627 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
628 header.HeaderSize()) {
629 if (nrecv == 0)
630 return 0;
631 return -1;
632 }
633 }
634
635 // Swap header data if needed
636 if (header.IsSwapped())
637 header.Swap();
638
639 // Is header valid...
640 if (!header.IsValid()) {
641 Error("ReadHeader", "invalid header format");
642 // try recovery... how?
643 return -1;
644 }
645 if (header.GetEventSize() < (UInt_t)header.HeaderSize()) {
646 Error("ReadHeader", "invalid header size");
647 // try recovery... how?
648 return -1;
649 }
650
651 return nrecv;
652}
653
654//______________________________________________________________________________
655Int_t AliMDC::ReadEquipmentHeader(AliRawEquipmentHeader &header,
656 Bool_t isSwapped, void *eb)
657{
658 // Read equipment header info from DATE data stream. Returns bytes read
659 // (i.e. AliRawEquipmentHeader::HeaderSize()), -1 in case of error and
660 // 0 for EOF. If isSwapped is kTRUE the event data is byte swapped
661 // and we will swap the header to host format.
662
663 Int_t nrecv;
664
665 if (eb) {
666 // read from event builder memory area
667 memcpy(header.HeaderBegin(), eb, header.HeaderSize());
668 nrecv = header.HeaderSize();
669 } else {
670 // read from fifo or file
671 if ((nrecv = Read(header.HeaderBegin(), header.HeaderSize())) !=
672 header.HeaderSize()) {
673 if (nrecv == 0)
674 return 0;
675 return -1;
676 }
677 }
678
679 // Swap equipment header data if needed
680 if (isSwapped)
681 header.Swap();
682
683 if (header.GetEquipmentSize() < (UInt_t)header.HeaderSize()) {
684 Error("ReadEquipmentHeader", "invalid equipment header size");
685 // try recovery... how?
686 return -1;
687 }
688
689 return nrecv;
690}
691
692//______________________________________________________________________________
693Int_t AliMDC::ReadRawData(AliRawData &raw, Int_t size, void *eb)
694{
695 // Read raw data from DATE data stream. Returns bytes read (i.e.
696 // AliRawEventHeader::HeaderSize()), -1 in case of error and 0 for EOF.
697
698 Int_t nrecv;
699
700 if (eb) {
701 // read from event builder memory area
702 raw.SetBuffer(eb, size);
703 nrecv = size;
704 } else {
705 // read from fifo or file
706 raw.SetSize(size);
707 if ((nrecv = Read(raw.GetBuffer(), size)) != size) {
708 if (nrecv == 0) {
709 Error("ReadRawData", "unexpected EOF");
710 return 0;
711 }
712 return -1;
713 }
714 }
715
716 return nrecv;
717}
718
719//______________________________________________________________________________
720Int_t AliMDC::DumpEvent(Int_t toRead)
721{
722 // This case should not happen, but if it does try to handle it
723 // gracefully by reading the rest of the event and discarding it.
724 // Returns bytes read, -1 in case of fatal error and 0 for EOF.
725
726 Error("DumpEvent", "dumping %d bytes of event %d", toRead, fNumEvents);
727
728 Int_t nrecv;
729 char *tbuf = new char[toRead];
730 if ((nrecv = Read(tbuf, toRead)) != toRead) {
731 if (nrecv == 0) {
732 Error("DumpEvent", "unexpected EOF");
733 return 0;
734 }
735 return -1;
736 }
737 delete [] tbuf;
738
739 return nrecv;
740}
741
742//______________________________________________________________________________
743Int_t AliMDC::Filter(AliRawData &raw)
744{
745 // Call 3rd level filter for this raw data segment.
746
747#ifdef USE_HLT
748
749 // Add HLT code here
750
751#else
752
753 raw.GetSize();
754 printf("Filter called for event %d\n", fNumEvents);
755
756#endif
757
758 return 0;
759}
760
761//______________________________________________________________________________
762AliMDC::AliMDCInterruptHandler::AliMDCInterruptHandler(const
763 AliMDCInterruptHandler&
764 handler):
765 TSignalHandler(handler)
766{
767// copy constructor
768
769 Fatal("AliMDCInterruptHandler", "copy constructor not implemented");
770}
771
772//______________________________________________________________________________
773AliMDC::AliMDCInterruptHandler&
774 AliMDC::AliMDCInterruptHandler::operator = (const AliMDCInterruptHandler&
775 /*handler*/)
776{
777// assignment operator
778
779 Fatal("operator =", "assignment operator not implemented");
780 return *this;
781}