]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OnlineAnalysis/AliHLTMUONHitReconstructorComponent.cxx
Replacement of AliMpIntPair object with algoritmic
[u/mrichter/AliRoot.git] / HLT / MUON / OnlineAnalysis / AliHLTMUONHitReconstructorComponent.cxx
CommitLineData
b0201cbe 1/**************************************************************************
ffc1a6f6 2 * This file is property of and copyright by the ALICE HLT Project *
960d54ad 3 * All rights reserved. *
b0201cbe 4 * *
960d54ad 5 * Primary Authors: *
6 * Indranil Das <indra.das@saha.ac.in> *
ffc1a6f6 7 * Artur Szostak <artursz@iafrica.com> *
b0201cbe 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 *
ffc1a6f6 14 * about the suitability of this software for any purpose. It is *
b0201cbe 15 * provided "as is" without express or implied warranty. *
16 **************************************************************************/
17
18/* $Id$ */
19
6253e09b 20///
ffc1a6f6 21/// @file AliHLTMUONHitReconstructorComponent.cxx
22/// @author Indranil Das <indra.das@saha.ac.in> | <indra.ehep@gmail.com>, Artur Szostak <artursz@iafrica.com>
23/// @date 28 May 2007
24/// @brief Implementation of the hit Reconstruction processing component.
6253e09b 25///
26/// The HitRec Component is designed to deal the rawdata inputfiles to findout the
27/// the reconstructed hits. The output is send to the output block for further
28/// processing.
29///
30/// Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
31///
b0201cbe 32
960d54ad 33#include "AliHLTMUONRecHitsBlockStruct.h"
b0201cbe 34#include "AliHLTMUONHitReconstructorComponent.h"
b12fe461 35#include "AliHLTMUONHitReconstructor.h"
960d54ad 36#include "AliHLTMUONConstants.h"
668eee9f 37#include "AliHLTMUONUtils.h"
5ff5f960 38#include "AliHLTMUONDataBlockWriter.h"
a6b16447 39#include "AliHLTMUONHitReconstructor.h"
b0201cbe 40#include "AliHLTLogging.h"
41#include "AliHLTSystem.h"
42#include "AliHLTDefinitions.h"
29486e5a 43#include <cstdlib>
44#include <cerrno>
45#include <cassert>
93a75941 46#include <fstream>
b0201cbe 47
ffc1a6f6 48#include "TMap.h"
49
50//STEER
ee3678d3 51#include "AliCDBManager.h"
52#include "AliGeomManager.h"
53
54//MUON
55#include "AliMUONGeometryTransformer.h"
56#include "AliMUONCalibrationData.h"
57#include "AliMUONVCalibParam.h"
58
a6b16447 59//MUON/mapping
ee3678d3 60#include "AliMpCDB.h"
61#include "AliMpPad.h"
62#include "AliMpSegmentation.h"
63#include "AliMpDDLStore.h"
64#include "AliMpDEIterator.h"
65#include "AliMpVSegmentation.h"
66#include "AliMpDEManager.h"
67#include "AliMpDetElement.h"
68
b0201cbe 69ClassImp(AliHLTMUONHitReconstructorComponent)
70
71
29486e5a 72AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
154cba94 73 AliHLTMUONProcessor(),
29486e5a 74 fHitRec(NULL),
a6b16447 75 fDDL(-1),
93a75941 76 fLutSize(0),
77 fLut(NULL),
ee3678d3 78 fIdToEntry(),
90af8855 79 fWarnForUnexpecedBlock(false),
80 fUseIdealGain(false)
b0201cbe 81{
6253e09b 82 ///
83 /// Default constructor.
84 ///
b0201cbe 85}
86
960d54ad 87
b0201cbe 88AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
89{
6253e09b 90 ///
91 /// Default destructor.
92 ///
ee3678d3 93
94 if (fHitRec != NULL)
95 {
96 delete fHitRec;
97 }
93a75941 98 if (fLut != NULL)
99 {
878cb83d 100 delete [] fLut;
93a75941 101 }
960d54ad 102}
b0201cbe 103
960d54ad 104const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
105{
6253e09b 106 ///
107 /// Inherited from AliHLTComponent. Returns the component ID.
108 ///
109
29486e5a 110 return AliHLTMUONConstants::HitReconstructorId();
b0201cbe 111}
112
b0201cbe 113
ffb64d3e 114void AliHLTMUONHitReconstructorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
960d54ad 115{
6253e09b 116 ///
117 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
118 ///
119
29486e5a 120 list.clear();
668eee9f 121 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
960d54ad 122}
b0201cbe 123
b0201cbe 124
960d54ad 125AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
126{
6253e09b 127 ///
128 /// Inherited from AliHLTComponent. Returns the output data type.
129 ///
130
29486e5a 131 return AliHLTMUONConstants::RecHitsBlockDataType();
960d54ad 132}
b0201cbe 133
b0201cbe 134
ffb64d3e 135void AliHLTMUONHitReconstructorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
960d54ad 136{
6253e09b 137 ///
138 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
139 ///
140
979076f8 141 constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType) + 1024*1024;
29486e5a 142 inputMultiplier = 1;
960d54ad 143}
b0201cbe 144
b0201cbe 145
960d54ad 146AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
147{
6253e09b 148 ///
149 /// Inherited from AliHLTComponent. Creates a new object instance.
150 ///
151
29486e5a 152 return new AliHLTMUONHitReconstructorComponent;
960d54ad 153}
b0201cbe 154
b0201cbe 155
29486e5a 156int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
960d54ad 157{
6253e09b 158 ///
159 /// Inherited from AliHLTComponent.
160 /// Parses the command line parameters and initialises the component.
161 ///
b0201cbe 162
ee3678d3 163 HLTInfo("Initialising dHLT hit reconstruction component.");
ffb64d3e 164
165 // Inherit the parents functionality.
166 int result = AliHLTMUONProcessor::DoInit(argc, argv);
167 if (result != 0) return result;
960d54ad 168
93a75941 169 // Must make sure that fHitRec and fLut is deleted if it is still
170 // allocated for whatever reason.
a6b16447 171 FreeMemory();
172
a6b16447 173 // Initialise fields with default values then parse the command line.
174 fDDL = -1;
175 fIdToEntry.clear();
ee3678d3 176 fWarnForUnexpecedBlock = false;
90af8855 177 fUseIdealGain = false;
ee3678d3 178 const char* lutFileName = NULL;
ee3678d3 179 bool useCDB = false;
a9afae73 180 typedef AliHLTMUONHitReconstructor HR;
181 HR::ERecoveryMode recoveryMode = HR::kDontTryRecover;
ffc1a6f6 182 AliHLTInt32_t dccut = -1;
a9afae73 183 bool skipParityErrors = false;
184 bool dontPrintParityErrors = false;
ee3678d3 185
186 for (int i = 0; i < argc; i++)
187 {
ffb64d3e 188 // To keep the legacy behaviour we need to have the following check
189 // for -cdbpath here, before ArgumentAlreadyHandled.
190 if (strcmp(argv[i], "-cdbpath") == 0)
191 {
192 useCDB = true;
193 }
194
195 if (ArgumentAlreadyHandled(i, argv[i])) continue;
ee3678d3 196
197 if (strcmp( argv[i], "-ddl" ) == 0)
198 {
ffc1a6f6 199 if (fDDL != -1)
200 {
201 HLTWarning("DDL number was already specified."
202 " Will replace previous value given by -ddl or -ddlid."
203 );
204 }
205
ee3678d3 206 if (argc <= i+1)
207 {
208 HLTError("The DDL number was not specified. Must be in the range [13..20].");
a6b16447 209 return -EINVAL;
ee3678d3 210 }
211
212 char* cpErr = NULL;
213 unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
214 if (cpErr == NULL or *cpErr != '\0')
215 {
93a75941 216 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
a6b16447 217 return -EINVAL;
ee3678d3 218 }
219 if (num < 13 or 20 < num)
220 {
221 HLTError("The DDL number must be in the range [13..20].");
a6b16447 222 return -EINVAL;
ee3678d3 223 }
93a75941 224 fDDL = num - 1; // convert to range [12..19]
ee3678d3 225
226 i++;
227 continue;
228 } // -ddl argument
229
a3d4b6ba 230 if (strcmp( argv[i], "-ddlid" ) == 0)
231 {
ffc1a6f6 232 if (fDDL != -1)
233 {
234 HLTWarning("DDL number was already specified."
235 " Will replace previous value given by -ddl or -ddlid."
236 );
237 }
238
a3d4b6ba 239 if ( argc <= i+1 )
240 {
241 HLTError("DDL equipment ID number not specified. It must be in the range [2572..2579]" );
a3d4b6ba 242 return -EINVAL;
243 }
244
245 char* cpErr = NULL;
246 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
247 if (cpErr == NULL or *cpErr != '\0')
248 {
249 HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]);
a3d4b6ba 250 return -EINVAL;
251 }
252 fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
253 if (fDDL < 12 or 19 < fDDL)
254 {
255 HLTError("The DDL equipment ID number must be in the range [2572..2579].");
a3d4b6ba 256 return -EINVAL;
257 }
258
259 i++;
260 continue;
261 }
262
ee3678d3 263 if (strcmp( argv[i], "-lut" ) == 0)
264 {
ffc1a6f6 265 if (lutFileName != NULL)
266 {
267 HLTWarning("LUT path was already specified."
268 " Will replace previous value given by -lut."
269 );
270 }
271
ee3678d3 272 if (argc <= i+1)
273 {
274 HLTError("The lookup table filename was not specified.");
a6b16447 275 return -EINVAL;
ee3678d3 276 }
277 lutFileName = argv[i+1];
278 i++;
279 continue;
280 } // -lut argument
281
282 if (strcmp( argv[i], "-cdb" ) == 0)
283 {
284 useCDB = true;
285 continue;
286 } // -cdb argument
287
ffc1a6f6 288 if (strcmp( argv[i], "-dccut" ) == 0)
289 {
290 if (dccut != -1)
291 {
292 HLTWarning("DC cut parameter was already specified."
293 " Will replace previous value given by -dccut."
294 );
295 }
296
297 if ( argc <= i+1 )
298 {
299 HLTError("No DC cut value was specified. It should be a positive integer value." );
ffc1a6f6 300 return -EINVAL;
301 }
302
303 char* cpErr = NULL;
304 dccut = AliHLTInt32_t( strtol(argv[i+1], &cpErr, 0) );
305 if (cpErr == NULL or *cpErr != '\0' or dccut < 0)
306 {
307 HLTError("Cannot convert '%s' to a valid DC cut value."
308 " Expected a positive integer value.", argv[i+1]
309 );
ffc1a6f6 310 return -EINVAL;
311 }
312
313 i++;
314 continue;
315 }
316
ee3678d3 317 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
318 {
319 fWarnForUnexpecedBlock = true;
320 continue;
321 }
a5d4696f 322
323 if (strcmp( argv[i], "-tryrecover" ) == 0)
324 {
a9afae73 325 if (argc > i+1)
326 {
327 // There might be an optional parameter so check
328 // if it is a recognised one. If not then assume it
329 // is the next argument, so no error message.
330 if (strcmp(argv[i+1], "full") == 0)
331 {
332 recoveryMode = HR::kRecoverFull;
333 i++;
334 }
335 else if (strcmp(argv[i+1], "skip") == 0)
336 {
337 recoveryMode = HR::kRecoverJustSkip;
338 i++;
339 }
340 else if (strcmp(argv[i+1], "parityerrors") == 0)
341 {
342 recoveryMode = HR::kRecoverFromParityErrorsOnly;
343 i++;
344 }
345 else
346 {
347 recoveryMode = HR::kRecoverFull;
348 }
349 }
350 else
351 {
352 recoveryMode = HR::kRecoverFull;
353 }
354 continue;
355 }
356
357 if (strcmp( argv[i], "-skipparityerrors" ) == 0)
358 {
359 skipParityErrors = true;
360 continue;
361 }
362
363 if (strcmp( argv[i], "-dontprintparityerrors" ) == 0)
364 {
365 dontPrintParityErrors = true;
a5d4696f 366 continue;
367 }
90af8855 368
369 if (strcmp( argv[i], "-useidealgain" ) == 0)
370 {
371 fUseIdealGain = true;
372 continue;
373 }
ee3678d3 374
375 HLTError("Unknown option '%s'", argv[i]);
a6b16447 376 return -EINVAL;
ee3678d3 377
378 } // for loop
379
ffb64d3e 380 try
381 {
382 fHitRec = new AliHLTMUONHitReconstructor();
383 }
384 catch (const std::bad_alloc&)
385 {
386 HLTError("Could not allocate more memory for the hit reconstructor component.");
387 return -ENOMEM;
388 }
389
2b7af22a 390 if (dccut != -1 and useCDB)
391 {
392 HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
393 " this component should read from the CDB, but then the -dccut argument"
394 " was also used. Will override the value from CDB with the command"
395 " line DC cut parameter given."
396 );
397 }
398
399 if (lutFileName != NULL and useCDB == true)
400 {
401 HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
402 " this component should read from the CDB, but then the -lut argument"
403 " was also used. Will ignore the -lut option and load from CDB anyway."
404 );
405 }
406
93a75941 407 if (lutFileName == NULL) useCDB = true;
408
ffb64d3e 409 if (fDDL == -1 and not DelaySetup())
a6b16447 410 {
411 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
412 }
413
ee3678d3 414 if (useCDB)
415 {
ffb64d3e 416 if (not DelaySetup())
ffc1a6f6 417 {
418 HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
419 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
420 );
4e22efc4 421 result = ReadLutFromCDB();
ffc1a6f6 422 if (result != 0)
423 {
424 // Error messages already generated in ReadLutFromCDB.
425 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
426 return result;
427 }
428 fHitRec->SetLookUpTable(fLut, &fIdToEntry);
429 }
960d54ad 430 }
ee3678d3 431 else
432 {
93a75941 433 HLTInfo("Loading lookup table information from file %s.", lutFileName);
4e22efc4 434 result = ReadLookUpTable(lutFileName);
ffc1a6f6 435 if (result != 0)
436 {
437 // Error messages already generated in ReadLookUpTable.
438 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
439 return result;
440 }
441 fHitRec->SetLookUpTable(fLut, &fIdToEntry);
ee3678d3 442 }
ffc1a6f6 443
444 if (dccut == -1)
ee3678d3 445 {
ffb64d3e 446 if (not DelaySetup())
ffc1a6f6 447 {
448 HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).",
449 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
450 );
4e22efc4 451 result = ReadDCCutFromCDB();
ffc1a6f6 452 if (result != 0)
453 {
454 // Error messages already generated in ReadDCCutFromCDB.
455 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
456 return result;
457 }
2b7af22a 458 }
459 else
460 {
461 // Print the debug messages here since ReadDCCutFromCDB does not get called,
462 // in-which the debug messages would have been printed.
ffc1a6f6 463 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
464 }
465 }
466 else
467 {
ffc1a6f6 468 fHitRec->SetDCCut(dccut);
469 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
ee3678d3 470 }
471
a9afae73 472 fHitRec->TryRecover(recoveryMode);
473 fHitRec->SkipParityErrors(skipParityErrors);
474 fHitRec->DontPrintParityErrors(dontPrintParityErrors);
90af8855 475 HLTDebug("dHLT hit reconstruction component is initialized.");
ee3678d3 476 return 0;
b0201cbe 477}
478
960d54ad 479
480int AliHLTMUONHitReconstructorComponent::DoDeinit()
481{
6253e09b 482 ///
483 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
484 ///
485
ee3678d3 486 HLTInfo("Deinitialising dHLT hit reconstruction component.");
a6b16447 487 FreeMemory();
ee3678d3 488 return 0;
b0201cbe 489}
490
b0201cbe 491
ffc1a6f6 492int AliHLTMUONHitReconstructorComponent::Reconfigure(
493 const char* cdbEntry, const char* componentId
494 )
495{
496 /// Inherited from AliHLTComponent. This method will reload CDB configuration
497 /// entries for this component from the CDB.
498 /// \param cdbEntry If this is NULL then it is assumed that all CDB entries should
499 /// be reloaded. Otherwise a particular value for 'cdbEntry' will trigger
500 /// reloading of the LUT if the path contains 'MUON/' and reloading of the DC
2b7af22a 501 /// cut parameter if 'cdbEntry' equals "HLT/ConfigMUON/HitReconstructor".
502 /// \param componentId The name of the component in the current chain.
503
504 bool startsWithMUON = TString(cdbEntry).Index("MUON/", 5, 0, TString::kExact) == 0;
505 bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::HitReconstructorCDBPath()) == 0;
ffc1a6f6 506
2b7af22a 507 if (cdbEntry == NULL or startsWithMUON or givenConfigPath)
ffc1a6f6 508 {
2b7af22a 509 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
510 }
ffc1a6f6 511
2b7af22a 512 if (cdbEntry == NULL or startsWithMUON)
513 {
514 // First clear the current LUT data and then load in the new values.
515 if (fLut != NULL)
ffc1a6f6 516 {
2b7af22a 517 delete [] fLut;
518 fLut = NULL;
519 fLutSize = 0;
ffc1a6f6 520 }
521
2b7af22a 522 fIdToEntry.clear();
523
524 int result = ReadLutFromCDB();
525 if (result != 0) return result;
526 fHitRec->SetLookUpTable(fLut, &fIdToEntry);
527 }
528
529 if (cdbEntry == NULL or not startsWithMUON)
530 {
531 int result = ReadDCCutFromCDB();
532 if (result != 0) return result;
ffc1a6f6 533 }
534
535 return 0;
536}
537
538
539int AliHLTMUONHitReconstructorComponent::ReadPreprocessorValues(const char* modules)
540{
541 /// Inherited from AliHLTComponent.
542 /// Updates the configuration of this component if either HLT or MUON have
543 /// been specified in the 'modules' list.
544
545 TString mods = modules;
546 if (mods.Contains("ALL") or (mods.Contains("HLT") and mods.Contains("MUON")))
547 {
548 return Reconfigure(NULL, GetComponentID());
549 }
550 if (mods.Contains("HLT"))
551 {
552 return Reconfigure(AliHLTMUONConstants::HitReconstructorCDBPath(), GetComponentID());
553 }
554 if (mods.Contains("MUON"))
555 {
556 return Reconfigure("MUON/*", GetComponentID());
557 }
558 return 0;
559}
560
561
960d54ad 562int AliHLTMUONHitReconstructorComponent::DoEvent(
563 const AliHLTComponentEventData& evtData,
b8d467da 564 const AliHLTComponentBlockData* blocks,
ffb64d3e 565 AliHLTComponentTriggerData& trigData,
b8d467da 566 AliHLTUInt8_t* outputPtr,
960d54ad 567 AliHLTUInt32_t& size,
ffb64d3e 568 AliHLTComponentBlockDataList& outputBlocks
960d54ad 569 )
570{
6253e09b 571 ///
572 /// Inherited from AliHLTProcessor. Processes the new event data.
573 ///
ffb64d3e 574
ffc1a6f6 575 // Initialise the LUT and DC cut parameter from CDB if we were requested
576 // to initialise only when the first event was received.
ffb64d3e 577 if (DelaySetup())
ffc1a6f6 578 {
579 // Use the specification given by the first data block if we
580 // have not been given a DDL number on the command line.
581 if (fDDL == -1)
582 {
48ccb241 583 bool blockFound = false;
584 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt and not blockFound; n++)
585 {
586 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()) continue;
587 blockFound = true;
588
589 fDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
590
591 if (fDDL == -1)
592 {
593 HLTError("Received a data block with a specification (0x%8.8X)"
594 " indicating multiple DDL data sources, but we must only"
595 " receive raw DDL data from one tracking station DDL.",
596 blocks[n].fSpecification
597 );
598 return -EPROTO;
599 }
600 }
601
602 if (not blockFound)
ffc1a6f6 603 {
604 HLTError("The initialisation from CDB of the component has"
605 " been delayed to the first received event. However,"
48ccb241 606 " no raw DDL data blocks have been found in the first event."
ffc1a6f6 607 );
608 return -ENOENT;
609 }
ffc1a6f6 610 }
611
612 // Check that the LUT was not already loaded in DoInit.
613 if (fLut == NULL)
614 {
615 HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
616 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
617 );
618 int result = ReadLutFromCDB();
619 if (result != 0) return result;
620
621 fHitRec->SetLookUpTable(fLut, &fIdToEntry);
622 }
623
624 // Check that the DC cut was not already loaded in DoInit.
625 if (fHitRec->GetDCCut() == -1)
626 {
627 HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).",
628 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
629 );
630 int result = ReadDCCutFromCDB();
631 if (result != 0) return result;
ffc1a6f6 632 }
633
ffb64d3e 634 DoneDelayedSetup();
ffc1a6f6 635 }
636
637 if (fLut == NULL)
638 {
639 HLTFatal("Lookup table not loaded! Cannot continue processing data.");
640 return -ENOENT;
641 }
642
29486e5a 643 // Process an event
644 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
b0201cbe 645
29486e5a 646 HLTDebug("Processing event %llu with %u input data blocks.",
647 evtData.fEventID, evtData.fBlockCnt
648 );
649
650 // Loop over all input blocks in the event
450e0b36 651 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
5ff5f960 652 {
450e0b36 653 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
654 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
5ff5f960 655 );
29486e5a 656
668eee9f 657 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
658 or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
659 )
29486e5a 660 {
661 // Log a message indicating that we got a data block that we
662 // do not know how to handle.
29486e5a 663 if (fWarnForUnexpecedBlock)
450e0b36 664 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
665 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
29486e5a 666 );
4e22efc4 667#ifdef __DEBUG
29486e5a 668 else
450e0b36 669 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
670 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
29486e5a 671 );
4e22efc4 672#endif
29486e5a 673
674 continue;
675 }
676
a6b16447 677 if (fDDL != -1)
ee3678d3 678 {
a3d4b6ba 679 AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
680 if (receivedDDL != fDDL)
a6b16447 681 {
a3d4b6ba 682 HLTWarning("Received raw data from DDL %d (ID = %d),"
683 " but expect data only from DDL %d (ID = %d).",
684 receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL),
685 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
686 );
a6b16447 687 }
ee3678d3 688 }
689
29486e5a 690 // Create a new output data block and initialise the header.
691 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
692 if (not block.InitCommonHeader())
693 {
8bade2be 694 HLTError("There is not enough space in the output buffer for the new data block."
29486e5a 695 " We require at least %u bytes, but have %u bytes left.",
696 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
697 block.BufferSize()
698 );
699 break;
700 }
701
702 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
703 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
3240b3ce 704 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
705 + fHitRec->GetkDDLHeaderSize();
29486e5a 706 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
707
ee3678d3 708#ifdef DEBUG
29486e5a 709 HLTDebug("=========== Dumping DDL payload buffer ==========");
710 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
711 HLTDebug("buffer[%d] : %x",j,buffer[j]);
712 HLTDebug("================== End of dump =================");
ee3678d3 713#endif // DEBUG
29486e5a 714
715 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
716 {
154cba94 717 HLTError("Error while processing the hit reconstruction algorithm.");
ffb64d3e 718 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
29486e5a 719 size = totalSize; // Must tell the framework how much buffer space was used.
a6b16447 720 return -EIO;
29486e5a 721 }
722
723 // nofHit should now contain the number of reconstructed hits actually found
724 // and filled into the output data block, so we can set this number.
725 assert( nofHit <= block.MaxNumberOfEntries() );
726 block.SetNumberOfEntries(nofHit);
727
728 HLTDebug("Number of reconstructed hits found is %d", nofHit);
729
730 // Fill a block data structure for our output block.
731 AliHLTComponentBlockData bd;
732 FillBlockData(bd);
733 bd.fPtr = outputPtr;
734 // This block's start (offset) is after all other blocks written so far.
735 bd.fOffset = totalSize;
736 bd.fSize = block.BytesUsed();
737 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
738 bd.fSpecification = blocks[n].fSpecification;
739 outputBlocks.push_back(bd);
740
741 // Increase the total amount of data written so far to our output memory
742 totalSize += block.BytesUsed();
5ff5f960 743 }
29486e5a 744 // Finally we set the total size of output memory we consumed.
745 size = totalSize;
746
747 return 0;
b0201cbe 748}
749
750
a6b16447 751void AliHLTMUONHitReconstructorComponent::FreeMemory()
752{
753 /// Deletes any allocated objects if they are allocated else nothing is
754 /// done for objects not yet allocated.
755 /// This is used as a helper method to make sure the corresponding pointers
93a75941 756 /// are NULL and we get back to a well defined state.
a6b16447 757
758 if (fHitRec != NULL)
759 {
760 delete fHitRec;
761 fHitRec = NULL;
762 }
93a75941 763 if (fLut != NULL)
764 {
878cb83d 765 delete [] fLut;
93a75941 766 fLut = NULL;
767 fLutSize = 0;
768 }
a6b16447 769
770 fIdToEntry.clear();
771}
772
773
93a75941 774int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
ee3678d3 775{
93a75941 776 /// Read in the lookup table from a text file.
777 /// Note that this method could leave fLut allocated which is cleaned up
778 /// by DoInit with a call to FreeMemory().
779
780 assert( fLut == NULL );
781 assert( fLutSize == 0 );
782 assert( fIdToEntry.empty() );
783
784 std::ifstream file(lutFileName);
785 if (not file.good())
786 {
787 HLTError("Could not open the LUT file %s", lutFileName);
788 return -ENOENT;
789 }
790
791 // First count the number of lines of text in the LUT file before decoding.
792 // This is not the most optimal. It would be better to read and decode at the
793 // same time but we are not allowed to use STL and ROOT containers are too
794 // heavy for this task. At least this is done only at the start of run.
795 std::string str;
796 AliHLTUInt32_t lineCount = 0;
797 while (std::getline(file, str)) lineCount++;
798 if (not file.eof())
799 {
800 HLTError("There was a problem reading the LUT file %s", lutFileName);
801 return -EIO;
802 }
803 if (lineCount == 0)
804 {
805 HLTWarning("The LUT file %s was empty.", lutFileName);
806 }
807
808 // Add one extra LUT line for the first element which is used as a sentinel value.
809 lineCount++;
810
811 try
812 {
813 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
814 fLutSize = lineCount;
815 }
816 catch (const std::bad_alloc&)
817 {
818 HLTError("Could not allocate more memory for the lookuptable.");
819 return -ENOMEM;
820 }
821
822 // Initialise the sentinel value.
823 fLut[0].fDetElemId = 0;
824 fLut[0].fIX = 0;
825 fLut[0].fIY = 0;
826 fLut[0].fRealX = 0.0;
827 fLut[0].fRealY = 0.0;
828 fLut[0].fRealZ = 0.0;
829 fLut[0].fHalfPadSize = 0.0;
830 fLut[0].fPlane = -1;
831 fLut[0].fPed = -1;
832 fLut[0].fSigma = -1;
833 fLut[0].fA0 = -1;
834 fLut[0].fA1 = -1;
835 fLut[0].fThres = -1;
836 fLut[0].fSat = -1;
837
838 // Clear the eof flag and start reading from the beginning of the file again.
839 file.clear();
840 file.seekg(0, std::ios::beg);
841 if (not file.good())
842 {
843 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
844 return -EIO;
845 }
846
847 AliHLTInt32_t idManuChannel;
848 for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
849 {
850 if (std::getline(file, str).fail())
851 {
852 HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
853 return -EIO;
854 }
855
856 int result = sscanf(
857 str.c_str(), "%d\t%d\t%d\t%d\t%e\t%e\t%e\t%e\t%d\t%e\t%e\t%e\t%e\t%d\t%d",
858 &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
859 &fLut[i].fIY, &fLut[i].fRealX,
860 &fLut[i].fRealY, &fLut[i].fRealZ,
861 &fLut[i].fHalfPadSize, &fLut[i].fPlane,
862 &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
863 &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
864 );
865
866 if (result != 15)
867 {
868 HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
869 return -EIO;
870 }
871
872 fIdToEntry[idManuChannel] = i;
873 }
874
875 return 0;
ee3678d3 876}
877
878
ffc1a6f6 879int AliHLTMUONHitReconstructorComponent::ReadLutFromCDB()
b0201cbe 880{
dba14d7d 881 /// Reads LUT from CDB.
ffc1a6f6 882 /// To override the default CDB path and / or run number the
883 /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
884 /// method.
93a75941 885
886 assert( fLut == NULL );
887 assert( fLutSize == 0 );
888 assert( fIdToEntry.empty() );
889
a3d4b6ba 890 if (fDDL == -1)
891 {
892 HLTError("No DDL number specified for which to load LUT data from CDB.");
893 return -EINVAL;
894 }
895
93a75941 896 std::vector<AliHLTMUONHitRecoLutRow> lutList;
897 AliHLTMUONHitRecoLutRow lut;
898 AliHLTUInt32_t iEntry = 0;
899
ffc1a6f6 900 int result = FetchMappingStores();
dba14d7d 901 // Error message already generated in FetchMappingStores.
902 if (result != 0) return result;
93a75941 903 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
dba14d7d 904
93a75941 905 AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
906 if (mpSegFactory == NULL)
907 {
908 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
909 return -EIO;
910 }
911
61d982d3 912 // Only load geometry if not already loaded.
913 if (AliGeomManager::GetGeometry() == NULL)
914 {
915 AliGeomManager::LoadGeometry();
916 }
93a75941 917 AliMUONGeometryTransformer chamberGeometryTransformer;
918 if (not chamberGeometryTransformer.LoadGeometryData())
919 {
920 HLTError("Failed to load geomerty data.");
921 return -ENOENT;
922 }
923
ffc1a6f6 924 AliMUONCalibrationData calibData(AliCDBManager::Instance()->GetRun());
93a75941 925
926 Int_t chamberId;
927
928 for(Int_t iCh = 6; iCh < 10; iCh++)
929 {
930 chamberId = iCh;
931
932 AliMpDEIterator it;
933 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
934 {
935 Int_t detElemId = it.CurrentDEId();
936 int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
937 if (iDDL != fDDL) continue;
938
939 for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
940 {
941 AliMp::CathodType cath;
942
943 if(iCath == 0)
944 cath = AliMp::kCath0;
945 else
946 cath = AliMp::kCath1;
947
948 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
949 AliMp::PlaneType plane = seg->PlaneType();
950 Int_t maxIX = seg->MaxPadIndexX();
951 Int_t maxIY = seg->MaxPadIndexY();
952
953 Int_t idManuChannel, manuId, channelId, buspatchId;
954 AliHLTFloat32_t padSizeX, padSizeY;
955 AliHLTFloat32_t halfPadSize;
956 Double_t realX, realY, realZ;
957 Double_t localX, localY, localZ;
958 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
959 Int_t thresold,saturation;
960
961 // Pad Info of a slat to print in lookuptable
962 for (Int_t iX = 0; iX<= maxIX ; iX++)
963 for (Int_t iY = 0; iY<= maxIY ; iY++)
964 {
168e9c4d 965 if (not seg->HasPadByIndices(iX,iY)) continue;
93a75941 966
168e9c4d 967 AliMpPad pad = seg->PadByIndices(iX,iY, kFALSE);
93a75941 968
969 // Getting Manu id
168e9c4d 970 manuId = pad.GetManuId();
93a75941 971 manuId &= 0x7FF; // 11 bits
90af8855 972 if(!calibData.Pedestals(detElemId, manuId)) continue;
93a75941 973
974 buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
975
976 // Getting channel id
168e9c4d 977 channelId = pad.GetManuChannel();
93a75941 978 channelId &= 0x3F; // 6 bits
979
980 idManuChannel = buspatchId << 11;
981 idManuChannel = (idManuChannel | manuId) << 6;
982 idManuChannel |= channelId;
983
984 localX = pad.Position().X();
985 localY = pad.Position().Y();
986 localZ = 0.0;
987
988 chamberGeometryTransformer.Local2Global(
989 detElemId,localX,localY,localZ,
990 realX,realY,realZ
991 );
992
90af8855 993 padSizeX = AliHLTFloat32_t( pad.Dimensions().X() );
994 padSizeY = AliHLTFloat32_t( pad.Dimensions().Y() );
93a75941 995
90af8855 996 if (fUseIdealGain)
997 {
998 calibA0Coeff = 1.0;
999 calibA1Coeff = 0.0;
1000 thresold = 0;
1001 saturation = 0;
1002 }
1003 else
1004 {
1005 calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
1006 calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
1007 thresold = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 2);
1008 saturation = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 4);
1009 }
93a75941 1010
1011 pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
1012 sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
1013
1014 if (plane == 0)
1015 halfPadSize = padSizeX;
1016 else
1017 halfPadSize = padSizeY;
1018
1019 fIdToEntry[idManuChannel] = iEntry+1;
1020
1021 lut.fDetElemId = detElemId;
1022 lut.fIX = iX;
1023 lut.fIY = iY;
1024 lut.fRealX = realX;
1025 lut.fRealY = realY;
1026 lut.fRealZ = realZ;
1027 lut.fHalfPadSize = halfPadSize;
1028 lut.fPlane = plane;
1029 lut.fPed = pedestal;
1030 lut.fSigma = sigma;
1031 lut.fA0 = calibA0Coeff;
1032 lut.fA1 = calibA1Coeff;
1033 lut.fThres = thresold;
1034 lut.fSat = saturation;
1035
90af8855 1036 HLTDebug("lut : detele : %d, id : %d, manu : %d, channel : %d, iX : %d, iY: %d, (X,Y) : (%f, %f), padsize : %f, plane : %d, ped : %f, sigma : %f",
1037 lut.fDetElemId,idManuChannel,manuId,channelId,lut.fIX,lut.fIY,lut.fRealX,lut.fRealY,lut.fHalfPadSize,lut.fPlane,lut.fPed,lut.fSigma
1038 );
1039
93a75941 1040 lutList.push_back(lut);
1041 iEntry++;
1042 } // iX, iY loop
1043 } // iCath loop
1044 } // detElemId loop
1045 } // ichamber loop
1046
1047 try
1048 {
1049 // Use iEntry+1 since we add one extra LUT line for the first element
1050 // which is used as a sentinel value.
1051 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
1052 fLutSize = iEntry+1;
90af8855 1053 HLTDebug("Address of new LUT buffer at fLut = %p", fLut);
93a75941 1054 }
1055 catch (const std::bad_alloc&)
1056 {
1057 HLTError("Could not allocate more memory for the lookuptable.");
90af8855 1058 //lutList.clear(); not necessary, implicitly done during stack cleanup.
93a75941 1059 return -ENOMEM;
1060 }
1061
1062 // Initialise the sentinel value.
1063 fLut[0].fDetElemId = 0;
1064 fLut[0].fIX = 0;
1065 fLut[0].fIY = 0;
1066 fLut[0].fRealX = 0.0;
1067 fLut[0].fRealY = 0.0;
1068 fLut[0].fRealZ = 0.0;
1069 fLut[0].fHalfPadSize = 0.0;
1070 fLut[0].fPlane = -1;
1071 fLut[0].fPed = -1;
1072 fLut[0].fSigma = -1;
1073 fLut[0].fA0 = -1;
1074 fLut[0].fA1 = -1;
1075 fLut[0].fThres = -1;
1076 fLut[0].fSat = -1;
1077
1078 for (AliHLTUInt32_t i = 0; i < iEntry; i++)
1079 fLut[i+1] = lutList[i];
1080
1081 return 0;
b0201cbe 1082}
1083
b0201cbe 1084
2b7af22a 1085int AliHLTMUONHitReconstructorComponent::ReadDCCutFromCDB()
ffc1a6f6 1086{
1087 /// Reads the DC cut parameter from the CDB.
1088
1089 const char* pathToEntry = AliHLTMUONConstants::HitReconstructorCDBPath();
ffc1a6f6 1090
1091 TMap* map = NULL;
1092 int result = FetchTMapFromCDB(pathToEntry, map);
1093 if (result != 0) return result;
1094
1095 Int_t value = 0;
1096 result = GetPositiveIntFromTMap(map, "dccut", value, pathToEntry, "DC cut");
1097 if (result != 0) return result;
1098
1099 assert(fHitRec != NULL);
1100 fHitRec->SetDCCut(value);
1101
2b7af22a 1102 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
1103
ffc1a6f6 1104 return 0;
1105}
1106
1107
93a75941 1108bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
1109 AliHLTInt32_t ddl, const char* filename,
ee3678d3 1110 const char* cdbPath, Int_t run
1111 )
b0201cbe 1112{
93a75941 1113 /// Generates a ASCII text file containing the lookup table (LUT) from
1114 /// the CDB, which can be used for the hit reconstructor component later.
1115 /// @param ddl Must be the DDL for which to generate the DDL,
1116 /// in the range [13..20].
1117 /// @param filename The name of the LUT file to generate.
1118 /// @param cdbPath The CDB path to use.
1119 /// @param run The run number to use for the CDB.
1120 /// @return True if the generation of the LUT file succeeded.
1121
1122 AliHLTMUONHitReconstructorComponent comp;
1123
1124 if (ddl < 12 or 19 < ddl)
1125 {
1126 std::cerr << "ERROR: the DDL number must be in the range [12..19]." << std::endl;
1127 return false;
1128 }
1129
1130 comp.fDDL = ddl;
ffc1a6f6 1131 if (comp.SetCDBPathAndRunNo(cdbPath, run) != 0) return false;
1132 if (comp.ReadLutFromCDB() != 0) return false;
93a75941 1133
1134 char str[1024*4];
1135 std::fstream file(filename, std::ios::out);
1136 if (not file)
1137 {
1138 std::cerr << "ERROR: could not open file: " << filename << std::endl;
1139 return false;
1140 }
1141
1142 assert( comp.fLut != NULL );
1143
1144 for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
1145 id != comp.fIdToEntry.end();
1146 id++
1147 )
1148 {
1149 AliHLTInt32_t idManuChannel = id->first;
1150 AliHLTInt32_t row = id->second;
ee3678d3 1151
ffc1a6f6 1152 assert( AliHLTUInt32_t(row) < comp.fLutSize );
ee3678d3 1153
93a75941 1154 sprintf(str, "%d\t%d\t%d\t%d\t%.15e\t%.15e\t%.15e\t%.15e\t%d\t%.15e\t%.15e\t%.15e\t%.15e\t%d\t%d",
1155 idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
1156 comp.fLut[row].fIY, comp.fLut[row].fRealX,
1157 comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
1158 comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
1159 comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
1160 comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
1161 );
ee3678d3 1162
93a75941 1163 file << str << endl;
1164 if (file.fail())
1165 {
1166 std::cerr << "ERROR: There was an I/O error when writing to the file: "
1167 << filename << std::endl;
1168 return false;
1169 }
1170 }
1171
1172 return true;
b0201cbe 1173}