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