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