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 != NULL and *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 AliHLTComponentBlockDataList& outputBlocks
399 /// Inherited from AliHLTOfflineDataSource. Creates new event data blocks.
402 assert( fMCDataInterface != NULL or fDataInterface != NULL );
404 if (not IsDataEvent()) return 0; // ignore non data events.
406 AliHLTInt32_t trigRecId = 0;
408 // Check the size of the event descriptor structure.
409 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
411 Logging(kHLTLogError,
412 "AliHLTMUONTriggerRecordsSource::GetEvent",
413 "Invalid event descriptor",
414 "The event descriptor (AliHLTComponentEventData) size is"
415 " smaller than expected. It claims to be %d bytes, but"
416 " we expect it to be %d bytes.",
418 sizeof(AliHLTComponentEventData)
420 size = 0; // Important to tell framework that nothing was generated.
424 // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
425 // check it and load that event with the runloader.
426 // If fCurrentEventIndex is a positive number then use it instead and
428 UInt_t eventnumber = UInt_t(evtData.fEventID);
430 if (fMCDataInterface != NULL)
431 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
432 else if (fDataInterface != NULL)
433 maxevent = UInt_t(fDataInterface->NumberOfEvents());
434 if (fCurrentEventIndex != -1)
436 eventnumber = UInt_t(fCurrentEventIndex);
437 fCurrentEventIndex++;
438 if (UInt_t(fCurrentEventIndex) >= maxevent)
439 fCurrentEventIndex = 0;
441 if ( eventnumber >= maxevent )
443 Logging(kHLTLogError,
444 "AliHLTMUONTriggerRecordsSource::GetEvent",
446 "The event number (%d) is larger than the available number"
447 " of events on file (%d).",
451 size = 0; // Important to tell framework that nothing was generated.
455 // Create and initialise a new data block.
456 AliHLTMUONTriggerRecordsBlockWriter block(outputPtr, size);
457 if (not block.InitCommonHeader())
459 Logging(kHLTLogError,
460 "AliHLTMUONTriggerRecordsSource::GetEvent",
462 "There is not enough buffer space to create a new data block."
463 " We require at least %d bytes but the buffer is only %d bytes.",
464 sizeof(AliHLTMUONTriggerRecordsBlockWriter::HeaderType),
467 size = 0; // Important to tell framework that nothing was generated.
471 // Initialise the DDL list containing the DDLs which contributed to the
472 // data block. These are required to create the specification word later.
474 for (Int_t i = 0; i < 22; i++)
477 if (fMCDataInterface != NULL and fBuildFromHits)
479 Logging(kHLTLogDebug,
480 "AliHLTMUONTriggerRecordsSource::GetEvent",
482 "Filling data block with trigger records from GEANT hits for event %d.",
486 // Loop over all tracks, extract the hits from chambers 11 to 14 and
487 // create trigger records from them to write to the data block.
488 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
489 for (Int_t i = 0; i < ntracks; ++i)
491 AliMUONHit* hit11 = NULL;
492 AliMUONHit* hit12 = NULL;
493 AliMUONHit* hit13 = NULL;
494 AliMUONHit* hit14 = NULL;
500 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
502 TIter next(hitStore->CreateIterator());
503 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
505 // Select only hits on trigger chambers.
506 if (hit->Chamber() <= AliMUONConstants::NTrackingCh()) continue;
508 // Only select hits from the given part of the plane
509 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
510 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
512 // Workout which DDL this hit should be readout of.
513 Int_t ddl = FindDDLOfDetElement(hit->DetElemId());
514 if (not (0 <= ddl and ddl < 22))
517 Logging(kHLTLogError,
518 "AliHLTMUONTriggerRecordsSource::GetEvent",
520 "Could not find the DDL ID from which readout would take place."
524 switch (hit->Chamber())
526 case 11: hit11 = hit; ddl11 = ddl; break;
527 case 12: hit12 = hit; ddl12 = ddl; break;
528 case 13: hit13 = hit; ddl13 = ddl; break;
529 case 14: hit14 = hit; ddl14 = ddl; break;
534 // Check that there are at least 3 of 4 hits on the trigger chambers.
536 if (hit11 != NULL) hitCount++;
537 if (hit12 != NULL) hitCount++;
538 if (hit13 != NULL) hitCount++;
539 if (hit14 != NULL) hitCount++;
540 if (hitCount < 3) continue;
542 AliHLTMUONTriggerRecordStruct* trigRec = block.AddEntry();
545 Logging(kHLTLogError,
546 "AliHLTMUONTriggerRecordsSource::GetEvent",
548 "There is not enough buffer space to add more trigger records."
549 " We overflowed the buffer which is only %d bytes.",
552 size = 0; // Important to tell framework that nothing was generated.
556 // Fill the new trigger record with the hit information.
557 bool hitset[4] = {false, false, false, false};
558 AliHLTFloat32_t x1 = 0, y1 = 0, y2 = 0, z1 = 0, z2 = 0;
561 trigRec->fHit[0].fX = hit11->Xref();
562 trigRec->fHit[0].fY = hit11->Yref();
563 trigRec->fHit[0].fZ = hit11->Zref();
571 trigRec->fHit[1].fX = hit12->Xref();
572 trigRec->fHit[1].fY = hit12->Yref();
573 trigRec->fHit[1].fZ = hit12->Zref();
581 trigRec->fHit[2].fX = hit13->Xref();
582 trigRec->fHit[2].fY = hit13->Yref();
583 trigRec->fHit[2].fZ = hit13->Zref();
590 trigRec->fHit[3].fX = hit14->Xref();
591 trigRec->fHit[3].fY = hit14->Yref();
592 trigRec->fHit[3].fZ = hit14->Zref();
598 bool calculated = AliHLTMUONCalculations::ComputeMomentum(x1, y1, y2, z1, z2);
600 Logging(kHLTLogDebug,
601 "AliHLTMUONTriggerRecordsSource::GetEvent",
602 "Calculation failure",
603 "Something went wrong when calculating the momentum from"
604 " x1 = %f, y1 = %f, y2 = %f, z1 = %f, z2 = %f.",
608 trigRec->fId = trigRecId++;
609 trigRec->fFlags = AliHLTMUONUtils::PackTriggerRecordFlags(
610 AliHLTMUONCalculations::Sign(), hitset
612 trigRec->fPx = AliHLTMUONCalculations::Px();
613 trigRec->fPy = AliHLTMUONCalculations::Py();
614 trigRec->fPz = AliHLTMUONCalculations::Pz();
616 // Mark the DDLs over which this trigger record would be readout.
617 if (ddl11 != -1) ddlList[ddl11] = true;
618 if (ddl12 != -1) ddlList[ddl12] = true;
619 if (ddl13 != -1) ddlList[ddl13] = true;
620 if (ddl14 != -1) ddlList[ddl14] = true;
623 else if (fMCDataInterface != NULL and not fBuildFromHits)
625 Logging(kHLTLogDebug,
626 "AliHLTMUONTriggerRecordsSource::GetEvent",
628 "Filling data block with simulated local triggers for event %d.",
632 AliFatal("Sorry, -simdata option not yet implemented!");
635 else if (fDataInterface != NULL)
637 Logging(kHLTLogDebug,
638 "AliHLTMUONTriggerRecordsSource::GetEvent",
640 "Filling data block with reconstructed local triggers for event %d.",
644 AliFatal("Sorry, -recdata option not yet implemented!");
648 Logging(kHLTLogError,
649 "AliHLTMUONTriggerRecordsSource::GetEvent",
650 "Missing data interface",
651 "Neither AliMUONDataInterface nor AliMUONMCDataInterface were created."
653 size = 0; // Important to tell framework that nothing was generated.
657 AliHLTComponentBlockData bd;
661 bd.fSize = block.BytesUsed();
662 bd.fDataType = AliHLTMUONConstants::TriggerRecordsBlockDataType();
663 bd.fSpecification = AliHLTMUONUtils::PackSpecBits(ddlList);
664 outputBlocks.push_back(bd);
665 size = block.BytesUsed();