]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/Alieve/TPCSectorData.cxx
Removed overlaps. Geometry as installed, i.e. the drift length in both direction...
[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 Float_t      TPCSectorData::fgZLength  = 0;
30 Int_t        TPCSectorData::fgNAllRows = 0;
31 Int_t        TPCSectorData::fgNAllPads = 0;
32 Int_t*       TPCSectorData::fgRowBegs  = 0;
33
34 TPCSectorData::SegmentInfo TPCSectorData::fgInnSeg;
35 TPCSectorData::SegmentInfo TPCSectorData::fgOut1Seg;
36 TPCSectorData::SegmentInfo TPCSectorData::fgOut2Seg;
37
38 TPCSectorData::SegmentInfo* TPCSectorData::fgSegInfoPtrs[3] = {0};
39
40 /**************************************************************************/
41
42 void TPCSectorData::InitStatics()
43 {
44   if(fgParam != 0) return;
45
46   fgParam    = new AliTPCParamSR;
47   fgZLength  = fgParam->GetZLength(0)+0.275;
48   fgNAllRows = fgParam->GetNRowLow() + fgParam->GetNRowUp();
49   fgNAllPads = 0;
50   fgRowBegs  = new Int_t[fgNAllRows + 1];
51
52   Int_t row = 0;
53   for(Int_t i=0; i<fgParam->GetNRowLow(); ++i, ++row) {
54     fgRowBegs[row] = fgNAllPads;
55     fgNAllPads += fgParam->GetNPadsLow(i);
56   }
57   for(Int_t i=0; i<fgParam->GetNRowUp(); ++i, ++row) {
58     fgRowBegs[row] = fgNAllPads;
59     fgNAllPads += fgParam->GetNPadsUp(i);
60   }
61   fgRowBegs[fgNAllRows] = fgNAllPads;
62
63
64   // Fill SegmentInfos, used by rendering classes.
65
66   // General paramameters
67   fgInnSeg.fPadWidth   = fgParam->GetInnerPadPitchWidth();
68   fgInnSeg.fPadHeight  = fgParam->GetInnerPadPitchLength();
69   fgInnSeg.fRLow       = fgParam->GetPadRowRadiiLow(0);
70   fgInnSeg.fNRows      = fgParam->GetNRowLow();
71   fgInnSeg.fFirstRow   = 0;
72   fgInnSeg.fLastRow    = fgInnSeg.fNRows - 1;
73   fgInnSeg.fNMaxPads   = fgParam->GetNPadsLow(fgInnSeg.fNRows - 1);
74   fgSegInfoPtrs[0]     = &fgInnSeg;
75
76   fgOut1Seg.fPadWidth  = fgParam->GetOuterPadPitchWidth();
77   fgOut1Seg.fPadHeight = fgParam->GetOuter1PadPitchLength();
78   fgOut1Seg.fRLow      = fgParam->GetPadRowRadiiUp(0);
79   fgOut1Seg.fNRows     = fgParam->GetNRowUp1();
80   fgOut1Seg.fFirstRow  = fgInnSeg.fNRows;
81   fgOut1Seg.fLastRow   = fgOut1Seg.fFirstRow + fgOut1Seg.fNRows - 1;
82   fgOut1Seg.fNMaxPads  = fgParam->GetNPadsUp(fgOut1Seg.fNRows - 1);
83   fgSegInfoPtrs[1]     = &fgOut1Seg;
84  
85   fgOut2Seg.fPadWidth  = fgParam->GetOuterPadPitchWidth();
86   fgOut2Seg.fPadHeight = fgParam->GetOuter2PadPitchLength();
87   fgOut2Seg.fRLow      = fgParam->GetPadRowRadiiUp(fgOut1Seg.fNRows);
88   fgOut2Seg.fNRows     = fgParam->GetNRowUp() - fgOut1Seg.fNRows;
89   fgOut2Seg.fFirstRow  = fgOut1Seg.fLastRow + 1;
90   fgOut2Seg.fLastRow   = fgOut2Seg.fFirstRow + fgOut2Seg.fNRows - 1;
91   fgOut2Seg.fNMaxPads  = fgParam->GetNPadsUp(fgParam->GetNRowUp() - 1);
92   fgSegInfoPtrs[2]     = &fgOut2Seg;
93
94   // Set stepsize array
95   Int_t k, npads;
96   // Inn
97   k=0, npads = fgParam->GetNPadsLow(0);
98   for (int row = 0; row < fgInnSeg.fNRows; ++row) {
99     if (fgParam->GetNPadsLow(row) > npads) {
100       npads = fgParam->GetNPadsLow(row);
101       fgInnSeg.fYStep[k] = row*fgInnSeg.fPadHeight + fgInnSeg.fRLow;
102       k++;
103     }
104   }
105   fgInnSeg.fNYSteps = k;
106   // Out1 seg 
107   k=0; npads = fgParam->GetNPadsUp(0);
108   for (int row = 0; row < fgOut1Seg.fNRows; ++row) {
109     if (fgParam->GetNPadsUp(row) > npads) {
110       npads = fgParam->GetNPadsUp(row);
111       fgOut1Seg.fYStep[k] = row*fgOut1Seg.fPadHeight + fgOut1Seg.fRLow ;
112       k++;
113     }
114   }
115   fgOut1Seg.fNYSteps = k;
116   // Out2 seg
117   k=0; npads = fgParam->GetNPadsUp(fgOut1Seg.fNRows);
118   for (int row = fgOut1Seg.fNRows; row < fgParam->GetNRowUp() ;row++ ) {
119     if (fgParam->GetNPadsUp(row) > npads) {
120       npads = fgParam->GetNPadsUp(row);
121       fgOut2Seg.fYStep[k] = (row - fgOut1Seg.fNRows)*fgOut2Seg.fPadHeight + fgOut2Seg.fRLow ;
122       k++;
123     }
124   }
125   fgOut2Seg.fNYSteps = k;
126 }
127
128 Int_t TPCSectorData::GetNPadsInRow(Int_t row)
129 {
130   if(row < 0 || row >= fgNAllRows) return 0;
131   return fgRowBegs[row + 1] - fgRowBegs[row];
132 }
133
134 const TPCSectorData::SegmentInfo& TPCSectorData::GetSeg(Int_t seg)
135 {
136   static const SegmentInfo null;
137
138   if(seg < 0 || seg > 2)
139     return null;
140   else
141     return *fgSegInfoPtrs[seg];
142 }
143
144 /**************************************************************************/
145 // True member functions start here.
146 /**************************************************************************/
147
148 void TPCSectorData::NewBlock()
149 {
150   fBlocks.push_back(new Short_t[fBlockSize]);
151   fBlockPos = 0;
152 }
153
154 /**************************************************************************/
155
156 TPCSectorData::TPCSectorData(Int_t sector, Int_t bsize) :
157   fSectorID(sector), fNPadsFilled(0), fPads(),
158   fBlockSize(bsize), fBlockPos(0),    fBlocks(),
159   fCurrentRow(0), fCurrentPad(0), fCurrentPos(0), fCurrentStep(0),
160   fPadRowHackSet(0)
161 {
162   if(fgParam == 0) InitStatics();
163
164   fPads.assign(fgNAllPads, PadData());
165   fBlocks.reserve(16);
166   fBlockPos = fBlockSize; // Enforce creation of a new block.
167 }
168
169
170 TPCSectorData::~TPCSectorData()
171 {
172   for(std::vector<Short_t*>::iterator b=fBlocks.begin(); b!=fBlocks.end(); ++b)
173     delete [] *b;
174   DeletePadRowHack();
175 }
176
177 void TPCSectorData::DropData()
178 {
179   fPads.assign(fgNAllPads, PadData());
180   for(std::vector<Short_t*>::iterator b=fBlocks.begin(); b!=fBlocks.end(); ++b)
181     delete [] *b;
182   fBlocks.clear();
183   fBlockPos = fBlockSize; // Enforce creation of a new block.
184 }
185
186 /**************************************************************************/
187
188 void TPCSectorData::Print(Option_t* /*opt*/) const
189 {
190   printf("TPCSectorData sector=%d, NPadsFilled=%d, NBlocks=%d, BlockPos=%d\n",
191          fSectorID, fNPadsFilled, fBlocks.size(), fBlockPos);
192 }
193
194 /**************************************************************************/
195
196 void TPCSectorData::BeginPad(Int_t row, Int_t pad, Bool_t reverseTime)
197 {
198   fCurrentRow = row;
199   fCurrentPad = pad;
200   if(reverseTime) {
201     fCurrentPos  = 2046;
202     fCurrentStep = -2;
203   } else {
204     fCurrentPos  = 0;
205     fCurrentStep = 2;
206   }
207   //printf("begpad for row=%d pad=%d\n  buf=%p pos=%d step=%d\n",
208   //     fCurrentRow, fCurrentPad,
209   //     fPadBuffer, fCurrentPos, fCurrentStep);
210 }
211
212 void TPCSectorData::EndPad(Bool_t autoPedestal, Short_t threshold)
213 {
214   Short_t *beg, *end;
215   if(fCurrentStep > 0) {
216     beg = fPadBuffer;
217     end = fPadBuffer + fCurrentPos;
218   } else {
219     beg = fPadBuffer + fCurrentPos + 2;
220     end = fPadBuffer + 2048;
221   }
222
223   //printf("endpad for row=%d pad=%d\n  buf=%p beg=%p end=%p pos=%d step=%d\n",
224   //     fCurrentRow, fCurrentPad,
225   //     fPadBuffer, beg, end, fCurrentPos, fCurrentStep);
226   if(beg >= end)
227     return;
228
229   if(autoPedestal) {
230     Short_t array[1024];
231     Short_t* val;
232     val = beg + 1;    
233     while(val <= end) {
234       array[(val-beg)/2] = *val;
235       val += 2;
236     }    
237     Short_t pedestal = TMath::Nint(TMath::Median((end-beg)/2, array));
238     val = beg + 1;
239     while(val <= end) {
240       *val -= pedestal;
241       val += 2;
242     }
243     Short_t* wpos = beg;
244     Short_t* rpos = beg;
245     while(rpos < end) {
246       if(rpos[1] >= threshold) {
247         wpos[0] = rpos[0];
248         wpos[1] = rpos[1];
249         wpos += 2;
250       }
251       rpos += 2;
252     }
253     end = wpos;
254   }
255
256   Short_t* wpos = beg;
257   Short_t* rpos = beg;
258
259   // Compress pad buffer
260   while(rpos < end) {
261     Short_t* spos = rpos;
262     Short_t  t    = spos[0];
263     while(true) {
264       rpos += 2;
265       if(rpos >= end || *rpos > t + 1 || t == 0)
266         break;
267       ++t;
268     }
269     Short_t n = t - spos[0] + 1;
270     if(n == 1) {
271       wpos[0] = -spos[0];
272       wpos[1] =  spos[1];
273       wpos += 2;
274     } else {
275       wpos[0] = spos[0];
276       wpos[2] = spos[1];
277       wpos[1] = n;
278       wpos += 3; spos += 3;
279       while(--n) {
280         *wpos = *spos;
281         ++wpos; spos += 2;
282       }
283     }
284   }
285
286   // Copy buffer to storage, set PadData
287   if(wpos > beg) {
288     Short_t len = wpos - beg;
289     if(len > fBlockSize - fBlockPos)
290       NewBlock();
291     Short_t *dest = fBlocks.back() + fBlockPos;
292     memcpy(dest, beg, len*sizeof(Short_t));
293     fBlockPos += len;
294
295     PadData& pad = fPads[PadIndex(fCurrentRow, fCurrentPad)];
296     pad.SetDataLength(dest, len);
297   }
298
299   ++fNPadsFilled;
300 }
301
302 /**************************************************************************/
303
304 const TPCSectorData::PadData& TPCSectorData::GetPadData(Int_t padAddr)
305 {
306   static const PadData null;
307
308   if(padAddr < 0 || padAddr >= fgNAllPads) return null;
309   return fPads[padAddr];
310 }
311
312 const TPCSectorData::PadData& TPCSectorData::GetPadData(Int_t row, Int_t pad)
313 {
314   static const PadData null;
315
316   Int_t np = GetNPadsInRow(row);
317   if(np == 0 || pad < 0 || pad >= np) return null;
318   return GetPadData(fgRowBegs[row] + pad);
319 }
320
321 TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t padAddr, Short_t thr)
322 {
323   return PadIterator(GetPadData(padAddr), thr);
324 }
325
326 TPCSectorData::PadIterator TPCSectorData::MakePadIterator(Int_t row, Int_t pad, Short_t thr)
327 {
328   return PadIterator(GetPadData(row, pad), thr);
329 }
330
331 TPCSectorData::RowIterator TPCSectorData::MakeRowIterator(Int_t row, Short_t thr)
332 {
333   Short_t npads = GetNPadsInRow(row);
334   if(npads > 0)
335     return RowIterator(&fPads[fgRowBegs[row]], npads, thr);
336   else
337     return RowIterator(0, 0);
338 }
339
340 /**************************************************************************/
341 // TPCSectorData::PadData
342 /**************************************************************************/
343
344 void TPCSectorData::PadData::Print(Option_t* /*opt*/)
345 {
346   printf("addr=%p, len=%hd>\n", (void*)fData, fLength);
347   for(Int_t i=0; i<fLength; ++i)
348     printf("  %3d %hd\n", i, fData[i]);
349 }
350
351 /**************************************************************************/
352 // TPCSectorData::PadIterator
353 /**************************************************************************/
354
355 Bool_t TPCSectorData::PadIterator::Next()
356 {
357   if(fPos >= fEnd) return kFALSE;
358   if(fNChunk > 0) {
359     ++fTime;
360     --fNChunk;
361     fSignal = *fPos; ++fPos;
362   } else {
363     fTime = fPos[0];
364     if(fTime <= 0) {
365       fTime   = -fTime;
366       fSignal = fPos[1];
367       fPos += 2;
368     } else {
369       fNChunk = fPos[1] - 1;
370       fSignal = fPos[2];
371       fPos += 3;
372     }
373   }
374   return (fSignal > fThreshold) ? kTRUE : Next();
375 }
376
377 void TPCSectorData::PadIterator::Reset()
378 {
379   // Return to the beginning of the pad-data. Must call Next() to get to
380   // the first stored signal.
381
382   fPos    = fBeg;
383   fTime   = -1;
384   fSignal = -1;
385   fNChunk = 0;
386 }
387
388 void TPCSectorData::PadIterator::Reset(const PadData& pd)
389 {
390   // Reinitialize to new pad-data. Must call Next() to get to the
391   // first stored signal.
392
393   fBeg = pd.Data();
394   fEnd = pd.Data() + pd.Length();
395   fPos = pd.Data();
396   Reset();
397 }
398
399 void TPCSectorData::PadIterator::Test()
400 {
401   while(Next())
402     printf("  %3d %d\n", fTime, fSignal);
403 }
404
405 /**************************************************************************/
406 // TPCSectorData::RowIterator
407 /**************************************************************************/
408
409 Bool_t TPCSectorData::RowIterator::NextPad()
410 {
411   ++fPad;
412   if(fPad >= fNPads) return kFALSE;
413   Reset(fPadArray[fPad]);
414   return kTRUE;
415 }
416
417 void TPCSectorData::RowIterator::ResetRow()
418 {
419   // Return to the beginning of the row. Must call NextPad() to get to
420   // the zeroth pad.
421
422   fPad = -1;
423 }
424
425 void TPCSectorData::RowIterator::ResetRow(const PadData* first, Short_t npads)
426 {
427   // Reinitialize to another pad-data array. Must call NextPad() to
428   // get to the zeroth pad.
429
430   fPadArray =  first;
431   fNPads    =  npads;
432   fPad      = -1;
433 }
434
435 void TPCSectorData::RowIterator::Test()
436 {
437   while(NextPad()) {
438     printf("Pad %d\n", fPad);
439     PadIterator::Test();
440   }
441 }
442
443 /**************************************************************************/
444 // TPCSectorData::SegmentInfo
445 /**************************************************************************/
446
447 ClassImp(TPCSectorData::SegmentInfo)
448
449 TPCSectorData::SegmentInfo::SegmentInfo() :
450   TObject(),
451
452   fPadWidth(0), fPadHeight(0),
453   fRLow(0), fNRows(0), fFirstRow(0), fLastRow(0),
454   fNMaxPads(0),
455   fNYSteps(0)
456 {
457   memset(fYStep, sizeof(fYStep), 0);
458 }
459
460 /**************************************************************************/
461 // TPCSectorData::PadRowHack
462 /**************************************************************************/
463
464 TPCSectorData::PadRowHack* TPCSectorData::GetPadRowHack(Int_t r, Int_t p)
465 {
466   if(fPadRowHackSet == 0) return 0;
467   std::set<PadRowHack>* hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
468   std::set<PadRowHack>::iterator i = hs->find(PadRowHack(r,p));
469   return (i == hs->end()) ? 0 : const_cast<PadRowHack*>(&*i);
470 }
471
472 void TPCSectorData::AddPadRowHack(Int_t r, Int_t p, Int_t te, Float_t tf)
473 {
474   if(fPadRowHackSet == 0) fPadRowHackSet = new std::set<PadRowHack>;
475
476   PadRowHack* prh = GetPadRowHack(r, p);
477   if(prh == 0) {
478     std::set<PadRowHack>* hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
479     hs->insert(PadRowHack(r, p, te, tf));
480   } else {
481     prh->fThrExt += te;
482     prh->fThrFac *= tf;
483   }
484 }
485
486 void TPCSectorData::RemovePadRowHack(Int_t r, Int_t p)
487 {
488   if(fPadRowHackSet == 0) return;
489   std::set<PadRowHack>*hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
490   std::set<PadRowHack>::iterator i = hs->find(PadRowHack(r,p));
491   if(i != hs->end()) hs->erase(i);
492 }
493
494 void TPCSectorData::DeletePadRowHack()
495 {
496   if(fPadRowHackSet != 0) {
497     std::set<PadRowHack>*hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
498     delete hs;
499     fPadRowHackSet = 0;
500   }
501 }