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