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