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 "AliCDBManager.h"
34 #include "AliCDBStorage.h"
35 #include "AliGeomManager.h"
36 #include "AliMUONGeometryTransformer.h"
37 #include "AliMUONGeometryDetElement.h"
39 #include "AliMpDDLStore.h"
41 #include "AliMpSegmentation.h"
42 #include "AliMpDEIterator.h"
43 #include "AliMpVSegmentation.h"
44 #include "AliMpDEManager.h"
45 #include "AliMpLocalBoard.h"
46 #include "AliMpTriggerCrate.h"
53 ClassImp(AliHLTMUONTriggerReconstructorComponent)
56 AliHLTMUONTriggerReconstructorComponent::AliHLTMUONTriggerReconstructorComponent() :
60 fWarnForUnexpecedBlock(false),
61 fSuppressPartialTrigs(false)
64 /// Default constructor.
69 AliHLTMUONTriggerReconstructorComponent::~AliHLTMUONTriggerReconstructorComponent()
72 /// Default destructor.
75 if (fTrigRec != NULL) delete fTrigRec;
79 const char* AliHLTMUONTriggerReconstructorComponent::GetComponentID()
82 /// Inherited from AliHLTComponent. Returns the component ID.
85 return AliHLTMUONConstants::TriggerReconstructorId();
89 void AliHLTMUONTriggerReconstructorComponent::GetInputDataTypes( std::vector<AliHLTComponentDataType>& list)
92 /// Inherited from AliHLTProcessor. Returns the list of expected input data types.
96 list.push_back( AliHLTMUONConstants::DDLRawDataType() );
100 AliHLTComponentDataType AliHLTMUONTriggerReconstructorComponent::GetOutputDataType()
103 /// Inherited from AliHLTComponent. Returns the output data type.
106 return AliHLTMUONConstants::TriggerRecordsBlockDataType();
110 void AliHLTMUONTriggerReconstructorComponent::GetOutputDataSize(
111 unsigned long& constBase, double& inputMultiplier
115 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
118 constBase = sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType);
123 AliHLTComponent* AliHLTMUONTriggerReconstructorComponent::Spawn()
126 /// Inherited from AliHLTComponent. Creates a new object instance.
129 return new AliHLTMUONTriggerReconstructorComponent;
133 int AliHLTMUONTriggerReconstructorComponent::DoInit(int argc, const char** argv)
136 /// Inherited from AliHLTComponent.
137 /// Parses the command line parameters and initialises the component.
140 // perform initialization.
142 HLTInfo("Initialising dHLT trigger reconstructor component.");
144 // Make sure to cleanup fTrigRec if it is still there for some reason.
145 if (fTrigRec != NULL)
153 fTrigRec = new AliHLTMUONTriggerReconstructor();
155 catch (const std::bad_alloc&)
157 HLTError("Could not allocate more memory for the trigger reconstructor component.");
162 fWarnForUnexpecedBlock = false;
163 fSuppressPartialTrigs = false;
165 const char* lutFileName = NULL;
166 const char* cdbPath = NULL;
170 for (int i = 0; i < argc; i++)
172 if (strcmp( argv[i], "-lut" ) == 0)
176 HLTError("LookupTable filename not specified." );
177 // Make sure to delete fTrigRec to avoid partial initialisation.
183 lutFileName = argv[i+1];
189 if (strcmp( argv[i], "-ddl" ) == 0)
193 HLTError("DDL number not specified. It must be in the range [21..22]" );
194 // Make sure to delete fTrigRec to avoid partial initialisation.
201 unsigned long num = strtoul(argv[i+1], &cpErr, 0);
202 if (cpErr == NULL or *cpErr != '\0')
204 HLTError("Cannot convert '%s' to a DDL Number.", argv[i+1] );\
205 // Make sure to delete fTrigRec to avoid partial initialisation.
210 if (num < 21 or 22 < num)
212 HLTError("The DDL ID number must be in the range [21..22].");
213 // Make sure to delete fTrigRec to avoid partial initialisation.
218 fDDL = num - 1; // Convert to DDL number in the range 0..21
224 if (strcmp( argv[i], "-cdb" ) == 0)
230 if (strcmp( argv[i], "-cdbpath" ) == 0)
234 HLTError("The CDB path was not specified." );
235 // Make sure to delete fTrigRec to avoid partial initialisation.
246 if (strcmp( argv[i], "-run" ) == 0)
250 HLTError("The RUN number was not specified." );
251 // Make sure to delete fTrigRec 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 // Make sure to delete fTrigRec to avoid partial initialisation.
274 if (strcmp( argv[i], "-warn_on_unexpected_block" ) == 0)
276 fWarnForUnexpecedBlock = true;
280 if (strcmp( argv[i], "-suppress_partial_triggers" ) == 0)
282 fSuppressPartialTrigs = true;
286 HLTError("Unknown option '%s'.", argv[i] );
287 // Make sure to delete fTrigRec to avoid partial initialisation.
294 if (lutFileName == NULL) useCDB = true;
298 HLTWarning("DDL number not specified. Cannot check if incomming data is valid.");
304 HLTInfo("Loading lookup table information from CDB for DDL %d.", fDDL+1);
306 HLTWarning("DDL number not specified. The lookup table loaded from CDB will be empty!");
307 result = ReadCDB(cdbPath, run);
311 HLTInfo("Loading lookup table information from file %s.", lutFileName);
312 result = ReadLookUpTable(lutFileName);
316 // Error messages already generated in ReadCDB or ReadLookUpTable.
318 // Make sure to delete fTrigRec to avoid partial initialisation.
328 int AliHLTMUONTriggerReconstructorComponent::DoDeinit()
331 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
334 HLTInfo("Deinitialising dHLT trigger reconstructor component.");
336 if (fTrigRec != NULL)
345 int AliHLTMUONTriggerReconstructorComponent::DoEvent(
346 const AliHLTComponentEventData& evtData,
347 const AliHLTComponentBlockData* blocks,
348 AliHLTComponentTriggerData& /*trigData*/,
349 AliHLTUInt8_t* outputPtr,
350 AliHLTUInt32_t& size,
351 std::vector<AliHLTComponentBlockData>& outputBlocks
355 /// Inherited from AliHLTProcessor. Processes the new event data.
359 unsigned long totalSize = 0; // Amount of memory currently consumed in bytes.
361 HLTDebug("Processing event %llu with %u input data blocks.",
362 evtData.fEventID, evtData.fBlockCnt
365 // Loop over all input blocks in the event and run the trigger DDL
366 // reconstruction algorithm on the raw data.
367 for (AliHLTUInt32_t n = 0; n < evtData.fBlockCnt; n++)
369 HLTDebug("Handling block: %u, with fDataType = '%s', fPtr = %p and fSize = %u bytes.",
370 n, DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fPtr, blocks[n].fSize
373 if (blocks[n].fDataType != AliHLTMUONConstants::DDLRawDataType()
374 or not AliHLTMUONUtils::IsTriggerDDL(blocks[n].fSpecification)
377 // Log a message indicating that we got a data block that we
378 // do not know how to handle.
379 if (fWarnForUnexpecedBlock)
380 HLTWarning("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
381 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
384 HLTDebug("Received a data block of a type we cannot handle: '%s', spec: 0x%X",
385 DataType2Text(blocks[n].fDataType).c_str(), blocks[n].fSpecification
394 AliHLTMUONUtils::UnpackSpecBits(blocks[n].fSpecification, ddl);
397 HLTWarning("Received raw data from an unexpected DDL.");
401 // Create a new output data block and initialise the header.
402 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr+totalSize, size-totalSize);
403 if (not block.InitCommonHeader())
405 HLTError("There is not enough space in the output buffer for the new data block.",
406 " We require at least %ufTrigRec->GetkDDLHeaderSize() bytes, but have %u bytes left.",
407 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
413 AliHLTUInt32_t totalDDLSize = blocks[n].fSize / sizeof(AliHLTUInt32_t);
414 AliHLTUInt32_t ddlRawDataSize = totalDDLSize - 8;
415 AliHLTUInt32_t* buffer = reinterpret_cast<AliHLTUInt32_t*>(blocks[n].fPtr) + 8;
416 AliHLTUInt32_t nofTrigRec = block.MaxNumberOfEntries();
418 bool runOk = fTrigRec->Run(
419 buffer, ddlRawDataSize,
420 block.GetArray(), nofTrigRec,
421 fSuppressPartialTrigs
425 HLTError("Error while processing of trigger DDL reconstruction algorithm.");
426 size = totalSize; // Must tell the framework how much buffer space was used.
430 // nofTrigRec should now contain the number of triggers actually found
431 // and filled into the output data block, so we can set this number.
432 assert( nofTrigRec <= block.MaxNumberOfEntries() );
433 block.SetNumberOfEntries(nofTrigRec);
435 HLTDebug("Number of trigger records found is %d", nofTrigRec);
437 // Fill a block data structure for our output block.
438 AliHLTComponentBlockData bd;
441 // This block's start (offset) is after all other blocks written so far.
442 bd.fOffset = totalSize;
443 bd.fSize = block.BytesUsed();
444 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
445 bd.fSpecification = blocks[n].fSpecification;
446 outputBlocks.push_back(bd);
448 HLTDebug("Created a new output data block at fPtr = %p,"
449 " with fOffset = %u (0x%.X) and fSize = %u bytes.",
450 bd.fPtr, bd.fOffset, bd.fOffset, bd.fSize
453 // Increase the total amount of data written so far to our output memory.
454 totalSize += block.BytesUsed();
457 // Finally we set the total size of output memory we consumed.
463 int AliHLTMUONTriggerReconstructorComponent::ReadLookUpTable(const char* lutpath)
466 /// Read in the lookup table from file.
469 assert(fTrigRec != NULL);
472 file.open(lutpath, fstream::binary | fstream::in);
475 HLTError("Could not open file: %s", lutpath);
479 file.read(reinterpret_cast<char*>(fTrigRec->LookupTableBuffer()), fTrigRec->LookupTableSize());
482 HLTError("The file %s was too short to contain a valid lookup table for this component.", lutpath);
488 HLTError("Could not read from file: %s", lutpath);
498 int AliHLTMUONTriggerReconstructorComponent::ReadCDB(const char* cdbPath, Int_t run)
500 /// Loads the lookup table containing channel and geometrical position
501 /// information about trigger strips from CDB.
502 /// \param cdbPath This specifies the CDB path to use to load from.
503 /// Can be set to NULL meaning the default storage is used.
504 /// \param run Specifies the run number to use. If set to -1 then the
505 /// default / current run number set for the CDB is used.
506 /// \return 0 on success and non zero codes for errors.
510 HLTError("No DDL number specified for which to load LUT data from CDB.");
514 Bool_t warn = kFALSE;
516 AliCDBManager* cdbManager = AliCDBManager::Instance();
517 if (cdbManager == NULL)
519 HLTError("CDB manager instance does not exist.");
523 const char* cdbPathUsed = "unknown (not set)";
526 cdbManager->SetDefaultStorage(cdbPath);
527 cdbPathUsed = cdbPath;
531 AliCDBStorage* store = cdbManager->GetDefaultStorage();
532 if (store != NULL) cdbPathUsed = store->GetURI().Data();
535 if (run != -1) cdbManager->SetRun(run);
536 Int_t runUsed = cdbManager->GetRun();
538 if (not AliMpCDB::LoadDDLStore(warn))
540 HLTError("Failed to load DDL store specified for CDB path '%s' and run no. %d",
545 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
546 if (ddlStore == NULL)
548 HLTError("Could not find DDL store instance.");
551 AliMpSegmentation* segmentation = AliMpSegmentation::Instance();
552 if (segmentation == NULL)
554 HLTError("Could not find segmentation mapping (AliMpSegmentation) instance.");
558 AliGeomManager::LoadGeometry();
559 AliMUONGeometryTransformer transformer;
560 if (not transformer.LoadGeometryData())
562 HLTError("Could not load geometry into transformer.");
566 AliHLTMUONTriggerRecoLookupTable* lookupTable = fTrigRec->LookupTableBuffer();
568 for (Int_t i = 0; i < 8; i++)
569 for (Int_t j = 0; j < 16; j++)
570 for (Int_t k = 0; k < 4; k++)
571 for (Int_t n = 0; n < 2; n++)
572 for (Int_t m = 0; m < 16; m++)
574 lookupTable->fRow[i][j][k][n][m].fX = 0;
575 lookupTable->fRow[i][j][k][n][m].fY = 0;
576 lookupTable->fRow[i][j][k][n][m].fZ = 0;
579 AliMpDEIterator detElemIter;
580 for (Int_t iReg = 0; iReg < 8; iReg++)
582 AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(fDDL, iReg);
585 cerr << "ERROR: Could not get crate for regional header = " << iReg
586 << ", and DDL ID = " << fDDL << endl;
590 for (Int_t iLocBoard = 0; iLocBoard < 16; iLocBoard++)
592 Int_t boardId = crate->GetLocalBoardId(iLocBoard);
593 if (boardId == 0) continue;
595 AliMpLocalBoard* localBoard = ddlStore->GetLocalBoard(boardId);
596 if (localBoard == NULL)
598 cerr << "ERROR: Could not get loacl board: " << boardId << endl;
603 if (! localBoard->IsNotified()) continue;
605 for (Int_t iChamber = 0; iChamber < 4; iChamber++)
607 Int_t detElemId = ddlStore->GetDEfromLocalBoard(boardId, iChamber);
609 const AliMUONGeometryDetElement* detElemTransform = transformer.GetDetElement(detElemId);
610 if (detElemTransform == NULL)
612 cerr << "ERROR: Got NULL pointer for geometry transformer for detection element ID = "
613 << detElemId << endl;
617 for (Int_t iCathode = 0; iCathode <= 1; iCathode++)
619 const AliMpVSegmentation* seg = segmentation->GetMpSegmentation(
620 detElemId, AliMp::GetCathodType(iCathode)
623 for (Int_t bitxy = 0; bitxy < 16; bitxy++)
626 if (iCathode && localBoard->GetSwitch(6)) offset = -8;
628 AliMpPad pad = seg->PadByLocation(AliMpIntPair(boardId, bitxy+offset), kFALSE);
632 // There is no pad associated with the given local board and bit pattern.
636 // Get the global coodinates of the pad.
637 Float_t lx = pad.Position().X();
638 Float_t ly = pad.Position().Y();
640 detElemTransform->Local2Global(lx, ly, 0, gx, gy, gz);
643 lookupTable->fRow[iReg][iLocBoard][iChamber][iCathode][bitxy].fX = gx;
644 lookupTable->fRow[iReg][iLocBoard][iChamber][iCathode][bitxy].fY = gy;
645 lookupTable->fRow[iReg][iLocBoard][iChamber][iCathode][bitxy].fZ = gz;
656 bool AliHLTMUONTriggerReconstructorComponent::GenerateLookupTable(
657 AliHLTInt32_t ddl, const char* filename,
658 const char* cdbPath, Int_t run
661 /// Generates a binary file containing the lookup table (LUT) from the
662 /// CDB, which can be used for the trigger reconstructor component later.
663 /// @param ddl Must be the DDL for which to generate the DDL,
664 /// in the range [20..21].
665 /// @param filename The name of the LUT file to generate.
666 /// @param cdbPath The CDB path to use.
667 /// @param run The run number to use for the CDB.
668 /// @return True if the generation of the LUT file succeeded.
670 AliHLTMUONTriggerReconstructorComponent comp;
672 if (ddl < 20 or 21 < ddl)
674 std::cerr << "ERROR: the DDL number must be in the range [20..21]." << std::endl;
680 sprintf(ddlNum, "%d", ddl+1);
681 sprintf(runNum, "%d", run);
682 const char* argv[7] = {"-ddl", ddlNum, "-cdbpath", cdbPath, "-run", runNum, NULL};
683 int result = comp.DoInit(6, argv);
686 // Error message already generated in DoInit.
690 std::fstream file(filename, std::ios::out);
693 std::cerr << "ERROR: could not open file: " << filename << std::endl;
698 reinterpret_cast<char*>(comp.fTrigRec->LookupTableBuffer()),
699 comp.fTrigRec->LookupTableSize()
703 cerr << "ERROR: There was a problem writing to the file: " << filename << endl;