Making online tracklets usable in offline reconstruction
[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 /* $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 "AliTRDdataArrayF.h"
28 #include "AliTRDarrayI.h"
29 #include "AliTRDarrayF.h"
30
31 ClassImp(AliTRDdataArrayF)
32
33 //_____________________________________________________________________________
34 AliTRDdataArrayF::AliTRDdataArrayF()
35    :AliTRDdataArray()
36    ,fElements(0)
37    ,fThreshold(0)
38 {
39   //
40   // Default constructor
41   //
42
43 }
44
45 //_____________________________________________________________________________
46 AliTRDdataArrayF::AliTRDdataArrayF(Int_t nrow, Int_t ncol, Int_t ntime)
47    :AliTRDdataArray(nrow,ncol,ntime)
48    ,fElements(0)
49    ,fThreshold(0)
50 {
51   //
52   // Creates a AliTRDdataArrayF with the dimensions <nrow>, <ncol>, and <ntime>.
53   // The row- and column dimensions are compressible.
54   //
55
56   Allocate(nrow,ncol,ntime);
57   
58 }
59
60 //_____________________________________________________________________________
61 AliTRDdataArrayF::AliTRDdataArrayF(const AliTRDdataArrayF &a)
62    :AliTRDdataArray(a)
63    ,fElements(a.fElements)
64    ,fThreshold(a.fThreshold)
65 {
66   //
67   // AliTRDdataArrayF copy constructor
68   //
69
70 }
71
72 //_____________________________________________________________________________
73 AliTRDdataArrayF::~AliTRDdataArrayF()
74 {
75   //
76   // Destructor
77   //
78
79   if (fElements) {
80     delete fElements;
81     fElements = 0;
82   }
83   
84 }
85
86 //_____________________________________________________________________________
87 void AliTRDdataArrayF::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
88 {
89   //
90   // Allocates memory for a AliTRDdataArrayF with the dimensions 
91   // <nrow>, <ncol>, and <ntime>.
92   // The row- and column dimensions are compressible.
93   //
94
95   if (fNelems < 0) {
96     AliTRDdataArray::Allocate(nrow,ncol,ntime);
97   }
98
99   if (fElements) {
100     delete fElements;
101   }
102
103   fElements = new AliTRDarrayF();
104   fElements->Set(fNelems);
105
106 }
107
108 //_____________________________________________________________________________
109 void AliTRDdataArrayF::Copy(TObject &a) const
110 {
111   //
112   // Copy function
113   //
114
115   fElements->Copy(*((AliTRDdataArrayF &) a).fElements);
116
117   ((AliTRDdataArrayF &) a).fThreshold = fThreshold;
118
119   AliTRDdataArray::Copy(a);
120
121 }
122
123 //_____________________________________________________________________________
124 void AliTRDdataArrayF::Reset() 
125
126   //
127   // Reset the array (old content gets deleted)
128   //
129   
130   if (fElements) {
131     delete fElements;
132   }
133
134   fElements = new AliTRDarrayF();
135   fElements->Set(0); 
136
137   AliTRDdataArray::Reset();
138
139 }
140
141 //_____________________________________________________________________________
142 Int_t AliTRDdataArrayF::GetSize() const
143 {
144   //
145   // Returns the size of the complete object
146   //
147
148   Int_t size = sizeof(this);
149
150   if (fIndex)    size += sizeof(fIndex)    
151                          + fIndex->GetSize()    * sizeof(Int_t);
152   if (fElements) size += sizeof(fElements) 
153                          + fElements->GetSize() * sizeof(Float_t);
154
155   return size;
156
157 }
158
159 //_____________________________________________________________________________
160 Int_t AliTRDdataArrayF::GetDataSize() const 
161 {
162   //
163   // Returns the size of only the data part
164   //
165
166   if (fElements == 0) 
167     return 0;
168   else 
169     return sizeof(fElements) + fElements->GetSize() * sizeof(Float_t);
170
171 }
172
173 //_____________________________________________________________________________
174 Int_t AliTRDdataArrayF::GetOverThreshold(Float_t threshold) 
175 {
176   //
177   // Returns the number of entries over threshold
178   //
179  
180   if ((fElements == 0) || (fElements->GetSize() <= 0))
181     return 0;
182  
183   Int_t over = 0;
184
185   for (Bool_t cont = First(); cont == kTRUE; cont = Next()) {
186     if ((fCurrentIdx1 < 0) || (fCurrentIdx1 >= fNdim1)) continue;
187     if ((fCurrentIdx2 < 0) || (fCurrentIdx2 >= fNdim2)) continue;
188     if (fElements->At(fCurrentIndex) > threshold) over++;
189   }
190
191   return over;
192
193 }
194
195 //_____________________________________________________________________________
196 Float_t AliTRDdataArrayF::GetData(Int_t row, Int_t col, Int_t time) const
197 {
198   //
199   // Returns the data value at a given position of the array
200   // Includes boundary checking
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 Float_t AliTRDdataArrayF::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 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     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 AliTRDdataArrayF::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 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   memset(buf,0,fNelems*sizeof(Float_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 -= TMath::Nint(fElements->At(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 AliTRDdataArrayF::Compress1()
372 {
373   //
374   // Compress a buffer of type 1
375   //
376
377   AliTRDarrayF *buf   = new AliTRDarrayF();  
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 AliTRDdataArrayF::Expand2()
433 {
434   //
435   // Expands a buffer of type 2 
436   //
437
438   Int_t i, k;
439
440   Float_t *buf = new Float_t[fNelems];
441   memset(buf,0,fNelems*sizeof(Float_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 -= (Int_t) fElements->At(i); 
455       idx1 -= TMath::Nint(fElements->At(i)); 
456     }
457     else {
458       buf[(*fIndex)[idx2]+idx1] = fElements->At(i);
459       idx1++;
460     }
461     if (idx1 == fNdim1) {
462       idx1 = 0;
463       idx2++;
464     }
465     else { 
466       if (idx1 > fNdim1){
467         Reset();
468         return;
469       }      
470     }
471   }
472
473   fElements->Adopt(fNelems,buf);    
474
475 }
476
477 //_____________________________________________________________________________
478 void AliTRDdataArrayF::Compress2()
479 {
480   //
481   // Compress a buffer of type 2 - not implemented!
482   //
483
484 }
485
486 //_____________________________________________________________________________
487 Bool_t AliTRDdataArrayF::First0() 
488 {
489   //
490   // Returns the first entry for a buffer of type 0
491   //
492
493   fCurrentIdx1  = -1;
494   fCurrentIdx2  = -1;
495   fCurrentIndex = -1;
496
497   Int_t i;
498   for (i = 0; ((i < fNelems) && (fElements->At(i) <= fThreshold)); i++)
499   if (i == fNelems) return kFALSE;
500
501   fCurrentIdx1  = i % fNdim1;
502   fCurrentIdx2  = i / fNdim1;
503   fCurrentIndex = i;
504   return kTRUE; 
505
506 }
507
508 //_____________________________________________________________________________
509 Bool_t AliTRDdataArrayF::Next0()
510 {
511   //
512   // Returns the next entry for a buffer of type 0
513   //
514
515   if (fCurrentIndex < 0) return kFALSE; 
516
517   Int_t i;
518   for (i = fCurrentIndex + 1; 
519        ((i < fNelems) && (fElements->At(i) <= fThreshold)); 
520        i++) {}
521   if (i >= fNelems)  {
522     fCurrentIndex = -1;
523     return kFALSE;
524   }
525
526   fCurrentIdx1  = i % fNdim1;
527   fCurrentIdx2  = i / fNdim1;
528   fCurrentIndex = i;
529   return kTRUE; 
530
531 }
532
533 //_____________________________________________________________________________
534 Bool_t AliTRDdataArrayF::First1() 
535 {
536   //
537   // Returns the first entry for a buffer of type 1
538   //
539
540   fCurrentIdx1  = -1;
541   fCurrentIdx2  =  0;
542   fCurrentIndex = -1;
543
544   Int_t i;
545   for (i = 0; i < fNelems; i++){
546     if (fElements->At(i) < 0) {
547       //fCurrentIdx1 -= (Int_t) fElements->At(i);
548       fCurrentIdx1 -= TMath::Nint(fElements->At(i));
549     }
550     else {     
551       fCurrentIdx1++;
552     }
553     if (fCurrentIdx1 >= fNdim1) {
554       fCurrentIdx2++;
555       fCurrentIdx1 -= fNdim1;
556     }
557     if (fElements->At(i) > fThreshold) break;
558   }
559
560   fCurrentIndex = i;
561   if (fCurrentIndex >= 0) return kTRUE;
562   fCurrentIdx1  = -1;
563   fCurrentIdx2  = -1;
564   return kFALSE;        
565
566 }
567
568 //_____________________________________________________________________________
569 Bool_t AliTRDdataArrayF::Next1() 
570 {
571   //
572   // Returns the next entry for a buffer of type 1
573   //
574
575   if (fCurrentIndex < 0) return kFALSE;
576
577   Int_t i;
578   for (i = fCurrentIndex + 1; i < fNelems; i++){
579     if (fElements->At(i) < 0) {
580       //fCurrentIdx1 -= (Int_t) fElements->At(i);
581       fCurrentIdx1 -= TMath::Nint(fElements->At(i));
582     }
583     else {      
584       fCurrentIdx1++;
585     }
586     if (fCurrentIdx1 >= fNdim1) {
587       fCurrentIdx2++;
588       fCurrentIdx1 -= fNdim1;
589     }
590     if (fElements->At(i) > fThreshold) break;
591   }
592
593   fCurrentIndex =  i;
594   if ((i >= 0) && (i < fNelems)) return kTRUE;
595   fCurrentIdx1  = -1;
596   fCurrentIdx2  = -1;
597   return kFALSE;
598
599 }
600
601 //_____________________________________________________________________________
602 Float_t AliTRDdataArrayF::GetData1(Int_t idx1, Int_t idx2) const
603 {
604   //
605   // Returns the value at a given position of the array
606   //
607   
608   Int_t i, n2;
609
610   if ((idx2 + 1) >= fNdim2) {
611     n2 = fNelems;
612   }
613   else {
614     n2 = fIndex->At(idx2 + 1);
615   }
616
617   // Current idx1    
618   Int_t curidx1 = 0; 
619  
620   for (i = fIndex->At(idx2); ((i < n2) && (curidx1 < idx1)); i++){
621     if (fElements->At(i) < 0) {
622       //curidx1 -= (Int_t) fElements->At(i);
623       curidx1 -= TMath::Nint(fElements->At(i));
624     }
625     else {      
626       curidx1++;
627     }
628   }
629
630   if ((curidx1 == idx1) && (fElements->At(i) > 0)) {
631     return fElements->At(i);
632   }
633   else {
634     return 0;
635   }
636
637 }
638
639 //_____________________________________________________________________________
640 void AliTRDdataArrayF::SetData(Int_t row, Int_t col, Int_t time, Float_t value)
641 {
642   //
643   // Sets the data value at a given position of the array
644   // Includes boundary checking
645   //
646
647   if ((row >= 0) && (col >= 0) && (time >= 0)) {
648     Int_t idx1 = GetIdx1(row,col);
649     if ((idx1 >= 0) && (time < fNdim2)) {
650       SetDataFast(idx1,time,value);
651     }
652     else {
653       if (idx1 >= 0) {
654         AliError(Form("time %d out of bounds (size: %d, this: 0x%08x)"
655                      ,time,fNdim2,this));
656       }
657     }
658   }
659
660 }
661
662 //_____________________________________________________________________________
663 void AliTRDdataArrayF::SetDataFast(Int_t idx1, Int_t idx2, Float_t value)
664 {
665   //
666   // Sets the data value at a given position of the array
667   // No boundary checking
668   //
669
670   (*fElements)[fIndex->fArray[idx2]+idx1] = value;
671
672 }
673
674 //_____________________________________________________________________________
675 AliTRDdataArrayF &AliTRDdataArrayF::operator=(const AliTRDdataArrayF &a)
676 {
677   //
678   // Assignment operator
679   //
680
681   if (this != &a) ((AliTRDdataArrayF &) a).Copy(*this);
682   return *this;
683
684 }
685