First round of effc++ changes
[u/mrichter/AliRoot.git] / TRD / AliTRDdataArrayF.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 /* $Id$ */
17
18 ///////////////////////////////////////////////////////////////////////////////
19 //                                                                           //
20 //  General container for integer data of a TRD detector segment.            //
21 //  Adapted from AliDigits (origin: M.Ivanov).                               //
22 //                                                                           //
23 ///////////////////////////////////////////////////////////////////////////////
24
25 #include "AliLog.h"
26
27 #include "AliTRDdataArrayF.h"
28 #include "AliTRDarrayI.h"
29 #include "AliTRDarrayF.h"
30
31 ClassImp(AliTRDdataArrayF)
32
33 //_____________________________________________________________________________
34 AliTRDdataArrayF::AliTRDdataArrayF()
35    :AliTRDdataArray()
36    ,fElements(0)
37    ,fThreshold(0)
38 {
39   //
40   // Default constructor
41   //
42
43 }
44
45 //_____________________________________________________________________________
46 AliTRDdataArrayF::AliTRDdataArrayF(Int_t nrow, Int_t ncol, Int_t ntime)
47    :AliTRDdataArray(nrow,ncol,ntime)
48    ,fElements(0)
49    ,fThreshold(0)
50 {
51   //
52   // Creates a AliTRDdataArrayF with the dimensions <nrow>, <ncol>, and <ntime>.
53   // The row- and column dimensions are compressible.
54   //
55
56   Allocate(nrow,ncol,ntime);
57   
58 }
59
60 //_____________________________________________________________________________
61 AliTRDdataArrayF::AliTRDdataArrayF(const AliTRDdataArrayF &a)
62    :AliTRDdataArray(a)
63    ,fElements(a.fElements)
64    ,fThreshold(a.fThreshold)
65 {
66   //
67   // AliTRDdataArrayF copy constructor
68   //
69
70 }
71
72 //_____________________________________________________________________________
73 AliTRDdataArrayF::~AliTRDdataArrayF()
74 {
75   //
76   // Destructor
77   //
78
79   if (fElements) delete fElements;
80   
81 }
82
83 //_____________________________________________________________________________
84 void AliTRDdataArrayF::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
85 {
86   //
87   // Allocates memory for a AliTRDdataArrayF with the dimensions 
88   // <nrow>, <ncol>, and <ntime>.
89   // The row- and column dimensions are compressible.
90   //
91
92   if (fNelems < 0) AliTRDdataArray::Allocate(nrow,ncol,ntime);
93
94   if (fElements) delete fElements;
95   fElements = new AliTRDarrayF();
96   fElements->Set(fNelems);
97
98 }
99
100 //_____________________________________________________________________________
101 void AliTRDdataArrayF::Copy(TObject &a) const
102 {
103   //
104   // Copy function
105   //
106
107   fElements->Copy(*((AliTRDdataArrayF &) a).fElements);
108
109   ((AliTRDdataArrayF &) a).fThreshold = fThreshold;
110
111   AliTRDdataArray::Copy(a);
112
113 }
114
115 //_____________________________________________________________________________
116 void AliTRDdataArrayF::Reset() 
117
118   //
119   // Reset the array (old content gets deleted)
120   //
121   
122   if (fElements) delete fElements;
123   fElements = new AliTRDarrayF();
124   fElements->Set(0); 
125
126   AliTRDdataArray::Reset();
127
128 }
129
130 //_____________________________________________________________________________
131 Int_t AliTRDdataArrayF::GetSize() const
132 {
133   //
134   // Returns the size of the complete object
135   //
136
137   Int_t size = sizeof(this);
138
139   if (fIndex)    size += sizeof(fIndex)    
140                          + fIndex->GetSize()    * sizeof(Int_t);
141   if (fElements) size += sizeof(fElements) 
142                          + fElements->GetSize() * sizeof(Float_t);
143
144   return size;
145
146 }
147
148 //_____________________________________________________________________________
149 Int_t AliTRDdataArrayF::GetDataSize() const 
150 {
151   //
152   // Returns the size of only the data part
153   //
154
155   if (fElements == 0) 
156     return 0;
157   else 
158     return sizeof(fElements) + fElements->GetSize() * sizeof(Float_t);
159
160 }
161
162 //_____________________________________________________________________________
163 Int_t AliTRDdataArrayF::GetOverThreshold(Float_t threshold) 
164 {
165   //
166   // Returns the number of entries over threshold
167   //
168  
169   if ((fElements == 0) || (fElements->GetSize() <= 0))
170     return 0;
171  
172   Int_t over = 0;
173
174   for (Bool_t cont = First(); cont == kTRUE; cont = Next()) {
175     if ((fCurrentIdx1 < 0) || (fCurrentIdx1 >= fNdim1)) continue;
176     if ((fCurrentIdx2 < 0) || (fCurrentIdx2 >= fNdim2)) continue;
177     if (fElements->At(fCurrentIndex) > threshold) over++;
178   }
179
180   return over;
181
182 }
183
184 //_____________________________________________________________________________
185 Float_t AliTRDdataArrayF::GetData(Int_t row, Int_t col, Int_t time) const
186 {
187   //
188   // Returns the data value at a given position of the array
189   // Includes boundary checking
190   //
191
192   if ((row >= 0) && (col >= 0) && (time >= 0)) {
193     Int_t idx1 = GetIdx1(row,col);
194     if ((idx1 >= 0) && (time < fNdim2)) {
195       if (fBufType == 0) return GetDataFast(idx1,time);
196       if (fBufType == 1) return GetData1(idx1,time);
197     }
198     else {
199       if (idx1 >= 0) {
200         AliError(Form("time %d out of bounds (size: %d, this: 0x%08x)"
201                      ,time,fNdim2,this));
202       }
203     }
204   }
205
206   return -1;
207
208 }
209
210 //_____________________________________________________________________________
211 Float_t AliTRDdataArrayF::GetDataFast(Int_t idx1, Int_t idx2) const
212 {
213   //
214   // Returns the data value at a given position of the array
215   // No boundary checking
216   //
217
218   return fElements->At(fIndex->At(idx2)+idx1);
219
220 }
221
222 //_____________________________________________________________________________
223 void AliTRDdataArrayF::Compress(Int_t bufferType, Float_t threshold)
224 {
225   //
226   // Compresses the buffer
227   //
228
229   fThreshold = threshold;
230   Compress(bufferType);
231
232 }
233
234 //_____________________________________________________________________________
235 void AliTRDdataArrayF::Compress(Int_t bufferType)
236 {
237   //
238   // Compresses the buffer
239   //
240
241   if (fBufType  < 0) {
242     AliError("Buffer does not exist");
243     return;
244   }
245   if (fBufType == bufferType) {
246     return;
247   }  
248   if (fBufType > 0) {
249     Expand();
250   }
251   if (fBufType !=0)  {
252     AliError("Buffer does not exist");
253     return;
254   }
255
256   // Compress a buffer of type 1
257   if (bufferType == 1) {
258     Compress1();
259   }
260
261 }
262
263 //_____________________________________________________________________________
264 void AliTRDdataArrayF::Expand()
265 {  
266   //
267   // Expands the compressed buffer
268   //
269
270   if (fBufType  < 0) {
271     AliError("Buffer does not exist");
272     return;
273   }
274   if (fBufType == 0) {  
275     return;
276   } 
277  
278   // Expand a buffer of type 1
279   if (fBufType == 1) Expand1();
280   
281   fBufType = 0;
282
283 }
284
285 //_____________________________________________________________________________
286 Bool_t AliTRDdataArrayF::First() 
287 {
288   //
289   // Returns the position of the first valid data value
290   //
291
292   if (fBufType == 0) return First0();
293   if (fBufType == 1) return First1();
294   return kFALSE;
295
296 }
297
298 //_____________________________________________________________________________
299 Bool_t  AliTRDdataArrayF::Next()
300 {
301   //
302   // Returns the position of the next valid data value
303   //
304
305   if (fBufType == 0) return Next0();
306   if (fBufType == 1) return Next1();
307   return kFALSE;
308
309 }
310
311 //_____________________________________________________________________________
312 void AliTRDdataArrayF::Expand1()
313 {
314   //
315   // Expands a buffer of type 1
316   //
317
318   Int_t i, k;
319
320   fNelems = fNdim1 * fNdim2;
321
322   Float_t *buf = new Float_t[fNelems];
323   memset(buf,0,fNelems*sizeof(Float_t)); 
324
325   fIndex->Set(fNdim2);
326
327   for (i = 0, k = 0; i < fNdim2; i++, k += fNdim1) (*fIndex)[i] = k;
328
329   Int_t idx1 = 0;
330   Int_t idx2 = 0;
331   Int_t n    = fElements->fN;
332
333   for (i = 0; i < n; i++){
334
335     // Negative sign counts the unwritten values (under threshold)
336     if ((*fElements)[i] < 0) {
337       idx1 -= TMath::Nint(fElements->At(i));
338     } 
339     else {
340       buf[(*fIndex)[idx2] + idx1] = (*fElements)[i];
341       idx1++;
342     }
343     if (idx1 == fNdim1) {
344       idx1 = 0;
345       idx2++;
346     }
347     else { 
348       if (idx1 > fNdim1){
349         Reset();
350         return;
351       }      
352     }
353   }
354
355   fElements->Adopt(fNelems,buf); 
356    
357 }
358
359 //_____________________________________________________________________________
360 void AliTRDdataArrayF::Compress1()
361 {
362   //
363   // Compress a buffer of type 1
364   //
365
366   AliTRDarrayF *buf   = new AliTRDarrayF();  
367   buf->Set(fNelems);
368   AliTRDarrayI *index = new AliTRDarrayI();
369   index->Set(fNdim2);
370
371   Int_t icurrent = -1;
372   Int_t izero;
373   for (Int_t idx2 = 0; idx2 < fNdim2; idx2++){      
374
375     // Set the idx2 pointer
376     (*index)[idx2] = icurrent + 1;
377
378     // Reset the zero counter 
379     izero = 0;  
380
381     for (Int_t idx1 = 0; idx1 < fNdim1; idx1++){
382       // If below threshold
383       if (GetDataFast(idx1,idx2) <= fThreshold) {
384         izero++;
385       }
386       else {
387         if (izero > 0) {
388           // If we have currently izero counts under threshold
389           icurrent++;     
390           if (icurrent >= buf->fN) buf->Expand(icurrent*2);
391           // Store the number of entries below zero
392           (*buf)[icurrent] = -izero;  
393           izero = 0;
394         } 
395         icurrent++;
396         if (icurrent >= buf->fN) buf->Expand(icurrent*2);
397         (*buf)[icurrent] = GetDataFast(idx1,idx2);          
398       } // If signal larger than threshold              
399     } // End of loop over idx1
400
401     if (izero > 0) {
402       icurrent++;         
403       if (icurrent >= buf->fN) buf->Expand(icurrent*2);
404       // Store the number of entries below zero
405       (*buf)[icurrent] = -izero;  
406     }
407
408   }
409
410   buf->Expand(icurrent+1);
411   if (fElements) delete fElements;
412   fElements = buf;
413   fNelems   = fElements->fN;
414   fBufType  = 1;
415   if (fIndex) delete fIndex;
416   fIndex    = index;
417
418 }
419
420 //_____________________________________________________________________________
421 void AliTRDdataArrayF::Expand2()
422 {
423   //
424   // Expands a buffer of type 2 
425   //
426
427   Int_t i, k;
428
429   Float_t *buf = new Float_t[fNelems];
430   memset(buf,0,fNelems*sizeof(Float_t)); 
431
432   fNelems = fNdim1 * fNdim2;
433   fIndex->Set(fNdim2);
434
435   for (i = 0, k = 0; i < fNdim2; i++, k += fNdim1) (*fIndex)[i] = k;
436
437   Int_t idx1 = 0;
438   Int_t idx2 = 0;
439   Int_t n    = fElements->fN;
440   for (i = 0; i < n; i++){
441     // Negative sign counts the unwritten values (under threshold)
442     if ((*fElements)[i] < 0) {
443       //idx1 -= (Int_t) fElements->At(i); 
444       idx1 -= TMath::Nint(fElements->At(i)); 
445     }
446     else {
447       buf[(*fIndex)[idx2]+idx1] = fElements->At(i);
448       idx1++;
449     }
450     if (idx1 == fNdim1) {
451       idx1 = 0;
452       idx2++;
453     }
454     else { 
455       if (idx1 > fNdim1){
456         Reset();
457         return;
458       }      
459     }
460   }
461
462   fElements->Adopt(fNelems,buf);    
463
464 }
465
466 //_____________________________________________________________________________
467 void AliTRDdataArrayF::Compress2()
468 {
469   //
470   // Compress a buffer of type 2 - not implemented!
471   //
472
473 }
474
475 //_____________________________________________________________________________
476 Bool_t AliTRDdataArrayF::First0() 
477 {
478   //
479   // Returns the first entry for a buffer of type 0
480   //
481
482   fCurrentIdx1  = -1;
483   fCurrentIdx2  = -1;
484   fCurrentIndex = -1;
485
486   Int_t i;
487   for (i = 0; ((i < fNelems) && (fElements->At(i) <= fThreshold)); i++)
488   if (i == fNelems) return kFALSE;
489
490   fCurrentIdx1  = i % fNdim1;
491   fCurrentIdx2  = i / fNdim1;
492   fCurrentIndex = i;
493   return kTRUE; 
494
495 }
496
497 //_____________________________________________________________________________
498 Bool_t AliTRDdataArrayF::Next0()
499 {
500   //
501   // Returns the next entry for a buffer of type 0
502   //
503
504   if (fCurrentIndex < 0) return kFALSE; 
505
506   Int_t i;
507   for (i = fCurrentIndex + 1; 
508        ((i < fNelems) && (fElements->At(i) <= fThreshold)); 
509        i++);
510   if (i >= fNelems)  {
511     fCurrentIndex = -1;
512     return kFALSE;
513   }
514
515   fCurrentIdx1  = i % fNdim1;
516   fCurrentIdx2  = i / fNdim1;
517   fCurrentIndex = i;
518   return kTRUE; 
519
520 }
521
522 //_____________________________________________________________________________
523 Bool_t AliTRDdataArrayF::First1() 
524 {
525   //
526   // Returns the first entry for a buffer of type 1
527   //
528
529   fCurrentIdx1  = -1;
530   fCurrentIdx2  =  0;
531   fCurrentIndex = -1;
532
533   Int_t i;
534   for (i = 0; i < fNelems; i++){
535     if (fElements->At(i) < 0) {
536       //fCurrentIdx1 -= (Int_t) fElements->At(i);
537       fCurrentIdx1 -= TMath::Nint(fElements->At(i));
538     }
539     else {     
540       fCurrentIdx1++;
541     }
542     if (fCurrentIdx1 >= fNdim1) {
543       fCurrentIdx2++;
544       fCurrentIdx1 -= fNdim1;
545     }
546     if (fElements->At(i) > fThreshold) break;
547   }
548
549   fCurrentIndex = i;
550   if (fCurrentIndex >= 0) return kTRUE;
551   fCurrentIdx1  = -1;
552   fCurrentIdx2  = -1;
553   return kFALSE;        
554
555 }
556
557 //_____________________________________________________________________________
558 Bool_t AliTRDdataArrayF::Next1() 
559 {
560   //
561   // Returns the next entry for a buffer of type 1
562   //
563
564   if (fCurrentIndex < 0) return kFALSE;
565
566   Int_t i;
567   for (i = fCurrentIndex + 1; i < fNelems; i++){
568     if (fElements->At(i) < 0) {
569       //fCurrentIdx1 -= (Int_t) fElements->At(i);
570       fCurrentIdx1 -= TMath::Nint(fElements->At(i));
571     }
572     else {      
573       fCurrentIdx1++;
574     }
575     if (fCurrentIdx1 >= fNdim1) {
576       fCurrentIdx2++;
577       fCurrentIdx1 -= fNdim1;
578     }
579     if (fElements->At(i) > fThreshold) break;
580   }
581
582   fCurrentIndex =  i;
583   if ((i >= 0) && (i < fNelems)) return kTRUE;
584   fCurrentIdx1  = -1;
585   fCurrentIdx2  = -1;
586   return kFALSE;
587
588 }
589
590 //_____________________________________________________________________________
591 Float_t AliTRDdataArrayF::GetData1(Int_t idx1, Int_t idx2) const
592 {
593   //
594   // Returns the value at a given position of the array
595   //
596   
597   Int_t i, n2;
598
599   if ((idx2 + 1) >= fNdim2) {
600     n2 = fNelems;
601   }
602   else {
603     n2 = fIndex->At(idx2 + 1);
604   }
605
606   // Current idx1    
607   Int_t curidx1 = 0; 
608  
609   for (i = fIndex->At(idx2); ((i < n2) && (curidx1 < idx1)); i++){
610     if (fElements->At(i) < 0) {
611       //curidx1 -= (Int_t) fElements->At(i);
612       curidx1 -= TMath::Nint(fElements->At(i));
613     }
614     else {      
615       curidx1++;
616     }
617   }
618
619   if ((curidx1 == idx1) && (fElements->At(i) > 0)) {
620     return fElements->At(i);
621   }
622   else {
623     return 0;
624   }
625
626 }
627
628 //_____________________________________________________________________________
629 void AliTRDdataArrayF::SetData(Int_t row, Int_t col, Int_t time, Float_t value)
630 {
631   //
632   // Sets the data value at a given position of the array
633   // Includes boundary checking
634   //
635
636   if ((row >= 0) && (col >= 0) && (time >= 0)) {
637     Int_t idx1 = GetIdx1(row,col);
638     if ((idx1 >= 0) && (time < fNdim2)) {
639       SetDataFast(idx1,time,value);
640     }
641     else {
642       if (idx1 >= 0) {
643         AliError(Form("time %d out of bounds (size: %d, this: 0x%08x)"
644                      ,time,fNdim2,this));
645       }
646     }
647   }
648
649 }
650
651 //_____________________________________________________________________________
652 void AliTRDdataArrayF::SetDataFast(Int_t idx1, Int_t idx2, Float_t value)
653 {
654   //
655   // Sets the data value at a given position of the array
656   // No boundary checking
657   //
658
659   (*fElements)[fIndex->fArray[idx2]+idx1] = value;
660
661 }
662
663 //_____________________________________________________________________________
664 AliTRDdataArrayF &AliTRDdataArrayF::operator=(const AliTRDdataArrayF &a)
665 {
666   //
667   // Assignment operator
668   //
669
670   if (this != &a) ((AliTRDdataArrayF &) a).Copy(*this);
671   return *this;
672
673 }
674