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