Adding class AliHLTMUONTriggerRecordsSource
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONRecHitsSource.cxx
CommitLineData
3dd14e20 1/**************************************************************************
2 * Copyright(c) 1998-2007, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
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 **************************************************************************/
15
16/* $Id$ */
17
18/**
19 * @file AliHLTMUONRecHitsSource.cxx
20 * @author Artur Szostak <artursz@iafrica.com>
21 * @date
22 * @brief Implementation of the AliHLTMUONRecHitsSource component.
23 */
24
25#include "AliHLTMUONRecHitsSource.h"
26#include "AliHLTMUONConstants.h"
27#include "AliHLTMUONDataBlockWriter.h"
8d33d1c2 28#include "AliMUONMCDataInterface.h"
29#include "AliMUONDataInterface.h"
3dd14e20 30#include "AliMUONHit.h"
31#include "AliMUONRawCluster.h"
32#include "AliMUONConstants.h"
8d33d1c2 33#include "AliMUONVClusterStore.h"
34#include "AliMUONVHitStore.h"
3dd14e20 35#include "TClonesArray.h"
36#include <cstdlib>
37#include <cstdio>
38#include <cerrno>
39#include <cassert>
40#include <new>
41
5df25c2a 42namespace
43{
3dd14e20 44 // The global object used for automatic component registration.
45 // Note DO NOT use this component for calculation!
46 AliHLTMUONRecHitsSource gAliHLTMUONRecHitsSource;
5df25c2a 47}
3dd14e20 48
49
50ClassImp(AliHLTMUONRecHitsSource);
51
52
53AliHLTMUONRecHitsSource::AliHLTMUONRecHitsSource() :
54 AliHLTOfflineDataSource(),
8d33d1c2 55 fMCDataInterface(NULL), fDataInterface(NULL),
5df25c2a 56 fSelection(kWholePlane)
3dd14e20 57{
5df25c2a 58 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
59 fServeChamber[i] = false;
3dd14e20 60}
61
5df25c2a 62
3dd14e20 63AliHLTMUONRecHitsSource::~AliHLTMUONRecHitsSource()
64{
8d33d1c2 65 assert( fMCDataInterface == NULL );
66 assert( fDataInterface == NULL );
3dd14e20 67}
68
69
70int AliHLTMUONRecHitsSource::DoInit(int argc, const char** argv)
71{
72 // Parse the command line arguments:
73 bool simdata = false;
74 bool recdata = false;
5df25c2a 75 bool chamberWasSet = false;
76
77 for (int i = 0; i < argc; i++)
3dd14e20 78 {
5df25c2a 79 if (strcmp(argv[i], "-simdata") == 0)
80 {
3dd14e20 81 simdata = true;
5df25c2a 82 }
83 else if (strcmp(argv[i], "-recdata") == 0)
84 {
3dd14e20 85 recdata = true;
5df25c2a 86 }
87 else if (strcmp(argv[i], "-plane") == 0)
88 {
89 i++;
90 if (i >= argc)
91 {
92 Logging(kHLTLogError,
93 "AliHLTMUONRecHitsSource::DoInit",
94 "Missing parameter",
95 "Expected one of 'left', 'right' or 'all' after '-plane'."
96 );
97 return EINVAL;
98 }
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;
105 else
106 {
107 Logging(kHLTLogError,
108 "AliHLTMUONRecHitsSource::DoInit",
109 "Invalid parameter",
110 "The parameter '%s' is invalid and must be one of 'left',"
111 " 'right' or 'all'.",
112 argv[i]
113 );
114 return EINVAL;
115 }
116 }
117 else if (strcmp(argv[i], "-chamber") == 0)
118 {
119 i++;
120 if (i >= argc)
121 {
122 Logging(kHLTLogError,
123 "AliHLTMUONRecHitsSource::DoInit",
124 "Missing parameter",
125 "Expected a chamber number, range eg. '1-10' or list eg."
126 " '1,2,3' after '-chamber'."
127 );
128 return EINVAL;
129 }
130 int result = ParseChamberString(argv[i]);
131 if (result != 0) return result;
132 chamberWasSet = true;
133 }
3dd14e20 134 else
135 {
136 Logging(kHLTLogError,
137 "AliHLTMUONRecHitsSource::DoInit",
138 "Unknown argument",
139 "The argument '%s' is invalid.",
140 argv[i]
141 );
142 return EINVAL;
143 }
144 }
145
146 // Check the parameters we have parsed.
147 if (simdata and recdata)
148 {
149 Logging(kHLTLogError,
150 "AliHLTMUONRecHitsSource::DoInit",
151 "Invalid arguments",
152 "Cannot have both -simdata and -recdata set."
153 );
154 return EINVAL;
155 }
156
157 if (not simdata and not recdata)
158 {
159 Logging(kHLTLogError,
160 "AliHLTMUONRecHitsSource::DoInit",
161 "Missing arguments",
162 "Must have either -simdata or -recdata specified."
163 );
164 return EINVAL;
165 }
166
5df25c2a 167 if (not chamberWasSet)
168 {
169 Logging(kHLTLogInfo,
170 "AliHLTMUONRecHitsSource::DoInit",
171 "Setting Parameters",
172 "No chambers were selected so we will publish for all chambers."
173 );
174 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
175 fServeChamber[i] = true;
176 }
177
3dd14e20 178 // Now we can initialise the data interface objects and loaders.
179 if (simdata)
180 {
5df25c2a 181 Logging(kHLTLogDebug,
182 "AliHLTMUONRecHitsSource::DoInit",
183 "Data interface",
184 "Loading simulated GEANT hits with AliMUONSimData."
185 );
186
3dd14e20 187 try
188 {
8d33d1c2 189 fMCDataInterface = new AliMUONMCDataInterface("galice.root");
3dd14e20 190 }
191 catch (const std::bad_alloc&)
192 {
193 Logging(kHLTLogError,
194 "AliHLTMUONRecHitsSource::DoInit",
195 "Out of memory",
8d33d1c2 196 "Not enough memory to allocate AliMUONMCDataInterface."
3dd14e20 197 );
198 return ENOMEM;
199 }
3dd14e20 200 }
201 else if (recdata)
202 {
5df25c2a 203 Logging(kHLTLogDebug,
204 "AliHLTMUONRecHitsSource::DoInit",
205 "Data interface",
206 "Loading reconstructed clusters with AliMUONRecData."
207 );
208
3dd14e20 209 try
210 {
8d33d1c2 211 fDataInterface = new AliMUONDataInterface("galice.root");
3dd14e20 212 }
213 catch (const std::bad_alloc&)
214 {
215 Logging(kHLTLogError,
216 "AliHLTMUONRecHitsSource::DoInit",
217 "Out of memory",
8d33d1c2 218 "Not enough memory to allocate AliMUONDataInterface."
3dd14e20 219 );
220 return ENOMEM;
221 }
3dd14e20 222 }
223
3dd14e20 224 return 0;
225}
226
227
228int AliHLTMUONRecHitsSource::DoDeinit()
229{
8d33d1c2 230 delete fMCDataInterface;
231 fMCDataInterface = NULL;
232 delete fDataInterface;
233 fDataInterface = NULL;
3dd14e20 234 return 0;
235}
236
237
238const char* AliHLTMUONRecHitsSource::GetComponentID()
239{
240 return AliHLTMUONConstants::RecHitsSourceId();
241}
242
5df25c2a 243
3dd14e20 244AliHLTComponentDataType AliHLTMUONRecHitsSource::GetOutputDataType()
245{
246 return AliHLTMUONConstants::RecHitsBlockDataType();
247}
248
5df25c2a 249
3dd14e20 250void AliHLTMUONRecHitsSource::GetOutputDataSize(
251 unsigned long& constBase, double& inputMultiplier
252 )
253{
5df25c2a 254 constBase = sizeof(AliHLTMUONRecHitsBlockStruct) + 1024*4*8;
255 inputMultiplier = 0;
3dd14e20 256}
257
5df25c2a 258
3dd14e20 259AliHLTComponent* AliHLTMUONRecHitsSource::Spawn()
260{
261 return new AliHLTMUONRecHitsSource();
262}
263
264
265int AliHLTMUONRecHitsSource::GetEvent(
266 const AliHLTComponentEventData& evtData,
8d33d1c2 267 AliHLTComponentTriggerData& /*trigData*/,
3dd14e20 268 AliHLTUInt8_t* outputPtr,
269 AliHLTUInt32_t& size,
270 vector<AliHLTComponentBlockData>& outputBlocks
271 )
272{
8d33d1c2 273 assert( fMCDataInterface != NULL or fDataInterface != NULL );
3dd14e20 274
275 // Check the size of the event descriptor structure.
276 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
277 {
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.",
284 evtData.fStructSize,
285 sizeof(AliHLTComponentEventData)
286 );
287 size = 0; // Important to tell framework that nothing was generated.
288 return EINVAL;
289 }
290
291 // Use the fEventID as the event number to load, check it and load that
292 // event with the runloader.
5df25c2a 293 UInt_t eventnumber = UInt_t(evtData.fEventID);
8d33d1c2 294 UInt_t maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
295 if ( eventnumber >= maxevent )
3dd14e20 296 {
297 Logging(kHLTLogError,
298 "AliHLTMUONRecHitsSource::GetEvent",
299 "Bad event ID",
300 "The event number (%d) is larger than the available number"
301 " of events on file (%d).",
302 eventnumber,
8d33d1c2 303 maxevent
304 );
3dd14e20 305 size = 0; // Important to tell framework that nothing was generated.
306 return EINVAL;
307 }
3dd14e20 308
309 // Create and initialise a new data block.
310 AliHLTMUONRecHitsBlockWriter block(outputPtr, size);
311 if (not block.InitCommonHeader())
312 {
313 Logging(kHLTLogError,
314 "AliHLTMUONRecHitsSource::GetEvent",
315 "Buffer too small",
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),
319 block.BufferSize()
320 );
321 size = 0; // Important to tell framework that nothing was generated.
322 return ENOBUFS;
323 }
324
8d33d1c2 325 if (fMCDataInterface != NULL)
3dd14e20 326 {
5df25c2a 327 Logging(kHLTLogDebug,
328 "AliHLTMUONRecHitsSource::GetEvent",
329 "Filling hits",
330 "Filling data block with GEANT hits for event %d.",
331 eventnumber
332 );
333
3dd14e20 334 // Loop over all tracks, extract the hits and write them to the
335 // data block.
8d33d1c2 336 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
337 for (Int_t i = 0; i < ntracks; ++i)
3dd14e20 338 {
8d33d1c2 339 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
340 AliMUONHit* hit;
341 TIter next(hitStore->CreateIterator());
342 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
343 {
5df25c2a 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;
348
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;
3dd14e20 352
353 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
354 if (rechit == NULL)
355 {
356 Logging(kHLTLogError,
357 "AliHLTMUONRecHitsSource::GetEvent",
358 "Buffer overflow",
359 "There is not enough buffer space to add more hits."
360 " We overflowed the buffer which is only %d bytes.",
361 block.BufferSize()
362 );
3dd14e20 363 size = 0; // Important to tell framework that nothing was generated.
364 return ENOBUFS;
365 }
366
367 rechit->fX = hit->Xref();
368 rechit->fY = hit->Yref();
369 rechit->fZ = hit->Zref();
370 }
8d33d1c2 371 delete hitStore;
3dd14e20 372 }
373 }
8d33d1c2 374 else if (fDataInterface != NULL)
3dd14e20 375 {
5df25c2a 376 Logging(kHLTLogDebug,
377 "AliHLTMUONRecHitsSource::GetEvent",
378 "Filling hits",
379 "Filling data block with reconstructed raw clusters for event %d.",
380 eventnumber
381 );
382
8d33d1c2 383 AliMUONVClusterStore* clusterStore = fDataInterface->ClusterStore(eventnumber);
384
5df25c2a 385 // Loop over selected chambers and extract the raw clusters.
8d33d1c2 386 for (Int_t chamber = 0; chamber < AliMUONConstants::NTrackingCh(); chamber++)
3dd14e20 387 {
5df25c2a 388 // Select only hits on selected chambers.
389 if (not fServeChamber[chamber]) continue;
3dd14e20 390
8d33d1c2 391 TIter next(clusterStore->CreateChamberIterator(chamber,chamber));
392 AliMUONRawCluster* cluster;
393
394 while ( ( cluster = static_cast<AliMUONRawCluster*>(next()) ) )
395 {
5df25c2a 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;
3dd14e20 399
5df25c2a 400 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
401 if (rechit == NULL)
402 {
403 Logging(kHLTLogError,
404 "AliHLTMUONRecHitsSource::GetEvent",
405 "Buffer overflow",
406 "There is not enough buffer space to add more hits."
407 " We overflowed the buffer which is only %d bytes.",
408 block.BufferSize()
409 );
5df25c2a 410 size = 0; // Important to tell framework that nothing was generated.
411 return ENOBUFS;
412 }
413
414 rechit->fX = cluster->GetX();
415 rechit->fY = cluster->GetY();
416 rechit->fZ = cluster->GetZ();
417 }
3dd14e20 418 }
8d33d1c2 419 delete clusterStore;
3dd14e20 420 }
421 else
422 {
423 Logging(kHLTLogError,
424 "AliHLTMUONRecHitsSource::GetEvent",
425 "Missing data interface",
426 "Neither AliMUONSimData or AliMUONRecData were created."
427 );
428 size = 0; // Important to tell framework that nothing was generated.
429 return EFAULT;
430 }
5df25c2a 431
432 AliHLTComponentBlockData bd;
433 FillBlockData(bd);
434 bd.fPtr = outputPtr;
435 bd.fOffset = 0;
436 bd.fSize = block.BytesUsed();
437 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
438 bd.fSpecification = 7;
439 outputBlocks.push_back(bd);
440 size = block.BytesUsed();
3dd14e20 441
442 return 0;
443}
5df25c2a 444
445
446int AliHLTMUONRecHitsSource::ParseChamberString(const char* str)
447{
448 char* end = const_cast<char*>(str);
449 long lastChamber = -1;
450 do
451 {
452 // Parse the next number.
453 char* current = end;
454 long chamber = strtol(current, &end, 0);
455
456 // Check for parse errors of the number.
457 if (current == end)
458 {
459 Logging(kHLTLogError,
460 "AliHLTMUONRecHitsSource::GetEvent",
461 "Parse error",
462 "Expected a number in the range [1..%d] but got '%s'.",
463 AliMUONConstants::NTrackingCh(), current
464 );
465 return EINVAL;
466 }
467 if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
468 {
469 Logging(kHLTLogError,
470 "AliHLTMUONRecHitsSource::GetEvent",
471 "Parse error",
472 "Got the chamber number %d which is outside the valid range of [1..%d].",
473 AliMUONConstants::NTrackingCh(), chamber
474 );
475 return EINVAL;
476 }
477
478 // Skip any whitespace after the number
479 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
480
481 // Check if we are dealing with a list or range, or if we are at
482 // the end of the string.
483 if (*end == '-')
484 {
485 lastChamber = chamber;
486 end++;
487 continue;
488 }
489 else if (*end == ',')
490 {
491 assert( 1 <= chamber and chamber <= 10 );
492 fServeChamber[chamber-1] = true;
493 end++;
494 }
495 else if (*end == '\0')
496 {
497 assert( 1 <= chamber and chamber <= 10 );
498 fServeChamber[chamber-1] = true;
499 }
500 else
501 {
502 Logging(kHLTLogError,
503 "AliHLTMUONRecHitsSource::GetEvent",
504 "Parse error",
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
508 );
509 return EINVAL;
510 }
511
512 // Set the range of chambers to publish for.
513 if (lastChamber > 0)
514 {
515 Int_t min, max;
516 if (lastChamber < chamber)
517 {
518 min = lastChamber;
519 max = chamber;
520 }
521 else
522 {
523 min = chamber;
524 max = lastChamber;
525 }
526 assert( min >= 1 );
527 assert( max <= 10 );
528 for (Int_t i = min; i <= max; i++)
529 fServeChamber[i-1] = true;
530 }
531 lastChamber = -1;
532 }
533 while (*end != '\0');
534 return 0;
535}