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