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