minor coverity defect: added protection for self-assignment
[u/mrichter/AliRoot.git] / TRD / AliTRDarrayADC.cxx
1 /************************************************************************* 
2 * Copyright(c) 1998-2008, 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: AliTRDarrayADC.cxx 25392 2008-04-23 19:40:29Z cblume $ */
17
18 ////////////////////////////////////////////////////////
19 //                                                    //
20 // Container class for ADC values                     //
21 //                                                    //
22 // Author:                                            //
23 // Hermes Leon Vargas  (hleon@ikf.uni-frankfurt.de)   //
24 //                                                    // 
25 ////////////////////////////////////////////////////////
26
27 #include "AliTRDarrayADC.h"
28 #include "Cal/AliTRDCalPadStatus.h"
29 #include "AliTRDfeeParam.h"
30 #include "AliTRDSignalIndex.h"
31 #include "AliLog.h"
32
33 ClassImp(AliTRDarrayADC)
34
35 Short_t *AliTRDarrayADC::fgLutPadNumbering = 0x0;
36
37 //____________________________________________________________________________________
38 AliTRDarrayADC::AliTRDarrayADC()
39                :TObject()
40                ,fNdet(0)
41                ,fNrow(0)
42                ,fNcol(0)
43                ,fNumberOfChannels(0)
44                ,fNtime(0) 
45                ,fNAdim(0)
46                ,fADC(0)
47 {
48   //
49   // AliTRDarrayADC default constructor
50   //
51
52   CreateLut();
53
54 }
55
56 //____________________________________________________________________________________
57 AliTRDarrayADC::AliTRDarrayADC(Int_t nrow, Int_t ncol, Int_t ntime)
58                :TObject()
59                ,fNdet(0)               
60                ,fNrow(0)
61                ,fNcol(0)
62                ,fNumberOfChannels(0)
63                ,fNtime(0) 
64                ,fNAdim(0)
65                ,fADC(0)
66 {
67   //
68   // AliTRDarrayADC constructor
69   //
70
71   CreateLut();
72   Allocate(nrow,ncol,ntime);
73
74 }
75
76 //____________________________________________________________________________________
77 AliTRDarrayADC::AliTRDarrayADC(const AliTRDarrayADC &b)
78                :TObject()
79                ,fNdet(b.fNdet)
80                ,fNrow(b.fNrow)
81                ,fNcol(b.fNcol)
82                ,fNumberOfChannels(b.fNumberOfChannels)
83                ,fNtime(b.fNtime) 
84                ,fNAdim(b.fNAdim)
85                ,fADC(0)  
86 {
87   //
88   // AliTRDarrayADC copy constructor
89   //
90
91   fADC =  new Short_t[fNAdim];
92   memcpy(fADC,b.fADC, fNAdim*sizeof(Short_t));  
93
94 }
95
96 //____________________________________________________________________________________
97 AliTRDarrayADC::~AliTRDarrayADC()
98 {
99   //
100   // AliTRDarrayADC destructor
101   //
102
103   if(fADC)
104     {
105       delete [] fADC;
106       fADC=0;
107     }
108
109 }
110
111 //____________________________________________________________________________________
112 AliTRDarrayADC &AliTRDarrayADC::operator=(const AliTRDarrayADC &b)
113 {
114   //
115   // Assignment operator
116   //
117
118   if(this==&b)
119     {
120       return *this;
121     }
122   if(fADC)
123     {
124       delete [] fADC;
125     }
126   fNdet=b.fNdet;
127   fNrow=b.fNrow;
128   fNcol=b.fNcol;
129   fNumberOfChannels = b.fNumberOfChannels;
130   fNtime=b.fNtime;
131   fNAdim=b.fNAdim;
132   fADC = new Short_t[fNAdim];
133   memcpy(fADC,b.fADC, fNAdim*sizeof(Short_t));
134
135   return *this;
136
137 }
138
139 //____________________________________________________________________________________
140 void AliTRDarrayADC::Allocate(Int_t nrow, Int_t ncol, Int_t ntime)
141 {
142   //
143   // Allocate memory for an AliTRDarrayADC array with dimensions
144   // Row*NumberOfNecessaryMCMs*ADCchannelsInMCM*Time
145   //
146   
147   fNrow=nrow;
148   fNcol=ncol;
149   fNtime=ntime;
150   Int_t adcchannelspermcm = AliTRDfeeParam::GetNadcMcm(); 
151   Int_t padspermcm = AliTRDfeeParam::GetNcolMcm(); 
152   Int_t numberofmcms = fNcol/padspermcm; 
153   fNumberOfChannels = numberofmcms*adcchannelspermcm; 
154   fNAdim=nrow*fNumberOfChannels*ntime;
155
156   if(fADC)
157     {
158       delete [] fADC;
159     }
160   
161   fADC = new Short_t[fNAdim];
162   memset(fADC,0,sizeof(Short_t)*fNAdim);
163
164 }
165
166 //____________________________________________________________________________________
167 Short_t AliTRDarrayADC::GetDataBits(Int_t row, Int_t col, Int_t time) const
168 {
169   //
170   // Get the ADC value for a given position: row, col, time
171   // Taking bit masking into account
172   //
173   // Adapted from code of the class AliTRDdataArrayDigits 
174   //
175
176   Short_t tempval = GetData(row,col,time);
177   // Be aware of manipulations introduced by pad masking in the RawReader
178   // Only output the manipulated Value
179   CLRBIT(tempval, 10);
180   CLRBIT(tempval, 11);
181   CLRBIT(tempval, 12);
182   return tempval;
183
184 }
185
186 //____________________________________________________________________________________
187 UChar_t AliTRDarrayADC::GetPadStatus(Int_t row, Int_t col, Int_t time) const
188 {
189   // 
190   // Returns the pad status stored in the pad signal
191   //
192   // Output is a UChar_t value
193   // Status Codes:
194   //               Noisy Masking:           2
195   //               Bridged Left Masking     8
196   //               Bridged Right Masking    8
197   //               Not Connected Masking Digits
198   //
199   // Adapted from code of the class AliTRDdataArrayDigits
200   //
201
202   UChar_t padstatus = 0;
203   Short_t signal = GetData(row,col,time);
204   if(signal > 0 && TESTBIT(signal, 10)){
205     if(TESTBIT(signal, 11))
206       if(TESTBIT(signal, 12))
207         padstatus = AliTRDCalPadStatus::kPadBridgedRight;
208       else
209         padstatus = AliTRDCalPadStatus::kNotConnected;
210     else
211       if(TESTBIT(signal, 12))
212         padstatus = AliTRDCalPadStatus::kPadBridgedLeft;
213       else
214         padstatus = AliTRDCalPadStatus::kMasked;
215   }
216
217   return padstatus;
218
219 }
220
221 //____________________________________________________________________________________
222 void AliTRDarrayADC::SetPadStatus(Int_t row, Int_t col, Int_t time, UChar_t status)
223 {
224   //
225   // Setting the pad status into the signal using the Bits 10 to 14 
226   // (currently used: 10 to 12)
227   //
228   // Input codes (Unsigned char):
229   //               Noisy Masking:           2
230   //               Bridged Left Masking     8
231   //               Bridged Right Masking    8
232   //               Not Connected Masking    32
233   //
234   // Status codes: Any masking:             Bit 10(1)
235   //               Noisy masking:           Bit 11(0), Bit 12(0)
236   //               No Connection masking:   Bit 11(1), Bit 12(0)
237   //               Bridged Left masking:    Bit 11(0), Bit 12(1)
238   //               Bridged Right masking:   Bit 11(1), Bit 12(1)
239   // 
240   // Adapted from code of the class AliTRDdataArrayDigits
241   //
242
243   Short_t signal = GetData(row,col,time);
244
245   // Only set the Pad Status if the signal is > 0
246   if(signal > 0)
247     {
248       switch(status)
249         {
250         case AliTRDCalPadStatus::kMasked:
251           SETBIT(signal, 10);
252           CLRBIT(signal, 11);
253           CLRBIT(signal, 12);
254           break;
255         case AliTRDCalPadStatus::kNotConnected:
256           SETBIT(signal, 10);
257           SETBIT(signal, 11);
258           CLRBIT(signal, 12);
259           break;
260         case AliTRDCalPadStatus::kPadBridgedLeft:
261           SETBIT(signal, 10);
262           CLRBIT(signal, 11);
263           SETBIT(signal, 12);
264           break;
265         case AliTRDCalPadStatus::kPadBridgedRight:
266           SETBIT(signal, 10);
267           SETBIT(signal, 11);
268           SETBIT(signal, 12);
269           break;
270         default:
271           CLRBIT(signal, 10);
272           CLRBIT(signal, 11);
273           CLRBIT(signal, 12);
274         }
275       SetData(row, col, time, signal);
276     }
277
278 }
279
280 //____________________________________________________________________________________
281 Bool_t AliTRDarrayADC::IsPadCorrupted(Int_t row, Int_t col, Int_t time)
282 {
283   // 
284   // Checks if the pad has any masking as corrupted (Bit 10 in signal set)
285   // 
286   // Adapted from code of the class AliTRDdataArrayDigits
287   //
288
289   Short_t signal = GetData(row,col,time);
290   return (signal > 0 && TESTBIT(signal, 10)) ? kTRUE : kFALSE;
291
292 }
293
294 //____________________________________________________________________________________
295 void AliTRDarrayADC::Compress()
296 {
297   //
298   // Compress the array
299   //
300
301   if(fNAdim!=fNrow*fNumberOfChannels*fNtime)
302     {
303       AliDebug(1,"The ADC array is already compressed");
304       return;
305     }
306
307   Int_t counter=0;
308   Int_t newDim=0;
309   Int_t j;                  
310   Int_t l;                  
311   Int_t r=0;                
312   Int_t s=0;                
313   Int_t k=0;
314
315   Int_t *longm = new Int_t[fNAdim];  
316   Int_t *longz = new Int_t[fNAdim];
317
318   if(longz && longm && fADC)
319     {
320
321       memset(longz,0,sizeof(Int_t)*fNAdim);
322       memset(longm,0,sizeof(Int_t)*fNAdim);
323
324       for(Int_t i=0;i<fNAdim; i++)
325         {
326           j=0;
327           if(fADC[i]==-1)
328             {
329               for(k=i;k<fNAdim;k++)
330                 {
331                   if((fADC[k]==-1)&&(j<16000))   
332                     {
333                       j=j+1;
334                       longm[r]=j;                
335                     }
336                   else
337                     {
338                       break;
339                     }
340                 }
341               r=r+1;            
342             }
343           l=16001;
344           if(fADC[i]==0)
345             {
346               for(k=i;k<fNAdim;k++)
347                 {
348                   if((fADC[k]==0)&&(l<32767))     
349                     {                             
350                       l=l+1;
351                       longz[s]=l;                
352                     }
353                   else
354                     {
355                       break;
356                     }
357                 }
358               s=s+1;         
359             }
360           if(fADC[i]>0)
361             {
362               i=i+1;
363             }
364           i=i+j+(l-16001-1); 
365         }
366
367       //Calculate the size of the compressed array
368       for(Int_t i=0; i<fNAdim;i++)
369         {
370           if(longm[i]!=0)   
371             {
372               counter=counter+longm[i]-1;
373             }
374           if(longz[i]!=0)  
375             {
376               counter=counter+(longz[i]-16001)-1;
377             }
378         }
379
380       Int_t counterTwo=0;
381       newDim = fNAdim-counter;   //Dimension of the compressed array
382       Short_t* buffer = new Short_t[newDim];
383
384       if(buffer)
385         {
386
387           //Fill the buffer of the compressed array
388           Int_t g=0;
389           Int_t h=0; 
390           for(Int_t i=0; i<newDim; i++)
391             {
392               if(counterTwo<fNAdim)
393                 {
394                   if(fADC[counterTwo]>0)
395                     {
396                       buffer[i]=fADC[counterTwo];
397                     }
398                   if(fADC[counterTwo]==-1)
399                     {
400                       buffer[i]=-(longm[g]);
401                       counterTwo=counterTwo+longm[g]-1;
402                       g++;
403                     }  
404                   if(fADC[counterTwo]==0)
405                     {
406                       buffer[i]=-(longz[h]); 
407                       counterTwo=counterTwo+(longz[h]-16001)-1;
408                       h++;
409                     }  
410                   counterTwo++;
411                 }
412             }
413
414           //Copy the buffer
415           delete [] fADC;
416           fADC=0;
417           fADC = new Short_t[newDim];
418           fNAdim = newDim;
419           for(Int_t i=0; i<newDim; i++)
420             {
421               fADC[i] = buffer[i]; 
422             }
423
424           //Delete auxiliary arrays
425           delete [] buffer;
426           buffer=0;
427         } 
428
429     }
430
431   if (longz)
432     {
433       delete [] longz;
434       longz=0;
435     }
436   if (longm)
437     {
438       delete [] longm;
439       longm=0;
440
441     }
442
443 }
444
445 //____________________________________________________________________________________
446 void AliTRDarrayADC::Expand()
447 {
448   //
449   // Expand the array
450   //
451
452   if (fADC)
453     {
454
455       //Check if the array has not been already expanded
456       Int_t verif=0;
457       for(Int_t i=0; i<fNAdim; i++)
458         {
459           if(fADC[i]<-1)
460             {
461               verif++;
462             }
463         }
464   
465       if(verif==0)
466         {
467           AliDebug(1,"Nothing to expand");
468           return;
469         }
470
471       Int_t dimexp=0;
472       Int_t *longz = new Int_t[fNAdim];
473       Int_t *longm = new Int_t[fNAdim];
474
475       if (longz && longm)
476         {
477
478           //Initialize arrays
479           memset(longz,0,sizeof(Int_t)*fNAdim);
480           memset(longm,0,sizeof(Int_t)*fNAdim);
481           Int_t r2=0; 
482           Int_t r3=0; 
483           for(Int_t i=0; i<fNAdim;i++)
484             {
485               if((fADC[i]<0)&&(fADC[i]>=-16000))      
486                 {
487                   longm[r2]=-fADC[i];
488                   r2++;
489                 }
490               if(fADC[i]<-16000)  
491                 {
492                   longz[r3]=-fADC[i]-16001;  
493                   r3++;
494                 }
495             }
496
497           //Calculate the new dimensions of the array
498           for(Int_t i=0; i<fNAdim;i++)
499             {
500               if(longm[i]!=0)       
501                 {
502                   dimexp=dimexp+longm[i]-1;
503                 }
504               if(longz[i]!=0)      
505                 {
506                   dimexp=dimexp+longz[i]-1;
507                 }
508             }
509           dimexp=dimexp+fNAdim;   
510
511           //Write in the buffer the new array
512           Int_t contaexp =0;     
513           Int_t h=0;
514           Int_t l=0;  
515           Short_t* bufferE = new Short_t[dimexp];
516           if(bufferE)
517             {
518               for(Int_t i=0; i<dimexp; i++)
519                 {
520                   if(fADC[contaexp]>0)  
521                     {
522                       bufferE[i]=fADC[contaexp];
523                     }
524                   if((fADC[contaexp]<0)&&(fADC[contaexp]>=-16000))  
525                     {
526                       for(Int_t j=0; j<longm[h];j++)
527                         {
528                           bufferE[i+j]=-1;
529                         }
530                       i=i+longm[h]-1;
531                       h++;
532                     }
533                   if(fADC[contaexp]<-16000)  
534                     {
535                       for(Int_t j=0; j<longz[l];j++)
536                         {
537                           bufferE[i+j]=0;  
538                         }
539                       i=i+longz[l]-1;
540                       l++;
541                     }
542                   contaexp++;
543                 }
544               //Copy the buffer
545               delete [] fADC;
546               fADC = new Short_t[dimexp];
547               fNAdim = dimexp;
548               for(Int_t i=0; i<dimexp; i++)
549                 {
550                   fADC[i] = bufferE[i]; 
551                 }
552
553               delete [] bufferE;
554
555             }
556
557           //Delete auxiliary arrays
558           delete [] longm;
559           delete [] longz;
560
561         }
562
563     }
564
565 }
566 //____________________________________________________________________________________
567 void AliTRDarrayADC::DeleteNegatives()
568 {
569
570   //
571   //This method modifies the digits array, changing the negative values (-1)
572   //Produced during digitization into zero.
573   //
574
575   for(Int_t a=0; a<fNAdim; a++)
576     {
577       if(fADC[a]==-1)
578         {
579           fADC[a]=0;
580         }
581     }
582 }
583 //________________________________________________________________________________
584 void AliTRDarrayADC::Reset()
585 {
586   //
587   // Reset the array, the old contents are deleted
588   // The array keeps the same dimensions as before
589   //
590  
591   memset(fADC,0,sizeof(Short_t)*fNAdim);
592 }
593 //________________________________________________________________________________
594 void AliTRDarrayADC::ConditionalReset(AliTRDSignalIndex* idx)
595 {
596   //
597   // Reset the array, the old contents are deleted
598   // The array keeps the same dimensions as before
599   //
600  
601   if(idx->GetNoOfIndexes()>25)
602     memset(fADC,0,sizeof(Short_t)*fNAdim);
603   else
604     {
605       Int_t row, col;
606       while(idx->NextRCIndex(row, col)){
607         Int_t colnumb = fgLutPadNumbering[col];
608         memset(&fADC[(row*fNumberOfChannels+colnumb)*fNtime],0,fNtime);
609       }
610     }
611
612 }
613
614 //________________________________________________________________________________
615 void AliTRDarrayADC::CreateLut()
616 {
617   //
618   // Initializes the Look Up Table to relate
619   // pad numbering and mcm channel numbering
620   //
621
622   if(fgLutPadNumbering)  return;
623   
624    fgLutPadNumbering = new Short_t[AliTRDfeeParam::GetNcol()];
625    memset(fgLutPadNumbering,0,sizeof(Short_t)*AliTRDfeeParam::GetNcol());
626
627   for(Int_t mcm=0; mcm<8; mcm++)
628     {
629       Int_t lowerlimit=0+mcm*18;
630       Int_t upperlimit=18+mcm*18;
631       Int_t shiftposition = 1+3*mcm;
632       for(Int_t index=lowerlimit;index<upperlimit;index++)
633         {
634           fgLutPadNumbering[index]=index+shiftposition;
635         }
636     }
637 }