1 /**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
19 * @file AliHLTMUONRecHitsSource.cxx
20 * @author Artur Szostak <artursz@iafrica.com>
22 * @brief Implementation of the AliHLTMUONRecHitsSource component.
25 #include "AliHLTMUONRecHitsSource.h"
26 #include "AliHLTMUONConstants.h"
27 #include "AliHLTMUONDataBlockWriter.h"
28 #include "AliMUONMCDataInterface.h"
29 #include "AliMUONDataInterface.h"
30 #include "AliMUONHit.h"
31 #include "AliMUONRawCluster.h"
32 #include "AliMUONConstants.h"
33 #include "AliMUONVClusterStore.h"
34 #include "AliMUONVHitStore.h"
35 #include "TClonesArray.h"
44 // The global object used for automatic component registration.
45 // Note DO NOT use this component for calculation!
46 AliHLTMUONRecHitsSource gAliHLTMUONRecHitsSource;
50 ClassImp(AliHLTMUONRecHitsSource);
53 AliHLTMUONRecHitsSource::AliHLTMUONRecHitsSource() :
54 AliHLTOfflineDataSource(),
55 fMCDataInterface(NULL), fDataInterface(NULL),
56 fSelection(kWholePlane)
58 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
59 fServeChamber[i] = false;
63 AliHLTMUONRecHitsSource::~AliHLTMUONRecHitsSource()
65 assert( fMCDataInterface == NULL );
66 assert( fDataInterface == NULL );
70 int AliHLTMUONRecHitsSource::DoInit(int argc, const char** argv)
72 // Parse the command line arguments:
75 bool chamberWasSet = false;
77 for (int i = 0; i < argc; i++)
79 if (strcmp(argv[i], "-simdata") == 0)
83 else if (strcmp(argv[i], "-recdata") == 0)
87 else if (strcmp(argv[i], "-plane") == 0)
93 "AliHLTMUONRecHitsSource::DoInit",
95 "Expected one of 'left', 'right' or 'all' after '-plane'."
99 if (strcmp(argv[i], "left") == 0)
100 fSelection = kLeftPlane;
101 else if (strcmp(argv[i], "right") == 0)
102 fSelection = kRightPlane;
103 else if (strcmp(argv[i], "all") == 0)
104 fSelection = kWholePlane;
107 Logging(kHLTLogError,
108 "AliHLTMUONRecHitsSource::DoInit",
110 "The parameter '%s' is invalid and must be one of 'left',"
111 " 'right' or 'all'.",
117 else if (strcmp(argv[i], "-chamber") == 0)
122 Logging(kHLTLogError,
123 "AliHLTMUONRecHitsSource::DoInit",
125 "Expected a chamber number, range eg. '1-10' or list eg."
126 " '1,2,3' after '-chamber'."
130 int result = ParseChamberString(argv[i]);
131 if (result != 0) return result;
132 chamberWasSet = true;
136 Logging(kHLTLogError,
137 "AliHLTMUONRecHitsSource::DoInit",
139 "The argument '%s' is invalid.",
146 // Check the parameters we have parsed.
147 if (simdata and recdata)
149 Logging(kHLTLogError,
150 "AliHLTMUONRecHitsSource::DoInit",
152 "Cannot have both -simdata and -recdata set."
157 if (not simdata and not recdata)
159 Logging(kHLTLogError,
160 "AliHLTMUONRecHitsSource::DoInit",
162 "Must have either -simdata or -recdata specified."
167 if (not chamberWasSet)
170 "AliHLTMUONRecHitsSource::DoInit",
171 "Setting Parameters",
172 "No chambers were selected so we will publish for all chambers."
174 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
175 fServeChamber[i] = true;
178 // Now we can initialise the data interface objects and loaders.
181 Logging(kHLTLogDebug,
182 "AliHLTMUONRecHitsSource::DoInit",
184 "Loading simulated GEANT hits with AliMUONSimData."
189 fMCDataInterface = new AliMUONMCDataInterface("galice.root");
191 catch (const std::bad_alloc&)
193 Logging(kHLTLogError,
194 "AliHLTMUONRecHitsSource::DoInit",
196 "Not enough memory to allocate AliMUONMCDataInterface."
203 Logging(kHLTLogDebug,
204 "AliHLTMUONRecHitsSource::DoInit",
206 "Loading reconstructed clusters with AliMUONRecData."
211 fDataInterface = new AliMUONDataInterface("galice.root");
213 catch (const std::bad_alloc&)
215 Logging(kHLTLogError,
216 "AliHLTMUONRecHitsSource::DoInit",
218 "Not enough memory to allocate AliMUONDataInterface."
228 int AliHLTMUONRecHitsSource::DoDeinit()
230 delete fMCDataInterface;
231 fMCDataInterface = NULL;
232 delete fDataInterface;
233 fDataInterface = NULL;
238 const char* AliHLTMUONRecHitsSource::GetComponentID()
240 return AliHLTMUONConstants::RecHitsSourceId();
244 AliHLTComponentDataType AliHLTMUONRecHitsSource::GetOutputDataType()
246 return AliHLTMUONConstants::RecHitsBlockDataType();
250 void AliHLTMUONRecHitsSource::GetOutputDataSize(
251 unsigned long& constBase, double& inputMultiplier
254 constBase = sizeof(AliHLTMUONRecHitsBlockStruct) + 1024*4*8;
259 AliHLTComponent* AliHLTMUONRecHitsSource::Spawn()
261 return new AliHLTMUONRecHitsSource();
265 int AliHLTMUONRecHitsSource::GetEvent(
266 const AliHLTComponentEventData& evtData,
267 AliHLTComponentTriggerData& /*trigData*/,
268 AliHLTUInt8_t* outputPtr,
269 AliHLTUInt32_t& size,
270 vector<AliHLTComponentBlockData>& outputBlocks
273 assert( fMCDataInterface != NULL or fDataInterface != NULL );
275 // Check the size of the event descriptor structure.
276 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
278 Logging(kHLTLogError,
279 "AliHLTMUONRecHitsSource::GetEvent",
280 "Invalid event descriptor",
281 "The event descriptor (AliHLTComponentEventData) size is"
282 " smaller than expected. It claims to be %d bytes, but"
283 " we expect it to be %d bytes.",
285 sizeof(AliHLTComponentEventData)
287 size = 0; // Important to tell framework that nothing was generated.
291 // Use the fEventID as the event number to load, check it and load that
292 // event with the runloader.
293 UInt_t eventnumber = UInt_t(evtData.fEventID);
294 UInt_t maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
295 if ( eventnumber >= maxevent )
297 Logging(kHLTLogError,
298 "AliHLTMUONRecHitsSource::GetEvent",
300 "The event number (%d) is larger than the available number"
301 " of events on file (%d).",
305 size = 0; // Important to tell framework that nothing was generated.
309 // Create and initialise a new data block.
310 AliHLTMUONRecHitsBlockWriter block(outputPtr, size);
311 if (not block.InitCommonHeader())
313 Logging(kHLTLogError,
314 "AliHLTMUONRecHitsSource::GetEvent",
316 "There is not enough buffer space to create a new data block."
317 " We require at least %d bytes but the buffer is only %d bytes.",
318 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
321 size = 0; // Important to tell framework that nothing was generated.
325 if (fMCDataInterface != NULL)
327 Logging(kHLTLogDebug,
328 "AliHLTMUONRecHitsSource::GetEvent",
330 "Filling data block with GEANT hits for event %d.",
334 // Loop over all tracks, extract the hits and write them to the
336 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
337 for (Int_t i = 0; i < ntracks; ++i)
339 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
341 TIter next(hitStore->CreateIterator());
342 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
344 // Select only hits on selected chambers.
345 Int_t chamber = hit->Chamber() - 1;
346 if (chamber > AliMUONConstants::NTrackingCh()) continue;
347 if (not fServeChamber[chamber]) continue;
349 // Only select hits from the given part of the plane
350 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
351 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
353 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
356 Logging(kHLTLogError,
357 "AliHLTMUONRecHitsSource::GetEvent",
359 "There is not enough buffer space to add more hits."
360 " We overflowed the buffer which is only %d bytes.",
363 size = 0; // Important to tell framework that nothing was generated.
367 rechit->fX = hit->Xref();
368 rechit->fY = hit->Yref();
369 rechit->fZ = hit->Zref();
374 else if (fDataInterface != NULL)
376 Logging(kHLTLogDebug,
377 "AliHLTMUONRecHitsSource::GetEvent",
379 "Filling data block with reconstructed raw clusters for event %d.",
383 AliMUONVClusterStore* clusterStore = fDataInterface->ClusterStore(eventnumber);
385 // Loop over selected chambers and extract the raw clusters.
386 for (Int_t chamber = 0; chamber < AliMUONConstants::NTrackingCh(); chamber++)
388 // Select only hits on selected chambers.
389 if (not fServeChamber[chamber]) continue;
391 TIter next(clusterStore->CreateChamberIterator(chamber,chamber));
392 AliMUONRawCluster* cluster;
394 while ( ( cluster = static_cast<AliMUONRawCluster*>(next()) ) )
396 // Only select hits from the given part of the plane
397 if (fSelection == kLeftPlane and not (cluster->GetX() < 0)) continue;
398 if (fSelection == kRightPlane and not (cluster->GetX() >= 0)) continue;
400 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
403 Logging(kHLTLogError,
404 "AliHLTMUONRecHitsSource::GetEvent",
406 "There is not enough buffer space to add more hits."
407 " We overflowed the buffer which is only %d bytes.",
410 size = 0; // Important to tell framework that nothing was generated.
414 rechit->fX = cluster->GetX();
415 rechit->fY = cluster->GetY();
416 rechit->fZ = cluster->GetZ();
423 Logging(kHLTLogError,
424 "AliHLTMUONRecHitsSource::GetEvent",
425 "Missing data interface",
426 "Neither AliMUONSimData or AliMUONRecData were created."
428 size = 0; // Important to tell framework that nothing was generated.
432 AliHLTComponentBlockData bd;
436 bd.fSize = block.BytesUsed();
437 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
438 bd.fSpecification = 7;
439 outputBlocks.push_back(bd);
440 size = block.BytesUsed();
446 int AliHLTMUONRecHitsSource::ParseChamberString(const char* str)
448 char* end = const_cast<char*>(str);
449 long lastChamber = -1;
452 // Parse the next number.
454 long chamber = strtol(current, &end, 0);
456 // Check for parse errors of the number.
459 Logging(kHLTLogError,
460 "AliHLTMUONRecHitsSource::GetEvent",
462 "Expected a number in the range [1..%d] but got '%s'.",
463 AliMUONConstants::NTrackingCh(), current
467 if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
469 Logging(kHLTLogError,
470 "AliHLTMUONRecHitsSource::GetEvent",
472 "Got the chamber number %d which is outside the valid range of [1..%d].",
473 AliMUONConstants::NTrackingCh(), chamber
478 // Skip any whitespace after the number
479 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
481 // Check if we are dealing with a list or range, or if we are at
482 // the end of the string.
485 lastChamber = chamber;
489 else if (*end == ',')
491 assert( 1 <= chamber and chamber <= 10 );
492 fServeChamber[chamber-1] = true;
495 else if (*end == '\0')
497 assert( 1 <= chamber and chamber <= 10 );
498 fServeChamber[chamber-1] = true;
502 Logging(kHLTLogError,
503 "AliHLTMUONRecHitsSource::GetEvent",
505 "Could not understand parameter list '%s'. Expected '-', ','"
506 " or end of line but got '%c' at character %d.",
507 str, *end, (int)(end - str) +1
512 // Set the range of chambers to publish for.
516 if (lastChamber < chamber)
528 for (Int_t i = min; i <= max; i++)
529 fServeChamber[i-1] = true;
533 while (*end != '\0');