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> *
8 * Permission to use, copy, modify and distribute this software and its *
9 * documentation strictly for non-commercial purposes is hereby granted *
10 * without fee, provided that the above copyright notice appears in all *
11 * copies and that both the copyright notice and this permission notice *
12 * appear in the supporting documentation. The authors make no claims *
13 * about the suitability of this software for any purpose. It is *
14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
21 /// The HitRec Component is designed to deal the rawdata inputfiles to findout the
22 /// the reconstructed hits. The output is send to the output block for further
25 /// Author : Indranil Das ( indra.das@saha.ac.in || indra.ehep@gmail.com )
28 #include "AliHLTMUONRecHitsBlockStruct.h"
29 #include "AliHLTMUONHitReconstructorComponent.h"
30 #include "AliHLTMUONHitReconstructor.h"
31 #include "AliHLTMUONConstants.h"
32 #include "AliHLTMUONUtils.h"
33 #include "AliHLTMUONDataBlockWriter.h"
34 #include "AliHLTMUONHitReconstructor.h"
35 #include "AliHLTLogging.h"
36 #include "AliHLTSystem.h"
37 #include "AliHLTDefinitions.h"
44 #include "AliCDBManager.h"
45 #include "AliCDBStorage.h"
46 #include "AliGeomManager.h"
49 #include "AliMUONGeometryTransformer.h"
50 #include "AliMUONCalibrationData.h"
51 #include "AliMUONVCalibParam.h"
56 #include "AliMpSegmentation.h"
57 #include "AliMpDDLStore.h"
58 #include "AliMpDEIterator.h"
59 #include "AliMpVSegmentation.h"
60 #include "AliMpDEManager.h"
61 #include "AliMpDetElement.h"
63 ClassImp(AliHLTMUONHitReconstructorComponent)
66 AliHLTMUONHitReconstructorComponent::AliHLTMUONHitReconstructorComponent() :
67 AliHLTMUONProcessor(),
73 fWarnForUnexpecedBlock(false)
76 /// Default constructor.
81 AliHLTMUONHitReconstructorComponent::~AliHLTMUONHitReconstructorComponent()
84 /// Default destructor.
97 const char* AliHLTMUONHitReconstructorComponent::GetComponentID()
100 /// Inherited from AliHLTComponent. Returns the component ID.
103 return AliHLTMUONConstants::HitReconstructorId();
107 void AliHLTMUONHitReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
110 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
114 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
118 AliHLTComponentDataType AliHLTMUONHitReconstructorComponent::GetOutputDataType()
121 /// Inherited from AliHLTComponent. Returns the output data type.
124 return AliHLTMUONConstants::RecHitsBlockDataType();
128 void AliHLTMUONHitReconstructorComponent::GetOutputDataSize( unsigned long& constBase, double& inputMultiplier )
131 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
134 constBase = sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType);
139 AliHLTComponent* AliHLTMUONHitReconstructorComponent::Spawn()
142 /// Inherited from AliHLTComponent. Creates a new object instance.
145 return new AliHLTMUONHitReconstructorComponent;
149 int AliHLTMUONHitReconstructorComponent::DoInit(int argc, const char** argv)
152 /// Inherited from AliHLTComponent.
153 /// Parses the command line parameters and initialises the component.
156 HLTInfo("Initialising dHLT hit reconstruction component.");
158 // Must make sure that fHitRec and fLut is deleted if it is still
159 // allocated for whatever reason.
164 fHitRec = new AliHLTMUONHitReconstructor();
166 catch (const std::bad_alloc&)
168 HLTError("Could not allocate more memory for the hit reconstructor component.");
172 // Initialise fields with default values then parse the command line.
175 fWarnForUnexpecedBlock = false;
177 const char* lutFileName = NULL;
178 const char* cdbPath = NULL;
182 for (int i = 0; i < argc; i++)
184 HLTDebug("argv[%d] == %s", i, argv[i]);
186 if (strcmp( argv[i], "-ddl" ) == 0)
190 HLTError("The DDL number was not specified. Must be in the range [13..20].");
191 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
196 unsigned long num = strtoul( argv[i+1], &cpErr, 0 );
197 if (cpErr == NULL or *cpErr != '\0')
199 HLTError("Cannot convert '%s' to DDL a number.", argv[i+1] );
200 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
203 if (num < 13 or 20 < num)
205 HLTError("The DDL number must be in the range [13..20].");
206 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
209 fDDL = num - 1; // convert to range [12..19]
215 if (strcmp( argv[i], "-lut" ) == 0)
219 HLTError("The lookup table filename was not specified.");
220 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
223 lutFileName = argv[i+1];
228 if (strcmp( argv[i], "-cdb" ) == 0)
234 if (strcmp( argv[i], "-cdbpath" ) == 0)
238 HLTError("The CDB path was not specified." );
239 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
248 if (strcmp( argv[i], "-run" ) == 0)
252 HLTError("The RUN number was not specified." );
253 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
258 run = Int_t( strtoul(argv[i+1], &cpErr, 0) );
259 if (cpErr == NULL or *cpErr != '\0')
261 HLTError("Cannot convert '%s' to a valid run number."
262 " Expected an integer value.", argv[i+1]
264 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
272 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
274 fWarnForUnexpecedBlock = true;
278 HLTError("Unknown option '%s'", argv[i]);
279 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
284 if (lutFileName == NULL) useCDB = true;
288 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
294 HLTInfo("Loading lookup table information from CDB for DDL %d.", fDDL+1);
296 HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!");
297 result = ReadCDB(cdbPath, run);
301 HLTInfo("Loading lookup table information from file %s.", lutFileName);
302 result = ReadLookUpTable(lutFileName);
306 // Error messages already generated in ReadCDB or ReadLookUpTable.
307 FreeMemory(); // Make sure we cleanup to avoid partial initialisation.
311 fHitRec->SetLookUpTable(fLut, &fIdToEntry);
317 int AliHLTMUONHitReconstructorComponent::DoDeinit()
320 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
323 HLTInfo("Deinitialising dHLT hit reconstruction component.");
329 int AliHLTMUONHitReconstructorComponent::DoEvent(
330 const AliHLTComponentEventData& evtData,
331 const AliHLTComponentBlockData* blocks,
332 AliHLTComponentTriggerData& /*trigData*/,
333 AliHLTUInt8_t* outputPtr,
334 AliHLTUInt32_t& size,
335 std::vector<AliHLTComponentBlockData>& outputBlocks
339 /// Inherited from AliHLTProcessor. Processes the new event data.
343 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
345 HLTDebug("Processing event %llu with %u input data blocks.",
346 evtData.fEventID, evtData.fBlockCnt
349 // Loop over all input blocks in the event
350 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
352 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
353 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
356 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
357 or not AliHLTMUONUtils::IsTrackerDDL(blocks[n].fSpecification)
360 // Log a message indicating that we got a data block that we
361 // do not know how to handle.
362 if (fWarnForUnexpecedBlock)
363 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
364 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
367 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
368 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
376 if (AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification) != fDDL)
378 HLTWarning("Received raw data from an unexpected DDL.");
382 // Create a new output data block and initialise the header.
383 AliHLTMUONRecHitsBlockWriter block(outputPtr+totalSize, size-totalSize);
384 if (not block.InitCommonHeader())
386 HLTError("There is not enough space in the output buffer for the new data block."
387 " We require at least %u bytes, but have %u bytes left.",
388 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
394 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
395 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - fHitRec->GetkDDLHeaderSize();
396 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr)
397 + fHitRec->GetkDDLHeaderSize();
398 AliHLTUInt32_t nofHit = block.MaxNumberOfEntries();
401 HLTDebug("=========== Dumping DDL payload buffer ==========");
402 for (AliHLTUInt32_t j = 0; j < totalDDLSize; j++)
403 HLTDebug("buffer[%d] : %x",j,buffer[j]);
404 HLTDebug("================== End of dump =================");
407 if (not fHitRec->Run(buffer, ddlRawDataSize, block.GetArray(), nofHit))
409 HLTError("Error while processing the hit reconstruction algorithm.");
410 size = totalSize; // Must tell the framework how much buffer space was used.
414 // nofHit should now contain the number of reconstructed hits actually found
415 // and filled into the output data block, so we can set this number.
416 assert( nofHit <= block.MaxNumberOfEntries() );
417 block.SetNumberOfEntries(nofHit);
419 HLTDebug("Number of reconstructed hits found is %d", nofHit);
421 // Fill a block data structure for our output block.
422 AliHLTComponentBlockData bd;
425 // This block's start (offset) is after all other blocks written so far.
426 bd.fOffset = totalSize;
427 bd.fSize = block.BytesUsed();
428 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
429 bd.fSpecification = blocks[n].fSpecification;
430 outputBlocks.push_back(bd);
432 // Increase the total amount of data written so far to our output memory
433 totalSize += block.BytesUsed();
435 // Finally we set the total size of output memory we consumed.
442 void AliHLTMUONHitReconstructorComponent::FreeMemory()
444 /// Deletes any allocated objects if they are allocated else nothing is
445 /// done for objects not yet allocated.
446 /// This is used as a helper method to make sure the corresponding pointers
447 /// are NULL and we get back to a well defined state.
465 int AliHLTMUONHitReconstructorComponent::ReadLookUpTable(const char* lutFileName)
467 /// Read in the lookup table from a text file.
468 /// Note that this method could leave fLut allocated which is cleaned up
469 /// by DoInit with a call to FreeMemory().
471 assert( fLut == NULL );
472 assert( fLutSize == 0 );
473 assert( fIdToEntry.empty() );
475 std::ifstream file(lutFileName);
478 HLTError("Could not open the LUT file %s", lutFileName);
482 // First count the number of lines of text in the LUT file before decoding.
483 // This is not the most optimal. It would be better to read and decode at the
484 // same time but we are not allowed to use STL and ROOT containers are too
485 // heavy for this task. At least this is done only at the start of run.
487 AliHLTUInt32_t lineCount = 0;
488 while (std::getline(file, str)) lineCount++;
491 HLTError("There was a problem reading the LUT file %s", lutFileName);
496 HLTWarning("The LUT file %s was empty.", lutFileName);
499 // Add one extra LUT line for the first element which is used as a sentinel value.
504 fLut = new AliHLTMUONHitRecoLutRow[lineCount];
505 fLutSize = lineCount;
507 catch (const std::bad_alloc&)
509 HLTError("Could not allocate more memory for the lookuptable.");
513 // Initialise the sentinel value.
514 fLut[0].fDetElemId = 0;
517 fLut[0].fRealX = 0.0;
518 fLut[0].fRealY = 0.0;
519 fLut[0].fRealZ = 0.0;
520 fLut[0].fHalfPadSize = 0.0;
529 // Clear the eof flag and start reading from the beginning of the file again.
531 file.seekg(0, std::ios::beg);
534 HLTError("There was a problem seeking in the LUT file %s", lutFileName);
538 AliHLTInt32_t idManuChannel;
539 for (AliHLTUInt32_t i = 1; i < fLutSize; i++)
541 if (std::getline(file, str).fail())
543 HLTError("There was a problem reading line %d of LUT file %s", i, lutFileName);
548 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",
549 &idManuChannel, &fLut[i].fDetElemId, &fLut[i].fIX,
550 &fLut[i].fIY, &fLut[i].fRealX,
551 &fLut[i].fRealY, &fLut[i].fRealZ,
552 &fLut[i].fHalfPadSize, &fLut[i].fPlane,
553 &fLut[i].fPed, &fLut[i].fSigma, &fLut[i].fA0,
554 &fLut[i].fA1, &fLut[i].fThres, &fLut[i].fSat
559 HLTError("Line %d in LUT file %s does not contain 15 elements.", i, lutFileName);
563 fIdToEntry[idManuChannel] = i;
570 int AliHLTMUONHitReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run)
572 /// Reads LUT from CDB.
574 assert( fLut == NULL );
575 assert( fLutSize == 0 );
576 assert( fIdToEntry.empty() );
578 std::vector<AliHLTMUONHitRecoLutRow> lutList;
579 AliHLTMUONHitRecoLutRow lut;
580 AliHLTUInt32_t iEntry = 0;
582 int result = FetchMappingStores(cdbPath, run);
583 // Error message already generated in FetchMappingStores.
584 if (result != 0) return result;
585 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
587 AliMpSegmentation* mpSegFactory = AliMpSegmentation::Instance();
588 if (mpSegFactory == NULL)
590 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
594 // Only load geometry if not already loaded.
595 if (AliGeomManager::GetGeometry() == NULL)
597 AliGeomManager::LoadGeometry();
599 AliMUONGeometryTransformer chamberGeometryTransformer;
600 if (not chamberGeometryTransformer.LoadGeometryData())
602 HLTError("Failed to load geomerty data.");
606 AliMUONCalibrationData calibData(run);
610 for(Int_t iCh = 6; iCh < 10; iCh++)
615 for ( it.First(chamberId); ! it.IsDone(); it.Next() )
617 Int_t detElemId = it.CurrentDEId();
618 int iDDL = ddlStore->GetDetElement(detElemId)->GetDdlId();
619 if (iDDL != fDDL) continue;
621 for (Int_t iCath = 0 ; iCath <= 1 ; iCath++)
623 AliMp::CathodType cath;
626 cath = AliMp::kCath0;
628 cath = AliMp::kCath1;
630 const AliMpVSegmentation* seg = mpSegFactory->GetMpSegmentation(detElemId, cath);
631 AliMp::PlaneType plane = seg->PlaneType();
632 Int_t maxIX = seg->MaxPadIndexX();
633 Int_t maxIY = seg->MaxPadIndexY();
635 Int_t idManuChannel, manuId, channelId, buspatchId;
636 AliHLTFloat32_t padSizeX, padSizeY;
637 AliHLTFloat32_t halfPadSize;
638 Double_t realX, realY, realZ;
639 Double_t localX, localY, localZ;
640 Float_t calibA0Coeff,calibA1Coeff,pedestal,sigma;
641 Int_t thresold,saturation;
643 // Pad Info of a slat to print in lookuptable
644 for (Int_t iX = 0; iX<= maxIX ; iX++)
645 for (Int_t iY = 0; iY<= maxIY ; iY++)
647 if (not seg->HasPad(AliMpIntPair(iX,iY))) continue;
649 AliMpPad pad = seg->PadByIndices(AliMpIntPair(iX,iY), kFALSE);
652 manuId = pad.GetLocation().GetFirst();
653 manuId &= 0x7FF; // 11 bits
655 buspatchId = ddlStore->GetBusPatchId(detElemId,manuId);
657 // Getting channel id
658 channelId = pad.GetLocation().GetSecond();
659 channelId &= 0x3F; // 6 bits
661 idManuChannel = buspatchId << 11;
662 idManuChannel = (idManuChannel | manuId) << 6;
663 idManuChannel |= channelId;
665 localX = pad.Position().X();
666 localY = pad.Position().Y();
669 chamberGeometryTransformer.Local2Global(
670 detElemId,localX,localY,localZ,
674 padSizeX = pad.Dimensions().X();
675 padSizeY = pad.Dimensions().Y();
677 calibA0Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 0);
678 calibA1Coeff = (calibData.Gains(detElemId, manuId))->ValueAsFloat(channelId, 1);
679 thresold = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 2);
680 saturation = (calibData.Gains(detElemId, manuId))->ValueAsInt(channelId, 4);
682 pedestal = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 0);
683 sigma = (calibData.Pedestals(detElemId, manuId))->ValueAsFloat(channelId, 1);
686 halfPadSize = padSizeX;
688 halfPadSize = padSizeY;
690 fIdToEntry[idManuChannel] = iEntry+1;
692 lut.fDetElemId = detElemId;
698 lut.fHalfPadSize = halfPadSize;
702 lut.fA0 = calibA0Coeff;
703 lut.fA1 = calibA1Coeff;
704 lut.fThres = thresold;
705 lut.fSat = saturation;
707 lutList.push_back(lut);
716 // Use iEntry+1 since we add one extra LUT line for the first element
717 // which is used as a sentinel value.
718 fLut = new AliHLTMUONHitRecoLutRow[iEntry+1];
721 catch (const std::bad_alloc&)
723 HLTError("Could not allocate more memory for the lookuptable.");
727 // Initialise the sentinel value.
728 fLut[0].fDetElemId = 0;
731 fLut[0].fRealX = 0.0;
732 fLut[0].fRealY = 0.0;
733 fLut[0].fRealZ = 0.0;
734 fLut[0].fHalfPadSize = 0.0;
743 for (AliHLTUInt32_t i = 0; i < iEntry; i++)
744 fLut[i+1] = lutList[i];
750 bool AliHLTMUONHitReconstructorComponent::GenerateLookupTable(
751 AliHLTInt32_t ddl, const char* filename,
752 const char* cdbPath, Int_t run
755 /// Generates a ASCII text file containing the lookup table (LUT) from
756 /// the CDB, which can be used for the hit reconstructor component later.
757 /// @param ddl Must be the DDL for which to generate the DDL,
758 /// in the range [13..20].
759 /// @param filename The name of the LUT file to generate.
760 /// @param cdbPath The CDB path to use.
761 /// @param run The run number to use for the CDB.
762 /// @return True if the generation of the LUT file succeeded.
764 AliHLTMUONHitReconstructorComponent comp;
766 if (ddl < 12 or 19 < ddl)
768 std::cerr << "ERROR: the DDL number must be in the range [12..19]." << std::endl;
773 if (comp.ReadCDB(cdbPath, run) != 0) return false;
776 std::fstream file(filename, std::ios::out);
779 std::cerr << "ERROR: could not open file: " << filename << std::endl;
783 assert( comp.fLut != NULL );
785 for (IdManuChannelToEntry::iterator id = comp.fIdToEntry.begin();
786 id != comp.fIdToEntry.end();
790 AliHLTInt32_t idManuChannel = id->first;
791 AliHLTInt32_t row = id->second;
793 assert( row < comp.fLutSize );
795 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",
796 idManuChannel, comp.fLut[row].fDetElemId, comp.fLut[row].fIX,
797 comp.fLut[row].fIY, comp.fLut[row].fRealX,
798 comp.fLut[row].fRealY, comp.fLut[row].fRealZ,
799 comp.fLut[row].fHalfPadSize, comp.fLut[row].fPlane,
800 comp.fLut[row].fPed, comp.fLut[row].fSigma, comp.fLut[row].fA0,
801 comp.fLut[row].fA1, comp.fLut[row].fThres, comp.fLut[row].fSat
807 std::cerr << "ERROR: There was an I/O error when writing to the file: "
808 << filename << std::endl;