Support for automatic pedestal estimation per pad (Marian and Matevz).
[u/mrichter/AliRoot.git] / EVE / Alieve / TPCSectorData.cxx
CommitLineData
915dabe1 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
23using namespace Reve;
24using namespace Alieve;
25
2aef44c1 26ClassImp(TPCSectorData)
915dabe1 27
28AliTPCParam* TPCSectorData::fgParam = 0;
29Int_t TPCSectorData::fgNAllRows = 0;
30Int_t TPCSectorData::fgNAllPads = 0;
31Int_t* TPCSectorData::fgRowBegs = 0;
32
33TPCSectorData::SegmentInfo TPCSectorData::fgInnSeg;
34TPCSectorData::SegmentInfo TPCSectorData::fgOut1Seg;
35TPCSectorData::SegmentInfo TPCSectorData::fgOut2Seg;
36
37TPCSectorData::SegmentInfo* TPCSectorData::fgSegInfoPtrs[3] = {0};
38
39/**************************************************************************/
40
41void 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
126Int_t TPCSectorData::GetNPadsInRow(Int_t row)
127{
128 if(row < 0 || row >= fgNAllRows) return 0;
129 return fgRowBegs[row + 1] - fgRowBegs[row];
130}
131
132const 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
146void TPCSectorData::NewBlock()
147{
148 fBlocks.push_back(new Short_t[fBlockSize]);
149 fBlockPos = 0;
150}
151
152/**************************************************************************/
153
154TPCSectorData::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
167TPCSectorData::~TPCSectorData()
168{
169 for(std::vector<Short_t*>::iterator b=fBlocks.begin(); b!=fBlocks.end(); ++b)
170 delete [] *b;
171}
172
173/**************************************************************************/
174
175void 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
183void 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
d6433e5d 196void TPCSectorData::EndPad(Bool_t autoPedestal, Short_t threshold)
915dabe1 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 }
d6433e5d 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
915dabe1 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
282const 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
290const 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
299TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t padAddr, Short_t thr)
300{
301 return PadIterator(GetPadData(padAddr), thr);
302}
303
304TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t row, Int_t pad, Short_t thr)
305{
306 return PadIterator(GetPadData(row, pad), thr);
307}
308
309TPCSectorData::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
322void 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
333Bool_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
355void 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
366void 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
377void TPCSectorData::PadIterator::Test()
378{
379 while(Next())
380 printf(" %3d %d\n", fTime, fSignal);
381}
382
383/**************************************************************************/
384// TPCSectorData::RowIterator
385/**************************************************************************/
386
387Bool_t TPCSectorData::RowIterator::NextPad()
388{
389 ++fPad;
390 if(fPad >= fNPads) return kFALSE;
391 Reset(fPadArray[fPad]);
392 return kTRUE;
393}
394
395void 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
403void 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
413void 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
2aef44c1 425ClassImp(TPCSectorData::SegmentInfo)
915dabe1 426
427TPCSectorData::SegmentInfo::SegmentInfo()
428{
429 memset(this, sizeof(SegmentInfo), 0);
430}