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