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