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 AliHLTMUONRecHitsSource.cxx
21 * @author Artur Szostak <artursz@iafrica.com>
23 * @brief Implementation of the AliHLTMUONRecHitsSource component.
26 #include "AliHLTMUONRecHitsSource.h"
27 #include "AliHLTMUONConstants.h"
28 #include "AliHLTMUONUtils.h"
29 #include "AliHLTMUONDataBlockWriter.h"
30 #include "AliMUONMCDataInterface.h"
31 #include "AliMUONDataInterface.h"
32 #include "AliMUONHit.h"
33 #include "AliMUONVCluster.h"
34 #include "AliMUONConstants.h"
35 #include "AliMUONVClusterStore.h"
36 #include "AliMUONVHitStore.h"
37 #include "mapping/AliMpCDB.h"
38 #include "mapping/AliMpDEManager.h"
39 #include "mapping/AliMpDetElement.h"
40 #include "TClonesArray.h"
49 // The global object used for automatic component registration.
50 // Note DO NOT use this component for calculation!
51 AliHLTMUONRecHitsSource gAliHLTMUONRecHitsSource;
55 ClassImp(AliHLTMUONRecHitsSource);
58 AliHLTMUONRecHitsSource::AliHLTMUONRecHitsSource() :
59 AliHLTOfflineDataSource(),
60 fMCDataInterface(NULL),
62 fSelection(kWholePlane),
65 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
66 fServeChamber[i] = false;
70 AliHLTMUONRecHitsSource::~AliHLTMUONRecHitsSource()
72 assert( fMCDataInterface == NULL );
73 assert( fDataInterface == NULL );
77 int AliHLTMUONRecHitsSource::DoInit(int argc, const char** argv)
79 assert( fMCDataInterface == NULL );
80 assert( fDataInterface == NULL );
82 // Parse the command line arguments:
85 bool chamberWasSet = false;
87 bool firstEventSet = false;
88 bool eventNumLitSet = false;
90 for (int i = 0; i < argc; i++)
92 if (strcmp(argv[i], "-simdata") == 0)
96 else if (strcmp(argv[i], "-recdata") == 0)
100 else if (strcmp(argv[i], "-plane") == 0)
105 Logging(kHLTLogError,
106 "AliHLTMUONRecHitsSource::DoInit",
108 "Expected one of 'left', 'right' or 'all' after '-plane'."
112 if (strcmp(argv[i], "left") == 0)
113 fSelection = kLeftPlane;
114 else if (strcmp(argv[i], "right") == 0)
115 fSelection = kRightPlane;
116 else if (strcmp(argv[i], "all") == 0)
117 fSelection = kWholePlane;
120 Logging(kHLTLogError,
121 "AliHLTMUONRecHitsSource::DoInit",
123 "The parameter '%s' is invalid and must be one of 'left',"
124 " 'right' or 'all'.",
130 else if (strcmp(argv[i], "-chamber") == 0)
135 Logging(kHLTLogError,
136 "AliHLTMUONRecHitsSource::DoInit",
138 "Expected a chamber number, range eg. '1-10' or list eg."
139 " '1,2,3' after '-chamber'."
143 int result = ParseChamberString(argv[i]);
144 if (result != 0) return result;
145 chamberWasSet = true;
147 else if (strcmp(argv[i], "-firstevent") == 0)
151 HLTWarning("The -firstevent flag is overridden by a"
152 " previous use of -event_number_literal."
158 HLTError("Expected a positive number after -firstevent.");
162 long num = strtol(argv[i], &end, 0);
163 if (*end != '\0' or num < 0) // Check if the conversion is OK.
166 "Expected a positive number after -firstevent"
167 " but got: %s", argv[i]
171 fCurrentEvent = Int_t(num);
172 firstEventSet = true;
174 else if (strcmp(argv[i], "-event_number_literal") == 0)
178 HLTWarning("The -event_number_literal option will"
179 " override -firstevent."
183 eventNumLitSet = true;
187 Logging(kHLTLogError,
188 "AliHLTMUONRecHitsSource::DoInit",
190 "The argument '%s' is invalid.",
197 // Check the parameters we have parsed.
198 if (simdata and recdata)
200 Logging(kHLTLogError,
201 "AliHLTMUONRecHitsSource::DoInit",
203 "Cannot have both -simdata and -recdata set."
208 if (not simdata and not recdata)
210 Logging(kHLTLogError,
211 "AliHLTMUONRecHitsSource::DoInit",
213 "Must have either -simdata or -recdata specified."
218 if (not chamberWasSet)
221 "AliHLTMUONRecHitsSource::DoInit",
222 "Setting Parameters",
223 "No chambers were selected so we will publish for all chambers."
225 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
226 fServeChamber[i] = true;
229 // Must load the mapping data for AliMpDetElement::GetDdlId()
230 // to return useful information later on.
231 AliMpCDB::LoadDDLStore();
233 // Now we can initialise the data interface objects and loaders.
236 Logging(kHLTLogDebug,
237 "AliHLTMUONRecHitsSource::DoInit",
239 "Loading simulated GEANT hits with AliMUONMCDataInterface."
244 fMCDataInterface = new AliMUONMCDataInterface("galice.root");
246 catch (const std::bad_alloc&)
248 Logging(kHLTLogError,
249 "AliHLTMUONRecHitsSource::DoInit",
251 "Not enough memory to allocate AliMUONMCDataInterface."
258 Logging(kHLTLogDebug,
259 "AliHLTMUONRecHitsSource::DoInit",
261 "Loading reconstructed clusters with AliMUONDataInterface."
266 fDataInterface = new AliMUONDataInterface("galice.root");
268 catch (const std::bad_alloc&)
270 Logging(kHLTLogError,
271 "AliHLTMUONRecHitsSource::DoInit",
273 "Not enough memory to allocate AliMUONDataInterface."
279 // Check that the fCurrentEvent number falls within the correct range.
281 if (fMCDataInterface != NULL)
282 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
283 else if (fDataInterface != NULL)
284 maxevent = UInt_t(fDataInterface->NumberOfEvents());
285 if (fCurrentEvent != -1 and UInt_t(fCurrentEvent) >= maxevent and maxevent != 0)
288 HLTWarning(Form("The selected first event number (%d) was larger than"
289 " the available number of events (%d). Resetting the event"
290 " counter to zero.", fCurrentEvent, maxevent
298 int AliHLTMUONRecHitsSource::DoDeinit()
300 if (fMCDataInterface != NULL)
302 delete fMCDataInterface;
303 fMCDataInterface = NULL;
305 if (fDataInterface != NULL)
307 delete fDataInterface;
308 fDataInterface = NULL;
314 const char* AliHLTMUONRecHitsSource::GetComponentID()
316 return AliHLTMUONConstants::RecHitsSourceId();
320 AliHLTComponentDataType AliHLTMUONRecHitsSource::GetOutputDataType()
322 return AliHLTMUONConstants::RecHitsBlockDataType();
326 void AliHLTMUONRecHitsSource::GetOutputDataSize(
327 unsigned long& constBase, double& inputMultiplier
330 constBase = sizeof(AliHLTMUONRecHitsBlockStruct)
331 + 256*16*sizeof(AliHLTMUONRecHitStruct);
336 AliHLTComponent* AliHLTMUONRecHitsSource::Spawn()
338 return new AliHLTMUONRecHitsSource();
342 int AliHLTMUONRecHitsSource::GetEvent(
343 const AliHLTComponentEventData& evtData,
344 AliHLTComponentTriggerData& /*trigData*/,
345 AliHLTUInt8_t* outputPtr,
346 AliHLTUInt32_t& size,
347 vector<AliHLTComponentBlockData>& outputBlocks
350 assert( fMCDataInterface != NULL or fDataInterface != NULL );
352 // Check the size of the event descriptor structure.
353 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
355 Logging(kHLTLogError,
356 "AliHLTMUONRecHitsSource::GetEvent",
357 "Invalid event descriptor",
358 "The event descriptor (AliHLTComponentEventData) size is"
359 " smaller than expected. It claims to be %d bytes, but"
360 " we expect it to be %d bytes.",
362 sizeof(AliHLTComponentEventData)
364 size = 0; // Important to tell framework that nothing was generated.
368 // Use the fEventID as the event number to load if fCurrentEvent == -1,
369 // check it and load that event with the runloader.
370 // If fCurrentEvent is a positive number then us it instead and
372 UInt_t eventnumber = UInt_t(evtData.fEventID);
373 UInt_t maxevent = fMCDataInterface != NULL ?
374 UInt_t(fMCDataInterface->NumberOfEvents())
375 : UInt_t(fDataInterface->NumberOfEvents());
376 if (fCurrentEvent != -1)
378 eventnumber = UInt_t(fCurrentEvent);
380 if (UInt_t(fCurrentEvent) >= maxevent)
383 if ( eventnumber >= maxevent )
385 Logging(kHLTLogError,
386 "AliHLTMUONRecHitsSource::GetEvent",
388 "The event number (%d) is larger than the available number"
389 " of events on file (%d).",
393 size = 0; // Important to tell framework that nothing was generated.
397 // Create and initialise a new data block.
398 AliHLTMUONRecHitsBlockWriter block(outputPtr, size);
399 if (not block.InitCommonHeader())
401 Logging(kHLTLogError,
402 "AliHLTMUONRecHitsSource::GetEvent",
404 "There is not enough buffer space to create a new data block."
405 " We require at least %d bytes but the buffer is only %d bytes.",
406 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
409 size = 0; // Important to tell framework that nothing was generated.
413 // Initialise the DDL list containing the DDLs which contributed to the
414 // data block. These are required to create the specification word later.
416 for (Int_t i = 0; i < 22; i++)
419 if (fMCDataInterface != NULL)
421 Logging(kHLTLogDebug,
422 "AliHLTMUONRecHitsSource::GetEvent",
424 "Filling data block with GEANT hits for event %d.",
428 // Loop over all tracks, extract the hits and write them to the
430 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
431 for (Int_t i = 0; i < ntracks; ++i)
433 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
435 TIter next(hitStore->CreateIterator());
436 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
438 // Select only hits on selected chambers.
439 Int_t chamber = hit->Chamber() - 1;
440 if (chamber > AliMUONConstants::NTrackingCh()) continue;
441 if (not fServeChamber[chamber]) continue;
443 // Only select hits from the given part of the plane
444 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
445 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
447 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
450 Logging(kHLTLogError,
451 "AliHLTMUONRecHitsSource::GetEvent",
453 "There is not enough buffer space to add more hits."
454 " We overflowed the buffer which is only %d bytes.",
457 size = 0; // Important to tell framework that nothing was generated.
461 rechit->fX = hit->Xref();
462 rechit->fY = hit->Yref();
463 rechit->fZ = hit->Zref();
465 // Workout which DDL this hit will be readout of.
466 AliMpDetElement* de = AliMpDEManager::GetDetElement(hit->DetElemId());
467 if (de != NULL and (0 <= de->GetDdlId() and de->GetDdlId() < 22))
468 ddlList[de->GetDdlId()] = true;
470 Logging(kHLTLogError,
471 "AliHLTMUONRecHitsSource::GetEvent",
473 "Could not find the DDL ID from which readout would take place."
478 else if (fDataInterface != NULL)
480 Logging(kHLTLogDebug,
481 "AliHLTMUONRecHitsSource::GetEvent",
483 "Filling data block with reconstructed raw clusters for event %d.",
487 AliMUONVClusterStore* clusterStore = fDataInterface->ClusterStore(eventnumber);
489 // Loop over selected chambers and extract the raw clusters.
490 for (Int_t chamber = 0; chamber < AliMUONConstants::NTrackingCh(); chamber++)
492 // Select only hits on selected chambers.
493 if (not fServeChamber[chamber]) continue;
495 TIter next(clusterStore->CreateChamberIterator(chamber,chamber));
496 AliMUONVCluster* cluster;
497 while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) )
499 // Only select hits from the given part of the plane
500 if (fSelection == kLeftPlane and not (cluster->GetX() < 0)) continue;
501 if (fSelection == kRightPlane and not (cluster->GetX() >= 0)) continue;
503 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
506 Logging(kHLTLogError,
507 "AliHLTMUONRecHitsSource::GetEvent",
509 "There is not enough buffer space to add more hits."
510 " We overflowed the buffer which is only %d bytes.",
513 size = 0; // Important to tell framework that nothing was generated.
517 rechit->fX = cluster->GetX();
518 rechit->fY = cluster->GetY();
519 rechit->fZ = cluster->GetZ();
521 // Workout which DDL this hit will be readout of.
522 AliMpDetElement* de = AliMpDEManager::GetDetElement(cluster->GetDetElemId());
523 if (de != NULL and (0 <= de->GetDdlId() and de->GetDdlId() < 22))
524 ddlList[de->GetDdlId()] = true;
526 Logging(kHLTLogError,
527 "AliHLTMUONRecHitsSource::GetEvent",
529 "Could not find the DDL ID from which readout would take place."
536 Logging(kHLTLogError,
537 "AliHLTMUONRecHitsSource::GetEvent",
538 "Missing data interface",
539 "Neither AliMUONDataInterface nor AliMUONMCDataInterface were created."
541 size = 0; // Important to tell framework that nothing was generated.
545 AliHLTComponentBlockData bd;
549 bd.fSize = block.BytesUsed();
550 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
551 bd.fSpecification = AliHLTMUONUtils::PackSpecBits(ddlList);
552 outputBlocks.push_back(bd);
553 size = block.BytesUsed();
559 int AliHLTMUONRecHitsSource::ParseChamberString(const char* str)
561 char* end = const_cast<char*>(str);
562 long lastChamber = -1;
565 // Parse the next number.
567 long chamber = strtol(current, &end, 0);
569 // Check for parse errors of the number.
572 Logging(kHLTLogError,
573 "AliHLTMUONRecHitsSource::GetEvent",
575 "Expected a number in the range [1..%d] but got '%s'.",
576 AliMUONConstants::NTrackingCh(), current
580 if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
582 Logging(kHLTLogError,
583 "AliHLTMUONRecHitsSource::GetEvent",
585 "Got the chamber number %d which is outside the valid range of [1..%d].",
586 chamber, AliMUONConstants::NTrackingCh()
591 // Skip any whitespace after the number
592 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
594 // Check if we are dealing with a list or range, or if we are at
595 // the end of the string.
598 lastChamber = chamber;
602 else if (*end == ',')
604 assert( 1 <= chamber and chamber <= 10 );
605 fServeChamber[chamber-1] = true;
608 else if (*end == '\0')
610 assert( 1 <= chamber and chamber <= 10 );
611 fServeChamber[chamber-1] = true;
615 Logging(kHLTLogError,
616 "AliHLTMUONRecHitsSource::GetEvent",
618 "Could not understand parameter list '%s'. Expected '-', ','"
619 " or end of line but got '%c' at character %d.",
620 str, *end, (int)(end - str) +1
625 // Set the range of chambers to publish for.
629 if (lastChamber < chamber)
641 for (Int_t i = min; i <= max; i++)
642 fServeChamber[i-1] = true;
646 while (*end != '\0');