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