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