]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/MUON/OfflineInterface/AliHLTMUONRecHitsSource.cxx
Filling out AliHLTMUONDigitPublisherComponent code to generate dimuon raw data on...
[u/mrichter/AliRoot.git] / HLT / MUON / OfflineInterface / AliHLTMUONRecHitsSource.cxx
CommitLineData
3dd14e20 1/**************************************************************************
d328bad2 2 * This file is property of and copyright by the ALICE HLT Project *
bef07620 3 * All rights reserved. *
3dd14e20 4 * *
bef07620 5 * Primary Authors: *
6 * Artur Szostak <artursz@iafrica.com> *
3dd14e20 7 * *
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 *
d328bad2 13 * about the suitability of this software for any purpose. It is *
3dd14e20 14 * provided "as is" without express or implied warranty. *
15 **************************************************************************/
16
17/* $Id$ */
18
6253e09b 19///
20/// @file AliHLTMUONRecHitsSource.cxx
21/// @author Artur Szostak <artursz@iafrica.com>
22/// @date
23/// @brief Implementation of the AliHLTMUONRecHitsSource component.
24///
3dd14e20 25
26#include "AliHLTMUONRecHitsSource.h"
27#include "AliHLTMUONConstants.h"
bef07620 28#include "AliHLTMUONUtils.h"
3dd14e20 29#include "AliHLTMUONDataBlockWriter.h"
8d33d1c2 30#include "AliMUONMCDataInterface.h"
31#include "AliMUONDataInterface.h"
3dd14e20 32#include "AliMUONHit.h"
8c58b039 33#include "AliMUONVCluster.h"
3dd14e20 34#include "AliMUONConstants.h"
8d33d1c2 35#include "AliMUONVClusterStore.h"
36#include "AliMUONVHitStore.h"
bef07620 37#include "mapping/AliMpCDB.h"
38#include "mapping/AliMpDEManager.h"
39#include "mapping/AliMpDetElement.h"
3dd14e20 40#include <cstdlib>
41#include <cstdio>
42#include <cerrno>
43#include <cassert>
44#include <new>
45
3dd14e20 46ClassImp(AliHLTMUONRecHitsSource);
47
48
49AliHLTMUONRecHitsSource::AliHLTMUONRecHitsSource() :
50 AliHLTOfflineDataSource(),
c06fe66f 51 fMCDataInterface(NULL),
52 fDataInterface(NULL),
53 fSelection(kWholePlane),
6253e09b 54 fCurrentEventIndex(0)
3dd14e20 55{
6253e09b 56 ///
57 /// Default constructor.
58 ///
59
5df25c2a 60 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
61 fServeChamber[i] = false;
3dd14e20 62}
63
5df25c2a 64
3dd14e20 65AliHLTMUONRecHitsSource::~AliHLTMUONRecHitsSource()
66{
6253e09b 67 ///
68 /// Default destructor.
69 ///
70
2ee47a65 71 if (fMCDataInterface != NULL) delete fMCDataInterface;
72 if (fDataInterface != NULL) delete fDataInterface;
3dd14e20 73}
74
75
76int AliHLTMUONRecHitsSource::DoInit(int argc, const char** argv)
77{
6253e09b 78 ///
79 /// Inherited from AliHLTComponent.
80 /// Parses the command line parameters and initialises the component.
81 ///
2ee47a65 82
83 HLTInfo("Initialising dHLT reconstructed hit source component.");
6253e09b 84
2ee47a65 85 if (fMCDataInterface != NULL)
86 {
87 delete fMCDataInterface;
88 fMCDataInterface = NULL;
89 }
90 if (fDataInterface != NULL)
91 {
92 delete fDataInterface;
93 fDataInterface = NULL;
94 }
bef07620 95
3dd14e20 96 // Parse the command line arguments:
97 bool simdata = false;
98 bool recdata = false;
5df25c2a 99 bool chamberWasSet = false;
6253e09b 100 fCurrentEventIndex = 0;
c06fe66f 101 bool firstEventSet = false;
102 bool eventNumLitSet = false;
5df25c2a 103
104 for (int i = 0; i < argc; i++)
3dd14e20 105 {
5df25c2a 106 if (strcmp(argv[i], "-simdata") == 0)
107 {
3dd14e20 108 simdata = true;
5df25c2a 109 }
110 else if (strcmp(argv[i], "-recdata") == 0)
111 {
3dd14e20 112 recdata = true;
5df25c2a 113 }
114 else if (strcmp(argv[i], "-plane") == 0)
115 {
116 i++;
117 if (i >= argc)
118 {
119 Logging(kHLTLogError,
120 "AliHLTMUONRecHitsSource::DoInit",
121 "Missing parameter",
122 "Expected one of 'left', 'right' or 'all' after '-plane'."
123 );
d328bad2 124 return -EINVAL;
5df25c2a 125 }
126 if (strcmp(argv[i], "left") == 0)
127 fSelection = kLeftPlane;
128 else if (strcmp(argv[i], "right") == 0)
129 fSelection = kRightPlane;
130 else if (strcmp(argv[i], "all") == 0)
131 fSelection = kWholePlane;
132 else
133 {
134 Logging(kHLTLogError,
135 "AliHLTMUONRecHitsSource::DoInit",
136 "Invalid parameter",
137 "The parameter '%s' is invalid and must be one of 'left',"
138 " 'right' or 'all'.",
139 argv[i]
140 );
d328bad2 141 return -EINVAL;
5df25c2a 142 }
143 }
144 else if (strcmp(argv[i], "-chamber") == 0)
145 {
146 i++;
147 if (i >= argc)
148 {
149 Logging(kHLTLogError,
150 "AliHLTMUONRecHitsSource::DoInit",
151 "Missing parameter",
152 "Expected a chamber number, range eg. '1-10' or list eg."
153 " '1,2,3' after '-chamber'."
154 );
d328bad2 155 return -EINVAL;
5df25c2a 156 }
157 int result = ParseChamberString(argv[i]);
158 if (result != 0) return result;
159 chamberWasSet = true;
160 }
c06fe66f 161 else if (strcmp(argv[i], "-firstevent") == 0)
162 {
163 if (eventNumLitSet)
164 {
165 HLTWarning("The -firstevent flag is overridden by a"
166 " previous use of -event_number_literal."
167 );
168 }
169 i++;
170 if (i >= argc)
171 {
172 HLTError("Expected a positive number after -firstevent.");
d328bad2 173 return -EINVAL;
c06fe66f 174 }
175 char* end = "";
176 long num = strtol(argv[i], &end, 0);
177 if (*end != '\0' or num < 0) // Check if the conversion is OK.
178 {
d328bad2 179 HLTError(
c06fe66f 180 "Expected a positive number after -firstevent"
181 " but got: %s", argv[i]
d328bad2 182 );
183 return -EINVAL;
c06fe66f 184 }
6253e09b 185 fCurrentEventIndex = Int_t(num);
c06fe66f 186 firstEventSet = true;
187 }
188 else if (strcmp(argv[i], "-event_number_literal") == 0)
189 {
190 if (firstEventSet)
191 {
192 HLTWarning("The -event_number_literal option will"
193 " override -firstevent."
194 );
195 }
6253e09b 196 fCurrentEventIndex = -1;
c06fe66f 197 eventNumLitSet = true;
198 }
3dd14e20 199 else
200 {
201 Logging(kHLTLogError,
202 "AliHLTMUONRecHitsSource::DoInit",
203 "Unknown argument",
204 "The argument '%s' is invalid.",
205 argv[i]
206 );
d328bad2 207 return -EINVAL;
3dd14e20 208 }
209 }
210
211 // Check the parameters we have parsed.
212 if (simdata and recdata)
213 {
214 Logging(kHLTLogError,
215 "AliHLTMUONRecHitsSource::DoInit",
216 "Invalid arguments",
217 "Cannot have both -simdata and -recdata set."
218 );
d328bad2 219 return -EINVAL;
3dd14e20 220 }
221
222 if (not simdata and not recdata)
223 {
224 Logging(kHLTLogError,
225 "AliHLTMUONRecHitsSource::DoInit",
226 "Missing arguments",
227 "Must have either -simdata or -recdata specified."
228 );
d328bad2 229 return -EINVAL;
3dd14e20 230 }
231
5df25c2a 232 if (not chamberWasSet)
233 {
234 Logging(kHLTLogInfo,
235 "AliHLTMUONRecHitsSource::DoInit",
236 "Setting Parameters",
237 "No chambers were selected so we will publish for all chambers."
238 );
239 for (Int_t i = 0; i < AliMUONConstants::NTrackingCh(); i++)
240 fServeChamber[i] = true;
241 }
242
bef07620 243 // Must load the mapping data for AliMpDetElement::GetDdlId()
244 // to return useful information later on.
245 AliMpCDB::LoadDDLStore();
246
3dd14e20 247 // Now we can initialise the data interface objects and loaders.
248 if (simdata)
249 {
5df25c2a 250 Logging(kHLTLogDebug,
251 "AliHLTMUONRecHitsSource::DoInit",
252 "Data interface",
bef07620 253 "Loading simulated GEANT hits with AliMUONMCDataInterface."
5df25c2a 254 );
bef07620 255
3dd14e20 256 try
257 {
8d33d1c2 258 fMCDataInterface = new AliMUONMCDataInterface("galice.root");
3dd14e20 259 }
260 catch (const std::bad_alloc&)
261 {
262 Logging(kHLTLogError,
263 "AliHLTMUONRecHitsSource::DoInit",
264 "Out of memory",
8d33d1c2 265 "Not enough memory to allocate AliMUONMCDataInterface."
3dd14e20 266 );
d328bad2 267 return -ENOMEM;
3dd14e20 268 }
3dd14e20 269 }
270 else if (recdata)
271 {
5df25c2a 272 Logging(kHLTLogDebug,
273 "AliHLTMUONRecHitsSource::DoInit",
274 "Data interface",
bef07620 275 "Loading reconstructed clusters with AliMUONDataInterface."
5df25c2a 276 );
277
3dd14e20 278 try
279 {
8d33d1c2 280 fDataInterface = new AliMUONDataInterface("galice.root");
3dd14e20 281 }
282 catch (const std::bad_alloc&)
283 {
284 Logging(kHLTLogError,
285 "AliHLTMUONRecHitsSource::DoInit",
286 "Out of memory",
8d33d1c2 287 "Not enough memory to allocate AliMUONDataInterface."
3dd14e20 288 );
d328bad2 289 return -ENOMEM;
3dd14e20 290 }
3dd14e20 291 }
292
6253e09b 293 // Check that the fCurrentEventIndex number falls within the correct range.
c06fe66f 294 UInt_t maxevent = 0;
295 if (fMCDataInterface != NULL)
296 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
297 else if (fDataInterface != NULL)
298 maxevent = UInt_t(fDataInterface->NumberOfEvents());
6253e09b 299 if (fCurrentEventIndex != -1 and UInt_t(fCurrentEventIndex) >= maxevent and maxevent != 0)
c06fe66f 300 {
6253e09b 301 fCurrentEventIndex = 0;
c06fe66f 302 HLTWarning(Form("The selected first event number (%d) was larger than"
303 " the available number of events (%d). Resetting the event"
6253e09b 304 " counter to zero.", fCurrentEventIndex, maxevent
c06fe66f 305 ));
306 }
307
3dd14e20 308 return 0;
309}
310
311
312int AliHLTMUONRecHitsSource::DoDeinit()
313{
6253e09b 314 ///
315 /// Inherited from AliHLTComponent. Performs a cleanup of the component.
316 ///
317
2ee47a65 318 HLTInfo("Deinitialising dHLT reconstructed hit source component.");
319
bef07620 320 if (fMCDataInterface != NULL)
321 {
322 delete fMCDataInterface;
323 fMCDataInterface = NULL;
324 }
325 if (fDataInterface != NULL)
326 {
327 delete fDataInterface;
328 fDataInterface = NULL;
329 }
3dd14e20 330 return 0;
331}
332
333
334const char* AliHLTMUONRecHitsSource::GetComponentID()
335{
6253e09b 336 ///
337 /// Inherited from AliHLTComponent. Returns the component ID.
338 ///
339
3dd14e20 340 return AliHLTMUONConstants::RecHitsSourceId();
341}
342
5df25c2a 343
3dd14e20 344AliHLTComponentDataType AliHLTMUONRecHitsSource::GetOutputDataType()
345{
6253e09b 346 ///
347 /// Inherited from AliHLTComponent. Returns the output data type.
348 ///
349
3dd14e20 350 return AliHLTMUONConstants::RecHitsBlockDataType();
351}
352
5df25c2a 353
3dd14e20 354void AliHLTMUONRecHitsSource::GetOutputDataSize(
355 unsigned long& constBase, double& inputMultiplier
356 )
357{
6253e09b 358 ///
359 /// Inherited from AliHLTComponent. Returns an estimate of the expected output data size.
360 ///
361
bef07620 362 constBase = sizeof(AliHLTMUONRecHitsBlockStruct)
363 + 256*16*sizeof(AliHLTMUONRecHitStruct);
5df25c2a 364 inputMultiplier = 0;
3dd14e20 365}
366
5df25c2a 367
3dd14e20 368AliHLTComponent* AliHLTMUONRecHitsSource::Spawn()
369{
6253e09b 370 ///
371 /// Inherited from AliHLTComponent. Creates a new object instance.
372 ///
373
3dd14e20 374 return new AliHLTMUONRecHitsSource();
375}
376
377
378int AliHLTMUONRecHitsSource::GetEvent(
379 const AliHLTComponentEventData& evtData,
8d33d1c2 380 AliHLTComponentTriggerData& /*trigData*/,
3dd14e20 381 AliHLTUInt8_t* outputPtr,
382 AliHLTUInt32_t& size,
383 vector<AliHLTComponentBlockData>& outputBlocks
384 )
385{
6253e09b 386 ///
387 /// Inherited from AliHLTOfflineDataSource. Creates new event data blocks.
388 ///
389
8d33d1c2 390 assert( fMCDataInterface != NULL or fDataInterface != NULL );
3dd14e20 391
392 // Check the size of the event descriptor structure.
393 if (evtData.fStructSize < sizeof(AliHLTComponentEventData))
394 {
395 Logging(kHLTLogError,
396 "AliHLTMUONRecHitsSource::GetEvent",
397 "Invalid event descriptor",
398 "The event descriptor (AliHLTComponentEventData) size is"
399 " smaller than expected. It claims to be %d bytes, but"
400 " we expect it to be %d bytes.",
401 evtData.fStructSize,
402 sizeof(AliHLTComponentEventData)
403 );
404 size = 0; // Important to tell framework that nothing was generated.
d328bad2 405 return -EINVAL;
3dd14e20 406 }
407
6253e09b 408 // Use the fEventID as the event number to load if fCurrentEventIndex == -1,
c06fe66f 409 // check it and load that event with the runloader.
2ee47a65 410 // If fCurrentEventIndex is a positive number then use it instead and
c06fe66f 411 // increment it.
5df25c2a 412 UInt_t eventnumber = UInt_t(evtData.fEventID);
2ee47a65 413 UInt_t maxevent = 0;
414 if (fMCDataInterface != NULL)
415 maxevent = UInt_t(fMCDataInterface->NumberOfEvents());
416 else if (fDataInterface != NULL)
417 maxevent = UInt_t(fDataInterface->NumberOfEvents());
6253e09b 418 if (fCurrentEventIndex != -1)
c06fe66f 419 {
6253e09b 420 eventnumber = UInt_t(fCurrentEventIndex);
421 fCurrentEventIndex++;
422 if (UInt_t(fCurrentEventIndex) >= maxevent)
423 fCurrentEventIndex = 0;
c06fe66f 424 }
8d33d1c2 425 if ( eventnumber >= maxevent )
3dd14e20 426 {
427 Logging(kHLTLogError,
428 "AliHLTMUONRecHitsSource::GetEvent",
429 "Bad event ID",
430 "The event number (%d) is larger than the available number"
431 " of events on file (%d).",
432 eventnumber,
bef07620 433 maxevent
434 );
3dd14e20 435 size = 0; // Important to tell framework that nothing was generated.
d328bad2 436 return -EINVAL;
3dd14e20 437 }
3dd14e20 438
439 // Create and initialise a new data block.
440 AliHLTMUONRecHitsBlockWriter block(outputPtr, size);
441 if (not block.InitCommonHeader())
442 {
443 Logging(kHLTLogError,
444 "AliHLTMUONRecHitsSource::GetEvent",
445 "Buffer too small",
446 "There is not enough buffer space to create a new data block."
447 " We require at least %d bytes but the buffer is only %d bytes.",
448 sizeof(AliHLTMUONRecHitsBlockWriter::HeaderType),
449 block.BufferSize()
450 );
451 size = 0; // Important to tell framework that nothing was generated.
d328bad2 452 return -ENOBUFS;
3dd14e20 453 }
454
bef07620 455 // Initialise the DDL list containing the DDLs which contributed to the
456 // data block. These are required to create the specification word later.
457 bool ddlList[22];
458 for (Int_t i = 0; i < 22; i++)
459 ddlList[i] = false;
460
8d33d1c2 461 if (fMCDataInterface != NULL)
3dd14e20 462 {
5df25c2a 463 Logging(kHLTLogDebug,
464 "AliHLTMUONRecHitsSource::GetEvent",
465 "Filling hits",
466 "Filling data block with GEANT hits for event %d.",
467 eventnumber
468 );
469
3dd14e20 470 // Loop over all tracks, extract the hits and write them to the
471 // data block.
bef07620 472 Int_t ntracks = fMCDataInterface->NumberOfTracks(eventnumber);
8d33d1c2 473 for (Int_t i = 0; i < ntracks; ++i)
3dd14e20 474 {
bef07620 475 AliMUONVHitStore* hitStore = fMCDataInterface->HitStore(eventnumber,i);
476 AliMUONHit* hit;
477 TIter next(hitStore->CreateIterator());
478 while ( ( hit = static_cast<AliMUONHit*>(next()) ) )
479 {
5df25c2a 480 // Select only hits on selected chambers.
481 Int_t chamber = hit->Chamber() - 1;
482 if (chamber > AliMUONConstants::NTrackingCh()) continue;
483 if (not fServeChamber[chamber]) continue;
484
485 // Only select hits from the given part of the plane
486 if (fSelection == kLeftPlane and not (hit->Xref() < 0)) continue;
487 if (fSelection == kRightPlane and not (hit->Xref() >= 0)) continue;
3dd14e20 488
489 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
490 if (rechit == NULL)
491 {
492 Logging(kHLTLogError,
493 "AliHLTMUONRecHitsSource::GetEvent",
494 "Buffer overflow",
495 "There is not enough buffer space to add more hits."
496 " We overflowed the buffer which is only %d bytes.",
497 block.BufferSize()
498 );
3dd14e20 499 size = 0; // Important to tell framework that nothing was generated.
d328bad2 500 return -ENOBUFS;
3dd14e20 501 }
502
503 rechit->fX = hit->Xref();
504 rechit->fY = hit->Yref();
505 rechit->fZ = hit->Zref();
bef07620 506
507 // Workout which DDL this hit will be readout of.
508 AliMpDetElement* de = AliMpDEManager::GetDetElement(hit->DetElemId());
509 if (de != NULL and (0 <= de->GetDdlId() and de->GetDdlId() < 22))
510 ddlList[de->GetDdlId()] = true;
511 else
512 Logging(kHLTLogError,
513 "AliHLTMUONRecHitsSource::GetEvent",
514 "No DDL ID",
515 "Could not find the DDL ID from which readout would take place."
516 );
3dd14e20 517 }
3dd14e20 518 }
519 }
8d33d1c2 520 else if (fDataInterface != NULL)
3dd14e20 521 {
5df25c2a 522 Logging(kHLTLogDebug,
523 "AliHLTMUONRecHitsSource::GetEvent",
524 "Filling hits",
525 "Filling data block with reconstructed raw clusters for event %d.",
526 eventnumber
527 );
528
8d33d1c2 529 AliMUONVClusterStore* clusterStore = fDataInterface->ClusterStore(eventnumber);
530
5df25c2a 531 // Loop over selected chambers and extract the raw clusters.
8d33d1c2 532 for (Int_t chamber = 0; chamber < AliMUONConstants::NTrackingCh(); chamber++)
3dd14e20 533 {
5df25c2a 534 // Select only hits on selected chambers.
535 if (not fServeChamber[chamber]) continue;
3dd14e20 536
bef07620 537 TIter next(clusterStore->CreateChamberIterator(chamber,chamber));
8c58b039 538 AliMUONVCluster* cluster;
539 while ( ( cluster = static_cast<AliMUONVCluster*>(next()) ) )
bef07620 540 {
5df25c2a 541 // Only select hits from the given part of the plane
542 if (fSelection == kLeftPlane and not (cluster->GetX() < 0)) continue;
543 if (fSelection == kRightPlane and not (cluster->GetX() >= 0)) continue;
3dd14e20 544
5df25c2a 545 AliHLTMUONRecHitStruct* rechit = block.AddEntry();
546 if (rechit == NULL)
547 {
548 Logging(kHLTLogError,
549 "AliHLTMUONRecHitsSource::GetEvent",
550 "Buffer overflow",
551 "There is not enough buffer space to add more hits."
552 " We overflowed the buffer which is only %d bytes.",
553 block.BufferSize()
554 );
5df25c2a 555 size = 0; // Important to tell framework that nothing was generated.
d328bad2 556 return -ENOBUFS;
5df25c2a 557 }
558
559 rechit->fX = cluster->GetX();
560 rechit->fY = cluster->GetY();
561 rechit->fZ = cluster->GetZ();
bef07620 562
563 // Workout which DDL this hit will be readout of.
8c58b039 564 AliMpDetElement* de = AliMpDEManager::GetDetElement(cluster->GetDetElemId());
bef07620 565 if (de != NULL and (0 <= de->GetDdlId() and de->GetDdlId() < 22))
566 ddlList[de->GetDdlId()] = true;
567 else
568 Logging(kHLTLogError,
569 "AliHLTMUONRecHitsSource::GetEvent",
570 "No DDL ID",
571 "Could not find the DDL ID from which readout would take place."
572 );
5df25c2a 573 }
3dd14e20 574 }
3dd14e20 575 }
576 else
577 {
578 Logging(kHLTLogError,
579 "AliHLTMUONRecHitsSource::GetEvent",
580 "Missing data interface",
bef07620 581 "Neither AliMUONDataInterface nor AliMUONMCDataInterface were created."
3dd14e20 582 );
583 size = 0; // Important to tell framework that nothing was generated.
d328bad2 584 return -EFAULT;
3dd14e20 585 }
5df25c2a 586
587 AliHLTComponentBlockData bd;
588 FillBlockData(bd);
589 bd.fPtr = outputPtr;
590 bd.fOffset = 0;
591 bd.fSize = block.BytesUsed();
592 bd.fDataType = AliHLTMUONConstants::RecHitsBlockDataType();
bef07620 593 bd.fSpecification = AliHLTMUONUtils::PackSpecBits(ddlList);
5df25c2a 594 outputBlocks.push_back(bd);
595 size = block.BytesUsed();
3dd14e20 596
597 return 0;
598}
5df25c2a 599
600
601int AliHLTMUONRecHitsSource::ParseChamberString(const char* str)
602{
6253e09b 603 ///
604 /// Parses a string with the following format:
605 /// <number>|<number>-<number>[,<number>|<number>-<number>]...
606 /// For example: 1 1,2,3 1-2 1,2-4,5 etc...
607 /// Flags in the fServeChamber will be set to 'true' for all appropriate
608 /// values parsed.
609 /// @param str The string to parse.
610 /// @return Zero on success and EINVAL if there is a parse error.
611 ///
612
5df25c2a 613 char* end = const_cast<char*>(str);
614 long lastChamber = -1;
615 do
616 {
617 // Parse the next number.
618 char* current = end;
619 long chamber = strtol(current, &end, 0);
620
621 // Check for parse errors of the number.
622 if (current == end)
623 {
624 Logging(kHLTLogError,
625 "AliHLTMUONRecHitsSource::GetEvent",
626 "Parse error",
627 "Expected a number in the range [1..%d] but got '%s'.",
628 AliMUONConstants::NTrackingCh(), current
629 );
d328bad2 630 return -EINVAL;
5df25c2a 631 }
632 if (chamber < 1 or AliMUONConstants::NTrackingCh() < chamber)
633 {
634 Logging(kHLTLogError,
635 "AliHLTMUONRecHitsSource::GetEvent",
636 "Parse error",
637 "Got the chamber number %d which is outside the valid range of [1..%d].",
bef07620 638 chamber, AliMUONConstants::NTrackingCh()
5df25c2a 639 );
d328bad2 640 return -EINVAL;
5df25c2a 641 }
642
643 // Skip any whitespace after the number
644 while (*end != '\0' and (*end == ' ' or *end == '\t' or *end == '\r' or *end == '\n')) end++;
645
646 // Check if we are dealing with a list or range, or if we are at
647 // the end of the string.
648 if (*end == '-')
649 {
650 lastChamber = chamber;
651 end++;
652 continue;
653 }
654 else if (*end == ',')
655 {
656 assert( 1 <= chamber and chamber <= 10 );
657 fServeChamber[chamber-1] = true;
658 end++;
659 }
660 else if (*end == '\0')
661 {
662 assert( 1 <= chamber and chamber <= 10 );
663 fServeChamber[chamber-1] = true;
664 }
665 else
666 {
667 Logging(kHLTLogError,
668 "AliHLTMUONRecHitsSource::GetEvent",
669 "Parse error",
670 "Could not understand parameter list '%s'. Expected '-', ','"
671 " or end of line but got '%c' at character %d.",
672 str, *end, (int)(end - str) +1
673 );
d328bad2 674 return -EINVAL;
5df25c2a 675 }
676
677 // Set the range of chambers to publish for.
678 if (lastChamber > 0)
679 {
680 Int_t min, max;
681 if (lastChamber < chamber)
682 {
683 min = lastChamber;
684 max = chamber;
685 }
686 else
687 {
688 min = chamber;
689 max = lastChamber;
690 }
691 assert( min >= 1 );
692 assert( max <= 10 );
693 for (Int_t i = min; i <= max; i++)
694 fServeChamber[i-1] = true;
695 }
696 lastChamber = -1;
697 }
698 while (*end != '\0');
699 return 0;
700}