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