]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/RCU/AliHLTAltroGenerator.cxx
compilation warnings fixed
[u/mrichter/AliRoot.git] / HLT / RCU / AliHLTAltroGenerator.cxx
CommitLineData
c3800c65 1// $Id$
2
3//**************************************************************************
4//* This file is property of and copyright by the ALICE HLT Project *
5//* ALICE Experiment at CERN, All rights reserved. *
6//* *
7//* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8//* for The ALICE HLT Project. *
9//* *
10//* Permission to use, copy, modify and distribute this software and its *
11//* documentation strictly for non-commercial purposes is hereby granted *
12//* without fee, provided that the above copyright notice appears in all *
13//* copies and that both the copyright notice and this permission notice *
14//* appear in the supporting documentation. The authors make no claims *
15//* about the suitability of this software for any purpose. It is *
16//* provided "as is" without express or implied warranty. *
17//**************************************************************************
18
19/** @file AliHLTAltroGenerator.cxx
20 @author Matthias Richter
21 @date
22 @brief Simulation class of 10/40bit Altro Data.
23*/
24
25#include <cassert>
26#include <cerrno>
27#include "AliHLTAltroGenerator.h"
28#include "TArrayS.h"
29#include "TArrayC.h"
30#include "TRandom.h"
31#include "TDatime.h"
32#include "AliRawDataHeader.h"
33#include "AliHLTAltroEncoder.h"
34
35/** ROOT macro for the implementation of ROOT specific class methods */
36ClassImp(AliHLTAltroGenerator)
37
38AliHLTAltroGenerator::AliHLTAltroGenerator(int maxChannels,
39 int maxBunches,
40 int maxBunchLength,
41 int maxTimebin,
42 int maxSignal)
43 :
44 fpData(NULL),
45 fpSimData(NULL),
46 fChannelPositions(),
47 fNof10BitWords(0),
48 fpCDH(NULL),
49 fCDHSize(0),
50 fpTrailer(NULL),
51 fTrailerSize(0),
52 fMaxChannels(maxChannels),
53 fMaxBunches(maxBunches),
54 fMaxBunchLength(maxBunchLength),
55 fMaxTimebin(maxTimebin),
56 fMaxSignal(maxSignal),
57 fpRand(NULL),
58 fDirection(kBackwards),
59 fCurrentPosition(-1),
60 fCurrentBunch(-1),
61 fCurrentTimeOffset(-1)
62{
63 // see header file for class documentation
64 // or
65 // refer to README to build package
66 // or
67 // visit http://web.ift.uib.no/~kjeks/doc/alice-hlt
68}
69
70AliHLTAltroGenerator::~AliHLTAltroGenerator()
71{
72 // see header file for class documentation
73 if (fpTrailer) delete[] fpTrailer;
74 if (fpCDH) delete[] fpCDH;
75 if (fpSimData) delete fpSimData;
76 if (fpData) delete fpData;
77}
78
79int AliHLTAltroGenerator::Generate()
80{
81 // see header file for class documentation
82 int iResult=0;
83
84 if (!fpSimData) fpSimData=new TArrayS;
85 if (!fpSimData) {
86 return -ENOMEM;
87 }
88
89 Reset();
90
91 int nofChannels=GetRandom(1, fMaxChannels);
92 if (nofChannels==0) nofChannels=1;
93
94 HLTDebug("number of channels: %d", nofChannels);
95 int channelAddress=-1;
96 int lastChannel=-1;
97 int dataPos=0;
98 int repetitions=0;
99 for (int channel=0; channel<nofChannels; channel++) {
100 channelAddress=GetRandom(0, fMaxChannels);
101 //HLTDebug("channel %d: address %d, %d bunch(es)", channel, channelAddress, nofBunches);
102 if (channelAddress==lastChannel) {
103 channel--;
104 if (repetitions++>5) break;
105 continue;
106 }
107 int nofBunches=GetRandom(1, fMaxBunches);
108 if (nofBunches==0) {
109 channel--;
110 if (repetitions++>5) break;
111 continue;
112 }
113 repetitions=0;
114 int totalBunches=0;
b0714bad 115 int bunchEndTime=0;
116 int lastBunchEndTime=0;
c3800c65 117
118 HLTDebug("simulate channel %d: address %d", channel, channelAddress);
119
120 // save beginning of this channel for better navigation
121 AliChannelPosition position={channelAddress, dataPos, 0};
122
123 // add channel address and bunch count at the beginning
124 if (fpSimData->GetSize()<dataPos+2) fpSimData->Set(dataPos+2);
125 (*fpSimData)[dataPos++]=channelAddress;
126 dataPos++; // placeholder for number of bunches
127
128 int bunch=0;
b0714bad 129
130 // Matthias Oct 2008:
131 // Data was simulated in the wrong order: bunches for the higher timebins
132 // first. But real data is the other way round: bunches are written in the order
133 // of ascending timebins. A new consistency check was added to AliAltroDecoder
134 // (AliAltroBunch) in revision 29090. Now the channels are checked for overlapping
135 // bunches, the time of a bunch must be smaller than time of the previous one
136 // minus its length.
137 // Data is now simulated in the right order in order to fullfil this check.
138 for (bunch=0; bunch<nofBunches && bunchEndTime<fMaxTimebin-3; bunch++) {
95e36f3d 139 while ((bunchEndTime+=GetRandom(0, fMaxTimebin-bunchEndTime))-lastBunchEndTime<3) {/*empty body*/};
b0714bad 140 int bunchLength=GetRandom(0, bunchEndTime-lastBunchEndTime<fMaxBunchLength?bunchEndTime-lastBunchEndTime:fMaxBunchLength);
c3800c65 141 if (bunchLength==0) continue;
142 totalBunches++;
143
144 HLTDebug(" bunch %d, length %d, end time %d ", bunch, bunchLength, bunchEndTime);
145
146 if (fpSimData->GetSize()<dataPos+bunchLength+4) fpSimData->Set(dataPos+bunchLength+4);
147 // write bunch length and time at both ends
148 (*fpSimData)[dataPos++]=bunchLength;
149 int time=bunchEndTime-bunchLength+1;
150 (*fpSimData)[dataPos++]=time;
151 for (; time<=bunchEndTime; time++) {
152 int signal=GetRandom(0, fMaxSignal);
153 (*fpSimData)[dataPos++]=signal;
154 }
155 (*fpSimData)[dataPos++]=bunchEndTime;
156 (*fpSimData)[dataPos++]=bunchLength;
157 fNof10BitWords+=bunchLength+2;
b0714bad 158 lastBunchEndTime=bunchEndTime;
159 bunchEndTime+=bunchLength;
c3800c65 160 }
161 if (totalBunches>0) {
162 (*fpSimData)[position.fPosition+1]=totalBunches;
163 if (fpSimData->GetSize()<dataPos+2) fpSimData->Set(dataPos+2);
164 (*fpSimData)[dataPos++]=totalBunches;
165 position.fEnd=dataPos;
166 (*fpSimData)[dataPos++]=channelAddress;
167 lastChannel=channelAddress;
168 fNof10BitWords=(fNof10BitWords+7)/4; fNof10BitWords*=4; // align to 4 and add 4
169 fChannelPositions.push_back(position);
170 assert((*fpSimData)[position.fPosition]==(*fpSimData)[position.fEnd]);
171 HLTDebug(" channel %d added: address %d, %d bunch(es)", channel, channelAddress, totalBunches);
172 } else {
173 dataPos-=2;
174 HLTDebug(" channel %d skipped: address %d, %d bunch(es)", channel, channelAddress, totalBunches);
175 }
176 }
177
178 assert(fNof10BitWords%4==0);
179 if (iResult<0) {
180 fpSimData->Set(0);
181 return iResult;
182 }
183 fpSimData->Set(dataPos);
184 return GetDataSize();
185}
186
187int AliHLTAltroGenerator::GetNof40BitAltroWords() const
188{
189 // see header file for class documentation
190 assert(fNof10BitWords%4==0);
191 return fNof10BitWords/4;
192}
193
194int AliHLTAltroGenerator::GetDataSize()
195{
196 // see header file for class documentation
197 int iResult=0;
198 iResult=(fNof10BitWords*5)/4;
199 if (fpTrailer) {
200 *(reinterpret_cast<AliHLTUInt32_t*>(fpTrailer))=GetNof40BitAltroWords();
201 iResult+=fTrailerSize;
202 }
203 if (fpCDH) iResult+=fCDHSize;
204 return iResult;
205}
206
207int AliHLTAltroGenerator::GetData(AliHLTUInt8_t* &pBuffer)
208{
209 // see header file for class documentation
210 int iResult=GetDataSize();
211 if (iResult>0) {
212 if (!fpData) fpData=new TArrayC(iResult);
213 if (fpData) {
214 if (fpData->GetSize()<iResult) fpData->Set(iResult);
215 if ((iResult=GetData(reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray()), fpData->GetSize()))>=0) {
216 pBuffer=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
217 }
218 } else {
219 iResult=-ENOMEM;
220 }
221 }
222 return iResult;
223}
224
225int AliHLTAltroGenerator::GetData(AliHLTUInt8_t* pBuffer, int size)
226{
227 // see header file for class documentation
228 int iResult=0;
229 int dataPos=0;
230
231 if (size<GetDataSize()) return -ENOSPC;
232
233 // copy Common Data Header
234 if (fpCDH) {
235 fpCDH->fSize=GetDataSize();
236 memcpy(pBuffer+dataPos, fpCDH, fCDHSize);
237 dataPos+=fCDHSize;
238 }
239
240 // encode simulated data
241 if ((iResult=EncodeData(pBuffer+dataPos, size-dataPos))>=0) {
242 dataPos+=iResult;
243 }
244
245 // copy trailer
246 if (fpTrailer) {
247 memcpy(pBuffer+dataPos, fpTrailer, fTrailerSize);
248 AliHLTUInt32_t* pLast=reinterpret_cast<AliHLTUInt32_t*>(fpTrailer+fTrailerSize-sizeof(AliHLTUInt32_t));
249 *pLast=GetNof40BitAltroWords();
250 dataPos+=fTrailerSize;
251 }
252
253 if (iResult<0) return iResult;
254 assert(fpCDH==NULL || (int)fpCDH->fSize==dataPos);
255 return dataPos;
256}
257
258int AliHLTAltroGenerator::SetCDH(AliRawDataHeader* pCDH, int size)
259{
260 // see header file for class documentation
261 int iResult=0;
262 if (pCDH && size>0) {
263 if (fpCDH) delete[] fpCDH;
264 fpCDH=new AliRawDataHeader;
265 if (fpCDH) {
266 memcpy(fpCDH, pCDH, size);
267 fCDHSize=size;
268 } else {
269 iResult=-ENOMEM;
270 }
271 } else {
272 iResult=-EINVAL;
273 }
274 return iResult;
275}
276
277int AliHLTAltroGenerator::SetRCUTrailer(AliHLTUInt8_t* pTrailer, int size)
278{
279 // see header file for class documentation
280 int iResult=0;
281 if (pTrailer && size>=(int)sizeof(AliHLTUInt32_t)) {
282 AliHLTUInt32_t* pLast=reinterpret_cast<AliHLTUInt32_t*>(pTrailer+size-sizeof(AliHLTUInt32_t));
283 if (size!=sizeof(AliHLTUInt32_t)) {
284 // if more than one trailer words, the last one is the trailer length (# 32bit words)
285 if (*pLast!=size/sizeof(AliHLTUInt32_t)) {
286 HLTError("invalid trailer: trailer length (last 32bit word) does not match trailer size (bytes)");
287 return -EBADF;
288 }
289 }
290 if (fpTrailer) delete[] fpTrailer;
291 fpTrailer=new AliHLTUInt8_t[size];
292 if (fpTrailer) {
293 memcpy(fpTrailer, pTrailer, size);
294 fTrailerSize=size;
295 } else {
296 iResult=-ENOMEM;
297 }
298 } else {
299 iResult=-EINVAL;
300 }
301 return iResult;
302}
303
304int AliHLTAltroGenerator::GetChannels(vector<AliHLTUInt16_t> list)
305{
306 // see header file for class documentation
307 int iResult=0;
308 list.clear();
309 for (vector<AliChannelPosition>::iterator element=fChannelPositions.begin();
310 element!=fChannelPositions.end();
311 element++) {
312 list.push_back(element->fChannel);
313 }
314 iResult=list.size();
315 return iResult;
316}
317
318int AliHLTAltroGenerator::SetSorting(AliHLTUInt16_t */*array*/, int /*arraySize*/)
319{
320 // see header file for class documentation
321 int iResult=0;
322 HLTError("function not yet implemented");
323 return iResult;
324}
325
326int AliHLTAltroGenerator::EncodeData(AliHLTUInt8_t* pBuffer, int size)
327{
328 // see header file for class documentation
329 int iResult=0;
330 if (!pBuffer) return -EINVAL;
331
332 AliHLTAltroEncoder encoder;
333 encoder.SetBuffer(pBuffer, size);
334
335 Short_t channelAddress=-1;
336 for (vector<AliChannelPosition>::iterator element=fChannelPositions.begin();
337 element!=fChannelPositions.end() && iResult>=0;
338 element++) {
339 if (!fpSimData ||
340 fpSimData->GetSize()<=element->fPosition ||
341 fNof10BitWords==0) {
342 iResult=-ENODATA;
343 break;
344 }
345 channelAddress=element->fChannel;
346 assert(fpSimData->At(element->fPosition)==channelAddress);
347 if (fpSimData->At(element->fPosition)!=channelAddress) {
348 iResult=-ENODATA;
349 break;
350 }
351 int dataPos=element->fPosition+1;
352 int nofBunches=fpSimData->At(dataPos++);
353 int bunch=0;
354 for (; bunch<nofBunches; bunch++) {
355 int bunchLength=fpSimData->At(dataPos++);
356 int startTime=fpSimData->At(dataPos++);
357 int time=startTime;
358 for (; time<startTime+bunchLength; time++) {
c5123824 359 iResult=encoder.AddSignal(fpSimData->At(dataPos++), time);
c3800c65 360 }
361 assert(time-1==fpSimData->At(dataPos));
362 dataPos++; // DO NOT PUT INTO ASSERT
363 assert(bunchLength==fpSimData->At(dataPos));
364 dataPos++; // DO NOT PUT INTO ASSERT
365 }
366
367 if (iResult>=0 && channelAddress>=0) {
368 assert(nofBunches==fpSimData->At(dataPos));
369 dataPos++; // DO NOT PUT INTO ASSERT
370 assert(channelAddress==fpSimData->At(dataPos));
371 dataPos++; // DO NOT PUT INTO ASSERT
372 }
c5123824 373 encoder.SetChannel(channelAddress);
c3800c65 374 }
c3800c65 375
376 if (iResult>=0) {
377 iResult=(encoder.GetTotal40bitWords()*5)/4;
378 }
379
380 return iResult;
381}
382
383int AliHLTAltroGenerator::GetRandom(int min, int max)
384{
385 // see header file for class documentation
386 if (max-min<2) return min;
387 bool setTheSeed=fpRand!=NULL;
388 if (fpRand==NULL) {
389 fpRand=new TRandom;
390 }
391 if (fpRand==NULL) return min;
392 if (!setTheSeed) {
393 TDatime dt;
394 fpRand->SetSeed(dt.Get());
395 }
396 return fpRand->Integer(max-min);
397}
398
399int AliHLTAltroGenerator::Reset()
400{
401 // see header file for class documentation
402 fChannelPositions.clear();
403 fNof10BitWords=0;
404 Rewind();
405 return 0;
406}
407
408int AliHLTAltroGenerator::Rewind()
409{
410 // see header file for class documentation
411 fCurrentPosition=-1;
412 fCurrentBunch=-1;
413 fCurrentTimeOffset=-1;
414 return 0;
415}
416
417bool AliHLTAltroGenerator::Next()
418{
419 // see header file for class documentation
420 bool haveData=false;
421 if (!fpSimData) return false;
422 do {
32f88fc5 423 if ((haveData=(fCurrentTimeOffset>=0 &&
424 fCurrentBunch>0 &&
425 ++fCurrentTimeOffset<GetBunchSize()))) {
c3800c65 426 break;
427 }
428
32f88fc5 429 if ((haveData=(NextBunch()) && GetBunchSize()>0)) {
c3800c65 430 fCurrentTimeOffset=0;
431 break;
432 }
433 } while (NextChannel());
434 return haveData;
435}
436
437AliHLTUInt16_t AliHLTAltroGenerator::GetSignal()
438{
439 // see header file for class documentation
440 if (!fpSimData || fCurrentTimeOffset<0) return 0;
441 assert(fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size());
442 assert(fCurrentBunch>=0);
443 if (fDirection==kForwards) {
444 return fpSimData->At(fCurrentBunch+2+fCurrentTimeOffset);
445 } else if (fDirection==kBackwards){
446 return fpSimData->At(fCurrentBunch-(2+fCurrentTimeOffset));
447 }
448 return 0;
449}
450
451bool AliHLTAltroGenerator::NextChannel()
452{
453 // see header file for class documentation
454 bool haveData=false;
455 if (fpSimData && fChannelPositions.size()==0) return false;
456 fpSimData->GetArray();
457 if (fCurrentPosition==-1) {
458 if (fDirection==kForwards) fCurrentPosition=0;
459 else fCurrentPosition=fChannelPositions.size()-1;
460 haveData=true;
461 } else {
462 if (fDirection==kForwards && (haveData=(fCurrentPosition+1<(int)fChannelPositions.size()))) {
463 fCurrentPosition++;
464 } else if (fDirection==kBackwards && (haveData=(fCurrentPosition>0))) {
465 fCurrentPosition--;
466 }
467 }
468
469 fCurrentBunch=-1;
470 fCurrentTimeOffset=-1;
471 return haveData;
472}
473
474AliHLTUInt16_t AliHLTAltroGenerator::GetHwAddress()
475{
476 // see header file for class documentation
477 if (fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size())
478 return fChannelPositions[fCurrentPosition].fChannel;
479 return ~((AliHLTUInt16_t)0);
480}
481
482int AliHLTAltroGenerator::GetBunchCount()
483{
484 // see header file for class documentation
485 if (fpSimData && fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size()) {
486 if (fDirection==kForwards)
487 return fpSimData->At(fChannelPositions[fCurrentPosition].fPosition+1);
488 else if (fDirection==kBackwards)
489 return fpSimData->At(fChannelPositions[fCurrentPosition].fEnd-1);
490 }
491 return ~((AliHLTUInt16_t)0);
492}
493
494bool AliHLTAltroGenerator::NextBunch()
495{
496 // see header file for class documentation
497 bool haveData=false;
498 if (fpSimData && fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size()) {
499 if (fDirection==kBackwards) {
500 if (fCurrentBunch<0) {
501 // bunch count in channel end - 1
32f88fc5 502 if ((haveData=(fpSimData->At(fChannelPositions[fCurrentPosition].fEnd-1))>0)) {
c3800c65 503 // first bunch length at channel end - 2
504 fCurrentBunch=fChannelPositions[fCurrentPosition].fEnd-2;
505 }
506 } else if (fCurrentBunch>fChannelPositions[fCurrentPosition].fPosition+1) {
507 fCurrentBunch-=fpSimData->At(fCurrentBunch)+4;
508 haveData=fCurrentBunch>fChannelPositions[fCurrentPosition].fPosition+1;
509 }
510 // cross check
511 if (haveData) {
512 assert(fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-3));
513 haveData=fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-3);
514 }
515 } else if (fDirection==kForwards) {
516 if (fCurrentBunch<0) {
517 // bunch count in channel start + 1
32f88fc5 518 if ((haveData=(fpSimData->At(fChannelPositions[fCurrentPosition].fPosition+1))>0)) {
c3800c65 519 // first bunch length at channel start + 2
520 fCurrentBunch=fChannelPositions[fCurrentPosition].fPosition+2;
521 }
522 } else if (fCurrentBunch<fChannelPositions[fCurrentPosition].fEnd-1) {
523 fCurrentBunch+=fpSimData->At(fCurrentBunch)+4;
524 haveData=fCurrentBunch<fChannelPositions[fCurrentPosition].fEnd-1;
525 }
526 // cross check
527 if (haveData) {
528 assert(fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+3));
529 haveData=fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+3);
530 }
531 }
532 }
533 fCurrentTimeOffset=-1;
534 return haveData;
535}
536
537AliHLTUInt16_t AliHLTAltroGenerator::GetBunchSize()
538{
539 // see header file for class documentation
540 if (fCurrentBunch<0) return 0;
541 if (fCurrentBunch<fChannelPositions[fCurrentPosition].fPosition+2) return 0;
542 if (fCurrentBunch>fChannelPositions[fCurrentPosition].fEnd-2) return 0;
543 return fpSimData->At(fCurrentBunch);
544}
545
546AliHLTUInt16_t AliHLTAltroGenerator::GetStartTime()
547{
548 // see header file for class documentation
549 if (!fpSimData || GetBunchSize()==0) return 0;
550 AliHLTUInt16_t startTime=0;
551 if (fDirection==kForwards) {
552 startTime=fpSimData->At(fCurrentBunch+1);
553 } else if (fDirection==kBackwards) {
554 startTime=fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-2);
555 }
556 if (fCurrentTimeOffset>=0) {
557 if (fDirection==kForwards) {
558 startTime+=fCurrentTimeOffset;
559 } else if (fDirection==kBackwards) {
560 startTime=GetEndTime();
561 }
562 }
563 return startTime;
564}
565
566AliHLTUInt16_t AliHLTAltroGenerator::GetEndTime()
567{
568 // see header file for class documentation
569 if (!fpSimData || GetBunchSize()==0) return 0;
570 AliHLTUInt16_t endTime=0;
571 if (fDirection==kForwards) {
572 endTime=fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+2);
573 } else if (fDirection==kBackwards) {
574 endTime=fpSimData->At(fCurrentBunch-1);
575 }
576 if (fCurrentTimeOffset>=0) {
577 assert(fCurrentTimeOffset<fpSimData->At(fCurrentBunch));
578 if (fDirection==kForwards) {
579 endTime=GetStartTime();
580 } else if (fDirection==kBackwards) {
581 endTime-=fCurrentTimeOffset;
582 }
583 }
584 return endTime;
585}
586
587const Short_t* AliHLTAltroGenerator::GetSignals()
588{
589 // see header file for class documentation
590 if (!fpSimData || GetBunchSize()==0) return NULL;
591 if (fDirection==kForwards) {
592 return fpSimData->GetArray()+fCurrentBunch+2;
593 } else if (fDirection==kBackwards) {
594 return fpSimData->GetArray()+(fCurrentBunch-fpSimData->At(fCurrentBunch)-1);
595 }
596 return NULL;
597}
598
599void AliHLTAltroGenerator::Print()
600{
601 // see header file for class documentation
602 cout << *this << endl;
603}
604
605ostream &operator<<(ostream &stream, AliHLTAltroGenerator &generator)
606{
607 // see header file for class documentation
608 int iResult=0;
609 Short_t channelAddress=-1;
610 for (vector<AliHLTAltroGenerator::AliChannelPosition>::iterator element=generator.fChannelPositions.begin();
611 element!=generator.fChannelPositions.end() && iResult>=0;
612 element++) {
613 if (!generator.fpSimData ||
614 generator.fpSimData->GetSize()<=element->fPosition ||
615 generator.fNof10BitWords==0) {
616 stream << "AliHLTAltroGenerator: no data available" << endl;;
617 break;
618 }
619 channelAddress=element->fChannel;
620 assert(generator.fpSimData->At(element->fPosition)==channelAddress);
621 if (generator.fpSimData->At(element->fPosition)!=channelAddress) {
622 stream << "AliHLTAltroGenerator: internal data mismatch" << endl;;
623 iResult=-ENODATA;
624 break;
625 }
626 int dataPos=element->fPosition+1;
627 int nofBunches=generator.fpSimData->At(dataPos++);
628 stream << "***************************************************************" << endl;
629 stream << "channel address: " << channelAddress << " " << nofBunches << " bunch(es)" << endl;
630 int bunch=0;
631 for (; bunch<nofBunches; bunch++) {
632 int bunchLength=generator.fpSimData->At(dataPos++);
633 int startTime=generator.fpSimData->At(dataPos++);
634 int time=startTime;
635 stream << " length " << bunchLength << " start time " << startTime << ": ";
636 for (; time<startTime+bunchLength; time++) {
637 stream << " " << generator.fpSimData->At(dataPos++);
638 }
639 assert(time-1==generator.fpSimData->At(dataPos));
640 dataPos++; // DO NOT PUT INTO ASSERT
641 assert(bunchLength==generator.fpSimData->At(dataPos));
642 dataPos++; // DO NOT PUT INTO ASSERT
643 stream << " -> end time " << time-1 << endl;
644 }
645
646 if (iResult>=0 && channelAddress>=0) {
647 assert(nofBunches==generator.fpSimData->At(dataPos));
648 dataPos++; // DO NOT PUT INTO ASSERT
649 assert(channelAddress==generator.fpSimData->At(dataPos));
650 dataPos++; // DO NOT PUT INTO ASSERT
651 }
652 }
653
654 return stream;
655}