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