]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONTriggerReconstructorComponent.cxx
Added a class for single event monitor computations in RESONANCE package
[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
227e7192 124 constBase = sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType);
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 );
435 int result = ReadLutFromCDB();
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);
2b7af22a 449 int result = ReadLookUpTable(lutFileName);
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
471 int result = ReadConfigFromCDB(not fZmiddleSpecified, not fBLSpecified);
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 );
616 else
450e0b36 617 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
618 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
5d1682b9 619 );
620
227e7192 621 continue;
622 }
623
406c5bc3 624 AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
a6b16447 625 if (fDDL != -1)
b39b98c8 626 {
406c5bc3 627 if (receivedDDL != fDDL)
a6b16447 628 {
a3d4b6ba 629 HLTWarning("Received raw data from DDL %d (ID = %d),"
630 " but expect data only from DDL %d (ID = %d).",
631 receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL),
632 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
633 );
a6b16447 634 }
b39b98c8 635 }
636
227e7192 637 // Create a new output data block and initialise the header.
638 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr+totalSize, size-totalSize);
639 if (not block.InitCommonHeader())
640 {
69c14678 641 HLTError("There is not enough space in the output buffer for the new data block."
b39b98c8 642 " We require at least %ufTrigRec->GetkDDLHeaderSize() bytes, but have %u bytes left.",
227e7192 643 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
644 block.BufferSize()
645 );
646 break;
647 }
648
69c14678 649 AliHLTUInt32_t totalDDLSize = blocks[n].fSize;
650 if (totalDDLSize < sizeof(AliRawDataHeader))
651 {
652 HLTError("Raw data block %d is %d bytes in size and is too short to"
653 " possibly contain valid DDL raw data. We expect it to have"
654 " at least %d bytes for the commond data header.",
655 n, totalDDLSize, sizeof(AliRawDataHeader)
656 );
657 continue;
658 }
3240b3ce 659 AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(blocks[n].fPtr);
69c14678 660 AliHLTUInt32_t payloadSize = totalDDLSize - sizeof(AliRawDataHeader);
a5d4696f 661 AliHLTUInt8_t* buffer = reinterpret_cast<AliHLTUInt8_t*>(header + 1);
227e7192 662 AliHLTUInt32_t nofTrigRec = block.MaxNumberOfEntries();
a5d4696f 663
664 // Decode if this is a scalar event or not.
665 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
666
406c5bc3 667 // Remember: the following does NOT change the mapping!
668 // It is just to generate unique trigger record IDs.
669 fTrigRec->SetDDL(receivedDDL);
670
80590aa1 671 bool runOk = fTrigRec->Run(
a5d4696f 672 buffer, payloadSize, scalarEvent,
a3d4b6ba 673 block.GetArray(), nofTrigRec
80590aa1 674 );
675 if (not runOk)
227e7192 676 {
154cba94 677 HLTError("Error while processing the trigger DDL reconstruction algorithm.");
ffb64d3e 678 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
a3d4b6ba 679 if (not fTrigRec->OverflowedOutputBuffer()
680 or (fTrigRec->OverflowedOutputBuffer() and fStopOnOverflow)
681 )
682 {
683 size = totalSize; // Must tell the framework how much buffer space was used.
684 return -EIO;
685 }
227e7192 686 }
687
688 // nofTrigRec should now contain the number of triggers actually found
689 // and filled into the output data block, so we can set this number.
690 assert( nofTrigRec <= block.MaxNumberOfEntries() );
691 block.SetNumberOfEntries(nofTrigRec);
692
693 HLTDebug("Number of trigger records found is %d", nofTrigRec);
694
695 // Fill a block data structure for our output block.
696 AliHLTComponentBlockData bd;
697 FillBlockData(bd);
698 bd.fPtr = outputPtr;
699 // This block's start (offset) is after all other blocks written so far.
700 bd.fOffset = totalSize;
701 bd.fSize = block.BytesUsed();
702 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
703 bd.fSpecification = blocks[n].fSpecification;
704 outputBlocks.push_back(bd);
705
706 HLTDebug("Created a new output data block at fPtr = %p,"
707 " with fOffset = %u (0x%.X) and fSize = %u bytes.",
708 bd.fPtr, bd.fOffset, bd.fOffset, bd.fSize
709 );
710
711 // Increase the total amount of data written so far to our output memory.
712 totalSize += block.BytesUsed();
713 }
960d54ad 714
227e7192 715 // Finally we set the total size of output memory we consumed.
716 size = totalSize;
717 return 0;
960d54ad 718}
719
6efe69e7 720
2b7af22a 721int AliHLTMUONTriggerReconstructorComponent::Reconfigure(
722 const char* cdbEntry, const char* componentId
723 )
724{
725 /// Inherited from AliHLTComponent. This method will reload CDB configuration
726 /// entries for this component from the CDB.
727 /// \param cdbEntry If this is NULL then it is assumed that all CDB entries should
728 /// be reloaded. Otherwise a particular value for 'cdbEntry' will trigger
729 /// reloading of the LUT if the path contains 'MUON/', but the other
730 /// configuration parameters will be loaded if 'cdbEntry' contains
731 /// "HLT/ConfigMUON/TriggerReconstructor".
732 /// \param componentId The name of the component in the current chain.
733
734 bool startsWithMUON = TString(cdbEntry).Index("MUON/", 5, 0, TString::kExact) == 0;
735 bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::TriggerReconstructorCDBPath()) == 0;
736
737 if (cdbEntry == NULL or startsWithMUON or givenConfigPath)
738 {
739 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
740 }
741
742 if (cdbEntry == NULL or startsWithMUON)
743 {
744 int result = ReadLutFromCDB();
745 if (result != 0) return result;
746 }
747
748 if (cdbEntry == NULL or givenConfigPath)
749 {
750 int result = ReadConfigFromCDB();
751 if (result != 0) return result;
752 }
753
754 return 0;
755}
756
757
758int AliHLTMUONTriggerReconstructorComponent::ReadPreprocessorValues(const char* modules)
759{
760 /// Inherited from AliHLTComponent.
761 /// Updates the configuration of this component if either HLT or MUON have
762 /// been specified in the 'modules' list.
763
764 TString mods = modules;
765 if (mods.Contains("ALL") or (mods.Contains("HLT") and mods.Contains("MUON")))
766 {
767 return Reconfigure(NULL, GetComponentID());
768 }
769 if (mods.Contains("HLT"))
770 {
771 return Reconfigure(AliHLTMUONConstants::TriggerReconstructorCDBPath(), GetComponentID());
772 }
773 if (mods.Contains("MUON"))
774 {
775 return Reconfigure("MUON/*", GetComponentID());
776 }
777 return 0;
778}
779
780
c95cf30c 781int AliHLTMUONTriggerReconstructorComponent::ReadLookUpTable(const char* lutpath)
6efe69e7 782{
6253e09b 783 ///
784 /// Read in the lookup table from file.
785 ///
786
b39b98c8 787 assert(fTrigRec != NULL);
6efe69e7 788
b39b98c8 789 fstream file;
790 file.open(lutpath, fstream::binary | fstream::in);
791 if (not file)
792 {
793 HLTError("Could not open file: %s", lutpath);
c95cf30c 794 return -ENOENT;
b39b98c8 795 }
796
797 file.read(reinterpret_cast<char*>(fTrigRec->LookupTableBuffer()), fTrigRec->LookupTableSize());
798 if (file.eof())
799 {
800 HLTError("The file %s was too short to contain a valid lookup table for this component.", lutpath);
801 file.close();
c95cf30c 802 return -EIO;
b39b98c8 803 }
c95cf30c 804 if (file.fail())
b39b98c8 805 {
806 HLTError("Could not read from file: %s", lutpath);
807 file.close();
c95cf30c 808 return -EIO;
809 }
810
811 file.close();
812 return 0;
813}
814
815
2b7af22a 816int AliHLTMUONTriggerReconstructorComponent::ReadConfigFromCDB(
817 bool setZmiddle, bool setBL
818 )
819{
820 /// Reads this component's configuration parameters from the CDB.
821 /// These include the middle of the dipole Z coordinate (zmiddle) and the
822 /// integrated magnetic field of the dipole.
823 /// \param setZmiddle Indicates if the zmiddle parameter should be set
824 /// (default true).
825 /// \param setBL Indicates if the integrated magnetic field parameter should
826 /// be set (default true).
827 /// \return 0 if no errors occured and negative error code compatible with
828 /// the HLT framework on errors.
829
830 const char* pathToEntry = AliHLTMUONConstants::TriggerReconstructorCDBPath();
831
832 TMap* map = NULL;
833 int result = FetchTMapFromCDB(pathToEntry, map);
834 if (result != 0) return result;
835
836 Double_t value = 0;
837 if (setZmiddle)
838 {
839 result = GetFloatFromTMap(map, "zmiddle", value, pathToEntry, "dipole middle Z coordinate");
840 if (result != 0) return result;
841 AliHLTMUONCalculations::Zf(value);
842 }
843
844 if (setBL)
845 {
846 result = GetFloatFromTMap(map, "bfieldintegral", value, pathToEntry, "integrated magnetic field");
847 if (result != 0) return result;
848 AliHLTMUONCalculations::QBL(value);
849 }
850
851 HLTDebug("Using the following configuration parameters:");
852 HLTDebug(" Middle of dipole Z coordinate = %f cm", AliHLTMUONCalculations::Zf());
853 HLTDebug(" Magnetic field integral = %f T.m", AliHLTMUONCalculations::QBL());
854
855 return 0;
856}
857
858
ffc1a6f6 859int AliHLTMUONTriggerReconstructorComponent::ReadLutFromCDB()
c95cf30c 860{
861 /// Loads the lookup table containing channel and geometrical position
862 /// information about trigger strips from CDB.
ffc1a6f6 863 ///
864 /// \note To override the default CDB path and / or run number the
865 /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
866 /// method.
867 ///
c95cf30c 868 /// \return 0 on success and non zero codes for errors.
869
870 if (fDDL == -1)
871 {
872 HLTError("No DDL number specified for which to load LUT data from CDB.");
873 return -EINVAL;
874 }
875
ffc1a6f6 876 int result = FetchMappingStores();
dba14d7d 877 // Error message already generated in FetchMappingStores.
878 if (result != 0) return result;
c95cf30c 879 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
dba14d7d 880
c95cf30c 881 AliMpSegmentation* segmentation = AliMpSegmentation::Instance();
882 if (segmentation == NULL)
883 {
884 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
885 return -EIO;
886 }
887
61d982d3 888 // Only load geometry if not already loaded.
889 if (AliGeomManager::GetGeometry() == NULL)
890 {
891 AliGeomManager::LoadGeometry();
892 }
c95cf30c 893 AliMUONGeometryTransformer transformer;
894 if (not transformer.LoadGeometryData())
895 {
896 HLTError("Could not load geometry into transformer.");
897 return -ENOENT;
898 }
899
900 AliHLTMUONTriggerRecoLookupTable* lookupTable = fTrigRec->LookupTableBuffer();
901
a3d4b6ba 902 for (Int_t i = 0; i < 16; i++)
c95cf30c 903 for (Int_t j = 0; j < 16; j++)
904 for (Int_t k = 0; k < 4; k++)
905 for (Int_t n = 0; n < 2; n++)
906 for (Int_t m = 0; m < 16; m++)
907 {
a090ff22 908 lookupTable->fRow[i][j][k][n][m].fIdFlags = 0x0;
c95cf30c 909 lookupTable->fRow[i][j][k][n][m].fX = 0;
910 lookupTable->fRow[i][j][k][n][m].fY = 0;
911 lookupTable->fRow[i][j][k][n][m].fZ = 0;
912 }
913
914 AliMpDEIterator detElemIter;
915 for (Int_t iReg = 0; iReg < 8; iReg++)
916 {
917 AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(fDDL, iReg);
918 if (crate == NULL)
919 {
a3d4b6ba 920 HLTError("Could not get crate mapping for regional header = %d"
921 " and DDL %d (ID = %d).",
922 iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
923 );
924 continue;
925 }
926 // Depending on the value of fUseCrateId, use either the crate ID as would
927 // be found in the regional header structures or the sequencial index number
928 // of the structure.
929 UInt_t crateId = (fUseCrateId ? crate->GetId() : iReg);
930 if (crateId >= 16)
931 {
932 HLTError("The crate ID number (%d) for regional header = %d and"
933 " DDL %d (ID = %d) is too big. It should be in the range [0..15]",
934 crateId, iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
935 );
c95cf30c 936 continue;
937 }
938
939 for (Int_t iLocBoard = 0; iLocBoard < 16; iLocBoard++)
940 {
941 Int_t boardId = crate->GetLocalBoardId(iLocBoard);
942 if (boardId == 0) continue;
943
944 AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(boardId);
945 if (localBoard == NULL)
946 {
a3d4b6ba 947 HLTError("Could not get local board: %d.", boardId);
c95cf30c 948 continue;
949 }
950
951 // skip copy cards
952 if (! localBoard->IsNotified()) continue;
953
954 for (Int_t iChamber = 0; iChamber < 4; iChamber++)
955 {
956 Int_t detElemId = ddlStore->GetDEfromLocalBoard(boardId, iChamber);
957
a090ff22 958 AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(iChamber+10, detElemId);
959
c95cf30c 960 const AliMUONGeometryDetElement* detElemTransform = transformer.GetDetElement(detElemId);
961 if (detElemTransform == NULL)
962 {
a3d4b6ba 963 HLTError("Got NULL pointer for geometry transformer"
964 " for detection element ID = %d.",
965 detElemId
966 );
c95cf30c 967 continue;
968 }
969
970 for (Int_t iCathode = 0; iCathode <= 1; iCathode++)
971 {
972 const AliMpVSegmentation* seg = segmentation->GetMpSegmentation(
973 detElemId, AliMp::GetCathodType(iCathode)
974 );
975
976 for (Int_t bitxy = 0; bitxy < 16; bitxy++)
977 {
978 Int_t offset = 0;
979 if (iCathode && localBoard->GetSwitch(6)) offset = -8;
980
981 AliMpPad pad = seg->PadByLocation(AliMpIntPair(boardId, bitxy+offset), kFALSE);
982
983 if (! pad.IsValid())
984 {
985 // There is no pad associated with the given local board and bit pattern.
986 continue;
987 }
988
989 // Get the global coodinates of the pad.
990 Float_t lx = pad.Position().X();
991 Float_t ly = pad.Position().Y();
992 Float_t gx, gy, gz;
993 detElemTransform->Local2Global(lx, ly, 0, gx, gy, gz);
994
995 // Fill the LUT
a3d4b6ba 996 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fIdFlags = idflags;
997 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fX = gx;
998 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fY = gy;
999 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fZ = gz;
c95cf30c 1000 }
1001 }
1002 }
1003 }
1004 }
61d982d3 1005
c95cf30c 1006 return 0;
1007}
1008
1009
1010bool AliHLTMUONTriggerReconstructorComponent::GenerateLookupTable(
1011 AliHLTInt32_t ddl, const char* filename,
2b7af22a 1012 const char* cdbPath, Int_t run, bool useCrateId
c95cf30c 1013 )
1014{
1015 /// Generates a binary file containing the lookup table (LUT) from the
1016 /// CDB, which can be used for the trigger reconstructor component later.
1017 /// @param ddl Must be the DDL for which to generate the DDL,
1018 /// in the range [20..21].
1019 /// @param filename The name of the LUT file to generate.
1020 /// @param cdbPath The CDB path to use.
1021 /// @param run The run number to use for the CDB.
2b7af22a 1022 /// @param useCrateId Indicates that the crate ID should be used rather
1023 /// than a sequencial number.
c95cf30c 1024 /// @return True if the generation of the LUT file succeeded.
1025
1026 AliHLTMUONTriggerReconstructorComponent comp;
1027
1028 if (ddl < 20 or 21 < ddl)
1029 {
1030 std::cerr << "ERROR: the DDL number must be in the range [20..21]." << std::endl;
1031 return false;
1032 }
1033
1034 char ddlNum[32];
1035 char runNum[32];
1036 sprintf(ddlNum, "%d", ddl+1);
1037 sprintf(runNum, "%d", run);
2b7af22a 1038 int argc = 7;
1039 const char* argv[8] = {"-ddl", ddlNum, "-cdbpath", cdbPath, "-run", runNum, "-dont_use_crateid", NULL};
1040 if (useCrateId)
1041 {
1042 argv[6] = NULL;
1043 argc--;
1044 }
1045 int result = comp.DoInit(argc, argv);
c95cf30c 1046 if (result != 0)
1047 {
1048 // Error message already generated in DoInit.
b39b98c8 1049 return false;
1050 }
1051
c95cf30c 1052 std::fstream file(filename, std::ios::out);
1053 if (not file)
1054 {
1055 std::cerr << "ERROR: could not open file: " << filename << std::endl;
1056 return false;
1057 }
1058
1059 file.write(
1060 reinterpret_cast<char*>(comp.fTrigRec->LookupTableBuffer()),
1061 comp.fTrigRec->LookupTableSize()
1062 );
1063 if (not file)
1064 {
a3d4b6ba 1065 std::cerr << "ERROR: There was a problem writing to the file: " << filename << std::endl;
c95cf30c 1066 return false;
1067 }
b39b98c8 1068 file.close();
c95cf30c 1069
1070 comp.DoDeinit();
1071
b39b98c8 1072 return true;
960d54ad 1073}