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