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