454d5d886a34ef22fda53eff8a4d26471ec5ec87
[u/mrichter/AliRoot.git] / EVE / Alieve / TPCSectorData.cxx
1 // $Header$
2
3 #include "TPCSectorData.h"
4 #include <AliTPCParamSR.h>
5
6 #include <string.h>
7
8 //______________________________________________________________________
9 // TPCSectorData
10 //
11 // Stores data from a fiven TPC sector.
12 //
13 // Row addresses grow linearly by radius, there is no separation on
14 // inner/outer segments. The SegmentInfo objects can be used to get
15 // information about low-level segments.
16 //
17 // A lot of TPC-sector information is stored as static data.
18 //
19 // For accessing data, see for example TPCSector2DGL::CreateTexture()
20 // and LoadPadrow().
21 //
22
23 using namespace Reve;
24 using namespace Alieve;
25
26 ClassImp(TPCSectorData)
27
28 AliTPCParam* TPCSectorData::fgParam    = 0;
29 Int_t        TPCSectorData::fgNAllRows = 0;
30 Int_t        TPCSectorData::fgNAllPads = 0;
31 Int_t*       TPCSectorData::fgRowBegs  = 0;
32
33 TPCSectorData::SegmentInfo TPCSectorData::fgInnSeg;
34 TPCSectorData::SegmentInfo TPCSectorData::fgOut1Seg;
35 TPCSectorData::SegmentInfo TPCSectorData::fgOut2Seg;
36
37 TPCSectorData::SegmentInfo* TPCSectorData::fgSegInfoPtrs[3] = {0};
38
39 /**************************************************************************/
40
41 void TPCSectorData::InitStatics()
42 {
43   if(fgParam != 0) return;
44
45   fgParam    = new AliTPCParamSR;
46   fgNAllRows = fgParam->GetNRowLow() + fgParam->GetNRowUp();
47   fgNAllPads = 0;
48   fgRowBegs  = new Int_t[fgNAllRows + 1];
49
50   Int_t row = 0;
51   for(Int_t i=0; i<fgParam->GetNRowLow(); ++i, ++row) {
52     fgRowBegs[row] = fgNAllPads;
53     fgNAllPads += fgParam->GetNPadsLow(i);
54   }
55   for(Int_t i=0; i<fgParam->GetNRowUp(); ++i, ++row) {
56     fgRowBegs[row] = fgNAllPads;
57     fgNAllPads += fgParam->GetNPadsUp(i);
58   }
59   fgRowBegs[fgNAllRows] = fgNAllPads;
60
61
62   // Fill SegmentInfos, used by rendering classes.
63
64   // General paramameters
65   fgInnSeg.fPadWidth   = fgParam->GetInnerPadPitchWidth();
66   fgInnSeg.fPadHeight  = fgParam->GetInnerPadPitchLength();
67   fgInnSeg.fRLow       = fgParam->GetPadRowRadiiLow(0);
68   fgInnSeg.fNRows      = fgParam->GetNRowLow();
69   fgInnSeg.fFirstRow   = 0;
70   fgInnSeg.fLastRow    = fgInnSeg.fNRows - 1;
71   fgInnSeg.fNMaxPads   = fgParam->GetNPadsLow(fgInnSeg.fNRows - 1);
72   fgSegInfoPtrs[0]     = &fgInnSeg;
73
74   fgOut1Seg.fPadWidth  = fgParam->GetOuterPadPitchWidth();
75   fgOut1Seg.fPadHeight = fgParam->GetOuter1PadPitchLength();
76   fgOut1Seg.fRLow      = fgParam->GetPadRowRadiiUp(0);
77   fgOut1Seg.fNRows     = fgParam->GetNRowUp1();
78   fgOut1Seg.fFirstRow  = fgInnSeg.fNRows;
79   fgOut1Seg.fLastRow   = fgOut1Seg.fFirstRow + fgOut1Seg.fNRows - 1;
80   fgOut1Seg.fNMaxPads  = fgParam->GetNPadsUp(fgOut1Seg.fNRows - 1);
81   fgSegInfoPtrs[1]     = &fgOut1Seg;
82  
83   fgOut2Seg.fPadWidth  = fgParam->GetOuterPadPitchWidth();
84   fgOut2Seg.fPadHeight = fgParam->GetOuter2PadPitchLength();
85   fgOut2Seg.fRLow      = fgParam->GetPadRowRadiiUp(fgOut1Seg.fNRows);
86   fgOut2Seg.fNRows     = fgParam->GetNRowUp() - fgOut1Seg.fNRows;
87   fgOut2Seg.fFirstRow  = fgOut1Seg.fLastRow + 1;
88   fgOut2Seg.fLastRow   = fgOut2Seg.fFirstRow + fgOut2Seg.fNRows - 1;
89   fgOut2Seg.fNMaxPads  = fgParam->GetNPadsUp(fgParam->GetNRowUp() - 1);
90   fgSegInfoPtrs[2]     = &fgOut2Seg;
91
92   // Set stepsize array
93   Int_t k, npads;
94   // Inn
95   k=0, npads = fgParam->GetNPadsLow(0);
96   for (int row = 0; row < fgInnSeg.fNRows; ++row) {
97     if (fgParam->GetNPadsLow(row) > npads) {
98       npads = fgParam->GetNPadsLow(row);
99       fgInnSeg.fYStep[k] = row*fgInnSeg.fPadHeight + fgInnSeg.fRLow;
100       k++;
101     }
102   }
103   fgInnSeg.fNYSteps = k;
104   // Out1 seg 
105   k=0; npads = fgParam->GetNPadsUp(0);
106   for (int row = 0; row < fgOut1Seg.fNRows; ++row) {
107     if (fgParam->GetNPadsUp(row) > npads) {
108       npads = fgParam->GetNPadsUp(row);
109       fgOut1Seg.fYStep[k] = row*fgOut1Seg.fPadHeight + fgOut1Seg.fRLow ;
110       k++;
111     }
112   }
113   fgOut1Seg.fNYSteps = k;
114   // Out2 seg
115   k=0; npads = fgParam->GetNPadsUp(fgOut1Seg.fNRows);
116   for (int row = fgOut1Seg.fNRows; row < fgParam->GetNRowUp() ;row++ ) {
117     if (fgParam->GetNPadsUp(row) > npads) {
118       npads = fgParam->GetNPadsUp(row);
119       fgOut2Seg.fYStep[k] = (row - fgOut1Seg.fNRows)*fgOut2Seg.fPadHeight + fgOut2Seg.fRLow ;
120       k++;
121     }
122   }
123   fgOut2Seg.fNYSteps = k;
124 }
125
126 Int_t TPCSectorData::GetNPadsInRow(Int_t row)
127 {
128   if(row < 0 || row >= fgNAllRows) return 0;
129   return fgRowBegs[row + 1] - fgRowBegs[row];
130 }
131
132 const TPCSectorData::SegmentInfo& TPCSectorData::GetSeg(Int_t seg)
133 {
134   static const SegmentInfo null;
135
136   if(seg < 0 || seg > 2)
137     return null;
138   else
139     return *fgSegInfoPtrs[seg];
140 }
141
142 /**************************************************************************/
143 // True member functions start here.
144 /**************************************************************************/
145
146 void TPCSectorData::NewBlock()
147 {
148   fBlocks.push_back(new Short_t[fBlockSize]);
149   fBlockPos = 0;
150 }
151
152 /**************************************************************************/
153
154 TPCSectorData::TPCSectorData(Int_t sector, Int_t bsize) :
155   fSectorID(sector), fNPadsFilled(0),
156   fBlockSize(bsize), fBlockPos(0),
157   fCurrentRow(0), fCurrentPad(0), fCurrentPos(0)
158 {
159   if(fgParam == 0) InitStatics();
160
161   fPads.assign(fgNAllPads, PadData());
162   fBlocks.reserve(16);
163   fBlockPos = fBlockSize; // Enforce creation of a new block.
164 }
165
166
167 TPCSectorData::~TPCSectorData()
168 {
169   for(std::vector<Short_t*>::iterator b=fBlocks.begin(); b!=fBlocks.end(); ++b)
170     delete [] *b;
171 }
172
173 /**************************************************************************/
174
175 void TPCSectorData::Print(Option_t* /*opt*/) const
176 {
177   printf("TPCSectorData sector=%d, NPadsFilled=%d, NBlocks=%d, BlockPos=%d\n",
178          fSectorID, fNPadsFilled, fBlocks.size(), fBlockPos);
179 }
180
181 /**************************************************************************/
182
183 void TPCSectorData::BeginPad(Int_t row, Int_t pad, Bool_t reverseTime)
184 {
185   fCurrentRow = row;
186   fCurrentPad = pad;
187   if(reverseTime) {
188     fCurrentPos  = 2046;
189     fCurrentStep = -2;
190   } else {
191     fCurrentPos  = 0;
192     fCurrentStep = 2;
193   }
194 }
195
196 void TPCSectorData::EndPad()
197 {
198   Short_t *beg, *end;
199   if(fCurrentStep > 0) {
200     beg = fPadBuffer;
201     end = fPadBuffer + fCurrentPos;
202   } else {
203     beg = fPadBuffer + fCurrentPos + 2;
204     end = fPadBuffer + 2048;
205   }
206   Short_t* wpos = beg;
207   Short_t* rpos = beg;
208
209   // Compress pad buffer
210   while(rpos < end) {
211     Short_t* spos = rpos;
212     Short_t  t    = spos[0];
213     while(true) {
214       rpos += 2;
215       if(rpos >= end || *rpos > t + 1 || t == 0)
216         break;
217       ++t;
218     }
219     Short_t n = t - spos[0] + 1;
220     if(n == 1) {
221       wpos[0] = -spos[0];
222       wpos[1] =  spos[1];
223       wpos += 2;
224     } else {
225       wpos[0] = spos[0];
226       wpos[2] = spos[1];
227       wpos[1] = n;
228       wpos += 3; spos += 3;
229       while(--n) {
230         *wpos = *spos;
231         ++wpos; spos += 2;
232       }
233     }
234   }
235
236   // Copy buffer to storage, set PadData
237   if(wpos > beg) {
238     Short_t len = wpos - beg;
239     if(len > fBlockSize - fBlockPos)
240       NewBlock();
241     Short_t *dest = fBlocks.back() + fBlockPos;
242     memcpy(dest, beg, len*sizeof(Short_t));
243     fBlockPos += len;
244
245     PadData& pad = fPads[PadIndex(fCurrentRow, fCurrentPad)];
246     pad.SetDataLength(dest, len);
247   }
248
249   ++fNPadsFilled;
250 }
251
252 /**************************************************************************/
253
254 const TPCSectorData::PadData& TPCSectorData::GetPadData(Int_t padAddr)
255 {
256   static const PadData null;
257
258   if(padAddr < 0 || padAddr >= fgNAllPads) return null;
259   return fPads[padAddr];
260 }
261
262 const TPCSectorData::PadData& TPCSectorData::GetPadData(Int_t row, Int_t pad)
263 {
264   static const PadData null;
265
266   Int_t np = GetNPadsInRow(row);
267   if(np == 0 || pad < 0 || pad >= np) return null;
268   return GetPadData(fgRowBegs[row] + pad);
269 }
270
271 TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t padAddr, Short_t thr)
272 {
273   return PadIterator(GetPadData(padAddr), thr);
274 }
275
276 TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t row, Int_t pad, Short_t thr)
277 {
278   return PadIterator(GetPadData(row, pad), thr);
279 }
280
281 TPCSectorData::RowIterator TPCSectorData::MakeRowIterator(Int_t row, Short_t thr)
282 {
283   Short_t npads = GetNPadsInRow(row);
284   if(npads > 0)
285     return RowIterator(&fPads[fgRowBegs[row]], npads, thr);
286   else
287     return RowIterator(0, 0);
288 }
289
290 /**************************************************************************/
291 // TPCSectorData::PadData
292 /**************************************************************************/
293
294 void TPCSectorData::PadData::Print(Option_t* /*opt*/)
295 {
296   printf("addr=%p, len=%hd>\n", (void*)fData, fLength);
297   for(Int_t i=0; i<fLength; ++i)
298     printf("  %3d %hd\n", i, fData[i]);
299 }
300
301 /**************************************************************************/
302 // TPCSectorData::PadIterator
303 /**************************************************************************/
304
305 Bool_t TPCSectorData::PadIterator::Next()
306 {
307   if(fPos >= fEnd) return kFALSE;
308   if(fNChunk > 0) {
309     ++fTime;
310     --fNChunk;
311     fSignal = *fPos; ++fPos;
312   } else {
313     fTime = fPos[0];
314     if(fTime <= 0) {
315       fTime   = -fTime;
316       fSignal = fPos[1];
317       fPos += 2;
318     } else {
319       fNChunk = fPos[1] - 1;
320       fSignal = fPos[2];
321       fPos += 3;
322     }
323   }
324   return (fSignal > fThreshold) ? kTRUE : Next();
325 }
326
327 void TPCSectorData::PadIterator::Reset()
328 {
329   // Return to the beginning of the pad-data. Must call Next() to get to
330   // the first stored signal.
331
332   fPos    = fBeg;
333   fTime   = -1;
334   fSignal = -1;
335   fNChunk = 0;
336 }
337
338 void TPCSectorData::PadIterator::Reset(const PadData& pd)
339 {
340   // Reinitialize to new pad-data. Must call Next() to get to the
341   // first stored signal.
342
343   fBeg = pd.Data();
344   fEnd = pd.Data() + pd.Length();
345   fPos = pd.Data();
346   Reset();
347 }
348
349 void TPCSectorData::PadIterator::Test()
350 {
351   while(Next())
352     printf("  %3d %d\n", fTime, fSignal);
353 }
354
355 /**************************************************************************/
356 // TPCSectorData::RowIterator
357 /**************************************************************************/
358
359 Bool_t TPCSectorData::RowIterator::NextPad()
360 {
361   ++fPad;
362   if(fPad >= fNPads) return kFALSE;
363   Reset(fPadArray[fPad]);
364   return kTRUE;
365 }
366
367 void TPCSectorData::RowIterator::ResetRow()
368 {
369   // Return to the beginning of the row. Must call NextPad() to get to
370   // the zeroth pad.
371
372   fPad = -1;
373 }
374
375 void TPCSectorData::RowIterator::ResetRow(const PadData* first, Short_t npads)
376 {
377   // Reinitialize to another pad-data array. Must call NextPad() to
378   // get to the zeroth pad.
379
380   fPadArray =  first;
381   fNPads    =  npads;
382   fPad      = -1;
383 }
384
385 void TPCSectorData::RowIterator::Test()
386 {
387   while(NextPad()) {
388     printf("Pad %d\n", fPad);
389     PadIterator::Test();
390   }
391 }
392
393 /**************************************************************************/
394 // TPCSectorData::SegmentInfo
395 /**************************************************************************/
396
397 ClassImp(TPCSectorData::SegmentInfo)
398
399 TPCSectorData::SegmentInfo::SegmentInfo()
400 {
401   memset(this, sizeof(SegmentInfo), 0);
402 }