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