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