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