1 /**************************************************************************
2 * This file is property of and copyright by the ALICE HLT Project *
3 * All rights reserved. *
6 * Artur Szostak <artursz@iafrica.com> *
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 **************************************************************************/
20 * @file AliHLTMUONTriggerRecordsSource.cxx
21 * @author Artur Szostak <artursz@iafrica.com>
23 * @brief Implementation of the AliHLTMUONTriggerRecordsSource component.
26 #include "AliHLTMUONTriggerRecordsSource.h"
27 #include "AliHLTMUONConstants.h"
28 #include "AliHLTMUONUtils.h"
29 #include "AliHLTMUONDataBlockWriter.h"
30 #include "AliHLTMUONCalculations.h"
31 #include "AliMUONMCDataInterface.h"
32 #include "AliMUONDataInterface.h"
33 #include "AliMUONHit.h"
34 #include "AliMUONRawCluster.h"
35 #include "AliMUONConstants.h"
36 #include "AliMUONVClusterStore.h"
37 #include "AliMUONVHitStore.h"
38 #include "mapping/AliMpCDB.h"
39 #include "mapping/AliMpDDLStore.h"
40 #include "mapping/AliMpLocalBoard.h"
41 #include "mapping/AliMpTriggerCrate.h"
42 #include "mapping/AliMpDEManager.h"
43 #include "mapping/AliMpDetElement.h"
45 #include "TClonesArray.h"
55 //TODO: The following method should be in MUON/mapping
56 Int_t FindDDLOfDetElement(Int_t detElemId)
58 // Find what the DDL ID number is for a detector element from
59 // trigger chambers 11 to 14. We first have to find the local
60 // board associated with the detector element and then we can
61 // associate that local board to the trigger crate which has
62 // the DDL number specified.
63 AliMpDDLStore* ddlStore = AliMpDDLStore::Instance();
64 if (ddlStore == NULL) return -1;
65 Int_t ddl = -1, boardIndex = 1;
68 AliMpLocalBoard* board = ddlStore->GetLocalBoard(boardIndex++);
69 if (board == NULL) break;
70 if (board->HasDEId(detElemId))
72 AliMpTriggerCrate* crate = ddlStore->GetTriggerCrate(board->GetCrate());
73 if (crate == NULL) continue;
74 ddl = crate->GetDdlId();
85 ClassImp(AliHLTMUONTriggerRecordsSource);
88 AliHLTMUONTriggerRecordsSource::AliHLTMUONTriggerRecordsSource() :
89 AliHLTOfflineDataSource(),
90 fMCDataInterface(NULL),
92 fBuildFromHits(false),
93 fSelection(kWholePlane),
97 /// Default constructor.
102 AliHLTMUONTriggerRecordsSource::~AliHLTMUONTriggerRecordsSource()
105 /// Default destructor.
108 if (fMCDataInterface != NULL) delete fMCDataInterface;
109 if (fDataInterface != NULL) delete fDataInterface;
113 int AliHLTMUONTriggerRecordsSource::DoInit(int argc, const char** argv)
116 /// Inherited from AliHLTComponent.
117 /// Parses the command line parameters and initialises the component.
120 HLTInfo("Initialising dHLT trigger record source component.");
122 if (fMCDataInterface != NULL)
124 delete fMCDataInterface;
125 fMCDataInterface = NULL;
127 if (fDataInterface != NULL)
129 delete fDataInterface;
130 fDataInterface = NULL;
133 // Parse the command line arguments:
134 bool hitdata = false;
135 bool simdata = false;
136 bool recdata = false;
137 fCurrentEventIndex = 0;
138 bool firstEventSet = false;
139 bool eventNumLitSet = false;
141 for (int i = 0; i < argc; i++)
143 if (strcmp(argv[i], "-hitdata") == 0)
147 else if (strcmp(argv[i], "-simdata") == 0)
151 else if (strcmp(argv[i], "-recdata") == 0)
155 else if (strcmp(argv[i], "-plane") == 0)
160 Logging(kHLTLogError,
161 "AliHLTMUONTriggerRecordsSource::DoInit",
163 "Expected one of 'left', 'right' or 'all' after '-plane'."
167 if (strcmp(argv[i], "left") == 0)
168 fSelection = kLeftPlane;
169 else if (strcmp(argv[i], "right") == 0)
170 fSelection = kRightPlane;
171 else if (strcmp(argv[i], "all") == 0)
172 fSelection = kWholePlane;
175 Logging(kHLTLogError,
176 "AliHLTMUONTriggerRecordsSource::DoInit",
178 "The parameter '%s' is invalid and must be one of 'left',"
179 " 'right' or 'all'.",
185 else if (strcmp(argv[i], "-firstevent") == 0)
189 HLTWarning("The -firstevent flag is overridden by a"
190 " previous use of -event_number_literal."
196 HLTError("Expected a positive number after -firstevent.");
200 long num = strtol(argv[i], &end, 0);
201 if (*end != '\0' or num < 0) // Check if the conversion is OK.
204 "Expected a positive number after -firstevent"
205 " but got: %s", argv[i]
209 fCurrentEventIndex = Int_t(num);
210 firstEventSet = true;
212 else if (strcmp(argv[i], "-event_number_literal") == 0)
216 HLTWarning("The -event_number_literal option will"
217 " override -firstevent."
220 fCurrentEventIndex = -1;
221 eventNumLitSet = true;
225 Logging(kHLTLogError,
226 "AliHLTMUONTriggerRecordsSource::DoInit",
228 "The argument '%s' is invalid.",
235 // Check that one and only one of the the -hitdata, -simdata or
236 // -recdata parameters was specified on the command line.
237 if ((not hitdata and not simdata and not recdata) or
238 (not hitdata and simdata and recdata) or
239 (hitdata and not simdata and recdata) or
240 (hitdata and simdata and not recdata) or
241 (hitdata and simdata and recdata)
244 Logging(kHLTLogError,
245 "AliHLTMUONTriggerRecordsSource::DoInit",
247 "Must have one and only one of -hitdata, -simdata or -recdata specified."
252 // Must load the mapping data for AliMpTriggerCrate::GetDdlId() //TODO AliMpTriggerCrate => AliMpDetElement
253 // to return useful information later on.
254 AliMpCDB::LoadDDLStore();
256 // Now we can initialise the data interface objects and loaders.
257 fBuildFromHits = hitdata;
258 if (hitdata or simdata)
260 const char* message = fBuildFromHits ?
261 "Loading simulated GEANT hits with AliMUONMCDataInterface."
262 : "Loading simulated local trigger objects with AliMUONMCDataInterface.";
264 Logging(kHLTLogDebug, "AliHLTMUONTriggerRecordsSource::DoInit",
265 "Data interface", message
270 fMCDataInterface = new AliMUONMCDataInterface("galice.root");
272 catch (const std::bad_alloc&)
274 Logging(kHLTLogError,
275 "AliHLTMUONTriggerRecordsSource::DoInit",
277 "Not enough memory to allocate AliMUONMCDataInterface."
284 Logging(kHLTLogDebug,
285 "AliHLTMUONTriggerRecordsSource::DoInit",
287 "Loading reconstructed local trigger objects with AliMUONDataInterface."
292 fDataInterface = new AliMUONDataInterface("galice.root");
294 catch (const std::bad_alloc&)
296 Logging(kHLTLogError,
297 "AliHLTMUONTriggerRecordsSource::DoInit",
299 "Not enough memory to allocate AliMUONDataInterface."
305 // Check that the fCurrentEventIndex number falls within the correct range.
307 if (fMCDataInterface != NULL)
308 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
309 else if (fDataInterface != NULL)
310 maxevent = UInt_t(fDataInterface->NumberOfEvents());
311 if (fCurrentEventIndex != -1 and UInt_t(fCurrentEventIndex) >= maxevent and maxevent != 0)
313 fCurrentEventIndex = 0;
314 HLTWarning(Form("The selected first event number (%d) was larger than"
315 " the available number of events (%d). Resetting the event"
316 " counter to zero.", fCurrentEventIndex, maxevent
324 int AliHLTMUONTriggerRecordsSource::DoDeinit()
327 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
330 HLTInfo("Deinitialising dHLT trigger record source component.");
332 if (fMCDataInterface != NULL)
334 delete fMCDataInterface;
335 fMCDataInterface = NULL;
337 if (fDataInterface != NULL)
339 delete fDataInterface;
340 fDataInterface = NULL;
346 const char* AliHLTMUONTriggerRecordsSource::GetComponentID()
349 /// Inherited from AliHLTComponent. Returns the component ID.
352 return AliHLTMUONConstants::TriggerRecordsSourceId();
356 AliHLTComponentDataType AliHLTMUONTriggerRecordsSource::GetOutputDataType()
359 /// Inherited from AliHLTComponent. Returns the output data type.
362 return AliHLTMUONConstants::TriggerRecordsBlockDataType();
366 void AliHLTMUONTriggerRecordsSource::GetOutputDataSize(
367 unsigned long& constBase, double& inputMultiplier
371 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
374 constBase = sizeof(AliHLTMUONTriggerRecordsBlockStruct) +
375 sizeof(AliHLTMUONTriggerRecordStruct) * AliMUONConstants::NTriggerCircuit();
380 AliHLTComponent* AliHLTMUONTriggerRecordsSource::Spawn()
383 /// Inherited from AliHLTComponent. Creates a new object instance.
386 return new AliHLTMUONTriggerRecordsSource();
390 int AliHLTMUONTriggerRecordsSource::GetEvent(
391 const AliHLTComponentEventData& evtData,
392 AliHLTComponentTriggerData& /*trigData*/,
393 AliHLTUInt8_t* outputPtr,
394 AliHLTUInt32_t& size,
395 vector<AliHLTComponentBlockData>& outputBlocks
399 /// Inherited from AliHLTOfflineDataSource. Creates new event data blocks.
402 assert( fMCDataInterface != NULL or fDataInterface != NULL );
404 AliHLTInt32_t trigRecId = 0;
406 // Check the size of the event descriptor structure.
407 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
409 Logging(kHLTLogError,
410 "AliHLTMUONTriggerRecordsSource::GetEvent",
411 "Invalid event descriptor",
412 "The event descriptor (AliHLTComponentEventData) size is"
413 " smaller than expected. It claims to be %d bytes, but"
414 " we expect it to be %d bytes.",
416 sizeof(AliHLTComponentEventData)
418 size = 0; // Important to tell framework that nothing was generated.
422 // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
423 // check it and load that event with the runloader.
424 // If fCurrentEventIndex is a positive number then use it instead and
426 UInt_t eventnumber = UInt_t(evtData.fEventID);
428 if (fMCDataInterface != NULL)
429 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
430 else if (fDataInterface != NULL)
431 maxevent = UInt_t(fDataInterface->NumberOfEvents());
432 if (fCurrentEventIndex != -1)
434 eventnumber = UInt_t(fCurrentEventIndex);
435 fCurrentEventIndex++;
436 if (UInt_t(fCurrentEventIndex) >= maxevent)
437 fCurrentEventIndex = 0;
439 if ( eventnumber >= maxevent )
441 Logging(kHLTLogError,
442 "AliHLTMUONTriggerRecordsSource::GetEvent",
444 "The event number (%d) is larger than the available number"
445 " of events on file (%d).",
449 size = 0; // Important to tell framework that nothing was generated.
453 // Create and initialise a new data block.
454 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr, size);
455 if (not block.InitCommonHeader())
457 Logging(kHLTLogError,
458 "AliHLTMUONTriggerRecordsSource::GetEvent",
460 "There is not enough buffer space to create a new data block."
461 " We require at least %d bytes but the buffer is only %d bytes.",
462 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
465 size = 0; // Important to tell framework that nothing was generated.
469 // Initialise the DDL list containing the DDLs which contributed to the
470 // data block. These are required to create the specification word later.
472 for (Int_t i = 0; i < 22; i++)
475 if (fMCDataInterface != NULL and fBuildFromHits)
477 Logging(kHLTLogDebug,
478 "AliHLTMUONTriggerRecordsSource::GetEvent",
480 "Filling data block with trigger records from GEANT hits for event %d.",
484 // Loop over all tracks, extract the hits from chambers 11 to 14 and
485 // create trigger records from them to write to the data block.
486 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
487 for (Int_t i = 0; i < ntracks; ++i)
489 AliMUONHit* hit11 = NULL;
490 AliMUONHit* hit12 = NULL;
491 AliMUONHit* hit13 = NULL;
492 AliMUONHit* hit14 = NULL;
498 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
500 TIter next(hitStore->CreateIterator());
501 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
503 // Select only hits on trigger chambers.
504 if (hit->Chamber() <= AliMUONConstants::NTrackingCh()) continue;
506 // Only select hits from the given part of the plane
507 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
508 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
510 // Workout which DDL this hit should be readout of.
511 Int_t ddl = FindDDLOfDetElement(hit->DetElemId());
512 if (not (0 <= ddl and ddl < 22))
515 Logging(kHLTLogError,
516 "AliHLTMUONTriggerRecordsSource::GetEvent",
518 "Could not find the DDL ID from which readout would take place."
522 switch (hit->Chamber())
524 case 11: hit11 = hit; ddl11 = ddl; break;
525 case 12: hit12 = hit; ddl12 = ddl; break;
526 case 13: hit13 = hit; ddl13 = ddl; break;
527 case 14: hit14 = hit; ddl14 = ddl; break;
532 // Check that there are at least 3 of 4 hits on the trigger chambers.
534 if (hit11 != NULL) hitCount++;
535 if (hit12 != NULL) hitCount++;
536 if (hit13 != NULL) hitCount++;
537 if (hit14 != NULL) hitCount++;
538 if (hitCount < 3) continue;
540 AliHLTMUONTriggerRecordStruct* trigRec = block.AddEntry();
543 Logging(kHLTLogError,
544 "AliHLTMUONTriggerRecordsSource::GetEvent",
546 "There is not enough buffer space to add more trigger records."
547 " We overflowed the buffer which is only %d bytes.",
550 size = 0; // Important to tell framework that nothing was generated.
554 // Fill the new trigger record with the hit information.
555 bool hitset[4] = {false, false, false, false};
556 AliHLTFloat32_t x1 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0;
559 trigRec->fHit[0].fX = hit11->Xref();
560 trigRec->fHit[0].fY = hit11->Yref();
561 trigRec->fHit[0].fZ = hit11->Zref();
569 trigRec->fHit[1].fX = hit12->Xref();
570 trigRec->fHit[1].fY = hit12->Yref();
571 trigRec->fHit[1].fZ = hit12->Zref();
579 trigRec->fHit[2].fX = hit13->Xref();
580 trigRec->fHit[2].fY = hit13->Yref();
581 trigRec->fHit[2].fZ = hit13->Zref();
588 trigRec->fHit[3].fX = hit14->Xref();
589 trigRec->fHit[3].fY = hit14->Yref();
590 trigRec->fHit[3].fZ = hit14->Zref();
596 bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
598 Logging(kHLTLogDebug,
599 "AliHLTMUONTriggerRecordsSource::GetEvent",
600 "Calculation failure",
601 "Something went wrong when calculating the momentum from"
602 " x1 = %f, y1 = %f, y2 = %f, z1 = %f, z2 = %f.",
606 trigRec->fId = trigRecId++;
607 trigRec->fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
608 AliHLTMUONCalculations::Sign(), hitset
610 trigRec->fPx = AliHLTMUONCalculations::Px();
611 trigRec->fPy = AliHLTMUONCalculations::Py();
612 trigRec->fPz = AliHLTMUONCalculations::Pz();
614 // Mark the DDLs over which this trigger record would be readout.
615 if (ddl11 != -1) ddlList[ddl11] = true;
616 if (ddl12 != -1) ddlList[ddl12] = true;
617 if (ddl13 != -1) ddlList[ddl13] = true;
618 if (ddl14 != -1) ddlList[ddl14] = true;
621 else if (fMCDataInterface != NULL and not fBuildFromHits)
623 Logging(kHLTLogDebug,
624 "AliHLTMUONTriggerRecordsSource::GetEvent",
626 "Filling data block with simulated local triggers for event %d.",
630 AliFatal("Sorry, -simdata option not yet implemented!");
633 else if (fDataInterface != NULL)
635 Logging(kHLTLogDebug,
636 "AliHLTMUONTriggerRecordsSource::GetEvent",
638 "Filling data block with reconstructed local triggers for event %d.",
642 AliFatal("Sorry, -recdata option not yet implemented!");
646 Logging(kHLTLogError,
647 "AliHLTMUONTriggerRecordsSource::GetEvent",
648 "Missing data interface",
649 "Neither AliMUONDataInterface nor AliMUONMCDataInterface were created."
651 size = 0; // Important to tell framework that nothing was generated.
655 AliHLTComponentBlockData bd;
659 bd.fSize = block.BytesUsed();
660 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
661 bd.fSpecification = AliHLTMUONUtils::PackSpecBits(ddlList);
662 outputBlocks.push_back(bd);
663 size = block.BytesUsed();