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