Removed missleading comment.
[u/mrichter/AliRoot.git] / TPC / AliDigits.cxx
1 /**************************************************************************
2  * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3  *                                                                        *
4  * Author: The ALICE Off-line Project.                                    *
5  * Contributors are mentioned in the code where appropriate.              *
6  *                                                                        *
7  * Permission to use, copy, modify and distribute this software and its   *
8  * documentation strictly for non-commercial purposes is hereby granted   *
9  * without fee, provided that the above copyright notice appears in all   *
10  * copies and that both the copyright notice and this permission notice   *
11  * appear in the supporting documentation. The authors make no claims     *
12  * about the suitability of this software for any purpose. It is          *
13  * provided "as is" without express or implied warranty.                  *
14  **************************************************************************/
15
16 /*
17
18 $Log$
19 Revision 1.2.4.3  2000/06/26 07:39:42  kowal2
20 Changes to obey the coding rules
21
22 Revision 1.2.4.2  2000/06/25 08:38:41  kowal2
23 Splitted from AliTPCtracking
24
25 Revision 1.2.4.1  2000/06/14 16:45:13  kowal2
26 Improved algorithms. Compiler warnings removed.
27
28 Revision 1.2  2000/04/17 09:37:33  kowal2
29 removed obsolete AliTPCDigitsDisplay.C
30
31 Revision 1.1.4.2  2000/04/10 11:37:42  kowal2
32
33 Digits handling in a new data structure
34
35 */
36
37 /*MI change -- for Rule checker
38           -- added copy constructor and assignmet operator 
39           -- new GetSize return size of object in Bytes
40           -- added GetDigitSize and GetOverTh function
41           -- added GetNRows, GetNCols function
42           -- for Marek -I had it in my code  
43 */ 
44
45 ///////////////////////////////////////////////////////////////////////////////
46 //                                                                           //
47 //   Alice  digits array  object  AliDigits                                  //
48 //                                                                           //
49 //                                                                           //
50 //                                                                           //
51 ///////////////////////////////////////////////////////////////////////////////
52
53
54 #include "TClass.h"
55 #include <iostream.h>
56 #include "TError.h"
57 #include "AliSegmentID.h"
58 #include "AliH2F.h"
59 #include "AliArrayI.h"
60 #include "AliArrayS.h"
61 #include "AliDigits.h"
62
63
64
65 //_____________________________________________________________________________
66 //_____________________________________________________________________________
67 //_____________________________________________________________________________
68 ClassImp(AliDigits)
69
70
71 AliDigits::AliDigits()
72 {
73   // 
74   //default constructor
75   fIndex = 0;
76   fElements = 0;
77   fThreshold =0;
78   Invalidate();
79 }
80
81 AliDigits::AliDigits(const AliDigits& digits)
82 {
83   //
84   //copy constructor
85   fNrows = digits.fNrows;
86   fNcols = digits.fNcols;
87   fElements = new AliArrayS(*(digits.fElements));
88   fIndex = new AliArrayI(*(digits.fIndex));
89   fBufType = digits.fBufType;
90   fThreshold = digits.fThreshold;
91   fNelems    = digits.fNelems;
92 }
93
94 AliDigits & AliDigits::operator =(const AliDigits & digits)
95 {
96  //assignment operator
97   fNrows = digits.fNrows;
98   fNcols = digits.fNcols;
99   if (fElements) delete fElements;
100   fElements = new AliArrayS(*(digits.fElements));
101   if (fIndex) delete fIndex;
102   fIndex = new AliArrayI(*(digits.fIndex));
103   fBufType = digits.fBufType;
104   fThreshold = digits.fThreshold;
105   fNelems    = digits.fNelems; 
106   return (*this);
107 }
108
109 AliDigits::~AliDigits()
110 {
111   //
112   //default destructor
113   if (fIndex !=0 ) fIndex->Delete();;
114   if (fElements != 0) fElements->Delete();
115   
116 }
117
118
119 Bool_t AliDigits::OutOfBoundsError(const char *where, Int_t row, Int_t column) 
120 {
121    // Generate an out-of-bounds error. Always returns false.
122    ::Error(where, "row %d  col %d out of bounds (size: %d x %d, this: 0x%08x)", 
123            row, column, fNrows, fNcols, this);
124    return kFALSE;
125 }
126
127
128 void AliDigits::Invalidate() 
129
130   //
131   //set default (invalid parameters)
132   if (fIndex != 0)  delete  fIndex;
133   fIndex = new AliArrayI;
134   
135   if (fElements!= 0)     delete  fElements;
136   
137   fElements = new AliArrayS;
138   
139   fNrows = fNcols =fNelems= -1; 
140   fElements->Set(0); 
141   fIndex->Set(0); 
142   fBufType = -1;
143 }
144
145 void AliDigits::Allocate(Int_t rows, Int_t columns)
146 {
147   //
148   //construct empty buffer fDigits with size rows x columns
149   Invalidate();
150   if (rows <= 0) {
151       Error("Allocate", "no of rows has to be positive");
152       return;
153    }
154    if (columns <= 0) {
155       Error("Allocate", "no of columns has to be positive");
156       return;
157    }
158   fNrows = rows;
159   fNcols=columns;
160   fNelems = fNrows * fNcols;
161   fElements->Set(fNelems);
162   fIndex->Set(fNcols);
163   for (Int_t i =0,k=0; i<fNcols;i++,k+=fNrows) 
164   (*fIndex)[i]=k;
165   fBufType =0;
166 }
167
168
169 Int_t AliDigits::GetSize()
170 {
171   //
172   //return size of object
173   //
174   Int_t size = sizeof(this);
175   if (fIndex!=0) size+= sizeof(fIndex)+fIndex->GetSize()*sizeof(Int_t);
176   if (fElements!=0) size+= sizeof(fElements)+fElements->GetSize()*sizeof(Short_t);
177   return size;
178 }
179
180 Int_t AliDigits::GetDigitSize() //return total size of pure digit
181 {
182   //
183   //return size of PURE DIGITS
184   //
185   if (fElements==0) return 0;
186   else return sizeof(fElements)+fElements->GetSize()*sizeof(Short_t);
187 }
188
189 Int_t AliDigits::GetOverTh(Float_t threshold,Float_t x1, Float_t x2, Float_t y1, Float_t y2)
190 {
191   //
192   //return number of digits over threshold
193   // 
194  if ( (fElements==0) || (fElements->GetSize()<=0)) return 0;
195  
196  if (x1<=x2) {
197     x1=0;
198     x2=fNrows;
199   }
200   if (y1<=y2) {
201      y1=0;
202      y2=fNcols;
203   }
204   Int_t over=0;
205
206   Bool_t cont=First();
207   for ( cont=First(); cont==kTRUE;cont=Next()) {
208     if ( (CurrentRow()<x1) || (CurrentRow()>x2)) continue;
209     if ( (CurrentColumn()<y1) || (CurrentColumn()>y2)) continue;
210     if (CurrentDigit()>threshold) over++;
211   }
212   return over;
213 }
214
215
216 Short_t AliDigits::GetDigit(Int_t row, Int_t column)
217 {
218   //
219   // return digit for given row and collumn
220   if (fBufType ==0) return GetDigitFast(row,column);
221   if (fBufType ==1) return GetDigit1(row,column);
222
223   return 0;
224 }
225
226
227 void AliDigits::ExpandBuffer()
228 {  
229   //
230   //expand buffer to two dimensional array
231   if (fBufType<0)  {
232     Error("ExpandBuffer", "buffer doesn't exist");
233     return;
234   }
235   if (fBufType==0)      return;
236   
237   //expanding of buffer type 1
238   if (fBufType==1) ExpandBuffer1();
239   
240   fBufType = 0;
241 }
242
243 void AliDigits::CompresBuffer(Int_t bufferType,Int_t threshold)
244 {
245   //
246   //compres buffer according buffertype algorithm
247   if (fBufType<0)  {
248     Error("CompressBuffer", "buffer doesn't exist");
249     return;
250   }
251   if (fBufType == bufferType) return;
252   //
253   if (fBufType>0) ExpandBuffer();
254   if (fBufType !=0)  {
255     Error("CompressBuffer", "buffer doesn't exist");
256     return;
257   }
258   fThreshold = threshold;
259   //compress buffer of type 1
260   if ( bufferType == 1) CompresBuffer1();//end of compresing bufer of type 1 
261 }
262
263 Bool_t AliDigits::First()
264 {
265   //adjust  first valid current digit
266   if (fBufType ==0) return First0();
267   if (fBufType ==1) return First1();
268   return kFALSE;
269 }
270
271 Bool_t  AliDigits::Next()
272 {
273   //addjust next valid current digit
274   if (fBufType ==0) return Next0();
275   if (fBufType ==1) return Next1();
276   return kFALSE;
277 }
278  
279 void AliDigits::AcceptHisto(AliH2F * his)
280 {
281   //
282   //make digits buffer with value according histograms values
283   //for testing purpose  
284   Int_t idim =his->GetNbinsX();
285   Int_t jdim =his->GetNbinsY();
286   if ( (idim<1)|| (jdim<1)) {
287     return;
288   }
289   //allocate proper buffer size
290   Allocate(idim,jdim);
291   //set digits values
292   for (Int_t i = 0; i<idim;i++)    
293     for (Int_t j = 0; j<jdim;j++)
294       {
295         Int_t index = his->GetBin(i+1,j+1);     
296         SetDigitFast((Short_t)his->GetBinContent(index),i,j);
297       }   
298 }
299
300 AliH2F *  AliDigits::GenerHisto()
301 {
302   //
303   //make digits histo 
304   char ch[30];
305   sprintf(ch,"Segment_%d ",GetID());
306   if ( (fNrows<1)|| (fNcols<1)) {
307     return 0;
308   }
309   AliH2F * his  = new AliH2F("Digit histo",ch,fNrows,0,fNrows,fNcols,0,fNcols);
310   ExpandBuffer();
311   //set histogram  values
312   for (Int_t i = 0; i<fNrows;i++)    
313     for (Int_t j = 0; j<fNcols;j++)
314         his->Fill(i,j,GetDigitFast(i,j));
315   return his;
316 }
317
318 AliH2F *AliDigits::DrawDigits(const char *option,Float_t x1, Float_t x2, Float_t y1, Float_t y2)
319 {
320   //
321   //draw digits in given array
322   //
323   AliH2F *h2f = GenerHisto();
324   if (x1>=0) {
325       AliH2F *h2fsub = h2f->GetSubrange2d(x1,x2,y1,y2);
326       delete h2f;
327       h2f=h2fsub;
328   }
329   if (h2f==0) return 0;
330   if (option!=0) h2f->Draw(option);
331   else h2f->Draw();
332   return h2f;  
333 }
334
335 void AliDigits::ExpandBuffer1()
336 {
337   //
338   //expand buffer of type to twodimensional array
339   Int_t i,k;
340   fNelems = fNrows*fNcols;
341   Short_t * buf = new Short_t[fNelems];
342   fIndex->Set(fNcols);
343   for (i =0,k=0 ;i<fNcols;i++,k+=fNrows) (*fIndex)[i]=k;
344   Int_t col=0;
345   Int_t row = 0;
346   Int_t n=fElements->fN;
347   for (i=0;i<n;i++){
348     //oposite signa means how many unwrited (under threshold) values
349     if ((*fElements)[i]<0) row-=fElements->At(i); 
350     else {
351       buf[(*fIndex)[col]+row]=fElements->At(i);
352       row++;
353     }
354     if (row==fNrows) {
355       row=0;
356       col++;
357     }else 
358       if (row>fNrows){
359         Invalidate();
360         return;
361       }      
362   }
363   fElements->Adopt(fNelems,buf);    
364 }
365 void AliDigits::CompresBuffer1()
366 {
367   //
368   //compres buffer according  algorithm 1
369   //
370   AliArrayS  buf;  //lets have the nearly the "worst case"
371   buf.Set(fNelems);
372   AliArrayI  index;
373   index.Set(fNcols);
374   Int_t icurrent=-1;
375   Int_t izero;
376   for (Int_t col = 0; col<fNcols; col++){      
377     index[col]=icurrent+1;//set collumn pointer
378     izero = 0;  //reset zer counter at the begining of the column
379     for (Int_t row = 0; row< fNrows;row++){
380       //if under threshold
381       if (GetDigitFast(row,col)<=fThreshold)  izero++;
382       else{
383         if (izero>0) {
384           //if we have currently izero count under threshold
385           icurrent++;     
386           if (icurrent>=buf.fN) buf.Expand(icurrent*2);
387           buf[icurrent]= -izero;  //write how many under zero
388           izero = 0;
389         } //end of reseting izero
390         icurrent++;
391         if (icurrent>=buf.fN) buf.Expand(icurrent*2);
392         buf[icurrent] = GetDigitFast(row,col);      
393       }//if signal bigger then threshold                
394     } //end of loop over rows
395     if (izero>0) {
396       icurrent++;         
397       if (icurrent>=buf.fN) buf.Expand(icurrent*2);
398       buf[icurrent]= -izero;  //write how many under zero
399     }
400   }//end of lopping over digits
401   buf.Expand(icurrent+1);
402   (*fElements)=buf;
403   fNelems = fElements->fN;
404   fBufType = 1;
405   (*fIndex) =index;
406   //end of compresing bufer of type 1 
407 }
408
409
410
411 Bool_t AliDigits::First0()
412 {
413   //
414   //first for the buffer type 0
415   fCurrentRow = -1;
416   fCurrentCol = -1;
417   fCurrentIndex = -1;
418   Int_t i;
419   for (i=0; (( i<fNelems) && (fElements->At(i)<=fThreshold));i++)
420   if (i == fNelems) return kFALSE;
421   fCurrentCol =i/fNrows;
422   fCurrentRow =i%fNrows;
423   fCurrentIndex = i;
424   return kTRUE; 
425 }
426
427 Bool_t AliDigits::Next0()
428 {
429   //
430   //next for the buffer type 0
431   //
432   if (fCurrentIndex<0) return kFALSE;  // if we didn't adjust first 
433   Int_t i;
434   for (i=fCurrentIndex+1; ( (i<fNelems) && (fElements->At(i)<=fThreshold) ) ;i++);
435   if (i >= fNelems)  {
436     fCurrentIndex = -1;
437     return kFALSE;
438   }
439   fCurrentCol =i/fNrows;
440   fCurrentRow =i%fNrows;
441   fCurrentIndex = i;
442   return kTRUE; 
443 }
444
445 Bool_t AliDigits::First1()
446 {
447   //
448   //first for the buffer type 1
449   fCurrentRow = -1;
450   fCurrentCol = 0;
451   fCurrentIndex = -1;
452   Int_t i;
453   for (i=0; i<fNelems; i++){
454     if (fElements->At(i) < 0) fCurrentRow-=fElements->At(i);
455     else      
456       fCurrentRow++;
457     if (fCurrentRow>=fNrows) {
458        fCurrentCol++;
459        fCurrentRow-=fNrows;
460     }
461     if (fElements->At(i)>fThreshold) break;
462   }
463   fCurrentIndex = i;
464   if (fCurrentIndex>=0) return kTRUE;
465   fCurrentRow =-1;
466   fCurrentCol =-1;
467   return kFALSE;        
468 }
469
470 Bool_t AliDigits::Next1()
471 {
472   //
473   //next for the buffer type 1
474   if (fCurrentIndex<0) return kFALSE;  // if we didn't adjust first 
475   Int_t i;
476   for (i=fCurrentIndex+1; i<fNelems;i++){
477     if (fElements->At(i) < 0) fCurrentRow-=fElements->At(i);
478     else      
479       fCurrentRow++;
480     if (fCurrentRow>=fNrows) {
481       fCurrentCol++;
482       fCurrentRow-=fNrows;
483     }
484     if (fElements->At(i)>fThreshold) break;
485   }
486   fCurrentIndex = i;
487   if ( (i>=0) && (i<fNelems) ) return kTRUE;
488   fCurrentRow =-1;
489   fCurrentCol =-1;
490   return kFALSE;
491 }
492
493 Short_t AliDigits::GetDigit1(Int_t row, Int_t column)
494 {
495   //
496   //return digit for given row and column  the buffer type 1
497   //no control performed
498   
499   Int_t i,n2;
500   if ( (column+1)>=fNcols) n2 = fNelems;
501   else
502     n2 = fIndex->At(column+1);
503   Int_t irow = 0; //current row    
504  
505   for (i=fIndex->At(column); ( (i<n2) && (irow<row) );i++){
506     if (fElements->At(i) < 0) irow-=fElements->At(i);
507     else      
508       irow++;
509   }
510   if ( irow == row ) return fElements->At(i);
511   return -1;
512 }
513