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