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