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