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