]>
Commit | Line | Data |
---|---|---|
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 | } |