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