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