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 AliHLTMUONTriggerReconstructorComponent.cxx
22 /// @author Indranil Das <indra.das@saha.ac.in>, Artur Szostak <artursz@iafrica.com>
24 /// @brief Implementation of the trigger DDL reconstructor component.
27 #include "AliHLTMUONTriggerReconstructorComponent.h"
28 #include "AliHLTMUONTriggerReconstructor.h"
29 #include "AliHLTMUONHitReconstructor.h"
30 #include "AliHLTMUONConstants.h"
31 #include "AliHLTMUONUtils.h"
32 #include "AliHLTMUONDataBlockWriter.h"
33 #include "AliRawDataHeader.h"
34 #include "AliCDBManager.h"
35 #include "AliCDBStorage.h"
36 #include "AliGeomManager.h"
37 #include "AliMUONGeometryTransformer.h"
38 #include "AliMUONGeometryDetElement.h"
40 #include "AliMpDDLStore.h"
42 #include "AliMpSegmentation.h"
43 #include "AliMpDEIterator.h"
44 #include "AliMpVSegmentation.h"
45 #include "AliMpDEManager.h"
46 #include "AliMpLocalBoard.h"
47 #include "AliMpTriggerCrate.h"
54 ClassImp(AliHLTMUONTriggerReconstructorComponent)
57 AliHLTMUONTriggerReconstructorComponent::AliHLTMUONTriggerReconstructorComponent() :
58 AliHLTMUONProcessor(),
61 fWarnForUnexpecedBlock(false),
62 fStopOnOverflow(false),
66 /// Default constructor.
71 AliHLTMUONTriggerReconstructorComponent::~AliHLTMUONTriggerReconstructorComponent()
74 /// Default destructor.
77 if (fTrigRec != NULL) delete fTrigRec;
81 const char* AliHLTMUONTriggerReconstructorComponent::GetComponentID()
84 /// Inherited from AliHLTComponent. Returns the component ID.
87 return AliHLTMUONConstants::TriggerReconstructorId();
91 void AliHLTMUONTriggerReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
94 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
98 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
102 AliHLTComponentDataType AliHLTMUONTriggerReconstructorComponent::GetOutputDataType()
105 /// Inherited from AliHLTComponent. Returns the output data type.
108 return AliHLTMUONConstants::TriggerRecordsBlockDataType();
112 void AliHLTMUONTriggerReconstructorComponent::GetOutputDataSize(
113 unsigned long& constBase, double& inputMultiplier
117 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
120 constBase = sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType);
125 AliHLTComponent* AliHLTMUONTriggerReconstructorComponent::Spawn()
128 /// Inherited from AliHLTComponent. Creates a new object instance.
131 return new AliHLTMUONTriggerReconstructorComponent;
135 int AliHLTMUONTriggerReconstructorComponent::DoInit(int argc, const char** argv)
138 /// Inherited from AliHLTComponent.
139 /// Parses the command line parameters and initialises the component.
142 // perform initialization.
144 HLTInfo("Initialising dHLT trigger reconstructor component.");
146 // Make sure to cleanup fTrigRec if it is still there for some reason.
147 if (fTrigRec != NULL)
155 fTrigRec = new AliHLTMUONTriggerReconstructor();
157 catch (const std::bad_alloc&)
159 HLTError("Could not allocate more memory for the trigger reconstructor component.");
164 fWarnForUnexpecedBlock = false;
165 fStopOnOverflow = false;
168 const char* lutFileName = NULL;
169 const char* cdbPath = NULL;
172 bool suppressPartialTrigs = true;
173 bool tryRecover = false;
175 for (int i = 0; i < argc; i++)
177 if (strcmp( argv[i], "-lut" ) == 0)
181 HLTError("LookupTable filename not specified." );
182 // Make sure to delete fTrigRec to avoid partial initialisation.
188 lutFileName = argv[i+1];
194 if (strcmp( argv[i], "-ddl" ) == 0)
198 HLTError("DDL number not specified. It must be in the range [21..22]" );
199 // Make sure to delete fTrigRec to avoid partial initialisation.
206 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
207 if (cpErr == NULL or *cpErr != '\0')
209 HLTError("Cannot convert '%s' to a DDL Number.", argv[i+1]);
210 // Make sure to delete fTrigRec to avoid partial initialisation.
215 if (num < 21 or 22 < num)
217 HLTError("The DDL number must be in the range [21..22].");
218 // Make sure to delete fTrigRec to avoid partial initialisation.
223 fDDL = num - 1; // Convert to DDL number in the range 0..21
229 if (strcmp( argv[i], "-ddlid" ) == 0)
233 HLTError("DDL equipment ID number not specified. It must be in the range [2816..2817]" );
234 // Make sure to delete fTrigRec to avoid partial initialisation.
241 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
242 if (cpErr == NULL or *cpErr != '\0')
244 HLTError("Cannot convert '%s' to a DDL equipment ID Number.", argv[i+1]);
245 // Make sure to delete fTrigRec to avoid partial initialisation.
250 fDDL = AliHLTMUONUtils::EquipIdToDDLNumber(num); // Convert to DDL number in the range 0..21
251 if (fDDL < 20 or 21 < fDDL)
253 HLTError("The DDL equipment ID number must be in the range [2816..2817].");
254 // Make sure to delete fTrigRec to avoid partial initialisation.
264 if (strcmp( argv[i], "-cdb" ) == 0)
270 if (strcmp( argv[i], "-cdbpath" ) == 0)
274 HLTError("The CDB path was not specified." );
275 // Make sure to delete fTrigRec to avoid partial initialisation.
286 if (strcmp( argv[i], "-run" ) == 0)
290 HLTError("The run number was not specified." );
291 // Make sure to delete fTrigRec to avoid partial initialisation.
298 run = Int_t( strtoul(argv[i+1], &cpErr, 0) );
299 if (cpErr == NULL or *cpErr != '\0')
301 HLTError("Cannot convert '%s' to a valid run number."
302 " Expected a positive integer value.", argv[i+1]
304 // Make sure to delete fTrigRec to avoid partial initialisation.
314 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
316 fWarnForUnexpecedBlock = true;
320 if (strcmp( argv[i], "-suppress_partial_triggers" ) == 0)
322 suppressPartialTrigs = true;
326 if (strcmp( argv[i], "-generate_partial_triggers" ) == 0)
328 suppressPartialTrigs = false;
332 if (strcmp( argv[i], "-stop_on_buffer_overflow" ) == 0)
334 fStopOnOverflow = true;
338 if (strcmp( argv[i], "-tryrecover" ) == 0)
344 if (strcmp( argv[i], "-dont_use_crateid" ) == 0)
350 HLTError("Unknown option '%s'.", argv[i] );
351 // Make sure to delete fTrigRec to avoid partial initialisation.
358 if (lutFileName == NULL) useCDB = true;
362 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
366 if (cdbPath != NULL or run != -1)
368 result = SetCDBPathAndRunNo(cdbPath, run);
371 if (result == 0 and useCDB)
373 HLTInfo("Loading lookup table information from CDB for DDL %d (ID = %d).",
374 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
377 HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!");
378 result = ReadLutFromCDB();
380 else if (result == 0)
382 HLTInfo("Loading lookup table information from file %s.", lutFileName);
383 result = ReadLookUpTable(lutFileName);
387 // Error messages already generated in ReadLutFromCDB or ReadLookUpTable.
389 // Make sure to delete fTrigRec to avoid partial initialisation.
395 fTrigRec->SuppressPartialTriggers(suppressPartialTrigs);
396 fTrigRec->TryRecover(tryRecover);
397 fTrigRec->UseCrateId(fUseCrateId);
403 int AliHLTMUONTriggerReconstructorComponent::DoDeinit()
406 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
409 HLTInfo("Deinitialising dHLT trigger reconstructor component.");
411 if (fTrigRec != NULL)
420 int AliHLTMUONTriggerReconstructorComponent::DoEvent(
421 const AliHLTComponentEventData& evtData,
422 const AliHLTComponentBlockData* blocks,
423 AliHLTComponentTriggerData& /*trigData*/,
424 AliHLTUInt8_t* outputPtr,
425 AliHLTUInt32_t& size,
426 std::vector<AliHLTComponentBlockData>& outputBlocks
430 /// Inherited from AliHLTProcessor. Processes the new event data.
434 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
436 HLTDebug("Processing event %llu with %u input data blocks.",
437 evtData.fEventID, evtData.fBlockCnt
440 // Loop over all input blocks in the event and run the trigger DDL
441 // reconstruction algorithm on the raw data.
442 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
444 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
445 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
448 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
449 or not AliHLTMUONUtils::IsTriggerDDL(blocks[n].fSpecification)
452 // Log a message indicating that we got a data block that we
453 // do not know how to handle.
454 if (fWarnForUnexpecedBlock)
455 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
456 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
459 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
460 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
466 AliHLTInt32_t receivedDDL = AliHLTMUONUtils::SpecToDDLNumber(blocks[n].fSpecification);
469 if (receivedDDL != fDDL)
471 HLTWarning("Received raw data from DDL %d (ID = %d),"
472 " but expect data only from DDL %d (ID = %d).",
473 receivedDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(receivedDDL),
474 fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
479 // Create a new output data block and initialise the header.
480 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr+totalSize, size-totalSize);
481 if (not block.InitCommonHeader())
483 HLTError("There is not enough space in the output buffer for the new data block."
484 " We require at least %ufTrigRec->GetkDDLHeaderSize() bytes, but have %u bytes left.",
485 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
491 AliHLTUInt32_t totalDDLSize = blocks[n].fSize;
492 if (totalDDLSize < sizeof(AliRawDataHeader))
494 HLTError("Raw data block %d is %d bytes in size and is too short to"
495 " possibly contain valid DDL raw data. We expect it to have"
496 " at least %d bytes for the commond data header.",
497 n, totalDDLSize, sizeof(AliRawDataHeader)
501 AliRawDataHeader* header = reinterpret_cast<AliRawDataHeader*>(
502 reinterpret_cast<char*>(blocks[n].fPtr) + blocks[n].fOffset
504 AliHLTUInt32_t payloadSize = totalDDLSize - sizeof(AliRawDataHeader);
505 AliHLTUInt8_t* buffer = reinterpret_cast<AliHLTUInt8_t*>(header + 1);
506 AliHLTUInt32_t nofTrigRec = block.MaxNumberOfEntries();
508 // Decode if this is a scalar event or not.
509 bool scalarEvent = ((header->GetL1TriggerMessage() & 0x1) == 0x1);
511 // Remember: the following does NOT change the mapping!
512 // It is just to generate unique trigger record IDs.
513 fTrigRec->SetDDL(receivedDDL);
515 bool runOk = fTrigRec->Run(
516 buffer, payloadSize, scalarEvent,
517 block.GetArray(), nofTrigRec
521 HLTError("Error while processing the trigger DDL reconstruction algorithm.");
522 if (not fTrigRec->OverflowedOutputBuffer()
523 or (fTrigRec->OverflowedOutputBuffer() and fStopOnOverflow)
526 size = totalSize; // Must tell the framework how much buffer space was used.
531 // nofTrigRec should now contain the number of triggers actually found
532 // and filled into the output data block, so we can set this number.
533 assert( nofTrigRec <= block.MaxNumberOfEntries() );
534 block.SetNumberOfEntries(nofTrigRec);
536 HLTDebug("Number of trigger records found is %d", nofTrigRec);
538 // Fill a block data structure for our output block.
539 AliHLTComponentBlockData bd;
542 // This block's start (offset) is after all other blocks written so far.
543 bd.fOffset = totalSize;
544 bd.fSize = block.BytesUsed();
545 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
546 bd.fSpecification = blocks[n].fSpecification;
547 outputBlocks.push_back(bd);
549 HLTDebug("Created a new output data block at fPtr = %p,"
550 " with fOffset = %u (0x%.X) and fSize = %u bytes.",
551 bd.fPtr, bd.fOffset, bd.fOffset, bd.fSize
554 // Increase the total amount of data written so far to our output memory.
555 totalSize += block.BytesUsed();
558 // Finally we set the total size of output memory we consumed.
564 int AliHLTMUONTriggerReconstructorComponent::ReadLookUpTable(const char* lutpath)
567 /// Read in the lookup table from file.
570 assert(fTrigRec != NULL);
573 file.open(lutpath, fstream::binary | fstream::in);
576 HLTError("Could not open file: %s", lutpath);
580 file.read(reinterpret_cast<char*>(fTrigRec->LookupTableBuffer()), fTrigRec->LookupTableSize());
583 HLTError("The file %s was too short to contain a valid lookup table for this component.", lutpath);
589 HLTError("Could not read from file: %s", lutpath);
599 int AliHLTMUONTriggerReconstructorComponent::ReadLutFromCDB()
601 /// Loads the lookup table containing channel and geometrical position
602 /// information about trigger strips from CDB.
604 /// \note To override the default CDB path and / or run number the
605 /// SetCDBPathAndRunNo(cdbPath, run) method should be called before this
608 /// \return 0 on success and non zero codes for errors.
612 HLTError("No DDL number specified for which to load LUT data from CDB.");
616 int result = FetchMappingStores();
617 // Error message already generated in FetchMappingStores.
618 if (result != 0) return result;
619 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
621 AliMpSegmentation* segmentation = AliMpSegmentation::Instance();
622 if (segmentation == NULL)
624 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
628 // Only load geometry if not already loaded.
629 if (AliGeomManager::GetGeometry() == NULL)
631 AliGeomManager::LoadGeometry();
633 AliMUONGeometryTransformer transformer;
634 if (not transformer.LoadGeometryData())
636 HLTError("Could not load geometry into transformer.");
640 AliHLTMUONTriggerRecoLookupTable* lookupTable = fTrigRec->LookupTableBuffer();
642 for (Int_t i = 0; i < 16; i++)
643 for (Int_t j = 0; j < 16; j++)
644 for (Int_t k = 0; k < 4; k++)
645 for (Int_t n = 0; n < 2; n++)
646 for (Int_t m = 0; m < 16; m++)
648 lookupTable->fRow[i][j][k][n][m].fIdFlags = 0x0;
649 lookupTable->fRow[i][j][k][n][m].fX = 0;
650 lookupTable->fRow[i][j][k][n][m].fY = 0;
651 lookupTable->fRow[i][j][k][n][m].fZ = 0;
654 AliMpDEIterator detElemIter;
655 for (Int_t iReg = 0; iReg < 8; iReg++)
657 AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(fDDL, iReg);
660 HLTError("Could not get crate mapping for regional header = %d"
661 " and DDL %d (ID = %d).",
662 iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
666 // Depending on the value of fUseCrateId, use either the crate ID as would
667 // be found in the regional header structures or the sequencial index number
669 UInt_t crateId = (fUseCrateId ? crate->GetId() : iReg);
672 HLTError("The crate ID number (%d) for regional header = %d and"
673 " DDL %d (ID = %d) is too big. It should be in the range [0..15]",
674 crateId, iReg, fDDL+1, AliHLTMUONUtils::DDLNumberToEquipId(fDDL)
679 for (Int_t iLocBoard = 0; iLocBoard < 16; iLocBoard++)
681 Int_t boardId = crate->GetLocalBoardId(iLocBoard);
682 if (boardId == 0) continue;
684 AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(boardId);
685 if (localBoard == NULL)
687 HLTError("Could not get local board: %d.", boardId);
692 if (! localBoard->IsNotified()) continue;
694 for (Int_t iChamber = 0; iChamber < 4; iChamber++)
696 Int_t detElemId = ddlStore->GetDEfromLocalBoard(boardId, iChamber);
698 AliHLTUInt32_t idflags = AliHLTMUONUtils::PackRecHitFlags(iChamber+10, detElemId);
700 const AliMUONGeometryDetElement* detElemTransform = transformer.GetDetElement(detElemId);
701 if (detElemTransform == NULL)
703 HLTError("Got NULL pointer for geometry transformer"
704 " for detection element ID = %d.",
710 for (Int_t iCathode = 0; iCathode <= 1; iCathode++)
712 const AliMpVSegmentation* seg = segmentation->GetMpSegmentation(
713 detElemId, AliMp::GetCathodType(iCathode)
716 for (Int_t bitxy = 0; bitxy < 16; bitxy++)
719 if (iCathode && localBoard->GetSwitch(6)) offset = -8;
721 AliMpPad pad = seg->PadByLocation(AliMpIntPair(boardId, bitxy+offset), kFALSE);
725 // There is no pad associated with the given local board and bit pattern.
729 // Get the global coodinates of the pad.
730 Float_t lx = pad.Position().X();
731 Float_t ly = pad.Position().Y();
733 detElemTransform->Local2Global(lx, ly, 0, gx, gy, gz);
736 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fIdFlags = idflags;
737 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fX = gx;
738 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fY = gy;
739 lookupTable->fRow[crateId][iLocBoard][iChamber][iCathode][bitxy].fZ = gz;
750 bool AliHLTMUONTriggerReconstructorComponent::GenerateLookupTable(
751 AliHLTInt32_t ddl, const char* filename,
752 const char* cdbPath, Int_t run
753 //TODO add option fCrateId
756 /// Generates a binary file containing the lookup table (LUT) from the
757 /// CDB, which can be used for the trigger reconstructor component later.
758 /// @param ddl Must be the DDL for which to generate the DDL,
759 /// in the range [20..21].
760 /// @param filename The name of the LUT file to generate.
761 /// @param cdbPath The CDB path to use.
762 /// @param run The run number to use for the CDB.
763 /// @return True if the generation of the LUT file succeeded.
765 AliHLTMUONTriggerReconstructorComponent comp;
767 if (ddl < 20 or 21 < ddl)
769 std::cerr << "ERROR: the DDL number must be in the range [20..21]." << std::endl;
775 sprintf(ddlNum, "%d", ddl+1);
776 sprintf(runNum, "%d", run);
777 const char* argv[7] = {"-ddl", ddlNum, "-cdbpath", cdbPath, "-run", runNum, NULL};
778 int result = comp.DoInit(6, argv);
781 // Error message already generated in DoInit.
785 std::fstream file(filename, std::ios::out);
788 std::cerr << "ERROR: could not open file: " << filename << std::endl;
793 reinterpret_cast<char*>(comp.fTrigRec->LookupTableBuffer()),
794 comp.fTrigRec->LookupTableSize()
798 std::cerr << "ERROR: There was a problem writing to the file: " << filename << std::endl;