Line data Source code
1 : /**************************************************************************
2 : * This file is property of and copyright by the ALICE HLT Project *
3 : * All rights reserved. *
4 : * *
5 : * Primary Authors: *
6 : * Indranil Das <indra.das@saha.ac.in> *
7 : * Artur Szostak <artursz@iafrica.com> *
8 : * *
9 : * Permission to use, copy, modify and distribute this software and its *
10 : * documentation strictly for non-commercial purposes is hereby granted *
11 : * without fee, provided that the above copyright notice appears in all *
12 : * copies and that both the copyright notice and this permission notice *
13 : * appear in the supporting documentation. The authors make no claims *
14 : * about the suitability of this software for any purpose. It is *
15 : * provided "as is" without express or implied warranty. *
16 : **************************************************************************/
17 :
18 : // $Id$
19 :
20 : ///
21 : /// @file AliHLTMUONTriggerReconstructorComponent.cxx
22 : /// @author Indranil Das <indra.das@saha.ac.in>, Artur Szostak <artursz@iafrica.com>
23 : /// @date 18 Sep 2007
24 : /// @brief Implementation of the trigger DDL reconstructor component.
25 : ///
26 :
27 : #include "AliHLTMUONTriggerReconstructorComponent.h"
28 : #include "AliHLTMUONTriggerReconstructor.h"
29 : #include "AliHLTMUONHitReconstructor.h"
30 : #include "AliHLTMUONConstants.h"
31 : #include "AliHLTMUONCalculations.h"
32 : #include "AliHLTMUONUtils.h"
33 : #include "AliHLTMUONDataBlockWriter.h"
34 : #include "AliRawDataHeader.h"
35 : #include "AliHLTCDHWrapper.h"
36 : #include "AliCDBManager.h"
37 : #include "AliCDBStorage.h"
38 : #include "AliGeomManager.h"
39 : #include "AliMUONGeometryTransformer.h"
40 : #include "AliMUONGeometryDetElement.h"
41 : #include "AliMpCDB.h"
42 : #include "AliMpDDLStore.h"
43 : #include "AliMpPad.h"
44 : #include "AliMpSegmentation.h"
45 : #include "AliMpDEIterator.h"
46 : #include "AliMpVSegmentation.h"
47 : #include "AliMpDEManager.h"
48 : #include "AliMpLocalBoard.h"
49 : #include "AliMpTriggerCrate.h"
50 : #include <cstdlib>
51 : #include <cerrno>
52 : #include <cassert>
53 : #include <fstream>
54 :
55 :
56 6 : ClassImp(AliHLTMUONTriggerReconstructorComponent)
57 :
58 :
59 : AliHLTMUONTriggerReconstructorComponent::AliHLTMUONTriggerReconstructorComponent() :
60 3 : AliHLTMUONProcessor(),
61 3 : fTrigRec(NULL),
62 3 : fDDL(-1),
63 3 : fWarnForUnexpecedBlock(false),
64 3 : fStopOnOverflow(false),
65 3 : fUseCrateId(true),
66 3 : fZmiddleSpecified(false),
67 3 : fBLSpecified(false),
68 3 : fLutInitialised(false)
69 15 : {
70 : ///
71 : /// Default constructor.
72 : ///
73 6 : }
74 :
75 :
76 : AliHLTMUONTriggerReconstructorComponent::~AliHLTMUONTriggerReconstructorComponent()
77 18 : {
78 : ///
79 : /// Default destructor.
80 : ///
81 :
82 3 : if (fTrigRec != NULL) delete fTrigRec;
83 9 : }
84 :
85 :
86 : const char* AliHLTMUONTriggerReconstructorComponent::GetComponentID()
87 : {
88 : ///
89 : /// Inherited from AliHLTComponent. Returns the component ID.
90 : ///
91 :
92 222 : return AliHLTMUONConstants::TriggerReconstructorId();
93 : }
94 :
95 :
96 : void AliHLTMUONTriggerReconstructorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
97 : {
98 : ///
99 : /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
100 : ///
101 :
102 0 : list.clear();
103 0 : list.push_back( AliHLTMUONConstants::DDLRawDataType() );
104 0 : }
105 :
106 :
107 : AliHLTComponentDataType AliHLTMUONTriggerReconstructorComponent::GetOutputDataType()
108 : {
109 : ///
110 : /// Inherited from AliHLTComponent. Returns kAliHLTMultipleDataType.
111 : ///
112 :
113 0 : return kAliHLTMultipleDataType;
114 : }
115 :
116 :
117 : int AliHLTMUONTriggerReconstructorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
118 : {
119 : /// Inherited from AliHLTComponent. Returns the output data types.
120 :
121 0 : assert( list.empty() );
122 0 : list.push_back( AliHLTMUONConstants::TriggerRecordsBlockDataType() );
123 0 : list.push_back( AliHLTMUONConstants::TrigRecsDebugBlockDataType() );
124 0 : return list.size();
125 : }
126 :
127 :
128 : void AliHLTMUONTriggerReconstructorComponent::GetOutputDataSize(
129 : unsigned long& constBase, double& inputMultiplier
130 : )
131 : {
132 : ///
133 : /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
134 : ///
135 :
136 0 : constBase = sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType) + 1024*1024;
137 0 : inputMultiplier = 4;
138 0 : }
139 :
140 :
141 : AliHLTComponent* AliHLTMUONTriggerReconstructorComponent::Spawn()
142 : {
143 : ///
144 : /// Inherited from AliHLTComponent. Creates a new object instance.
145 : ///
146 :
147 0 : return new AliHLTMUONTriggerReconstructorComponent;
148 0 : }
149 :
150 :
151 : int AliHLTMUONTriggerReconstructorComponent::DoInit(int argc, const char** argv)
152 : {
153 : ///
154 : /// Inherited from AliHLTComponent.
155 : /// Parses the command line parameters and initialises the component.
156 : ///
157 :
158 0 : HLTInfo("Initialising dHLT trigger reconstructor component.");
159 :
160 : // Inherit the parents functionality.
161 0 : int result = AliHLTMUONProcessor::DoInit(argc, argv);
162 0 : if (result != 0) return result;
163 :
164 : // Make sure to cleanup fTrigRec if it is still there for some reason.
165 0 : if (fTrigRec != NULL)
166 : {
167 0 : delete fTrigRec;
168 0 : fTrigRec = NULL;
169 0 : }
170 :
171 0 : fDDL = -1;
172 0 : fWarnForUnexpecedBlock = false;
173 0 : fStopOnOverflow = false;
174 0 : fUseCrateId = true;
175 0 : fZmiddleSpecified = false;
176 0 : fBLSpecified = false;
177 0 : fLutInitialised = false;
178 :
179 : const char* lutFileName = NULL;
180 : bool useCDB = false;
181 : bool suppressPartialTrigs = true;
182 : bool tryRecover = false;
183 : bool useLocalId = true;
184 : bool makeDebugInfo = false;
185 : bool dontPrintWrongEventError = false;
186 : double zmiddle = 0;
187 : double bfieldintegral = 0;
188 :
189 0 : for (int i = 0; i < argc; i++)
190 : {
191 : // To keep the legacy behaviour we need to have the following check
192 : // for -cdbpath here, before ArgumentAlreadyHandled.
193 0 : if (strcmp(argv[i], "-cdbpath") == 0)
194 : {
195 : useCDB = true;
196 0 : }
197 :
198 0 : if (ArgumentAlreadyHandled(i, argv[i])) continue;
199 :
200 0 : if (strcmp( argv[i], "-lut" ) == 0)
201 : {
202 0 : if (lutFileName != NULL)
203 : {
204 0 : HLTWarning("LUT path was already specified."
205 : " Will replace previous value given by -lut."
206 : );
207 : }
208 :
209 0 : if ( argc <= i+1 )
210 : {
211 0 : HLTError("The lookup table filename was not specified." );
212 0 : return -EINVAL;
213 : }
214 :
215 0 : lutFileName = argv[i+1];
216 :
217 0 : i++;
218 0 : continue;
219 : }
220 :
221 0 : if (strcmp( argv[i], "-ddl" ) == 0)
222 : {
223 0 : if (fDDL != -1)
224 : {
225 0 : HLTWarning("DDL number was already specified."
226 : " Will replace previous value given by -ddl or -ddlid."
227 : );
228 : }
229 :
230 0 : if ( argc <= i+1 )
231 : {
232 0 : HLTError("DDL number not specified. It must be in the range [21..22]");
233 0 : return -EINVAL;
234 : }
235 :
236 0 : char* cpErr = NULL;
237 0 : unsigned long num = strtoul(argv[i+1], &cpErr, 0);
238 0 : if (cpErr == NULL or *cpErr != '\0')
239 : {
240 0 : HLTError("Cannot convert '%s' to a DDL Number.", argv[i+1]);
241 0 : return -EINVAL;
242 : }
243 0 : if (num < 21 or 22 < num)
244 : {
245 0 : HLTError("The DDL number must be in the range [21..22].");
246 0 : return -EINVAL;
247 : }
248 0 : fDDL = num - 1; // Convert to DDL number in the range 0..21
249 :
250 0 : i++;
251 0 : continue;
252 0 : }
253 :
254 0 : if (strcmp( argv[i], "-ddlid" ) == 0)
255 : {
256 0 : if (fDDL != -1)
257 : {
258 0 : HLTWarning("DDL number was already specified."
259 : " Will replace previous value given by -ddl or -ddlid."
260 : );
261 : }
262 :
263 0 : if ( argc <= i+1 )
264 : {
265 0 : HLTError("DDL equipment ID number not specified. It must be in the range [2816..2817]");
266 0 : return -EINVAL;
267 : }
268 :
269 0 : char* cpErr = NULL;
270 0 : unsigned long num = strtoul(argv[i+1], &cpErr, 0);
271 0 : if (cpErr == NULL or *cpErr != '\0')
272 : {
273 0 : HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]);
274 0 : return -EINVAL;
275 : }
276 0 : fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
277 0 : if (fDDL < 20 or 21 < fDDL)
278 : {
279 0 : HLTError("The DDL equipment ID number must be in the range [2816..2817].");
280 0 : return -EINVAL;
281 : }
282 :
283 0 : i++;
284 0 : continue;
285 0 : }
286 :
287 0 : if (strcmp( argv[i], "-cdb" ) == 0)
288 : {
289 : useCDB = true;
290 0 : continue;
291 : }
292 :
293 0 : if (strcmp( argv[i], "-zmiddle" ) == 0)
294 : {
295 0 : if (fZmiddleSpecified)
296 : {
297 0 : HLTWarning("The Z coordinate for the middle of the dipole was already specified."
298 : " Will replace previous value given by -zmiddle."
299 : );
300 : }
301 :
302 0 : if ( argc <= i+1 )
303 : {
304 0 : HLTError("The Z coordinate for the middle of the dipole was not specified.");
305 0 : return -EINVAL;
306 : }
307 :
308 0 : char* cpErr = NULL;
309 0 : zmiddle = strtod(argv[i+1], &cpErr);
310 0 : if (cpErr == NULL or *cpErr != '\0')
311 : {
312 0 : HLTError("Cannot convert '%s' to a valid floating point number.",
313 : argv[i+1]
314 : );
315 0 : return -EINVAL;
316 : }
317 :
318 0 : fZmiddleSpecified = true;
319 0 : i++;
320 0 : continue;
321 0 : }
322 :
323 0 : if (strcmp( argv[i], "-bfieldintegral" ) == 0)
324 : {
325 0 : if (fBLSpecified)
326 : {
327 0 : HLTWarning("The magnetic field integral was already specified."
328 : " Will replace previous value given by -bfieldintegral."
329 : );
330 : }
331 :
332 0 : if ( argc <= i+1 )
333 : {
334 0 : HLTError("The magnetic field integral was not specified." );
335 0 : return -EINVAL;
336 : }
337 :
338 0 : char* cpErr = NULL;
339 0 : bfieldintegral = strtod(argv[i+1], &cpErr);
340 0 : if (cpErr == NULL or *cpErr != '\0')
341 : {
342 0 : HLTError("Cannot convert '%s' to a valid floating point number.",
343 : argv[i+1]
344 : );
345 0 : return -EINVAL;
346 : }
347 :
348 0 : fBLSpecified = true;
349 0 : i++;
350 0 : continue;
351 0 : }
352 :
353 0 : if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
354 : {
355 0 : fWarnForUnexpecedBlock = true;
356 0 : continue;
357 : }
358 :
359 0 : if (strcmp( argv[i], "-suppress_partial_triggers" ) == 0)
360 : {
361 : suppressPartialTrigs = true;
362 0 : continue;
363 : }
364 :
365 0 : if (strcmp( argv[i], "-generate_partial_triggers" ) == 0)
366 : {
367 : suppressPartialTrigs = false;
368 0 : continue;
369 : }
370 :
371 0 : if (strcmp( argv[i], "-stop_on_buffer_overflow" ) == 0)
372 : {
373 0 : fStopOnOverflow = true;
374 0 : continue;
375 : }
376 :
377 0 : if (strcmp( argv[i], "-tryrecover" ) == 0)
378 : {
379 : tryRecover = true;
380 0 : continue;
381 : }
382 :
383 0 : if (strcmp( argv[i], "-dont_use_crateid" ) == 0)
384 : {
385 0 : fUseCrateId = false;
386 0 : continue;
387 : }
388 :
389 0 : if (strcmp( argv[i], "-dont_use_localid" ) == 0)
390 : {
391 : useLocalId = false;
392 0 : continue;
393 : }
394 :
395 0 : if (strcmp( argv[i], "-makedebuginfo" ) == 0)
396 : {
397 : makeDebugInfo = true;
398 0 : continue;
399 : }
400 :
401 0 : if (strcmp( argv[i], "-dontprintwrongeventerror" ) == 0)
402 : {
403 : dontPrintWrongEventError = true;
404 0 : continue;
405 : }
406 :
407 0 : HLTError("Unknown option '%s'.", argv[i]);
408 0 : return -EINVAL;
409 :
410 : } // for loop
411 :
412 : try
413 : {
414 0 : fTrigRec = new AliHLTMUONTriggerReconstructor();
415 0 : }
416 : catch (const std::bad_alloc&)
417 : {
418 0 : HLTError("Could not allocate more memory for the trigger reconstructor component.");
419 : return -ENOMEM;
420 0 : }
421 :
422 0 : if (fZmiddleSpecified and useCDB)
423 : {
424 0 : HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
425 : " this component should read from the CDB, but then the -zmiddle argument"
426 : " was also used. Will override the value from CDB with the command"
427 : " line parameter given."
428 : );
429 : }
430 0 : if (fBLSpecified and useCDB)
431 : {
432 0 : HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
433 : " this component should read from the CDB, but then the -bfieldintegral"
434 : " argument was also used. Will override the value from CDB with the"
435 : " command line parameter given."
436 : );
437 : }
438 :
439 0 : if (lutFileName != NULL and useCDB == true)
440 : {
441 0 : HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
442 : " this component should read from the CDB, but then the -lut argument"
443 : " was also used. Will ignore the -lut option and load from CDB anyway."
444 : );
445 : }
446 :
447 0 : if (lutFileName == NULL) useCDB = true;
448 :
449 0 : if (fDDL == -1 and not DelaySetup())
450 : {
451 0 : HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
452 : }
453 :
454 0 : if (useCDB)
455 : {
456 0 : if (not DelaySetup())
457 : {
458 0 : HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
459 : fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
460 : );
461 0 : result = ReadLutFromCDB();
462 0 : if (result != 0)
463 : {
464 : // Error messages already generated in ReadLutFromCDB.
465 0 : delete fTrigRec; // Make sure to delete fTrigRec to avoid partial initialisation.
466 0 : fTrigRec = NULL;
467 0 : return result;
468 : }
469 0 : fLutInitialised = true;
470 0 : }
471 : }
472 : else
473 : {
474 0 : HLTInfo("Loading lookup table information from file %s.", lutFileName);
475 0 : result = ReadLookUpTable(lutFileName);
476 0 : if (result != 0)
477 : {
478 : // Error messages already generated in ReadLookUpTable.
479 0 : delete fTrigRec; // Make sure to delete fTrigRec to avoid partial initialisation.
480 0 : fTrigRec = NULL;
481 0 : return result;
482 : }
483 0 : fLutInitialised = true;
484 : }
485 :
486 0 : if (fZmiddleSpecified) AliHLTMUONCalculations::Zf(zmiddle);
487 0 : if (fBLSpecified) AliHLTMUONCalculations::QBL(bfieldintegral);
488 :
489 0 : if (not DelaySetup())
490 : {
491 0 : if (not fZmiddleSpecified or not fBLSpecified)
492 : {
493 0 : HLTInfo("Loading configuration parameters from CDB for DDL %d (ID = %d).",
494 : fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
495 : );
496 :
497 0 : result = ReadConfigFromCDB(not fZmiddleSpecified, not fBLSpecified);
498 0 : if (result != 0)
499 : {
500 : // Error messages already generated in ReadConfigFromCDB.
501 0 : delete fTrigRec; // Make sure to delete fTrigRec to avoid partial initialisation.
502 0 : fTrigRec = NULL;
503 0 : return result;
504 : }
505 : }
506 : else
507 : {
508 : // Print the debug messages here since ReadConfigFromCDB does not get called,
509 : // in-which the debug messages would have been printed.
510 : HLTDebug("Using the following configuration parameters:");
511 : HLTDebug(" Middle of dipole Z coordinate = %f cm", AliHLTMUONCalculations::Zf());
512 : HLTDebug(" Magnetic field integral = %f T.m", AliHLTMUONCalculations::QBL());
513 : }
514 : }
515 :
516 0 : fTrigRec->SuppressPartialTriggers(suppressPartialTrigs);
517 0 : fTrigRec->TryRecover(tryRecover);
518 0 : fTrigRec->UseCrateId(fUseCrateId);
519 0 : fTrigRec->UseLocalId(useLocalId);
520 0 : fTrigRec->StoreDebugInfo(makeDebugInfo);
521 0 : fTrigRec->DontPrintWrongEventError(dontPrintWrongEventError);
522 :
523 0 : return 0;
524 0 : }
525 :
526 :
527 : int AliHLTMUONTriggerReconstructorComponent::DoDeinit()
528 : {
529 : ///
530 : /// Inherited from AliHLTComponent. Performs a cleanup of the component.
531 : ///
532 :
533 0 : HLTInfo("Deinitialising dHLT trigger reconstructor component.");
534 :
535 0 : if (fTrigRec != NULL)
536 : {
537 0 : delete fTrigRec;
538 0 : fTrigRec = NULL;
539 0 : }
540 0 : return 0;
541 : }
542 :
543 :
544 : int AliHLTMUONTriggerReconstructorComponent::DoEvent(
545 : const AliHLTComponentEventData& evtData,
546 : const AliHLTComponentBlockData* blocks,
547 : AliHLTComponentTriggerData& trigData,
548 : AliHLTUInt8_t* outputPtr,
549 : AliHLTUInt32_t& size,
550 : AliHLTComponentBlockDataList& outputBlocks
551 : )
552 : {
553 : ///
554 : /// Inherited from AliHLTProcessor. Processes the new event data.
555 : ///
556 :
557 : // Initialise the LUT and configuration parameters from CDB if we were
558 : // requested to initialise only when the first event was received.
559 0 : if (DelaySetup())
560 : {
561 : // Use the specification given by the first data block if we
562 : // have not been given a DDL number on the command line.
563 0 : if (fDDL == -1)
564 : {
565 : bool blockFound = false;
566 0 : for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt and not blockFound; n++)
567 : {
568 0 : if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()) continue;
569 : blockFound = true;
570 :
571 0 : fDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
572 :
573 0 : if (fDDL == -1)
574 : {
575 0 : HLTError("Received a data block with a specification (0x%8.8X)"
576 : " indicating multiple DDL data sources, but we must only"
577 : " receive raw DDL data from one trigger station DDL.",
578 : blocks[n].fSpecification
579 : );
580 0 : return -EPROTO;
581 : }
582 : }
583 :
584 0 : if (not blockFound)
585 : {
586 0 : HLTError("The initialisation from CDB of the component has"
587 : " been delayed to the first received event. However,"
588 : " no raw DDL data blocks have been found in the first event."
589 : );
590 0 : return -ENOENT;
591 : }
592 0 : }
593 :
594 : // Check that the LUT was not already loaded in DoInit.
595 0 : if (not fLutInitialised)
596 : {
597 0 : HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
598 : fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
599 : );
600 0 : int result = ReadLutFromCDB();
601 0 : if (result != 0) return result;
602 0 : fLutInitialised = true;
603 0 : }
604 :
605 : // Load the configuration paramters from CDB if they have not been given
606 : // on the command line.
607 0 : if (not fZmiddleSpecified or not fBLSpecified)
608 : {
609 0 : HLTInfo("Loading configuration parameters from CDB for DDL %d (ID = %d).",
610 : fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
611 : );
612 0 : int result = ReadConfigFromCDB(not fZmiddleSpecified, not fBLSpecified);
613 0 : if (result != 0) return result;
614 0 : }
615 :
616 0 : DoneDelayedSetup();
617 0 : }
618 :
619 : // Process an event
620 : unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
621 :
622 : HLTDebug("Processing event %llu with %u input data blocks.",
623 : evtData.fEventID, evtData.fBlockCnt
624 : );
625 :
626 : // Loop over all input blocks in the event and run the trigger DDL
627 : // reconstruction algorithm on the raw data.
628 0 : for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
629 : {
630 : HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
631 : n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
632 : );
633 :
634 0 : if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
635 0 : or not AliHLTMUONUtils::IsTriggerDDL(blocks[n].fSpecification)
636 : )
637 : {
638 : // Log a message indicating that we got a data block that we
639 : // do not know how to handle.
640 0 : if (fWarnForUnexpecedBlock)
641 0 : HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
642 : DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
643 : );
644 : #ifdef __DEBUG
645 : else
646 : HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
647 : DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
648 : );
649 : #endif
650 :
651 : continue;
652 : }
653 :
654 0 : AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
655 0 : if (fDDL != -1)
656 : {
657 0 : if (receivedDDL != fDDL)
658 : {
659 0 : HLTWarning("Received raw data from DDL %d (ID = %d),"
660 : " but expect data only from DDL %d (ID = %d).",
661 : receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL),
662 : fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
663 : );
664 : }
665 : }
666 :
667 : // Create a new output data block and initialise the header.
668 0 : AliHLTMUONTriggerRecordsBlockWriter block(outputPtr+totalSize, size-totalSize);
669 0 : if (not block.InitCommonHeader())
670 : {
671 0 : HLTError("There is not enough space in the output buffer for the new data block."
672 : " We require at least %u bytes, but have %u bytes left.",
673 : sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
674 : block.BufferSize()
675 : );
676 0 : break;
677 : }
678 :
679 0 : AliHLTUInt32_t totalDDLSize = blocks[n].fSize;
680 0 : AliHLTCDHWrapper header(blocks[n].fPtr);
681 0 : if (totalDDLSize < sizeof(AliRawDataHeader) &&
682 0 : totalDDLSize < header.GetHeaderSize()) // if cdh v3
683 : {
684 0 : HLTError("Raw data block %d is %d bytes in size and is too short to"
685 : " possibly contain valid DDL raw data.",
686 : n, totalDDLSize
687 : );
688 0 : continue;
689 : }
690 0 : AliHLTUInt32_t payloadSize = totalDDLSize - header.GetHeaderSize();
691 0 : AliHLTUInt8_t* buffer = reinterpret_cast<AliHLTUInt8_t*>(blocks[n].fPtr);
692 0 : buffer += header.GetHeaderSize();
693 0 : AliHLTUInt32_t nofTrigRec = block.MaxNumberOfEntries();
694 :
695 : // Decode if this is a scalar event or not.
696 0 : bool scalarEvent = ((header.GetL1TriggerMessage() & 0x1) == 0x1);
697 :
698 : // Remember: the following does NOT change the mapping!
699 : // It is just to generate unique trigger record IDs.
700 0 : fTrigRec->SetDDL(receivedDDL);
701 :
702 0 : bool runOk = fTrigRec->Run(
703 0 : buffer, payloadSize, scalarEvent,
704 0 : block.GetArray(), nofTrigRec
705 : );
706 0 : if (not runOk)
707 : {
708 0 : HLTError("Error while processing the trigger DDL reconstruction algorithm.");
709 0 : if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
710 0 : if (not fTrigRec->OverflowedOutputBuffer()
711 0 : or (fTrigRec->OverflowedOutputBuffer() and fStopOnOverflow)
712 : )
713 : {
714 0 : size = totalSize; // Must tell the framework how much buffer space was used.
715 0 : return -EIO;
716 : }
717 : }
718 :
719 : // nofTrigRec should now contain the number of triggers actually found
720 : // and filled into the output data block, so we can set this number.
721 0 : assert( nofTrigRec <= block.MaxNumberOfEntries() );
722 0 : block.SetNumberOfEntries(nofTrigRec);
723 :
724 : HLTDebug("Number of trigger records found is %d", nofTrigRec);
725 :
726 : // Fill a block data structure for our output block.
727 0 : AliHLTComponentBlockData bd;
728 0 : FillBlockData(bd);
729 0 : bd.fPtr = outputPtr;
730 : // This block's start (offset) is after all other blocks written so far.
731 0 : bd.fOffset = totalSize;
732 0 : bd.fSize = block.BytesUsed();
733 0 : bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
734 0 : bd.fSpecification = blocks[n].fSpecification;
735 0 : outputBlocks.push_back(bd);
736 :
737 : HLTDebug("Created a new output data block at fPtr = %p,"
738 : " with fOffset = %u (0x%.X) and fSize = %u bytes.",
739 : bd.fPtr, bd.fOffset, bd.fOffset, bd.fSize
740 : );
741 :
742 : // Increase the total amount of data written so far to our output memory.
743 0 : totalSize += block.BytesUsed();
744 :
745 0 : if (fTrigRec->StoreDebugInfo())
746 : {
747 : // Create a new output data block and initialise the header.
748 0 : AliHLTMUONTrigRecsDebugBlockWriter infoblock(outputPtr+totalSize, size-totalSize);
749 0 : if (not infoblock.InitCommonHeader())
750 : {
751 0 : HLTError("There is not enough space in the output buffer for the new debug"
752 : " data block. We require at least %u bytes, but have %u bytes left.",
753 : sizeof(AliHLTMUONTrigRecsDebugBlockWriter::HeaderType),
754 : infoblock.BufferSize()
755 : );
756 0 : break;
757 : }
758 :
759 0 : infoblock.SetNumberOfEntries(fTrigRec->InfoBufferCount());
760 0 : for (AliHLTUInt32_t i = 0; i < fTrigRec->InfoBufferCount(); ++i)
761 : {
762 0 : infoblock[i] = fTrigRec->InfoBuffer()[i];
763 : }
764 0 : fTrigRec->ZeroInfoBuffer();
765 :
766 : // Fill the block data structure for our output block.
767 0 : AliHLTComponentBlockData bd2;
768 0 : FillBlockData(bd2);
769 0 : bd2.fPtr = outputPtr;
770 : // This block's start (offset) is after all other blocks written so far.
771 0 : bd2.fOffset = totalSize;
772 0 : bd2.fSize = infoblock.BytesUsed();
773 0 : bd2.fDataType = AliHLTMUONConstants::TrigRecsDebugBlockDataType();
774 0 : bd2.fSpecification = blocks[n].fSpecification;
775 0 : outputBlocks.push_back(bd2);
776 :
777 : HLTDebug("Created a new output data block for debug information at fPtr = %p,"
778 : " with fOffset = %u (0x%.X) and fSize = %u bytes.",
779 : bd2.fPtr, bd2.fOffset, bd2.fOffset, bd2.fSize
780 : );
781 :
782 : // Increase the total amount of data written so far to our output memory.
783 0 : totalSize += infoblock.BytesUsed();
784 0 : }
785 0 : }
786 :
787 : // Finally we set the total size of output memory we consumed.
788 0 : size = totalSize;
789 0 : return 0;
790 0 : }
791 :
792 :
793 : int AliHLTMUONTriggerReconstructorComponent::Reconfigure(
794 : const char* cdbEntry, const char* componentId
795 : )
796 : {
797 : /// Inherited from AliHLTComponent. This method will reload CDB configuration
798 : /// entries for this component from the CDB.
799 : /// \param cdbEntry If this is NULL then it is assumed that all CDB entries should
800 : /// be reloaded. Otherwise a particular value for 'cdbEntry' will trigger
801 : /// reloading of the LUT if the path contains 'MUON/', but the other
802 : /// configuration parameters will be loaded if 'cdbEntry' contains
803 : /// "HLT/ConfigMUON/TriggerReconstructor".
804 : /// \param componentId The name of the component in the current chain.
805 :
806 0 : TString path = cdbEntry;
807 0 : bool startsWithMUON = path.Index("MUON/", 5, 0, TString::kExact) == 0;
808 0 : bool givenConfigPath = (path == AliHLTMUONConstants::TriggerReconstructorCDBPath());
809 :
810 0 : if (cdbEntry == NULL or startsWithMUON or givenConfigPath)
811 : {
812 0 : HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
813 : }
814 :
815 0 : if (cdbEntry == NULL or startsWithMUON)
816 : {
817 0 : int result = ReadLutFromCDB();
818 0 : if (result != 0) return result;
819 0 : }
820 :
821 0 : if (cdbEntry == NULL or givenConfigPath)
822 : {
823 0 : int result = ReadConfigFromCDB();
824 0 : if (result != 0) return result;
825 0 : }
826 :
827 0 : return 0;
828 0 : }
829 :
830 :
831 : int AliHLTMUONTriggerReconstructorComponent::ReadPreprocessorValues(const char* modules)
832 : {
833 : /// Inherited from AliHLTComponent.
834 : /// Updates the configuration of this component if either HLT or MUON have
835 : /// been specified in the 'modules' list.
836 :
837 0 : TString mods = modules;
838 0 : if (mods.Contains("ALL") or (mods.Contains("HLT") and mods.Contains("MUON")))
839 : {
840 0 : return Reconfigure(NULL, GetComponentID());
841 : }
842 0 : if (mods.Contains("HLT"))
843 : {
844 0 : return Reconfigure(AliHLTMUONConstants::TriggerReconstructorCDBPath(), GetComponentID());
845 : }
846 0 : if (mods.Contains("MUON"))
847 : {
848 0 : return Reconfigure("MUON/*", GetComponentID());
849 : }
850 0 : return 0;
851 0 : }
852 :
853 :
854 : int AliHLTMUONTriggerReconstructorComponent::ReadLookUpTable(const char* lutpath)
855 : {
856 : ///
857 : /// Read in the lookup table from file.
858 : ///
859 :
860 0 : assert(fTrigRec != NULL);
861 :
862 0 : fstream file;
863 0 : file.open(lutpath, fstream::binary | fstream::in);
864 0 : if (not file)
865 : {
866 0 : HLTError("Could not open file: %s", lutpath);
867 0 : return -ENOENT;
868 : }
869 :
870 0 : file.read(reinterpret_cast<char*>(fTrigRec->LookupTableBuffer()), fTrigRec->LookupTableSize());
871 0 : if (file.eof())
872 : {
873 0 : HLTError("The file %s was too short to contain a valid lookup table for this component.", lutpath);
874 0 : file.close();
875 0 : return -EIO;
876 : }
877 0 : if (file.fail())
878 : {
879 0 : HLTError("Could not read from file: %s", lutpath);
880 0 : file.close();
881 0 : return -EIO;
882 : }
883 :
884 0 : file.close();
885 0 : return 0;
886 0 : }
887 :
888 :
889 : int AliHLTMUONTriggerReconstructorComponent::ReadConfigFromCDB(
890 : bool setZmiddle, bool setBL
891 : )
892 : {
893 : /// Reads this component's configuration parameters from the CDB.
894 : /// These include the middle of the dipole Z coordinate (zmiddle) and the
895 : /// integrated magnetic field of the dipole.
896 : /// \param setZmiddle Indicates if the zmiddle parameter should be set
897 : /// (default true).
898 : /// \param setBL Indicates if the integrated magnetic field parameter should
899 : /// be set (default true).
900 : /// \return 0 if no errors occured and negative error code compatible with
901 : /// the HLT framework on errors.
902 :
903 0 : const char* pathToEntry = AliHLTMUONConstants::TriggerReconstructorCDBPath();
904 :
905 0 : TMap* map = NULL;
906 0 : int result = FetchTMapFromCDB(pathToEntry, map);
907 0 : if (result != 0) return result;
908 :
909 0 : Double_t value = 0;
910 0 : if (setZmiddle)
911 : {
912 0 : result = GetFloatFromTMap(map, "zmiddle", value, pathToEntry, "dipole middle Z coordinate");
913 0 : if (result != 0) return result;
914 0 : AliHLTMUONCalculations::Zf(value);
915 0 : }
916 :
917 0 : if (setBL)
918 : {
919 0 : Double_t bfieldintegral;
920 0 : result = FetchFieldIntegral(bfieldintegral);
921 0 : if (result == 0)
922 : {
923 0 : AliHLTMUONCalculations::QBL(bfieldintegral);
924 0 : }
925 : else
926 : {
927 0 : HLTWarning("Failed to load the magnetic field integral from GRP information.");
928 0 : result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field");
929 0 : if (result != 0) return result;
930 0 : HLTWarning(Form("Using deprecated magnetic field integral value of %f T.m.", value));
931 0 : AliHLTMUONCalculations::QBL(value);
932 : }
933 0 : }
934 :
935 : HLTDebug("Using the following configuration parameters:");
936 : HLTDebug(" Middle of dipole Z coordinate = %f cm", AliHLTMUONCalculations::Zf());
937 : HLTDebug(" Magnetic field integral = %f T.m", AliHLTMUONCalculations::QBL());
938 :
939 0 : return 0;
940 0 : }
941 :
942 :
943 : int AliHLTMUONTriggerReconstructorComponent::ReadLutFromCDB()
944 : {
945 : /// Loads the lookup table containing channel and geometrical position
946 : /// information about trigger strips from CDB.
947 : ///
948 : /// \note To override the default CDB path and / or run number the
949 : /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
950 : /// method.
951 : ///
952 : /// \return 0 on success and non zero codes for errors.
953 :
954 0 : if (fDDL == -1)
955 : {
956 0 : HLTError("No DDL number specified for which to load LUT data from CDB.");
957 0 : return -EINVAL;
958 : }
959 :
960 0 : int result = FetchMappingStores();
961 : // Error message already generated in FetchMappingStores.
962 0 : if (result != 0) return result;
963 0 : AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
964 :
965 0 : AliMpSegmentation* segmentation = AliMpSegmentation::Instance();
966 0 : if (segmentation == NULL)
967 : {
968 0 : HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
969 0 : return -EIO;
970 : }
971 :
972 : // Only load geometry if not already loaded.
973 0 : if (AliGeomManager::GetGeometry() == NULL)
974 : {
975 0 : AliGeomManager::LoadGeometry();
976 0 : }
977 0 : AliMUONGeometryTransformer transformer;
978 0 : if (not transformer.LoadGeometryData())
979 : {
980 0 : HLTError("Could not load geometry into transformer.");
981 0 : return -ENOENT;
982 : }
983 :
984 0 : AliHLTMUONTriggerRecoLookupTable* lookupTable = fTrigRec->LookupTableBuffer();
985 :
986 0 : for (Int_t i = 0; i < 16; i++)
987 0 : for (Int_t j = 0; j < 16; j++)
988 0 : for (Int_t k = 0; k < 4; k++)
989 0 : for (Int_t n = 0; n < 2; n++)
990 0 : for (Int_t m = 0; m < 16; m++)
991 : {
992 0 : lookupTable->fRow[i][j][k][n][m].fIdFlags = 0x0;
993 0 : lookupTable->fRow[i][j][k][n][m].fX = 0;
994 0 : lookupTable->fRow[i][j][k][n][m].fY = 0;
995 0 : lookupTable->fRow[i][j][k][n][m].fZ = 0;
996 : }
997 :
998 0 : AliMpDEIterator detElemIter;
999 0 : for (Int_t iReg = 0; iReg < 8; iReg++)
1000 : {
1001 0 : AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(fDDL, iReg);
1002 0 : if (crate == NULL)
1003 : {
1004 0 : HLTError("Could not get crate mapping for regional header = %d"
1005 : " and DDL %d (ID = %d).",
1006 : iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
1007 : );
1008 0 : continue;
1009 : }
1010 : // Depending on the value of fUseCrateId, use either the crate ID as would
1011 : // be found in the regional header structures or the sequencial index number
1012 : // of the structure.
1013 0 : UInt_t crateId = (fUseCrateId ? crate->GetId() : iReg);
1014 0 : if (crateId >= 16)
1015 : {
1016 0 : HLTError("The crate ID number (%d) for regional header = %d and"
1017 : " DDL %d (ID = %d) is too big. It should be in the range [0..15]",
1018 : crateId, iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
1019 : );
1020 0 : continue;
1021 : }
1022 :
1023 0 : for (Int_t iLocBoard = 0; iLocBoard < 16; iLocBoard++)
1024 : {
1025 0 : Int_t boardId = crate->GetLocalBoardId(iLocBoard);
1026 0 : if (boardId == 0) continue;
1027 :
1028 0 : AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(boardId);
1029 0 : if (localBoard == NULL)
1030 : {
1031 0 : HLTError("Could not get local board: %d.", boardId);
1032 0 : continue;
1033 : }
1034 :
1035 : // skip copy cards
1036 0 : if (! localBoard->IsNotified()) continue;
1037 :
1038 0 : for (Int_t iChamber = 0; iChamber < 4; iChamber++)
1039 : {
1040 0 : Int_t detElemId = ddlStore->GetDEfromLocalBoard(boardId, iChamber);
1041 :
1042 0 : AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(iChamber+10, detElemId);
1043 :
1044 0 : const AliMUONGeometryDetElement* detElemTransform = transformer.GetDetElement(detElemId);
1045 0 : if (detElemTransform == NULL)
1046 : {
1047 0 : HLTError("Got NULL pointer for geometry transformer"
1048 : " for detection element ID = %d.",
1049 : detElemId
1050 : );
1051 0 : continue;
1052 : }
1053 :
1054 0 : for (Int_t iCathode = 0; iCathode <= 1; iCathode++)
1055 : {
1056 0 : const AliMpVSegmentation* seg = segmentation->GetMpSegmentation(
1057 0 : detElemId, AliMp::GetCathodType(iCathode)
1058 : );
1059 :
1060 0 : for (Int_t bitxy = 0; bitxy < 16; bitxy++)
1061 : {
1062 : Int_t offset = 0;
1063 0 : if (iCathode && localBoard->GetSwitch(6)) offset = -8;
1064 :
1065 : // just use this switch for simplicity for two different but shortly after each other applied changes
1066 : #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1067 0 : AliMpPad pad = seg->PadByLocation(boardId, bitxy+offset, kFALSE);
1068 : #else // old AliMpPad functionality < r 31742
1069 : AliMpPad pad = seg->PadByLocation(AliMpIntPair(boardId, bitxy+offset), kFALSE);
1070 : #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1071 :
1072 0 : if (! pad.IsValid())
1073 : {
1074 : // There is no pad associated with the given local board and bit pattern.
1075 0 : continue;
1076 : }
1077 :
1078 : // Get the global coodinates of the pad.
1079 : #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1080 0 : Float_t lx = pad.GetPositionX();
1081 0 : Float_t ly = pad.GetPositionY();
1082 : #else // old AliMpPad functionality < r 31769
1083 : Float_t lx = pad.Position().X();
1084 : Float_t ly = pad.Position().Y();
1085 : #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1086 0 : Float_t gx, gy, gz;
1087 0 : detElemTransform->Local2Global(lx, ly, 0, gx, gy, gz);
1088 :
1089 : // Fill the LUT
1090 0 : lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fIdFlags = idflags;
1091 0 : lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fX = gx;
1092 0 : lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fY = gy;
1093 0 : lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fZ = gz;
1094 0 : }
1095 : }
1096 0 : }
1097 0 : }
1098 0 : }
1099 :
1100 : return 0;
1101 0 : }
1102 :
1103 :
1104 : bool AliHLTMUONTriggerReconstructorComponent::GenerateLookupTable(
1105 : AliHLTInt32_t ddl, const char* filename,
1106 : const char* cdbPath, Int_t run, bool useCrateId
1107 : )
1108 : {
1109 : /// Generates a binary file containing the lookup table (LUT) from the
1110 : /// CDB, which can be used for the trigger reconstructor component later.
1111 : /// @param ddl Must be the DDL for which to generate the DDL,
1112 : /// in the range [20..21].
1113 : /// @param filename The name of the LUT file to generate.
1114 : /// @param cdbPath The CDB path to use.
1115 : /// @param run The run number to use for the CDB.
1116 : /// @param useCrateId Indicates that the crate ID should be used rather
1117 : /// than a sequencial number.
1118 : /// @return True if the generation of the LUT file succeeded.
1119 :
1120 0 : AliHLTMUONTriggerReconstructorComponent comp;
1121 : try
1122 : {
1123 : // Perform minimal initialisation to be able to fill the LUT buffer.
1124 0 : comp.fTrigRec = new AliHLTMUONTriggerReconstructor();
1125 0 : }
1126 : catch (const std::bad_alloc&)
1127 : {
1128 0 : std::cerr << "ERROR: Could not allocate more memory for the trigger reconstructor component." << std::endl;
1129 : return false;
1130 0 : }
1131 :
1132 0 : if (ddl < 20 or 21 < ddl)
1133 : {
1134 0 : std::cerr << "ERROR: the DDL number must be in the range [20..21]." << std::endl;
1135 0 : return false;
1136 : }
1137 :
1138 0 : comp.fDDL = ddl;
1139 0 : comp.fUseCrateId = useCrateId;
1140 0 : if (comp.SetCDBPathAndRunNo(cdbPath, run) != 0) return false;
1141 0 : if (comp.ReadLutFromCDB() != 0) return false;
1142 :
1143 0 : std::fstream file(filename, std::ios::out);
1144 0 : if (not file)
1145 : {
1146 0 : std::cerr << "ERROR: could not open file: " << filename << std::endl;
1147 0 : return false;
1148 : }
1149 :
1150 0 : file.write(
1151 0 : reinterpret_cast<char*>(comp.fTrigRec->LookupTableBuffer()),
1152 0 : comp.fTrigRec->LookupTableSize()
1153 : );
1154 0 : if (not file)
1155 : {
1156 0 : std::cerr << "ERROR: There was a problem writing to the file: " << filename << std::endl;
1157 0 : return false;
1158 : }
1159 0 : file.close();
1160 :
1161 0 : return true;
1162 0 : }
|