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