]> git.uio.no Git - u/mrichter/AliRoot.git/blob - EVE/EveDet/AliEveTPCSectorData.cxx
From Massimo: remove usage of AliITSgeom, use AliITSgeomTGeo instead.
[u/mrichter/AliRoot.git] / EVE / EveDet / AliEveTPCSectorData.cxx
1 // $Id$
2 // Main authors: Matevz Tadel & Alja Mrak-Tadel: 2006, 2007
3
4 /**************************************************************************
5  * Copyright(c) 1998-2008, ALICE Experiment at CERN, all rights reserved. *
6  * See http://aliceinfo.cern.ch/Offline/AliRoot/License.html for          *
7  * full copyright notice.                                                 *
8  **************************************************************************/
9
10 #include "AliEveTPCSectorData.h"
11 #include <AliTPCParamSR.h>
12
13 #include <string.h>
14
15 //______________________________________________________________________________
16 //
17 // Stores data from a fiven TPC sector.
18 //
19 // Row addresses grow linearly by radius, there is no separation on
20 // inner/outer segments. The SegmentInfo objects can be used to get
21 // information about low-level segments.
22 //
23 // A lot of TPC-sector geometry information is stored as static data.
24 //
25 // For accessing data, see for example AliEveTPCSector2DGL::CreateTexture()
26 // and LoadPadrow().
27 //
28
29 ClassImp(AliEveTPCSectorData)
30
31 AliTPCParam* AliEveTPCSectorData::fgParam    = 0;
32 Float_t      AliEveTPCSectorData::fgZLength  = 0;
33 Int_t        AliEveTPCSectorData::fgNAllRows = 0;
34 Int_t        AliEveTPCSectorData::fgNAllPads = 0;
35 Int_t*       AliEveTPCSectorData::fgRowBegs  = 0;
36
37 AliEveTPCSectorData::SegmentInfo AliEveTPCSectorData::fgInnSeg;
38 AliEveTPCSectorData::SegmentInfo AliEveTPCSectorData::fgOut1Seg;
39 AliEveTPCSectorData::SegmentInfo AliEveTPCSectorData::fgOut2Seg;
40
41 AliEveTPCSectorData::SegmentInfo* AliEveTPCSectorData::fgSegInfoPtrs[3] = {0};
42
43 /******************************************************************************/
44
45 void AliEveTPCSectorData::InitStatics()
46 {
47   // Initialize static variables.
48
49   if (fgParam != 0) return;
50
51   fgParam    = new AliTPCParamSR;
52   fgZLength  = fgParam->GetZLength(0) + 0.275;
53   fgNAllRows = fgParam->GetNRowLow()  + fgParam->GetNRowUp();
54   fgNAllPads = 0;
55   fgRowBegs  = new Int_t[fgNAllRows + 1];
56
57   Int_t row = 0;
58   for (Int_t i=0; i<fgParam->GetNRowLow(); ++i, ++row) {
59     fgRowBegs[row] = fgNAllPads;
60     fgNAllPads += fgParam->GetNPadsLow(i);
61   }
62   for (Int_t i=0; i<fgParam->GetNRowUp(); ++i, ++row) {
63     fgRowBegs[row] = fgNAllPads;
64     fgNAllPads += fgParam->GetNPadsUp(i);
65   }
66   fgRowBegs[fgNAllRows] = fgNAllPads;
67
68
69   // Fill SegmentInfos, used by rendering classes.
70
71   // General paramameters
72   fgInnSeg.fPadWidth   = fgParam->GetInnerPadPitchWidth();
73   fgInnSeg.fPadHeight  = fgParam->GetInnerPadPitchLength();
74   fgInnSeg.fRLow       = fgParam->GetPadRowRadiiLow(0);
75   fgInnSeg.fNRows      = fgParam->GetNRowLow();
76   fgInnSeg.fFirstRow   = 0;
77   fgInnSeg.fLastRow    = fgInnSeg.fNRows - 1;
78   fgInnSeg.fNMaxPads   = fgParam->GetNPadsLow(fgInnSeg.fNRows - 1);
79   fgSegInfoPtrs[0]     = &fgInnSeg;
80
81   fgOut1Seg.fPadWidth  = fgParam->GetOuterPadPitchWidth();
82   fgOut1Seg.fPadHeight = fgParam->GetOuter1PadPitchLength();
83   fgOut1Seg.fRLow      = fgParam->GetPadRowRadiiUp(0);
84   fgOut1Seg.fNRows     = fgParam->GetNRowUp1();
85   fgOut1Seg.fFirstRow  = fgInnSeg.fNRows;
86   fgOut1Seg.fLastRow   = fgOut1Seg.fFirstRow + fgOut1Seg.fNRows - 1;
87   fgOut1Seg.fNMaxPads  = fgParam->GetNPadsUp(fgOut1Seg.fNRows - 1);
88   fgSegInfoPtrs[1]     = &fgOut1Seg;
89
90   fgOut2Seg.fPadWidth  = fgParam->GetOuterPadPitchWidth();
91   fgOut2Seg.fPadHeight = fgParam->GetOuter2PadPitchLength();
92   fgOut2Seg.fRLow      = fgParam->GetPadRowRadiiUp(fgOut1Seg.fNRows);
93   fgOut2Seg.fNRows     = fgParam->GetNRowUp() - fgOut1Seg.fNRows;
94   fgOut2Seg.fFirstRow  = fgOut1Seg.fLastRow + 1;
95   fgOut2Seg.fLastRow   = fgOut2Seg.fFirstRow + fgOut2Seg.fNRows - 1;
96   fgOut2Seg.fNMaxPads  = fgParam->GetNPadsUp(fgParam->GetNRowUp() - 1);
97   fgSegInfoPtrs[2]     = &fgOut2Seg;
98
99   // Set stepsize array
100   Int_t k, npads;
101   // Inn
102   k=0, npads = fgParam->GetNPadsLow(0);
103   for (int row = 0; row < fgInnSeg.fNRows; ++row) {
104     if (fgParam->GetNPadsLow(row) > npads) {
105       npads = fgParam->GetNPadsLow(row);
106       fgInnSeg.fYStep[k] = row*fgInnSeg.fPadHeight + fgInnSeg.fRLow;
107       k++;
108     }
109   }
110   fgInnSeg.fNYSteps = k;
111   // Out1 seg
112   k=0; npads = fgParam->GetNPadsUp(0);
113   for (int row = 0; row < fgOut1Seg.fNRows; ++row) {
114     if (fgParam->GetNPadsUp(row) > npads) {
115       npads = fgParam->GetNPadsUp(row);
116       fgOut1Seg.fYStep[k] = row*fgOut1Seg.fPadHeight + fgOut1Seg.fRLow ;
117       k++;
118     }
119   }
120   fgOut1Seg.fNYSteps = k;
121   // Out2 seg
122   k=0; npads = fgParam->GetNPadsUp(fgOut1Seg.fNRows);
123   for (int row = fgOut1Seg.fNRows; row < fgParam->GetNRowUp() ;row++ ) {
124     if (fgParam->GetNPadsUp(row) > npads) {
125       npads = fgParam->GetNPadsUp(row);
126       fgOut2Seg.fYStep[k] = (row - fgOut1Seg.fNRows)*fgOut2Seg.fPadHeight + fgOut2Seg.fRLow ;
127       k++;
128     }
129   }
130   fgOut2Seg.fNYSteps = k;
131 }
132
133 Int_t AliEveTPCSectorData::GetNPadsInRow(Int_t row)
134 {
135   // Return number of pads in given row.
136
137   if(row < 0 || row >= fgNAllRows) return 0;
138   return fgRowBegs[row + 1] - fgRowBegs[row];
139 }
140
141 const AliEveTPCSectorData::SegmentInfo& AliEveTPCSectorData::GetSeg(Int_t seg)
142 {
143   // Return reference to segment geometry information.
144   // 0 ~ inner, 1 ~ middle, 2 ~ outer.
145
146   static const SegmentInfo null;
147
148   if(seg < 0 || seg > 2)
149     return null;
150   else
151     return *fgSegInfoPtrs[seg];
152 }
153
154 /******************************************************************************/
155 // True member functions start here.
156 /******************************************************************************/
157
158 void AliEveTPCSectorData::NewBlock()
159 {
160   // Create new data-block. Position is set to the beginning.
161
162   fBlocks.push_back(new Short_t[fBlockSize]);
163   fBlockPos = 0;
164 }
165
166 /******************************************************************************/
167
168 AliEveTPCSectorData::AliEveTPCSectorData(Int_t sector, Int_t bsize) :
169   fSectorID(sector), fNPadsFilled(0), fPads(),
170   fBlockSize(bsize), fBlockPos(0),    fBlocks(),
171   fCurrentRow(0), fCurrentPad(0), fCurrentPos(0), fCurrentStep(0),
172   fPadRowHackSet(0)
173 {
174   // Constructor.
175
176   if(fgParam == 0) InitStatics();
177
178   fPads.assign(fgNAllPads, PadData());
179   fBlocks.reserve(16);
180   fBlockPos = fBlockSize; // Enforce creation of a new block.
181 }
182
183
184 AliEveTPCSectorData::~AliEveTPCSectorData()
185 {
186   // Destructor.
187
188   for(std::vector<Short_t*>::iterator b=fBlocks.begin(); b!=fBlocks.end(); ++b)
189     delete [] *b;
190   DeletePadRowHack();
191 }
192
193 void AliEveTPCSectorData::DropData()
194 {
195   // Drop data, deallocate data-blocks.
196
197   fPads.assign(fgNAllPads, PadData());
198   for(std::vector<Short_t*>::iterator b=fBlocks.begin(); b!=fBlocks.end(); ++b)
199     delete [] *b;
200   fBlocks.clear();
201   fBlockPos = fBlockSize; // Enforce creation of a new block.
202 }
203
204 /******************************************************************************/
205
206 void AliEveTPCSectorData::Print(Option_t* /*opt*/) const
207 {
208   // Print summary information.
209
210   printf("AliEveTPCSectorData sector=%d, NPadsFilled=%d, NBlocks=%d, BlockPos=%d\n",
211          fSectorID, fNPadsFilled, fBlocks.size(), fBlockPos);
212 }
213
214 /******************************************************************************/
215
216 void AliEveTPCSectorData::BeginPad(Int_t row, Int_t pad, Bool_t reverseTime)
217 {
218   // Begin filling of pad-data as specified with arguments.
219
220   fCurrentRow = row;
221   fCurrentPad = pad;
222   if(reverseTime) {
223     fCurrentPos  = 2046;
224     fCurrentStep = -2;
225   } else {
226     fCurrentPos  = 0;
227     fCurrentStep = 2;
228   }
229   //printf("begpad for row=%d pad=%d\n  buf=%p pos=%d step=%d\n",
230   //     fCurrentRow, fCurrentPad,
231   //     fPadBuffer, fCurrentPos, fCurrentStep);
232 }
233
234 void AliEveTPCSectorData::EndPad(Bool_t autoPedestal, Short_t threshold)
235 {
236   // End filling of pad-data. At this point data is compressed and moved
237   // into the cuurent position in memory block.
238
239   Short_t *beg, *end;
240   if (fCurrentStep > 0) {
241     beg = fPadBuffer;
242     end = fPadBuffer + fCurrentPos;
243   } else {
244     beg = fPadBuffer + fCurrentPos + 2;
245     end = fPadBuffer + 2048;
246   }
247
248   //printf("endpad for row=%d pad=%d\n  buf=%p beg=%p end=%p pos=%d step=%d\n",
249   //     fCurrentRow, fCurrentPad,
250   //     fPadBuffer, beg, end, fCurrentPos, fCurrentStep);
251   if (beg >= end)
252     return;
253
254   if (autoPedestal) {
255     Short_t array[1024];
256     Short_t* val;
257     val = beg + 1;
258     while(val <= end) {
259       array[(val-beg)/2] = *val;
260       val += 2;
261     }
262     Short_t pedestal = TMath::Nint(TMath::Median((end-beg)/2, array));
263     val = beg + 1;
264     while (val <= end) {
265       *val -= pedestal;
266       val += 2;
267     }
268     Short_t* wpos = beg;
269     Short_t* rpos = beg;
270     while (rpos < end) {
271       if (rpos[1] >= threshold) {
272         wpos[0] = rpos[0];
273         wpos[1] = rpos[1];
274         wpos += 2;
275       }
276       rpos += 2;
277     }
278     end = wpos;
279   }
280
281   Short_t* wpos = beg;
282   Short_t* rpos = beg;
283
284   // Compress pad buffer
285   while (rpos < end) {
286     Short_t* spos = rpos;
287     Short_t  t    = spos[0];
288     while (true) {
289       rpos += 2;
290       if(rpos >= end || *rpos > t + 1 || t == 0)
291         break;
292       ++t;
293     }
294     Short_t n = t - spos[0] + 1;
295     if (n == 1) {
296       wpos[0] = -spos[0];
297       wpos[1] =  spos[1];
298       wpos += 2;
299     } else {
300       wpos[0] = spos[0];
301       wpos[2] = spos[1];
302       wpos[1] = n;
303       wpos += 3; spos += 3;
304       while (--n) {
305         *wpos = *spos;
306         ++wpos; spos += 2;
307       }
308     }
309   }
310
311   // Copy buffer to storage, set PadData
312   if (wpos > beg) {
313     Short_t len = wpos - beg;
314     if (len > fBlockSize - fBlockPos)
315       NewBlock();
316     Short_t *dest = fBlocks.back() + fBlockPos;
317     memcpy(dest, beg, len*sizeof(Short_t));
318     fBlockPos += len;
319
320     PadData& pad = fPads[PadIndex(fCurrentRow, fCurrentPad)];
321     pad.SetDataLength(dest, len);
322   }
323
324   ++fNPadsFilled;
325 }
326
327 /******************************************************************************/
328
329 const AliEveTPCSectorData::PadData& AliEveTPCSectorData::GetPadData(Int_t padAddr)
330 {
331   // Get pad-data reference by absolute index.
332
333   static const PadData null;
334
335   if(padAddr < 0 || padAddr >= fgNAllPads) return null;
336   return fPads[padAddr];
337 }
338
339 const AliEveTPCSectorData::PadData& AliEveTPCSectorData::GetPadData(Int_t row, Int_t pad)
340 {
341   // Get pad-data reference by row and pad number.
342
343   static const PadData null;
344
345   Int_t np = GetNPadsInRow(row);
346   if(np == 0 || pad < 0 || pad >= np) return null;
347   return GetPadData(fgRowBegs[row] + pad);
348 }
349
350 AliEveTPCSectorData::PadIterator AliEveTPCSectorData::MakePadIterator(Int_t padAddr, Short_t thr)
351 {
352   // Get pad-data iterator by absolute index.
353
354   return PadIterator(GetPadData(padAddr), thr);
355 }
356
357 AliEveTPCSectorData::PadIterator AliEveTPCSectorData::MakePadIterator(Int_t row, Int_t pad, Short_t thr)
358 {
359   // Get pad-data iterator by row and pad number.
360
361   return PadIterator(GetPadData(row, pad), thr);
362 }
363
364 AliEveTPCSectorData::RowIterator AliEveTPCSectorData::MakeRowIterator(Int_t row, Short_t thr)
365 {
366   // Get row iterator.
367
368   Short_t npads = GetNPadsInRow(row);
369   if(npads > 0)
370     return RowIterator(&fPads[fgRowBegs[row]], npads, thr);
371   else
372     return RowIterator(0, 0);
373 }
374
375 /******************************************************************************/
376 // AliEveTPCSectorData::PadData
377 /******************************************************************************/
378
379 void AliEveTPCSectorData::PadData::Print(Option_t* /*opt*/)
380 {
381   // Print summary information.
382
383   printf("addr=%p, len=%hd>\n", (void*)fData, fLength);
384   for(Int_t i=0; i<fLength; ++i)
385     printf("  %3d %hd\n", i, fData[i]);
386 }
387
388 /******************************************************************************/
389 // AliEveTPCSectorData::PadIterator
390 /******************************************************************************/
391
392 Bool_t AliEveTPCSectorData::PadIterator::Next()
393 {
394   // Move iterator to next signal above the iteration threshold.
395   // Returns false when the end of data is reached.
396
397   if (fPos >= fEnd) return kFALSE;
398   if (fNChunk > 0) {
399     ++fTime;
400     --fNChunk;
401     fSignal = *fPos; ++fPos;
402   } else {
403     fTime = fPos[0];
404     if (fTime <= 0) {
405       fTime   = -fTime;
406       fSignal = fPos[1];
407       fPos += 2;
408     } else {
409       fNChunk = fPos[1] - 1;
410       fSignal = fPos[2];
411       fPos += 3;
412     }
413   }
414   return (fSignal > fThreshold) ? kTRUE : Next();
415 }
416
417 void AliEveTPCSectorData::PadIterator::Reset()
418 {
419   // Return to the beginning of the pad-data. Must call Next() to get to
420   // the first stored signal.
421
422   fPos    = fBeg;
423   fTime   = -1;
424   fSignal = -1;
425   fNChunk = 0;
426 }
427
428 void AliEveTPCSectorData::PadIterator::Reset(const PadData& pd)
429 {
430   // Reinitialize to new pad-data. Must call Next() to get to the
431   // first stored signal.
432
433   fBeg = pd.Data();
434   fEnd = pd.Data() + pd.Length();
435   fPos = pd.Data();
436   Reset();
437 }
438
439 void AliEveTPCSectorData::PadIterator::Test()
440 {
441   while(Next())
442     printf("  %3d %d\n", fTime, fSignal);
443 }
444
445 /******************************************************************************/
446 // AliEveTPCSectorData::RowIterator
447 /******************************************************************************/
448
449 Bool_t AliEveTPCSectorData::RowIterator::NextPad()
450 {
451   // Move iterator to next pad.
452
453   ++fPad;
454   if(fPad >= fNPads) return kFALSE;
455   Reset(fPadArray[fPad]);
456   return kTRUE;
457 }
458
459 void AliEveTPCSectorData::RowIterator::ResetRow()
460 {
461   // Return to the beginning of the row. Must call NextPad() to get to
462   // the zeroth pad.
463
464   fPad = -1;
465 }
466
467 void AliEveTPCSectorData::RowIterator::ResetRow(const PadData* first, Short_t npads)
468 {
469   // Reinitialize to another pad-data array. Must call NextPad() to
470   // get to the zeroth pad.
471
472   fPadArray =  first;
473   fNPads    =  npads;
474   fPad      = -1;
475 }
476
477 /******************************************************************************/
478 // AliEveTPCSectorData::SegmentInfo
479 /******************************************************************************/
480
481 //______________________________________________________________________________
482 //
483 // Stores geometry data about a segment needed for fast data-access
484 // and rendering
485
486 ClassImp(AliEveTPCSectorData::SegmentInfo)
487
488 AliEveTPCSectorData::SegmentInfo::SegmentInfo() :
489   TObject(),
490
491   fPadWidth(0), fPadHeight(0),
492   fRLow(0), fNRows(0), fFirstRow(0), fLastRow(0),
493   fNMaxPads(0),
494   fNYSteps(0)
495 {
496   // Constructor.
497
498   memset(fYStep, sizeof(fYStep), 0);
499 }
500
501 /******************************************************************************/
502 // AliEveTPCSectorData::PadRowHack
503 /******************************************************************************/
504
505 AliEveTPCSectorData::PadRowHack* AliEveTPCSectorData::GetPadRowHack(Int_t r, Int_t p)
506 {
507   // Get PadRowHack applicable to given row and pad.
508
509   if (fPadRowHackSet == 0) return 0;
510   std::set<PadRowHack>* hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
511   std::set<PadRowHack>::iterator i = hs->find(PadRowHack(r,p));
512   return (i == hs->end()) ? 0 : const_cast<PadRowHack*>(&*i);
513 }
514
515 void AliEveTPCSectorData::AddPadRowHack(Int_t r, Int_t p, Int_t te, Float_t tf)
516 {
517   // Register PadRowHack for given row and pad.
518
519   if (fPadRowHackSet == 0) fPadRowHackSet = new std::set<PadRowHack>;
520
521   PadRowHack* prh = GetPadRowHack(r, p);
522   if (prh == 0) {
523     std::set<PadRowHack>* hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
524     hs->insert(PadRowHack(r, p, te, tf));
525   } else {
526     prh->fThrExt += te;
527     prh->fThrFac *= tf;
528   }
529 }
530
531 void AliEveTPCSectorData::RemovePadRowHack(Int_t r, Int_t p)
532 {
533   // Remove PadRowHack for given row and pad.
534
535   if (fPadRowHackSet == 0) return;
536   std::set<PadRowHack>*hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
537   std::set<PadRowHack>::iterator i = hs->find(PadRowHack(r,p));
538   if(i != hs->end()) hs->erase(i);
539 }
540
541 void AliEveTPCSectorData::DeletePadRowHack()
542 {
543   // Delete all PadRowHacks and their container.
544
545   if (fPadRowHackSet != 0) {
546     std::set<PadRowHack>*hs = static_cast<std::set<PadRowHack>*>(fPadRowHackSet);
547     delete hs;
548     fPadRowHackSet = 0;
549   }
550 }