]> git.uio.no Git - u/mrichter/AliRoot.git/blame - HLT/RCU/AliHLTAltroGenerator.cxx
Fix loading of TPC clusters; SEGV occured with events generated with today's HEAD.
[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;
115 int bunchEndTime=fMaxTimebin;
116
117 HLTDebug("simulate channel %d: address %d", channel, channelAddress);
118
119 // save beginning of this channel for better navigation
120 AliChannelPosition position={channelAddress, dataPos, 0};
121
122 // add channel address and bunch count at the beginning
123 if (fpSimData->GetSize()<dataPos+2) fpSimData->Set(dataPos+2);
124 (*fpSimData)[dataPos++]=channelAddress;
125 dataPos++; // placeholder for number of bunches
126
127 int bunch=0;
128 for (bunch=0; bunch<nofBunches && bunchEndTime>0; bunch++) {
129 bunchEndTime=GetRandom(0, bunchEndTime-1);
130 int bunchLength=GetRandom(0, bunchEndTime<fMaxBunchLength?bunchEndTime:fMaxBunchLength);
131 if (bunchLength==0) continue;
132 totalBunches++;
133
134 HLTDebug(" bunch %d, length %d, end time %d ", bunch, bunchLength, bunchEndTime);
135
136 if (fpSimData->GetSize()<dataPos+bunchLength+4) fpSimData->Set(dataPos+bunchLength+4);
137 // write bunch length and time at both ends
138 (*fpSimData)[dataPos++]=bunchLength;
139 int time=bunchEndTime-bunchLength+1;
140 (*fpSimData)[dataPos++]=time;
141 for (; time<=bunchEndTime; time++) {
142 int signal=GetRandom(0, fMaxSignal);
143 (*fpSimData)[dataPos++]=signal;
144 }
145 (*fpSimData)[dataPos++]=bunchEndTime;
146 (*fpSimData)[dataPos++]=bunchLength;
147 fNof10BitWords+=bunchLength+2;
148 }
149 if (totalBunches>0) {
150 (*fpSimData)[position.fPosition+1]=totalBunches;
151 if (fpSimData->GetSize()<dataPos+2) fpSimData->Set(dataPos+2);
152 (*fpSimData)[dataPos++]=totalBunches;
153 position.fEnd=dataPos;
154 (*fpSimData)[dataPos++]=channelAddress;
155 lastChannel=channelAddress;
156 fNof10BitWords=(fNof10BitWords+7)/4; fNof10BitWords*=4; // align to 4 and add 4
157 fChannelPositions.push_back(position);
158 assert((*fpSimData)[position.fPosition]==(*fpSimData)[position.fEnd]);
159 HLTDebug(" channel %d added: address %d, %d bunch(es)", channel, channelAddress, totalBunches);
160 } else {
161 dataPos-=2;
162 HLTDebug(" channel %d skipped: address %d, %d bunch(es)", channel, channelAddress, totalBunches);
163 }
164 }
165
166 assert(fNof10BitWords%4==0);
167 if (iResult<0) {
168 fpSimData->Set(0);
169 return iResult;
170 }
171 fpSimData->Set(dataPos);
172 return GetDataSize();
173}
174
175int AliHLTAltroGenerator::GetNof40BitAltroWords() const
176{
177 // see header file for class documentation
178 assert(fNof10BitWords%4==0);
179 return fNof10BitWords/4;
180}
181
182int AliHLTAltroGenerator::GetDataSize()
183{
184 // see header file for class documentation
185 int iResult=0;
186 iResult=(fNof10BitWords*5)/4;
187 if (fpTrailer) {
188 *(reinterpret_cast<AliHLTUInt32_t*>(fpTrailer))=GetNof40BitAltroWords();
189 iResult+=fTrailerSize;
190 }
191 if (fpCDH) iResult+=fCDHSize;
192 return iResult;
193}
194
195int AliHLTAltroGenerator::GetData(AliHLTUInt8_t* &pBuffer)
196{
197 // see header file for class documentation
198 int iResult=GetDataSize();
199 if (iResult>0) {
200 if (!fpData) fpData=new TArrayC(iResult);
201 if (fpData) {
202 if (fpData->GetSize()<iResult) fpData->Set(iResult);
203 if ((iResult=GetData(reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray()), fpData->GetSize()))>=0) {
204 pBuffer=reinterpret_cast<AliHLTUInt8_t*>(fpData->GetArray());
205 }
206 } else {
207 iResult=-ENOMEM;
208 }
209 }
210 return iResult;
211}
212
213int AliHLTAltroGenerator::GetData(AliHLTUInt8_t* pBuffer, int size)
214{
215 // see header file for class documentation
216 int iResult=0;
217 int dataPos=0;
218
219 if (size<GetDataSize()) return -ENOSPC;
220
221 // copy Common Data Header
222 if (fpCDH) {
223 fpCDH->fSize=GetDataSize();
224 memcpy(pBuffer+dataPos, fpCDH, fCDHSize);
225 dataPos+=fCDHSize;
226 }
227
228 // encode simulated data
229 if ((iResult=EncodeData(pBuffer+dataPos, size-dataPos))>=0) {
230 dataPos+=iResult;
231 }
232
233 // copy trailer
234 if (fpTrailer) {
235 memcpy(pBuffer+dataPos, fpTrailer, fTrailerSize);
236 AliHLTUInt32_t* pLast=reinterpret_cast<AliHLTUInt32_t*>(fpTrailer+fTrailerSize-sizeof(AliHLTUInt32_t));
237 *pLast=GetNof40BitAltroWords();
238 dataPos+=fTrailerSize;
239 }
240
241 if (iResult<0) return iResult;
242 assert(fpCDH==NULL || (int)fpCDH->fSize==dataPos);
243 return dataPos;
244}
245
246int AliHLTAltroGenerator::SetCDH(AliRawDataHeader* pCDH, int size)
247{
248 // see header file for class documentation
249 int iResult=0;
250 if (pCDH && size>0) {
251 if (fpCDH) delete[] fpCDH;
252 fpCDH=new AliRawDataHeader;
253 if (fpCDH) {
254 memcpy(fpCDH, pCDH, size);
255 fCDHSize=size;
256 } else {
257 iResult=-ENOMEM;
258 }
259 } else {
260 iResult=-EINVAL;
261 }
262 return iResult;
263}
264
265int AliHLTAltroGenerator::SetRCUTrailer(AliHLTUInt8_t* pTrailer, int size)
266{
267 // see header file for class documentation
268 int iResult=0;
269 if (pTrailer && size>=(int)sizeof(AliHLTUInt32_t)) {
270 AliHLTUInt32_t* pLast=reinterpret_cast<AliHLTUInt32_t*>(pTrailer+size-sizeof(AliHLTUInt32_t));
271 if (size!=sizeof(AliHLTUInt32_t)) {
272 // if more than one trailer words, the last one is the trailer length (# 32bit words)
273 if (*pLast!=size/sizeof(AliHLTUInt32_t)) {
274 HLTError("invalid trailer: trailer length (last 32bit word) does not match trailer size (bytes)");
275 return -EBADF;
276 }
277 }
278 if (fpTrailer) delete[] fpTrailer;
279 fpTrailer=new AliHLTUInt8_t[size];
280 if (fpTrailer) {
281 memcpy(fpTrailer, pTrailer, size);
282 fTrailerSize=size;
283 } else {
284 iResult=-ENOMEM;
285 }
286 } else {
287 iResult=-EINVAL;
288 }
289 return iResult;
290}
291
292int AliHLTAltroGenerator::GetChannels(vector<AliHLTUInt16_t> list)
293{
294 // see header file for class documentation
295 int iResult=0;
296 list.clear();
297 for (vector<AliChannelPosition>::iterator element=fChannelPositions.begin();
298 element!=fChannelPositions.end();
299 element++) {
300 list.push_back(element->fChannel);
301 }
302 iResult=list.size();
303 return iResult;
304}
305
306int AliHLTAltroGenerator::SetSorting(AliHLTUInt16_t */*array*/, int /*arraySize*/)
307{
308 // see header file for class documentation
309 int iResult=0;
310 HLTError("function not yet implemented");
311 return iResult;
312}
313
314int AliHLTAltroGenerator::EncodeData(AliHLTUInt8_t* pBuffer, int size)
315{
316 // see header file for class documentation
317 int iResult=0;
318 if (!pBuffer) return -EINVAL;
319
320 AliHLTAltroEncoder encoder;
321 encoder.SetBuffer(pBuffer, size);
322
323 Short_t channelAddress=-1;
324 for (vector<AliChannelPosition>::iterator element=fChannelPositions.begin();
325 element!=fChannelPositions.end() && iResult>=0;
326 element++) {
327 if (!fpSimData ||
328 fpSimData->GetSize()<=element->fPosition ||
329 fNof10BitWords==0) {
330 iResult=-ENODATA;
331 break;
332 }
333 channelAddress=element->fChannel;
334 assert(fpSimData->At(element->fPosition)==channelAddress);
335 if (fpSimData->At(element->fPosition)!=channelAddress) {
336 iResult=-ENODATA;
337 break;
338 }
339 int dataPos=element->fPosition+1;
340 int nofBunches=fpSimData->At(dataPos++);
341 int bunch=0;
342 for (; bunch<nofBunches; bunch++) {
343 int bunchLength=fpSimData->At(dataPos++);
344 int startTime=fpSimData->At(dataPos++);
345 int time=startTime;
346 for (; time<startTime+bunchLength; time++) {
347 //iResult=encoder.AddSignal(fpSimData->At(dataPos++), time);
348 iResult=encoder.AddChannelSignal(fpSimData->At(dataPos++), time, channelAddress);
349 }
350 assert(time-1==fpSimData->At(dataPos));
351 dataPos++; // DO NOT PUT INTO ASSERT
352 assert(bunchLength==fpSimData->At(dataPos));
353 dataPos++; // DO NOT PUT INTO ASSERT
354 }
355
356 if (iResult>=0 && channelAddress>=0) {
357 assert(nofBunches==fpSimData->At(dataPos));
358 dataPos++; // DO NOT PUT INTO ASSERT
359 assert(channelAddress==fpSimData->At(dataPos));
360 dataPos++; // DO NOT PUT INTO ASSERT
361 }
362 //encoder.SetChannel(channelAddress);
363 }
364 if (iResult>=0 && channelAddress>=0) {
365 encoder.SetChannel(channelAddress);
366 }
367
368 if (iResult>=0) {
369 iResult=(encoder.GetTotal40bitWords()*5)/4;
370 }
371
372 return iResult;
373}
374
375int AliHLTAltroGenerator::GetRandom(int min, int max)
376{
377 // see header file for class documentation
378 if (max-min<2) return min;
379 bool setTheSeed=fpRand!=NULL;
380 if (fpRand==NULL) {
381 fpRand=new TRandom;
382 }
383 if (fpRand==NULL) return min;
384 if (!setTheSeed) {
385 TDatime dt;
386 fpRand->SetSeed(dt.Get());
387 }
388 return fpRand->Integer(max-min);
389}
390
391int AliHLTAltroGenerator::Reset()
392{
393 // see header file for class documentation
394 fChannelPositions.clear();
395 fNof10BitWords=0;
396 Rewind();
397 return 0;
398}
399
400int AliHLTAltroGenerator::Rewind()
401{
402 // see header file for class documentation
403 fCurrentPosition=-1;
404 fCurrentBunch=-1;
405 fCurrentTimeOffset=-1;
406 return 0;
407}
408
409bool AliHLTAltroGenerator::Next()
410{
411 // see header file for class documentation
412 bool haveData=false;
413 if (!fpSimData) return false;
414 do {
415 if (haveData=(fCurrentTimeOffset>=0 &&
416 fCurrentBunch>0 &&
417 ++fCurrentTimeOffset<GetBunchSize())) {
418 break;
419 }
420
421 if (haveData=(NextBunch() && GetBunchSize()>0)) {
422 fCurrentTimeOffset=0;
423 break;
424 }
425 } while (NextChannel());
426 return haveData;
427}
428
429AliHLTUInt16_t AliHLTAltroGenerator::GetSignal()
430{
431 // see header file for class documentation
432 if (!fpSimData || fCurrentTimeOffset<0) return 0;
433 assert(fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size());
434 assert(fCurrentBunch>=0);
435 if (fDirection==kForwards) {
436 return fpSimData->At(fCurrentBunch+2+fCurrentTimeOffset);
437 } else if (fDirection==kBackwards){
438 return fpSimData->At(fCurrentBunch-(2+fCurrentTimeOffset));
439 }
440 return 0;
441}
442
443bool AliHLTAltroGenerator::NextChannel()
444{
445 // see header file for class documentation
446 bool haveData=false;
447 if (fpSimData && fChannelPositions.size()==0) return false;
448 fpSimData->GetArray();
449 if (fCurrentPosition==-1) {
450 if (fDirection==kForwards) fCurrentPosition=0;
451 else fCurrentPosition=fChannelPositions.size()-1;
452 haveData=true;
453 } else {
454 if (fDirection==kForwards && (haveData=(fCurrentPosition+1<(int)fChannelPositions.size()))) {
455 fCurrentPosition++;
456 } else if (fDirection==kBackwards && (haveData=(fCurrentPosition>0))) {
457 fCurrentPosition--;
458 }
459 }
460
461 fCurrentBunch=-1;
462 fCurrentTimeOffset=-1;
463 return haveData;
464}
465
466AliHLTUInt16_t AliHLTAltroGenerator::GetHwAddress()
467{
468 // see header file for class documentation
469 if (fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size())
470 return fChannelPositions[fCurrentPosition].fChannel;
471 return ~((AliHLTUInt16_t)0);
472}
473
474int AliHLTAltroGenerator::GetBunchCount()
475{
476 // see header file for class documentation
477 if (fpSimData && fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size()) {
478 if (fDirection==kForwards)
479 return fpSimData->At(fChannelPositions[fCurrentPosition].fPosition+1);
480 else if (fDirection==kBackwards)
481 return fpSimData->At(fChannelPositions[fCurrentPosition].fEnd-1);
482 }
483 return ~((AliHLTUInt16_t)0);
484}
485
486bool AliHLTAltroGenerator::NextBunch()
487{
488 // see header file for class documentation
489 bool haveData=false;
490 if (fpSimData && fCurrentPosition>=0 && fCurrentPosition<(int)fChannelPositions.size()) {
491 if (fDirection==kBackwards) {
492 if (fCurrentBunch<0) {
493 // bunch count in channel end - 1
494 if (haveData=(fpSimData->At(fChannelPositions[fCurrentPosition].fEnd-1))>0) {
495 // first bunch length at channel end - 2
496 fCurrentBunch=fChannelPositions[fCurrentPosition].fEnd-2;
497 }
498 } else if (fCurrentBunch>fChannelPositions[fCurrentPosition].fPosition+1) {
499 fCurrentBunch-=fpSimData->At(fCurrentBunch)+4;
500 haveData=fCurrentBunch>fChannelPositions[fCurrentPosition].fPosition+1;
501 }
502 // cross check
503 if (haveData) {
504 assert(fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-3));
505 haveData=fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-3);
506 }
507 } else if (fDirection==kForwards) {
508 if (fCurrentBunch<0) {
509 // bunch count in channel start + 1
510 if (haveData=(fpSimData->At(fChannelPositions[fCurrentPosition].fPosition+1))>0) {
511 // first bunch length at channel start + 2
512 fCurrentBunch=fChannelPositions[fCurrentPosition].fPosition+2;
513 }
514 } else if (fCurrentBunch<fChannelPositions[fCurrentPosition].fEnd-1) {
515 fCurrentBunch+=fpSimData->At(fCurrentBunch)+4;
516 haveData=fCurrentBunch<fChannelPositions[fCurrentPosition].fEnd-1;
517 }
518 // cross check
519 if (haveData) {
520 assert(fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+3));
521 haveData=fpSimData->At(fCurrentBunch)==fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+3);
522 }
523 }
524 }
525 fCurrentTimeOffset=-1;
526 return haveData;
527}
528
529AliHLTUInt16_t AliHLTAltroGenerator::GetBunchSize()
530{
531 // see header file for class documentation
532 if (fCurrentBunch<0) return 0;
533 if (fCurrentBunch<fChannelPositions[fCurrentPosition].fPosition+2) return 0;
534 if (fCurrentBunch>fChannelPositions[fCurrentPosition].fEnd-2) return 0;
535 return fpSimData->At(fCurrentBunch);
536}
537
538AliHLTUInt16_t AliHLTAltroGenerator::GetStartTime()
539{
540 // see header file for class documentation
541 if (!fpSimData || GetBunchSize()==0) return 0;
542 AliHLTUInt16_t startTime=0;
543 if (fDirection==kForwards) {
544 startTime=fpSimData->At(fCurrentBunch+1);
545 } else if (fDirection==kBackwards) {
546 startTime=fpSimData->At(fCurrentBunch-fpSimData->At(fCurrentBunch)-2);
547 }
548 if (fCurrentTimeOffset>=0) {
549 if (fDirection==kForwards) {
550 startTime+=fCurrentTimeOffset;
551 } else if (fDirection==kBackwards) {
552 startTime=GetEndTime();
553 }
554 }
555 return startTime;
556}
557
558AliHLTUInt16_t AliHLTAltroGenerator::GetEndTime()
559{
560 // see header file for class documentation
561 if (!fpSimData || GetBunchSize()==0) return 0;
562 AliHLTUInt16_t endTime=0;
563 if (fDirection==kForwards) {
564 endTime=fpSimData->At(fCurrentBunch+fpSimData->At(fCurrentBunch)+2);
565 } else if (fDirection==kBackwards) {
566 endTime=fpSimData->At(fCurrentBunch-1);
567 }
568 if (fCurrentTimeOffset>=0) {
569 assert(fCurrentTimeOffset<fpSimData->At(fCurrentBunch));
570 if (fDirection==kForwards) {
571 endTime=GetStartTime();
572 } else if (fDirection==kBackwards) {
573 endTime-=fCurrentTimeOffset;
574 }
575 }
576 return endTime;
577}
578
579const Short_t* AliHLTAltroGenerator::GetSignals()
580{
581 // see header file for class documentation
582 if (!fpSimData || GetBunchSize()==0) return NULL;
583 if (fDirection==kForwards) {
584 return fpSimData->GetArray()+fCurrentBunch+2;
585 } else if (fDirection==kBackwards) {
586 return fpSimData->GetArray()+(fCurrentBunch-fpSimData->At(fCurrentBunch)-1);
587 }
588 return NULL;
589}
590
591void AliHLTAltroGenerator::Print()
592{
593 // see header file for class documentation
594 cout << *this << endl;
595}
596
597ostream &operator<<(ostream &stream, AliHLTAltroGenerator &generator)
598{
599 // see header file for class documentation
600 int iResult=0;
601 Short_t channelAddress=-1;
602 for (vector<AliHLTAltroGenerator::AliChannelPosition>::iterator element=generator.fChannelPositions.begin();
603 element!=generator.fChannelPositions.end() && iResult>=0;
604 element++) {
605 if (!generator.fpSimData ||
606 generator.fpSimData->GetSize()<=element->fPosition ||
607 generator.fNof10BitWords==0) {
608 stream << "AliHLTAltroGenerator: no data available" << endl;;
609 break;
610 }
611 channelAddress=element->fChannel;
612 assert(generator.fpSimData->At(element->fPosition)==channelAddress);
613 if (generator.fpSimData->At(element->fPosition)!=channelAddress) {
614 stream << "AliHLTAltroGenerator: internal data mismatch" << endl;;
615 iResult=-ENODATA;
616 break;
617 }
618 int dataPos=element->fPosition+1;
619 int nofBunches=generator.fpSimData->At(dataPos++);
620 stream << "***************************************************************" << endl;
621 stream << "channel address: " << channelAddress << " " << nofBunches << " bunch(es)" << endl;
622 int bunch=0;
623 for (; bunch<nofBunches; bunch++) {
624 int bunchLength=generator.fpSimData->At(dataPos++);
625 int startTime=generator.fpSimData->At(dataPos++);
626 int time=startTime;
627 stream << " length " << bunchLength << " start time " << startTime << ": ";
628 for (; time<startTime+bunchLength; time++) {
629 stream << " " << generator.fpSimData->At(dataPos++);
630 }
631 assert(time-1==generator.fpSimData->At(dataPos));
632 dataPos++; // DO NOT PUT INTO ASSERT
633 assert(bunchLength==generator.fpSimData->At(dataPos));
634 dataPos++; // DO NOT PUT INTO ASSERT
635 stream << " -> end time " << time-1 << endl;
636 }
637
638 if (iResult>=0 && channelAddress>=0) {
639 assert(nofBunches==generator.fpSimData->At(dataPos));
640 dataPos++; // DO NOT PUT INTO ASSERT
641 assert(channelAddress==generator.fpSimData->At(dataPos));
642 dataPos++; // DO NOT PUT INTO ASSERT
643 }
644 }
645
646 return stream;
647}