Latest version
[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.10  2002/02/11 14:27:54  cblume
19 Geometry and hit structure update
20
21 Revision 1.9  2001/05/07 08:08:05  cblume
22 Update of TRD code
23
24 Revision 1.8  2000/11/23 14:34:08  cblume
25 Fixed bug in expansion routine of arrays (initialize buffers properly)
26
27 Revision 1.7  2000/11/20 08:56:07  cblume
28 Cleanup of data arrays
29
30 Revision 1.6  2000/11/01 14:53:20  cblume
31 Merge with TRD-develop
32
33 Revision 1.1.2.3  2000/10/06 16:49:46  cblume
34 Made Getters const
35
36 Revision 1.1.2.2  2000/10/04 16:34:58  cblume
37 Replace include files by forward declarations
38
39 Revision 1.5  2000/06/27 13:08:50  cblume
40 Changed to Copy(TObject &A) to appease the HP-compiler
41
42 Revision 1.4  2000/06/09 11:10:07  cblume
43 Compiler warnings and coding conventions, next round
44
45 Revision 1.3  2000/06/08 18:32:58  cblume
46 Make code compliant to coding conventions
47
48 Revision 1.2  2000/05/08 16:17:27  cblume
49 Merge TRD-develop
50
51 Revision 1.1.2.1  2000/05/08 15:14:34  cblume
52 Add new data array classes
53
54 */
55
56 ///////////////////////////////////////////////////////////////////////////////
57 //                                                                           //
58 //  General container for integer data of a TRD detector segment.            //
59 //  Adapted from AliDigits (origin: M.Ivanov).                               //
60 //                                                                           //
61 ///////////////////////////////////////////////////////////////////////////////
62
63 #include "AliTRDdataArrayI.h"
64 #include "AliTRDarrayI.h"
65
66 ClassImp(AliTRDdataArrayI)
67
68 //_____________________________________________________________________________
69 AliTRDdataArrayI::AliTRDdataArrayI():AliTRDdataArray()
70 {
71   //
72   // Default constructor
73   //
74
75   fElements = 0;
76
77 }
78
79 //_____________________________________________________________________________
80 AliTRDdataArrayI::AliTRDdataArrayI(Int_t nrow, Int_t ncol, Int_t ntime)
81                  :AliTRDdataArray(nrow,ncol,ntime)
82 {
83   //
84   // Creates a AliTRDdataArrayI with the dimensions <nrow>, <ncol>, and <ntime>.
85   // The row- and column dimensions are compressible.
86   //
87
88   fElements = 0;
89
90   Allocate(nrow,ncol,ntime);
91   
92 }
93
94 //_____________________________________________________________________________
95 AliTRDdataArrayI::AliTRDdataArrayI(const AliTRDdataArrayI &a)
96 {
97   //
98   // AliTRDdataArrayI copy constructor
99   //
100
101   ((AliTRDdataArrayI &) a).Copy(*this);
102
103 }
104
105 //_____________________________________________________________________________
106 AliTRDdataArrayI::~AliTRDdataArrayI()
107 {
108   //
109   // Destructor
110   //
111
112   if (fElements) delete fElements;
113   
114 }
115
116 //_____________________________________________________________________________
117 void AliTRDdataArrayI::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
118 {
119   //
120   // Allocates memory for a AliTRDdataArrayI with the dimensions 
121   // <nrow>, <ncol>, and <ntime>.
122   // The row- and column dimensions are compressible.
123   //
124
125   if (fNelems < 0) AliTRDdataArray::Allocate(nrow,ncol,ntime);
126
127   if (fElements) delete fElements;
128   fElements = new AliTRDarrayI();
129   fElements->Set(fNelems);
130
131 }
132
133 //_____________________________________________________________________________
134 void AliTRDdataArrayI::Copy(TObject &a)
135 {
136   //
137   // Copy function
138   //
139
140   fElements->Copy(*((AliTRDdataArrayI &) a).fElements);
141
142   ((AliTRDdataArrayI &) a).fThreshold = fThreshold;
143
144   AliTRDdataArray::Copy(a);
145
146 }
147
148 //_____________________________________________________________________________
149 void AliTRDdataArrayI::Reset() 
150
151   //
152   // Reset the array (old content gets deleted)
153   //
154
155   if (fElements) delete fElements;
156   fElements = new AliTRDarrayI();
157   fElements->Set(0); 
158
159   AliTRDdataArray::Reset();
160
161
162 }
163
164 //_____________________________________________________________________________
165 Int_t AliTRDdataArrayI::GetSize() const
166 {
167   //
168   // Returns the size of the complete object
169   //
170
171   Int_t size = sizeof(this);
172
173   if (fIndex)    size += sizeof(fIndex)    
174                          + fIndex->GetSize()    * sizeof(Int_t);
175   if (fElements) size += sizeof(fElements) 
176                          + fElements->GetSize() * sizeof(Int_t);
177
178   return size;
179
180 }
181
182 //_____________________________________________________________________________
183 Int_t AliTRDdataArrayI::GetDataSize() const
184 {
185   //
186   // Returns the size of only the data part
187   //
188
189   if (fElements == 0) 
190     return 0;
191   else 
192     return sizeof(fElements) + fElements->GetSize() * sizeof(Int_t);
193
194 }
195
196 //_____________________________________________________________________________
197 Int_t AliTRDdataArrayI::GetOverThreshold(Int_t threshold)
198 {
199   //
200   // Returns the number of entries over threshold
201   //
202  
203   if ((fElements == 0) || (fElements->GetSize() <= 0))
204     return 0;
205  
206   Int_t over = 0;
207
208   for (Bool_t cont = First(); cont == kTRUE; cont = Next()) {
209     if ((fCurrentIdx1 < 0) || (fCurrentIdx1 >= fNdim1)) continue;
210     if ((fCurrentIdx2 < 0) || (fCurrentIdx2 >= fNdim2)) continue;
211     if (fElements->At(fCurrentIndex) > threshold) over++;
212   }
213
214   return over;
215
216 }
217
218 //_____________________________________________________________________________
219 Int_t AliTRDdataArrayI::GetData(Int_t row, Int_t col, Int_t time) const
220 {
221   //
222   // Returns the data value at a given position of the array
223   //
224
225   if ((row >= 0) && (col >= 0) && (time >= 0)) {
226     Int_t idx1 = GetIdx1(row,col);
227     if ((idx1 >= 0) && (time < fNdim2)) {
228       if (fBufType == 0) return GetDataFast(idx1,time);
229       if (fBufType == 1) return GetData1(idx1,time);
230     }
231     else {
232       if (idx1 >= 0) {
233         TObject::Error("GetData"
234                       ,"time %d out of bounds (size: %d, this: 0x%08x)"
235                       ,time,fNdim2,this);
236       }
237     }
238   }
239
240   return -1;
241
242 }
243
244 //_____________________________________________________________________________
245 Int_t AliTRDdataArrayI::GetDataFast(Int_t idx1, Int_t idx2) const
246 {
247   //
248   // Returns the data value at a given position of the array
249   // No boundary checking
250   //
251
252   return fElements->At(fIndex->At(idx2)+idx1);
253
254 }
255
256 //_____________________________________________________________________________
257 void AliTRDdataArrayI::Compress(Int_t bufferType, Int_t threshold)
258 {
259   //
260   // Compresses the buffer
261   //
262
263   fThreshold = threshold;
264   Compress(bufferType);
265
266 }
267
268 //_____________________________________________________________________________
269 void AliTRDdataArrayI::Compress(Int_t bufferType)
270 {
271   //
272   // Compresses the buffer
273   //
274
275   if (fBufType  < 0) {
276     Error("AliTRDdataArrayI::Compress","Buffer does not exist");
277     return;
278   }
279   if (fBufType == bufferType) {
280     return;
281   }  
282   if (fBufType > 0) {
283     Expand();
284   }
285   if (fBufType !=0)  {
286     Error("AliTRDdataArrayI::Compress","Buffer does not exist");
287     return;
288   }
289
290   // Compress a buffer of type 1
291   if (bufferType == 1) {
292     Compress1();
293   }
294
295 }
296
297 //_____________________________________________________________________________
298 void AliTRDdataArrayI::Expand()
299 {  
300   //
301   // Expands the compressed buffer
302   //
303
304   if (fBufType  < 0) {
305     Error("AliTRDdataArrayI::Expand","Buffer does not exist");
306     return;
307   }
308   if (fBufType == 0) {  
309     return;
310   } 
311  
312   // Expand a buffer of type 1
313   if (fBufType == 1) Expand1();
314   
315   fBufType = 0;
316
317 }
318
319 //_____________________________________________________________________________
320 Bool_t AliTRDdataArrayI::First()
321 {
322   //
323   // Returns the position of the first valid data value
324   //
325
326   if (fBufType == 0) return First0();
327   if (fBufType == 1) return First1();
328   return kFALSE;
329
330 }
331
332 //_____________________________________________________________________________
333 Bool_t  AliTRDdataArrayI::Next()
334 {
335   //
336   // Returns the position of the next valid data value
337   //
338
339   if (fBufType == 0) return Next0();
340   if (fBufType == 1) return Next1();
341   return kFALSE;
342
343 }
344
345 //_____________________________________________________________________________
346 void AliTRDdataArrayI::Expand1()
347 {
348   //
349   // Expands a buffer of type 1
350   //
351
352   Int_t i, k;
353
354   fNelems = fNdim1 * fNdim2;
355
356   Int_t *buf = new Int_t[fNelems];
357   memset(buf,0,fNelems*sizeof(Int_t));
358
359   fIndex->Set(fNdim2);
360
361   for (i = 0, k = 0; i < fNdim2; i++, k += fNdim1) (*fIndex)[i] = k;
362
363   Int_t idx1 = 0;
364   Int_t idx2 = 0;
365   Int_t n    = fElements->fN;
366
367   for (i = 0; i < n; i++){
368
369     // Negative sign counts the unwritten values (under threshold)
370     if ((*fElements)[i] < 0) {
371       idx1 -= (*fElements)[i];
372     } 
373     else {
374       buf[(*fIndex)[idx2] + idx1] = (*fElements)[i];
375       idx1++;
376     }
377     if (idx1 == fNdim1) {
378       idx1 = 0;
379       idx2++;
380     }
381     else { 
382       if (idx1 > fNdim1){
383         Reset();
384         return;
385       }      
386     }
387   }
388
389   fElements->Adopt(fNelems,buf); 
390    
391 }
392
393 //_____________________________________________________________________________
394 void AliTRDdataArrayI::Compress1()
395 {
396   //
397   // Compress a buffer of type 1
398   //
399
400   AliTRDarrayI *buf   = new AliTRDarrayI();  
401   buf->Set(fNelems);
402   AliTRDarrayI *index = new AliTRDarrayI();
403   index->Set(fNdim2);
404
405   Int_t icurrent = -1;
406   Int_t izero;
407   for (Int_t idx2 = 0; idx2 < fNdim2; idx2++){      
408
409     // Set the idx2 pointer
410     (*index)[idx2] = icurrent + 1;
411
412     // Reset the zero counter 
413     izero = 0;  
414
415     for (Int_t idx1 = 0; idx1 < fNdim1; idx1++){
416       // If below threshold
417       if (GetDataFast(idx1,idx2) <= fThreshold) {
418         izero++;
419       }
420       else {
421         if (izero > 0) {
422           // If we have currently izero counts under threshold
423           icurrent++;     
424           if (icurrent >= buf->fN) buf->Expand(icurrent*2);
425           // Store the number of entries below zero
426           (*buf)[icurrent] = -izero;  
427           izero = 0;
428         } 
429         icurrent++;
430         if (icurrent >= buf->fN) buf->Expand(icurrent*2);
431         (*buf)[icurrent] = GetDataFast(idx1,idx2);          
432       } // If signal larger than threshold              
433     } // End of loop over idx1
434
435     if (izero > 0) {
436       icurrent++;         
437       if (icurrent >= buf->fN) buf->Expand(icurrent*2);
438       // Store the number of entries below zero
439       (*buf)[icurrent] = -izero; 
440     }
441
442   }
443
444   buf->Expand(icurrent+1);
445   if (fElements) delete fElements;
446   fElements = buf;
447   fNelems   = fElements->fN;
448   fBufType  = 1;
449   if (fIndex) delete fIndex;
450   fIndex    = index;
451
452 }
453
454 //_____________________________________________________________________________
455 void AliTRDdataArrayI::Expand2()
456 {
457   //
458   // Expands a buffer of type 2 
459   //
460
461   Int_t i, k;
462
463   Int_t *buf = new Int_t[fNelems];
464   memset(buf,0,fNelems*sizeof(Int_t)); 
465
466   fNelems = fNdim1 * fNdim2;
467   fIndex->Set(fNdim2);
468
469   for (i = 0, k = 0; i < fNdim2; i++, k += fNdim1) (*fIndex)[i] = k;
470
471   Int_t idx1 = 0;
472   Int_t idx2 = 0;
473   Int_t n    = fElements->fN;
474   for (i = 0; i < n; i++){
475     // Negative sign counts the unwritten values (under threshold)
476     if ((*fElements)[i] < 0) {
477       idx1 -= fElements->At(i); 
478     }
479     else {
480       buf[(*fIndex)[idx2]+idx1] = fElements->At(i);
481       idx1++;
482     }
483     if (idx1 == fNdim1) {
484       idx1 = 0;
485       idx2++;
486     }
487     else { 
488       if (idx1 > fNdim1){
489         Reset();
490         return;
491       }      
492     }
493   }
494
495   fElements->Adopt(fNelems,buf);    
496
497 }
498
499 //_____________________________________________________________________________
500 void AliTRDdataArrayI::Compress2()
501 {
502   //
503   // Compress a buffer of type 2 - not implemented!
504   //
505
506 }
507
508 //_____________________________________________________________________________
509 Bool_t AliTRDdataArrayI::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 AliTRDdataArrayI::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 AliTRDdataArrayI::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 AliTRDdataArrayI::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 AliTRDdataArrayI::GetData1(Int_t idx1, Int_t idx2) const
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
658 //_____________________________________________________________________________
659 void AliTRDdataArrayI::SetData(Int_t row, Int_t col, Int_t time, Int_t value)
660 {
661   //
662   // Sets the data value at a given position of the array
663   // Includes boundary checking
664   //
665
666   if ((row >= 0) && (col >= 0) && (time >= 0)) {
667     Int_t idx1 = GetIdx1(row,col);
668     if ((idx1 >= 0) && (time < fNdim2)) {
669        SetDataFast(idx1,time,value);
670     }
671     else {
672       if (idx1 >= 0) {
673         TObject::Error("SetData"
674                       ,"time %d out of bounds (size: %d, this: 0x%08x)"
675                       ,time,fNdim2,this);
676       }
677     }
678   }
679
680 }
681
682 //_____________________________________________________________________________
683 void AliTRDdataArrayI::SetDataFast(Int_t idx1, Int_t idx2, Int_t value)
684 {
685   //
686   // Sets the data value at a given position of the array
687   // No boundary checking
688   //
689
690   (*fElements)[fIndex->fArray[idx2]+idx1] = value;
691
692 }
693
694 //_____________________________________________________________________________
695 AliTRDdataArrayI &AliTRDdataArrayI::operator=(const AliTRDdataArrayI &a)
696 {
697   //
698   // Assignment operator
699   //
700
701   if (this != &a) ((AliTRDdataArrayI &) a).Copy(*this);
702   return *this;
703
704 }