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