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