4bff842117a6991959ab44ee1e42f7f491630eec
[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(Bool_t autoPedestal, Short_t threshold)
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
207   if(autoPedestal) {
208     Short_t array[1024];
209     Short_t* val;
210     val = beg + 1;    
211     while(val <= end) {
212       array[(val-beg)/2] = *val;
213       val += 2;
214     }    
215     Short_t pedestal = TMath::Nint(TMath::Median((end-beg)/2, array));
216     val = beg + 1;
217     while(val <= end) {
218       *val -= pedestal;
219       val += 2;
220     }
221     Short_t* wpos = beg;
222     Short_t* rpos = beg;
223     while(rpos < end) {
224       if(rpos[1] > threshold) {
225         wpos[0] = rpos[0];
226         wpos[1] = rpos[1];
227         wpos += 2;
228       }
229       rpos += 2;
230     }
231     end = wpos;
232   }
233
234   Short_t* wpos = beg;
235   Short_t* rpos = beg;
236
237   // Compress pad buffer
238   while(rpos < end) {
239     Short_t* spos = rpos;
240     Short_t  t    = spos[0];
241     while(true) {
242       rpos += 2;
243       if(rpos >= end || *rpos > t + 1 || t == 0)
244         break;
245       ++t;
246     }
247     Short_t n = t - spos[0] + 1;
248     if(n == 1) {
249       wpos[0] = -spos[0];
250       wpos[1] =  spos[1];
251       wpos += 2;
252     } else {
253       wpos[0] = spos[0];
254       wpos[2] = spos[1];
255       wpos[1] = n;
256       wpos += 3; spos += 3;
257       while(--n) {
258         *wpos = *spos;
259         ++wpos; spos += 2;
260       }
261     }
262   }
263
264   // Copy buffer to storage, set PadData
265   if(wpos > beg) {
266     Short_t len = wpos - beg;
267     if(len > fBlockSize - fBlockPos)
268       NewBlock();
269     Short_t *dest = fBlocks.back() + fBlockPos;
270     memcpy(dest, beg, len*sizeof(Short_t));
271     fBlockPos += len;
272
273     PadData& pad = fPads[PadIndex(fCurrentRow, fCurrentPad)];
274     pad.SetDataLength(dest, len);
275   }
276
277   ++fNPadsFilled;
278 }
279
280 /**************************************************************************/
281
282 const TPCSectorData::PadData& TPCSectorData::GetPadData(Int_t padAddr)
283 {
284   static const PadData null;
285
286   if(padAddr < 0 || padAddr >= fgNAllPads) return null;
287   return fPads[padAddr];
288 }
289
290 const TPCSectorData::PadData& TPCSectorData::GetPadData(Int_t row, Int_t pad)
291 {
292   static const PadData null;
293
294   Int_t np = GetNPadsInRow(row);
295   if(np == 0 || pad < 0 || pad >= np) return null;
296   return GetPadData(fgRowBegs[row] + pad);
297 }
298
299 TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t padAddr, Short_t thr)
300 {
301   return PadIterator(GetPadData(padAddr), thr);
302 }
303
304 TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t row, Int_t pad, Short_t thr)
305 {
306   return PadIterator(GetPadData(row, pad), thr);
307 }
308
309 TPCSectorData::RowIterator TPCSectorData::MakeRowIterator(Int_t row, Short_t thr)
310 {
311   Short_t npads = GetNPadsInRow(row);
312   if(npads > 0)
313     return RowIterator(&fPads[fgRowBegs[row]], npads, thr);
314   else
315     return RowIterator(0, 0);
316 }
317
318 /**************************************************************************/
319 // TPCSectorData::PadData
320 /**************************************************************************/
321
322 void TPCSectorData::PadData::Print(Option_t* /*opt*/)
323 {
324   printf("addr=%p, len=%hd>\n", (void*)fData, fLength);
325   for(Int_t i=0; i<fLength; ++i)
326     printf("  %3d %hd\n", i, fData[i]);
327 }
328
329 /**************************************************************************/
330 // TPCSectorData::PadIterator
331 /**************************************************************************/
332
333 Bool_t TPCSectorData::PadIterator::Next()
334 {
335   if(fPos >= fEnd) return kFALSE;
336   if(fNChunk > 0) {
337     ++fTime;
338     --fNChunk;
339     fSignal = *fPos; ++fPos;
340   } else {
341     fTime = fPos[0];
342     if(fTime <= 0) {
343       fTime   = -fTime;
344       fSignal = fPos[1];
345       fPos += 2;
346     } else {
347       fNChunk = fPos[1] - 1;
348       fSignal = fPos[2];
349       fPos += 3;
350     }
351   }
352   return (fSignal > fThreshold) ? kTRUE : Next();
353 }
354
355 void TPCSectorData::PadIterator::Reset()
356 {
357   // Return to the beginning of the pad-data. Must call Next() to get to
358   // the first stored signal.
359
360   fPos    = fBeg;
361   fTime   = -1;
362   fSignal = -1;
363   fNChunk = 0;
364 }
365
366 void TPCSectorData::PadIterator::Reset(const PadData& pd)
367 {
368   // Reinitialize to new pad-data. Must call Next() to get to the
369   // first stored signal.
370
371   fBeg = pd.Data();
372   fEnd = pd.Data() + pd.Length();
373   fPos = pd.Data();
374   Reset();
375 }
376
377 void TPCSectorData::PadIterator::Test()
378 {
379   while(Next())
380     printf("  %3d %d\n", fTime, fSignal);
381 }
382
383 /**************************************************************************/
384 // TPCSectorData::RowIterator
385 /**************************************************************************/
386
387 Bool_t TPCSectorData::RowIterator::NextPad()
388 {
389   ++fPad;
390   if(fPad >= fNPads) return kFALSE;
391   Reset(fPadArray[fPad]);
392   return kTRUE;
393 }
394
395 void TPCSectorData::RowIterator::ResetRow()
396 {
397   // Return to the beginning of the row. Must call NextPad() to get to
398   // the zeroth pad.
399
400   fPad = -1;
401 }
402
403 void TPCSectorData::RowIterator::ResetRow(const PadData* first, Short_t npads)
404 {
405   // Reinitialize to another pad-data array. Must call NextPad() to
406   // get to the zeroth pad.
407
408   fPadArray =  first;
409   fNPads    =  npads;
410   fPad      = -1;
411 }
412
413 void TPCSectorData::RowIterator::Test()
414 {
415   while(NextPad()) {
416     printf("Pad %d\n", fPad);
417     PadIterator::Test();
418   }
419 }
420
421 /**************************************************************************/
422 // TPCSectorData::SegmentInfo
423 /**************************************************************************/
424
425 ClassImp(TPCSectorData::SegmentInfo)
426
427 TPCSectorData::SegmentInfo::SegmentInfo()
428 {
429   memset(this, sizeof(SegmentInfo), 0);
430 }