1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Indranil Das <indra.das@saha.ac.in> *
7 * Artur Szostak <artursz@iafrica.com> *
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 **************************************************************************/
21 /// @file AliHLTMUONHitReconstructorComponent.cxx
22 /// @author Indranil Das <indra.das@saha.ac.in> | <indra.ehep@gmail.com>, Artur Szostak <artursz@iafrica.com>
24 /// @brief Implementation of the hit Reconstruction processing component.
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
30 /// Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
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"
51 #include "AliCDBManager.h"
52 #include "AliGeomManager.h"
55 #include "AliMUONGeometryTransformer.h"
56 #include "AliMUONCalibrationData.h"
57 #include "AliMUONVCalibParam.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"
69 ClassImp(AliHLTMUONHitReconstructorComponent)
72 AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
73 AliHLTMUONProcessor(),
79 fMaxEntryPerBusPatch(),
80 fWarnForUnexpecedBlock(false),
82 fWarnIfPadSkipped(false)
85 /// Default constructor.
90 AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
93 /// Default destructor.
106 const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
109 /// Inherited from AliHLTComponent. Returns the component ID.
112 return AliHLTMUONConstants::HitReconstructorId();
116 void AliHLTMUONHitReconstructorComponent::GetInputDataTypes(AliHLTComponentDataTypeList& list)
119 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
123 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
127 AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
130 /// Inherited from AliHLTComponent. Returns the output data type.
133 return kAliHLTMultipleDataType;
137 int AliHLTMUONHitReconstructorComponent::GetOutputDataTypes(AliHLTComponentDataTypeList& list)
139 /// Inherited from AliHLTComponent. Returns the output data types.
141 assert( list.empty() );
142 list.push_back( AliHLTMUONConstants::RecHitsBlockDataType() );
143 list.push_back( AliHLTMUONConstants::ClusterBlockDataType() );
144 list.push_back( AliHLTMUONConstants::ChannelBlockDataType() );
149 void AliHLTMUONHitReconstructorComponent::GetOutputDataSize(unsigned long& constBase, double& inputMultiplier)
152 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
155 constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType) + 1024*1024;
160 AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
163 /// Inherited from AliHLTComponent. Creates a new object instance.
166 return new AliHLTMUONHitReconstructorComponent;
170 int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
173 /// Inherited from AliHLTComponent.
174 /// Parses the command line parameters and initialises the component.
177 HLTInfo("Initialising dHLT hit reconstruction component.");
179 // Inherit the parents functionality.
180 int result = AliHLTMUONProcessor::DoInit(argc, argv);
181 if (result != 0) return result;
183 // Must make sure that fHitRec and fLut is deleted if it is still
184 // allocated for whatever reason.
187 // Initialise fields with default values then parse the command line.
190 fMaxEntryPerBusPatch.clear();
191 fWarnForUnexpecedBlock = false;
192 fUseIdealGain = false;
193 fWarnIfPadSkipped = false;
194 const char* lutFileName = NULL;
196 typedef AliHLTMUONHitReconstructor HR;
197 HR::ERecoveryMode recoveryMode = HR::kDontTryRecover;
198 AliHLTInt32_t dccut = -1;
199 bool skipParityErrors = false;
200 bool dontPrintParityErrors = false;
201 bool makeClusters = false;
202 bool makeChannels = false;
204 for (int i = 0; i < argc; i++)
206 // To keep the legacy behaviour we need to have the following check
207 // for -cdbpath here, before ArgumentAlreadyHandled.
208 if (strcmp(argv[i], "-cdbpath") == 0)
213 if (ArgumentAlreadyHandled(i, argv[i])) continue;
215 if (strcmp( argv[i], "-ddl" ) == 0)
219 HLTWarning("DDL number was already specified."
220 " Will replace previous value given by -ddl or -ddlid."
226 HLTError("The DDL number was not specified. Must be in the range [1..20].");
231 unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
232 if (cpErr == NULL or *cpErr != '\0')
234 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
237 if (num < 1 or 20 < num)
239 HLTError("The DDL number must be in the range [1..20].");
242 fDDL = num - 1; // convert to range [0..19]
248 if (strcmp( argv[i], "-ddlid" ) == 0)
252 HLTWarning("DDL number was already specified."
253 " Will replace previous value given by -ddl or -ddlid."
259 HLTError("DDL equipment ID number not specified. It must be in the range [2560..2579]" );
264 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
265 if (cpErr == NULL or *cpErr != '\0')
267 HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]);
270 fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
271 if (fDDL < 0 or 19 < fDDL)
273 HLTError("The DDL equipment ID number must be in the range [2560..2579].");
281 if (strcmp( argv[i], "-lut" ) == 0)
283 if (lutFileName != NULL)
285 HLTWarning("LUT path was already specified."
286 " Will replace previous value given by -lut."
292 HLTError("The lookup table filename was not specified.");
295 lutFileName = argv[i+1];
300 if (strcmp( argv[i], "-cdb" ) == 0)
306 if (strcmp( argv[i], "-dccut" ) == 0)
310 HLTWarning("DC cut parameter was already specified."
311 " Will replace previous value given by -dccut."
317 HLTError("No DC cut value was specified. It should be a positive integer value." );
322 dccut = AliHLTInt32_t( strtol(argv[i+1], &cpErr, 0) );
323 if (cpErr == NULL or *cpErr != '\0' or dccut < 0)
325 HLTError("Cannot convert '%s' to a valid DC cut value."
326 " Expected a positive integer value.", argv[i+1]
335 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
337 fWarnForUnexpecedBlock = true;
341 if (strcmp( argv[i], "-tryrecover" ) == 0)
345 // There might be an optional parameter so check
346 // if it is a recognised one. If not then assume it
347 // is the next argument, so no error message.
348 if (strcmp(argv[i+1], "full") == 0)
350 recoveryMode = HR::kRecoverFull;
353 else if (strcmp(argv[i+1], "skip") == 0)
355 recoveryMode = HR::kRecoverJustSkip;
358 else if (strcmp(argv[i+1], "parityerrors") == 0)
360 recoveryMode = HR::kRecoverFromParityErrorsOnly;
365 recoveryMode = HR::kRecoverFull;
370 recoveryMode = HR::kRecoverFull;
375 if (strcmp( argv[i], "-skipparityerrors" ) == 0)
377 skipParityErrors = true;
381 if (strcmp( argv[i], "-dontprintparityerrors" ) == 0)
383 dontPrintParityErrors = true;
387 if (strcmp( argv[i], "-useidealgain" ) == 0)
389 fUseIdealGain = true;
393 if (strcmp( argv[i], "-makeclusters" ) == 0)
399 if (strcmp( argv[i], "-makechannels" ) == 0)
405 if (strcmp( argv[i], "-warnifpadskipped" ) == 0)
407 fWarnIfPadSkipped = true;
411 HLTError("Unknown option '%s'", argv[i]);
418 fHitRec = new AliHLTMUONHitReconstructor();
420 catch (const std::bad_alloc&)
422 HLTError("Could not allocate more memory for the hit reconstructor component.");
426 if (dccut != -1 and useCDB)
428 HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
429 " this component should read from the CDB, but then the -dccut argument"
430 " was also used. Will override the value from CDB with the command"
431 " line DC cut parameter given."
435 if (lutFileName != NULL and useCDB == true)
437 HLTWarning("The -cdb or -cdbpath parameter was specified, which indicates that"
438 " this component should read from the CDB, but then the -lut argument"
439 " was also used. Will ignore the -lut option and load from CDB anyway."
443 if (lutFileName == NULL) useCDB = true;
445 if (fDDL == -1 and not DelaySetup())
447 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
452 if (not DelaySetup())
454 HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
455 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
457 result = ReadLutFromCDB();
460 // Error messages already generated in ReadLutFromCDB.
461 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
464 fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
469 HLTInfo("Loading lookup table information from file %s.", lutFileName);
470 result = ReadLookUpTable(lutFileName);
473 // Error messages already generated in ReadLookUpTable.
474 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
477 fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
482 if (not DelaySetup())
484 HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).",
485 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
487 result = ReadDCCutFromCDB();
490 // Error messages already generated in ReadDCCutFromCDB.
491 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
497 // Print the debug messages here since ReadDCCutFromCDB does not get called,
498 // in-which the debug messages would have been printed.
499 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
504 fHitRec->SetDCCut(dccut);
505 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
508 fHitRec->TryRecover(recoveryMode);
509 fHitRec->SkipParityErrors(skipParityErrors);
510 fHitRec->DontPrintParityErrors(dontPrintParityErrors);
511 fHitRec->GenerateClusterInfo(makeClusters);
512 fHitRec->GenerateChannelInfo(makeChannels);
513 fHitRec->DDLNumber(fDDL);
514 //The DDL number has to be set before the following InitDetElemInDDLArray() method
515 fHitRec->InitDetElemInDDLArray();
516 HLTDebug("dHLT hit reconstruction component is initialized.");
521 int AliHLTMUONHitReconstructorComponent::DoDeinit()
524 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
526 fHitRec->DeInitDetElemInDDLArray();
527 HLTInfo("Deinitialising dHLT hit reconstruction component.");
533 int AliHLTMUONHitReconstructorComponent::Reconfigure(
534 const char* cdbEntry, const char* componentId
537 /// Inherited from AliHLTComponent. This method will reload CDB configuration
538 /// entries for this component from the CDB.
539 /// \param cdbEntry If this is NULL then it is assumed that all CDB entries should
540 /// be reloaded. Otherwise a particular value for 'cdbEntry' will trigger
541 /// reloading of the LUT if the path contains 'MUON/' and reloading of the DC
542 /// cut parameter if 'cdbEntry' equals "HLT/ConfigMUON/HitReconstructor".
543 /// \param componentId The name of the component in the current chain.
545 bool startsWithMUON = TString(cdbEntry).Index("MUON/", 5, 0, TString::kExact) == 0;
546 bool givenConfigPath = strcmp(cdbEntry, AliHLTMUONConstants::HitReconstructorCDBPath()) == 0;
548 if (cdbEntry == NULL or startsWithMUON or givenConfigPath)
550 HLTInfo("Reading new configuration entries from CDB for component '%s'.", componentId);
553 if (cdbEntry == NULL or startsWithMUON)
555 // First clear the current LUT data and then load in the new values.
564 fMaxEntryPerBusPatch.clear();
565 int result = ReadLutFromCDB();
566 if (result != 0) return result;
567 fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
570 if (cdbEntry == NULL or not startsWithMUON)
572 int result = ReadDCCutFromCDB();
573 if (result != 0) return result;
580 int AliHLTMUONHitReconstructorComponent::ReadPreprocessorValues(const char* modules)
582 /// Inherited from AliHLTComponent.
583 /// Updates the configuration of this component if either HLT or MUON have
584 /// been specified in the 'modules' list.
586 TString mods = modules;
587 if (mods.Contains("ALL") or (mods.Contains("HLT") and mods.Contains("MUON")))
589 return Reconfigure(NULL, GetComponentID());
591 if (mods.Contains("HLT"))
593 return Reconfigure(AliHLTMUONConstants::HitReconstructorCDBPath(), GetComponentID());
595 if (mods.Contains("MUON"))
597 return Reconfigure("MUON/*", GetComponentID());
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
613 /// Inherited from AliHLTProcessor. Processes the new event data.
616 // Initialise the LUT and DC cut parameter from CDB if we were requested
617 // to initialise only when the first event was received.
620 // Use the specification given by the first data block if we
621 // have not been given a DDL number on the command line.
624 bool blockFound = false;
625 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt and not blockFound; n++)
627 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()) continue;
630 fDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
634 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
645 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."
653 // Check that the LUT was not already loaded in DoInit.
656 HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
657 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
659 int result = ReadLutFromCDB();
660 if (result != 0) return result;
662 fHitRec->SetLookUpTable(fLut, &fIdToEntry, &fMaxEntryPerBusPatch);
665 // Check that the DC cut was not already loaded in DoInit.
666 if (fHitRec->GetDCCut() == -1)
668 HLTInfo("Loading DC cut parameters from CDB for DDL %d (ID = %d).",
669 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
671 int result = ReadDCCutFromCDB();
672 if (result != 0) return result;
680 HLTFatal("Lookup table not loaded! Cannot continue processing data.");
685 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
687 HLTDebug("Processing event %llu with %u input data blocks.",
688 evtData.fEventID, evtData.fBlockCnt
691 // Loop over all input blocks in the event
692 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
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
698 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
699 or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
702 // Log a message indicating that we got a data block that we
703 // do not know how to handle.
704 if (fWarnForUnexpecedBlock)
705 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
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
720 AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
721 if (receivedDDL != fDDL)
723 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)
731 // Create a new output data block and initialise the header.
732 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
733 if (not block.InitCommonHeader())
735 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),
743 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
744 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
745 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
746 + fHitRec->GetkDDLHeaderSize();
747 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
750 HLTDebug("=========== Dumping DDL payload buffer ==========");
751 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
752 HLTDebug("buffer[%d] : %x",j,buffer[j]);
753 HLTDebug("================== End of dump =================");
756 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
758 HLTError("Error while processing the hit reconstruction algorithm.");
759 if (DumpDataOnError()) DumpEvent(evtData, blocks, trigData, outputPtr, size, outputBlocks);
760 size = totalSize; // Must tell the framework how much buffer space was used.
764 // nofHit should now contain the number of reconstructed hits actually found
765 // and filled into the output data block, so we can set this number.
766 assert( nofHit <= block.MaxNumberOfEntries() );
767 block.SetNumberOfEntries(nofHit);
769 HLTDebug("Number of reconstructed hits found is %d", nofHit);
771 // Fill a block data structure for our output block.
772 AliHLTComponentBlockData bd;
775 // This block's start (offset) is after all other blocks written so far.
776 bd.fOffset = totalSize;
777 bd.fSize = block.BytesUsed();
778 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
779 bd.fSpecification = blocks[n].fSpecification;
780 outputBlocks.push_back(bd);
782 // Increase the total amount of data written so far to our output memory
783 totalSize += block.BytesUsed();
785 if (fHitRec->GenerateClusterInfo())
787 // Create a new output clusters data block and initialise the header.
788 AliHLTMUONClustersBlockWriter clustblock(outputPtr+totalSize, size-totalSize);
789 if (not clustblock.InitCommonHeader())
791 HLTError("There is not enough space in the output buffer for the new clusters data block."
792 " We require at least %u bytes, but have %u bytes left.",
793 sizeof(AliHLTMUONClustersBlockWriter::HeaderType),
794 clustblock.BufferSize()
799 AliHLTUInt32_t nofClusters = clustblock.MaxNumberOfEntries();
800 bool filledOk = fHitRec->FillClusterData(clustblock.GetArray(), nofClusters);
801 // nofClusters should now contain the number of clusters filled.
802 assert( nofClusters <= clustblock.MaxNumberOfEntries() );
803 clustblock.SetNumberOfEntries(nofClusters);
805 // Fill a block data structure for our output block.
806 AliHLTComponentBlockData bdc;
808 bdc.fPtr = outputPtr;
809 // This block's start (offset) is after all other blocks written so far.
810 bdc.fOffset = totalSize;
811 bdc.fSize = clustblock.BytesUsed();
812 bdc.fDataType = AliHLTMUONConstants::ClusterBlockDataType();
813 bdc.fSpecification = blocks[n].fSpecification;
814 outputBlocks.push_back(bdc);
816 // Increase the total amount of data written so far to our output memory
817 totalSize += clustblock.BytesUsed();
821 HLTError("We have overflowed the output buffer space for the new clusters data block.");
826 if (fHitRec->GenerateChannelInfo())
828 // Create a new output channels data block and initialise the header.
829 AliHLTMUONChannelsBlockWriter channelblock(outputPtr+totalSize, size-totalSize);
830 if (not channelblock.InitCommonHeader())
832 HLTError("There is not enough space in the output buffer for the new channels data block."
833 " We require at least %u bytes, but have %u bytes left.",
834 sizeof(AliHLTMUONChannelsBlockWriter::HeaderType),
835 channelblock.BufferSize()
840 AliHLTUInt32_t nofChannels = channelblock.MaxNumberOfEntries();
841 bool filledOk = fHitRec->FillChannelData(channelblock.GetArray(), nofChannels);
842 // nofChannels should now contain the number of channels filled.
843 assert( nofChannels <= channelblock.MaxNumberOfEntries() );
844 channelblock.SetNumberOfEntries(nofChannels);
846 // Fill a block data structure for our output block.
847 AliHLTComponentBlockData bdc;
849 bdc.fPtr = outputPtr;
850 // This block's start (offset) is after all other blocks written so far.
851 bdc.fOffset = totalSize;
852 bdc.fSize = channelblock.BytesUsed();
853 bdc.fDataType = AliHLTMUONConstants::ChannelBlockDataType();
854 bdc.fSpecification = blocks[n].fSpecification;
855 outputBlocks.push_back(bdc);
857 // Increase the total amount of data written so far to our output memory
858 totalSize += channelblock.BytesUsed();
862 HLTError("We have overflowed the output buffer space for the new channels data block.");
867 // Finally we set the total size of output memory we consumed.
874 void AliHLTMUONHitReconstructorComponent::FreeMemory()
876 /// Deletes any allocated objects if they are allocated else nothing is
877 /// done for objects not yet allocated.
878 /// This is used as a helper method to make sure the corresponding pointers
879 /// are NULL and we get back to a well defined state.
894 fMaxEntryPerBusPatch.clear();
898 int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
900 /// Read in the lookup table from a text file.
901 /// Note that this method could leave fLut allocated which is cleaned up
902 /// by DoInit with a call to FreeMemory().
904 assert( fLut == NULL );
905 assert( fLutSize == 0 );
906 assert( fIdToEntry.empty() );
907 assert( fMaxEntryPerBusPatch.empty() );
909 std::ifstream file(lutFileName);
912 HLTError("Could not open the LUT file %s", lutFileName);
916 // First count the number of lines of text in the LUT file before decoding.
917 // This is not the most optimal. It would be better to read and decode at the
918 // same time but we are not allowed to use STL and ROOT containers are too
919 // heavy for this task. At least this is done only at the start of run.
921 AliHLTUInt32_t lineCount = 0;
922 while (std::getline(file, str)) lineCount++;
925 HLTError("There was a problem reading the LUT file %s", lutFileName);
930 HLTWarning("The LUT file %s was empty.", lutFileName);
933 // Add one extra LUT line for the first element which is used as a sentinel value.
938 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
939 fLutSize = lineCount;
941 catch (const std::bad_alloc&)
943 HLTError("Could not allocate more memory for the lookuptable.");
947 // Initialise the sentinel value.
948 fLut[0].fDetElemId = 0;
951 fLut[0].fRealX = 0.0;
952 fLut[0].fRealY = 0.0;
953 fLut[0].fRealZ = 0.0;
954 fLut[0].fHalfPadSize = 0.0;
963 // Clear the eof flag and start reading from the beginning of the file again.
965 file.seekg(0, std::ios::beg);
968 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
972 AliHLTInt32_t idManuChannel,buspatchId;
973 for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
975 if (std::getline(file, str).fail())
977 HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
982 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",
983 &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
984 &fLut[i].fIY, &fLut[i].fRealX,
985 &fLut[i].fRealY, &fLut[i].fRealZ,
986 &fLut[i].fHalfPadSize, &fLut[i].fPlane,
987 &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
988 &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
993 HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
996 buspatchId = (idManuChannel>>17) & 0x7FF;
997 fIdToEntry[idManuChannel] = i;
998 fMaxEntryPerBusPatch[buspatchId] = fMaxEntryPerBusPatch[buspatchId] + 1;
1002 MaxEntryPerBusPatch::iterator it;
1003 for(it=fMaxEntryPerBusPatch.begin(); it!=fMaxEntryPerBusPatch.end(); it++){
1004 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1005 fMaxEntryPerBusPatch[it->first] = AliHLTInt32_t(0.05*(it->second));///< for 10% occupancy
1006 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1013 int AliHLTMUONHitReconstructorComponent::ReadLutFromCDB()
1015 /// Reads LUT from CDB.
1016 /// To override the default CDB path and / or run number the
1017 /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
1020 assert( fLut == NULL );
1021 assert( fLutSize == 0 );
1022 assert( fIdToEntry.empty() );
1023 assert( fMaxEntryPerBusPatch.empty() );
1027 HLTError("No DDL number specified for which to load LUT data from CDB.");
1031 std::vector<AliHLTMUONHitRecoLutRow> lutList;
1032 AliHLTMUONHitRecoLutRow lut;
1033 AliHLTUInt32_t iEntry = 0;
1035 int result = FetchMappingStores();
1036 // Error message already generated in FetchMappingStores.
1037 if (result != 0) return result;
1038 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
1040 AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
1041 if (mpSegFactory == NULL)
1043 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
1047 // Only load geometry if not already loaded.
1048 if (AliGeomManager::GetGeometry() == NULL)
1050 AliGeomManager::LoadGeometry();
1052 AliMUONGeometryTransformer chamberGeometryTransformer;
1053 if (not chamberGeometryTransformer.LoadGeometryData())
1055 HLTError("Failed to load geomerty data.");
1059 AliMUONCalibrationData calibData(AliCDBManager::Instance()->GetRun());
1061 bool skippedPads = false;
1064 for(Int_t iCh = 0; iCh < 10; iCh++)
1069 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
1071 Int_t detElemId = it.CurrentDEId();
1072 int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
1073 if (iDDL != fDDL) continue;
1075 for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
1077 AliMp::CathodType cath;
1080 cath = AliMp::kCath0;
1082 cath = AliMp::kCath1;
1084 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
1085 AliMp::PlaneType plane = seg->PlaneType();
1086 Int_t maxIX = seg->MaxPadIndexX();
1087 Int_t maxIY = seg->MaxPadIndexY();
1089 Int_t idManuChannel, manuId, channelId, buspatchId;
1090 AliHLTFloat32_t padSizeX, padSizeY;
1091 AliHLTFloat32_t halfPadSize;
1092 AliHLTFloat32_t padSizeXY;
1093 Double_t realX, realY, realZ;
1094 Double_t localX, localY, localZ;
1095 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
1096 Float_t thresold,saturation;
1098 // Pad Info of a slat to print in lookuptable
1099 for (Int_t iX = 0; iX<= maxIX ; iX++)
1100 for (Int_t iY = 0; iY<= maxIY ; iY++)
1102 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1103 if (not seg->HasPadByIndices(iX,iY)) continue;
1104 #else // old AliMpPad functionality < r 31742
1105 if (not seg->HasPad(AliMpIntPair(iX,iY))) continue;
1108 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1109 AliMpPad pad = seg->PadByIndices(iX,iY, kFALSE);
1110 #else // old AliMpPad functionality < r 31742
1111 AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE);
1115 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1116 manuId = pad.GetManuId();
1117 #else // old AliMpPad functionality < r 31742
1118 manuId = pad.GetLocation().GetFirst();
1120 manuId &= 0x7FF; // 11 bits
1121 if (calibData.Gains(detElemId, manuId) == NULL) continue;
1122 if (calibData.Pedestals(detElemId, manuId) == NULL) continue;
1124 buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
1126 // Getting channel id
1127 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1128 channelId = pad.GetManuChannel();
1129 #else // old AliMpPad functionality < r 31742
1130 channelId = pad.GetLocation().GetSecond();
1132 channelId &= 0x3F; // 6 bits
1134 idManuChannel = buspatchId << 11;
1135 idManuChannel = (idManuChannel | manuId) << 6;
1136 idManuChannel |= channelId;
1138 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1139 localX = pad.GetPositionX();
1140 localY = pad.GetPositionY();
1141 #else // old AliMpPad functionality < r 31769
1142 localX = pad.Position().X();
1143 localY = pad.Position().Y();
1144 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1147 chamberGeometryTransformer.Local2Global(
1148 detElemId,localX,localY,localZ,
1152 #ifndef HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1153 padSizeX = AliHLTFloat32_t( pad.GetDimensionX() );
1154 padSizeY = AliHLTFloat32_t( pad.GetDimensionY() );
1155 #else // old AliMpPad functionality < r 31769
1156 padSizeX = AliHLTFloat32_t( pad.Dimensions().X() );
1157 padSizeY = AliHLTFloat32_t( pad.Dimensions().Y() );
1158 #endif //HAVE_NOT_MUON_ALIMPPAD_GETPOSITION
1169 calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
1170 calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
1171 thresold = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 2);
1172 saturation = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 4);
1175 pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
1176 sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
1178 // Check if any of the values fetched from the calibration data are
1179 // invalid. If they are then skip this pad.
1180 if (calibA0Coeff == AliMUONVCalibParam::InvalidFloatValue() or
1181 calibA1Coeff == AliMUONVCalibParam::InvalidFloatValue() or
1182 thresold == AliMUONVCalibParam::InvalidFloatValue() or
1183 saturation == AliMUONVCalibParam::InvalidFloatValue() or
1184 pedestal == AliMUONVCalibParam::InvalidFloatValue() or
1185 sigma == AliMUONVCalibParam::InvalidFloatValue()
1188 if (fWarnIfPadSkipped)
1190 HLTWarning("Skipping pad on detection element %d, MANU %d, channel %d, since"
1191 " the calibration data contains invalid values in that channel.",
1192 detElemId, manuId, channelId
1201 halfPadSize = padSizeX;
1202 padSizeXY = padSizeY;
1204 halfPadSize = padSizeY;
1205 padSizeXY = padSizeX;
1208 fIdToEntry[idManuChannel] = iEntry+1;
1209 fMaxEntryPerBusPatch[buspatchId] = fMaxEntryPerBusPatch[buspatchId] + 1;
1211 lut.fDetElemId = detElemId;
1217 lut.fHalfPadSize = halfPadSize;
1218 lut.fPadSizeXY = padSizeXY;
1220 lut.fPed = pedestal;
1222 lut.fA0 = calibA0Coeff;
1223 lut.fA1 = calibA1Coeff;
1224 lut.fThres = Int_t(thresold);
1225 lut.fSat = Int_t(saturation);
1227 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",
1228 lut.fDetElemId,idManuChannel,manuId,channelId,lut.fIX,lut.fIY,lut.fRealX,lut.fRealY,lut.fHalfPadSize,lut.fPlane,lut.fPed,lut.fSigma
1231 lutList.push_back(lut);
1238 if (skippedPads and not fWarnIfPadSkipped)
1240 HLTWarning("Skipped pads since they contained invalid calibration values."
1241 " Use the -warnifpadskipped argument to generate detailed information"
1242 " about which pads were skipped."
1248 // Use iEntry+1 since we add one extra LUT line for the first element
1249 // which is used as a sentinel value.
1250 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
1251 fLutSize = iEntry+1;
1252 HLTDebug("Address of new LUT buffer at fLut = %p", fLut);
1254 catch (const std::bad_alloc&)
1256 HLTError("Could not allocate more memory for the lookuptable.");
1257 //lutList.clear(); not necessary, implicitly done during stack cleanup.
1261 // Initialise the sentinel value.
1262 fLut[0].fDetElemId = 0;
1265 fLut[0].fRealX = 0.0;
1266 fLut[0].fRealY = 0.0;
1267 fLut[0].fRealZ = 0.0;
1268 fLut[0].fHalfPadSize = 0.0;
1269 fLut[0].fPadSizeXY = 0.0;
1270 fLut[0].fPlane = -1;
1272 fLut[0].fSigma = -1;
1275 fLut[0].fThres = -1;
1278 for (AliHLTUInt32_t i = 0; i < iEntry; i++)
1279 fLut[i+1] = lutList[i];
1282 MaxEntryPerBusPatch::iterator it;
1283 for(it=fMaxEntryPerBusPatch.begin(); it!=fMaxEntryPerBusPatch.end(); it++){
1284 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1285 fMaxEntryPerBusPatch[it->first] = AliHLTInt32_t(0.05*(it->second));///< for 10% occupancy
1286 HLTDebug("fMaxEntryPerBusPatch[%d] : %d",it->first,it->second);
1293 int AliHLTMUONHitReconstructorComponent::ReadDCCutFromCDB()
1295 /// Reads the DC cut parameter from the CDB.
1297 const char* pathToEntry = AliHLTMUONConstants::HitReconstructorCDBPath();
1300 int result = FetchTMapFromCDB(pathToEntry, map);
1301 if (result != 0) return result;
1304 result = GetPositiveIntFromTMap(map, "dccut", value, pathToEntry, "DC cut");
1305 if (result != 0) return result;
1307 assert(fHitRec != NULL);
1308 fHitRec->SetDCCut(value);
1310 HLTDebug("Using DC cut parameter of %d ADC channels.", fHitRec->GetDCCut());
1316 bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
1317 AliHLTInt32_t ddl, const char* filename,
1318 const char* cdbPath, Int_t run
1321 /// Generates a ASCII text file containing the lookup table (LUT) from
1322 /// the CDB, which can be used for the hit reconstructor component later.
1323 /// @param ddl Must be the DDL for which to generate the DDL,
1324 /// in the range [0..19].
1325 /// @param filename The name of the LUT file to generate.
1326 /// @param cdbPath The CDB path to use.
1327 /// @param run The run number to use for the CDB.
1328 /// @return True if the generation of the LUT file succeeded.
1330 AliHLTMUONHitReconstructorComponent comp;
1332 if (ddl < 0 or 19 < ddl)
1334 std::cerr << "ERROR: the DDL number must be in the range [0..19]." << std::endl;
1339 if (comp.SetCDBPathAndRunNo(cdbPath, run) != 0) return false;
1340 if (comp.ReadLutFromCDB() != 0) return false;
1343 std::fstream file(filename, std::ios::out);
1346 std::cerr << "ERROR: could not open file: " << filename << std::endl;
1350 assert( comp.fLut != NULL );
1352 for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
1353 id != comp.fIdToEntry.end();
1357 AliHLTInt32_t idManuChannel = id->first;
1358 AliHLTInt32_t row = id->second;
1360 assert( AliHLTUInt32_t(row) < comp.fLutSize );
1362 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",
1363 idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
1364 comp.fLut[row].fIY, comp.fLut[row].fRealX,
1365 comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
1366 comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
1367 comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
1368 comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
1371 file << str << endl;
1374 std::cerr << "ERROR: There was an I/O error when writing to the file: "
1375 << filename << std::endl;