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