Add new TRD classes
[u/mrichter/AliRoot.git] / TRD / AliTRDdataArray.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 */
19
20 ///////////////////////////////////////////////////////////////////////////////
21 //                                                                           //
22 //  General container for data of a TRD detector segment.                    //
23 //  Adapted from AliDigits (origin: M.Ivanov).                               //
24 //  The main difference is that we used 4 byte integer, so that this class   //
25 //  can also be used as a dictionary between digits and MC particles.        //
26 //                                                                           //
27 ///////////////////////////////////////////////////////////////////////////////
28
29 #include "TClass.h"
30 #include "TError.h"
31 #include "AliTRDsegmentID.h"
32 #include "AliTRDarrayI.h"
33 #include "AliTRDdataArray.h"
34
35 ClassImp(AliTRDdataArray)
36
37 //_____________________________________________________________________________
38 AliTRDdataArray::AliTRDdataArray()
39 {
40   //
41   // Default constructor
42   //
43
44   fIndex     = 0;
45   fElements  = 0;
46   fThreshold = 0;
47   Reset();
48
49 }
50
51 //_____________________________________________________________________________
52 AliTRDdataArray::~AliTRDdataArray()
53 {
54   //
55   // Destructor
56   //
57
58   if (fIndex)    fIndex->Delete();;
59   if (fElements) fElements->Delete();
60   
61 }
62
63
64 //_____________________________________________________________________________
65 void AliTRDdataArray::Reset() 
66
67   //
68   // Reset the array (old content gets deleted)
69   //
70
71   if (fIndex)    delete fIndex;
72   fIndex    = new AliTRDarrayI;
73   
74   if (fElements) delete fElements;
75   fElements = new AliTRDarrayI;
76
77   fNdim1 = fNdim2 = fNelems = -1; 
78   fElements->Set(0); 
79   fIndex->Set(0); 
80   fBufType = -1;
81
82   fNrow  = 0;
83   fNcol  = 0;
84   fNtime = 0;
85
86 }
87
88 //_____________________________________________________________________________
89 void AliTRDdataArray::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
90 {
91   //
92   // Allocate an empty buffer of the size <nrow> x <ncol> x <ntime>
93   //
94
95   Reset();
96
97   if (nrow  <= 0) {
98     Error("AliTRDdataArray::Allocate","The number of rows has to be positive");
99     return;
100   }
101   if (ncol  <= 0) {
102     Error("AliTRDdataArray::Allocate","The number of columns has to be positive");
103     return;
104   }
105   if (ntime <= 0) {
106     Error("AliTRDdataArray::Allocate","The number of timebins has to be positive");
107     return;
108   }
109
110   // The two-dimensional array row/column gets mapped into the first 
111   // dimension of the array. The second array dimension, which is not compressible,
112   // corresponds to the time direction
113   fNdim1  = nrow * ncol;
114   fNdim2  = ntime;
115   fNelems = fNdim1 * fNdim2;
116
117   fNrow   = nrow;
118   fNcol   = ncol;
119   fNtime  = ntime;
120
121   fElements->Set(fNelems);
122   fIndex->Set(fNdim2);
123
124   for (Int_t i = 0, k = 0; i < fNdim2; i++, k += fNdim1) { 
125     (*fIndex)[i] = k;
126   }
127
128   fBufType = 0;
129
130 }
131
132 //_____________________________________________________________________________
133 Int_t AliTRDdataArray::GetSize()
134 {
135   //
136   // Returns the size of the complete object
137   //
138
139   Int_t size = sizeof(this);
140
141   if (fIndex)    size += sizeof(fIndex)    
142                          + fIndex->GetSize()    * sizeof(Int_t);
143   if (fElements) size += sizeof(fElements) 
144                          + fElements->GetSize() * sizeof(Int_t);
145
146   return size;
147
148 }
149
150 //_____________________________________________________________________________
151 Int_t AliTRDdataArray::GetDataSize()
152 {
153   //
154   // Returns the size of only the data part
155   //
156
157   if (fElements == 0) 
158     return 0;
159   else 
160     return sizeof(fElements) + fElements->GetSize() * sizeof(Int_t);
161
162 }
163
164 //_____________________________________________________________________________
165 Int_t AliTRDdataArray::GetOverThreshold(Float_t threshold)
166 {
167   //
168   // Returns the number of entries over threshold
169   //
170  
171   if ((fElements == 0) || (fElements->GetSize() <= 0))
172     return 0;
173  
174   Int_t  over = 0;
175
176   for (Bool_t cont = First(); cont == kTRUE; cont = Next()) {
177     if ((fCurrentIdx1 < 0) || (fCurrentIdx1 > fNdim1)) continue;
178     if ((fCurrentIdx2 < 0) || (fCurrentIdx2 > fNdim2)) continue;
179     if (fElements->At(fCurrentIndex) > threshold) over++;
180   }
181
182   return over;
183
184 }
185
186 //_____________________________________________________________________________
187 Int_t AliTRDdataArray::GetData(Int_t row, Int_t col, Int_t time)
188 {
189   //
190   // Returns the data value at a given position of the array
191   //
192
193   if (fBufType == 0) return GetDataFast(GetIdx1(row,col),time);
194   if (fBufType == 1) return GetData1(GetIdx1(row,col),time);
195
196   return 0;
197
198 }
199
200 //_____________________________________________________________________________
201 void AliTRDdataArray::SetData(Int_t row, Int_t col, Int_t time, Int_t value)
202 {
203   //
204   // Sets the data value at a given position of the array
205   //
206
207   SetDataFast(GetIdx1(row,col),time,value);
208
209 }
210
211 //_____________________________________________________________________________
212 void AliTRDdataArray::Expand()
213 {  
214   //
215   // Expands the compressed buffer
216   //
217
218   if (fBufType  < 0) {
219     Error("AliTRDdataArray::Expand","Buffer does not exist");
220     return;
221   }
222   if (fBufType == 0) {  
223     return;
224   } 
225  
226   // Expand a buffer of type 1
227   if (fBufType == 1) Expand1();
228   
229   fBufType = 0;
230
231 }
232
233 //_____________________________________________________________________________
234 void AliTRDdataArray::Compress(Int_t bufferType)
235 {
236   //
237   // Compresses the buffer
238   //
239
240   if (fBufType  < 0) {
241     Error("AliTRDdataArray::Compress","Buffer does not exist");
242     return;
243   }
244   if (fBufType == bufferType) {
245     return;
246   }  
247   if (fBufType > 0) {
248     Expand();
249   }
250   if (fBufType !=0)  {
251     Error("AliTRDdataArray::Compress","Buffer does not exist");
252     return;
253   }
254
255   // Compress a buffer of type 1
256   if (bufferType == 1) {
257     Compress1();
258   }
259
260 }
261
262 //_____________________________________________________________________________
263 void AliTRDdataArray::Compress(Int_t bufferType, Int_t threshold)
264 {
265   //
266   // Compresses the buffer
267   //
268
269   fThreshold = threshold;
270   Compress(bufferType);
271
272 }
273
274 //_____________________________________________________________________________
275 Bool_t AliTRDdataArray::First()
276 {
277   //
278   // Returns the position of the first valid data value
279   //
280
281   if (fBufType == 0) return First0();
282   if (fBufType == 1) return First1();
283   return kFALSE;
284
285 }
286
287 //_____________________________________________________________________________
288 Bool_t  AliTRDdataArray::Next()
289 {
290   //
291   // Returns the position of the next valid data value
292   //
293
294   if (fBufType == 0) return Next0();
295   if (fBufType == 1) return Next1();
296   return kFALSE;
297
298 }
299  
300 //_____________________________________________________________________________
301 void AliTRDdataArray::Expand1()
302 {
303   //
304   // Expands a buffer of type 1
305   //
306
307   Int_t i, k;
308
309   fNelems = fNdim1 * fNdim2;
310
311   Int_t *buf = new Int_t[fNelems];
312
313   fIndex->Set(fNdim2);
314
315   for (i = 0, k = 0; i < fNdim2; i++, k += fNdim1) (*fIndex)[i] = k;
316
317   Int_t idx1 = 0;
318   Int_t idx2 = 0;
319   Int_t N    = fElements->fN;
320
321   for (i = 0; i < N; i++){
322
323     // Negative sign counts the unwritten values (under threshold)
324     if ((*fElements)[i] < 0) {
325       idx1 -= fElements->At(i);
326     } 
327     else {
328       buf[(*fIndex)[idx2] + idx1] = fElements->At(i);
329       idx1++;
330     }
331     if (idx1 == fNdim1) {
332       idx1 = 0;
333       idx2++;
334     }
335     else { 
336       if (idx1 > fNdim1){
337         Reset();
338         return;
339       }      
340     }
341   }
342
343   fElements->Adopt(fNelems,buf); 
344    
345 }
346
347 //_____________________________________________________________________________
348 void AliTRDdataArray::Compress1()
349 {
350   //
351   // Compress a buffer of type 1
352   //
353
354   AliTRDarrayI  buf;  
355   buf.Set(fNelems);
356   AliTRDarrayI  index;
357   index.Set(fNdim2);
358
359   Int_t icurrent = -1;
360   Int_t izero;
361   for (Int_t idx2 = 0; idx2 < fNdim2; idx2++){      
362
363     // Set the idx2 pointer
364     index[idx2] = icurrent + 1;
365
366     // Reset the zero counter 
367     izero = 0;  
368
369     for (Int_t idx1 = 0; idx1 < fNdim1; idx1++){
370       // If below threshold
371       if (GetDataFast(idx1,idx2) <= fThreshold) {
372         izero++;
373       }
374       else {
375         if (izero > 0) {
376           // If we have currently izero counts under threshold
377           icurrent++;     
378           if (icurrent >= buf.fN) buf.Expand(icurrent*2);
379           // Store the number of entries below zero
380           buf[icurrent] = -izero;  
381           izero = 0;
382         } 
383         icurrent++;
384         if (icurrent >= buf.fN) buf.Expand(icurrent*2);
385         buf[icurrent] = GetDataFast(idx1,idx2);     
386       } // If signal larger than threshold              
387     } // End of loop over idx1
388
389     if (izero > 0) {
390       icurrent++;         
391       if (icurrent >= buf.fN) buf.Expand(icurrent*2);
392       // Store the number of entries below zero
393       buf[icurrent] = -izero; 
394     }
395
396   }
397
398   buf.Expand(icurrent+1);
399   (*fElements) = buf;
400   fNelems   = fElements->fN;
401   fBufType  = 1;
402   (*fIndex) = index;
403
404 }
405
406 //_____________________________________________________________________________
407 void AliTRDdataArray::Expand2()
408 {
409   //
410   // Expands a buffer of type 2 
411   //
412
413   Int_t i, k;
414   Int_t *buf = new Int_t[fNelems];
415
416   fNelems = fNdim1 * fNdim2;
417   fIndex->Set(fNdim2);
418
419   for (i = 0, k = 0; i < fNdim2; i++, k += fNdim1) (*fIndex)[i] = k;
420
421   Int_t idx1 = 0;
422   Int_t idx2 = 0;
423   Int_t N    = fElements->fN;
424   for (i = 0; i < N; i++){
425     // Negative sign counts the unwritten values (under threshold)
426     if ((*fElements)[i] < 0) {
427       idx1 -= fElements->At(i); 
428     }
429     else {
430       buf[(*fIndex)[idx2]+idx1] = fElements->At(i);
431       idx1++;
432     }
433     if (idx1 == fNdim1) {
434       idx1 = 0;
435       idx2++;
436     }
437     else { 
438       if (idx1 > fNdim1){
439         Reset();
440         return;
441       }      
442     }
443   }
444
445   fElements->Adopt(fNelems,buf);    
446
447 }
448
449 //_____________________________________________________________________________
450 void AliTRDdataArray::Compress2()
451 {
452   /*
453
454   //
455   // Compress a buffer of type 2
456   //
457
458   AliArrayS  buf;  //lets have the nearly the "worst case"
459   buf.Set(fNelems);
460   AliTRDarrayI  index;
461   index.Set(fNdim2);
462   Int_t icurrent=-1;
463   Int_t izero;
464
465   for (Int_t col = 0; col<fNdim2; col++){      
466     index[col]=icurrent+1;//set collumn pointer
467     izero = 0;  //reset zer counter at the begining of the column
468     Int_t lastrow=0;
469     Int_t lastrowval=GetDigitFast(row,0);
470
471     for (Int_t row = 1; row< fNdim1;row++){
472       //if under threshold
473       Int_t val = GetDigitFast(row,col);
474       Int_t dif = val -lastrowval;
475       
476       if (TMath::Abs(dif)<fThreshold)  izero++;
477       else{
478         if (izero>0) {
479           //if we have currently izero count under threshold
480           icurrent++;     
481           if (icurrent>=buf.fN) buf.Expand(icurrent*2);
482           buf[icurrent]= -izero;  //write how many under zero
483           izero = 0;
484         } //end of reseting izero
485         icurrent++;
486         if (icurrent>=buf.fN) buf.Expand(icurrent*2);
487         buf[icurrent] = GetDigitFast(row,col);      
488       }//if signal bigger then threshold                
489     } //end of loop over rows
490     
491     if (izero>0) {
492       icurrent++;         
493       if (icurrent>=buf.fN) buf.Expand(icurrent*2);
494       buf[icurrent]= -izero;  //write how many under zero
495     }
496   }//end of lopping over digits
497   buf.Expand(icurrent+1);
498   (*fElements)=buf;
499   fNelems = fElements->fN;
500   fBufType = 1;
501   (*fIndex) =index;
502   //end of compresing bufer of type 1 
503
504   */
505
506 }
507
508 //_____________________________________________________________________________
509 Bool_t AliTRDdataArray::First0()
510 {
511   //
512   // Returns the first entry for a buffer of type 0
513   //
514
515   fCurrentIdx1  = -1;
516   fCurrentIdx2  = -1;
517   fCurrentIndex = -1;
518
519   Int_t i;
520   for (i = 0; ((i < fNelems) && (fElements->At(i) <= fThreshold)); i++)
521   if (i == fNelems) return kFALSE;
522
523   fCurrentIdx1  = i % fNdim1;
524   fCurrentIdx2  = i / fNdim1;
525   fCurrentIndex = i;
526   return kTRUE; 
527
528 }
529
530 //_____________________________________________________________________________
531 Bool_t AliTRDdataArray::Next0()
532 {
533   //
534   // Returns the next entry for a buffer of type 0
535   //
536
537   if (fCurrentIndex < 0) return kFALSE; 
538
539   Int_t i;
540   for (i = fCurrentIndex + 1; 
541        ((i < fNelems) && (fElements->At(i) <= fThreshold)); 
542        i++);
543   if (i >= fNelems)  {
544     fCurrentIndex = -1;
545     return kFALSE;
546   }
547
548   fCurrentIdx1  = i % fNdim1;
549   fCurrentIdx2  = i / fNdim1;
550   fCurrentIndex = i;
551   return kTRUE; 
552
553 }
554
555 //_____________________________________________________________________________
556 Bool_t AliTRDdataArray::First1()
557 {
558   //
559   // Returns the first entry for a buffer of type 1
560   //
561
562   fCurrentIdx1  = -1;
563   fCurrentIdx2  =  0;
564   fCurrentIndex = -1;
565
566   Int_t i;
567   for (i = 0; i < fNelems; i++){
568     if (fElements->At(i) < 0) {
569       fCurrentIdx1-=fElements->At(i);
570     }
571     else {     
572       fCurrentIdx1++;
573     }
574     if (fCurrentIdx1 >= fNdim1) {
575       fCurrentIdx2++;
576       fCurrentIdx1 -= fNdim1;
577     }
578     if (fElements->At(i) > fThreshold) break;
579   }
580
581   fCurrentIndex = i;
582   if (fCurrentIndex >= 0) return kTRUE;
583   fCurrentIdx1  = -1;
584   fCurrentIdx2  = -1;
585   return kFALSE;        
586
587 }
588
589 //_____________________________________________________________________________
590 Bool_t AliTRDdataArray::Next1()
591 {
592   //
593   // Returns the next entry for a buffer of type 1
594   //
595
596   if (fCurrentIndex < 0) return kFALSE;
597
598   Int_t i;
599   for (i = fCurrentIndex + 1; i < fNelems; i++){
600     if (fElements->At(i) < 0) {
601       fCurrentIdx1 -= fElements->At(i);
602     }
603     else {      
604       fCurrentIdx1++;
605     }
606     if (fCurrentIdx1 >= fNdim1) {
607       fCurrentIdx2++;
608       fCurrentIdx1 -= fNdim1;
609     }
610     if (fElements->At(i) > fThreshold) break;
611   }
612
613   fCurrentIndex =  i;
614   if ((i >= 0) && (i < fNelems)) return kTRUE;
615   fCurrentIdx1  = -1;
616   fCurrentIdx2  = -1;
617   return kFALSE;
618
619 }
620
621 //_____________________________________________________________________________
622 Int_t AliTRDdataArray::GetData1(Int_t idx1, Int_t idx2)
623 {
624   //
625   // Returns the value at a given position of the array
626   //
627   
628   Int_t i, n2;
629
630   if ((idx2 + 1) >= fNdim2) {
631     n2 = fNelems;
632   }
633   else {
634     n2 = fIndex->At(idx2 + 1);
635   }
636
637   // Current idx1    
638   Int_t curidx1 = 0; 
639  
640   for (i = fIndex->At(idx2); ((i < n2) && (curidx1 < idx1)); i++){
641     if (fElements->At(i) < 0) {
642       curidx1 -= fElements->At(i);
643     }
644     else {      
645       curidx1++;
646     }
647   }
648
649   if ((curidx1 == idx1) && (fElements->At(i) > 0)) {
650     return fElements->At(i);
651   }
652   else {
653     return 0;
654   }
655
656 }
657