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