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