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