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