]> git.uio.no Git - u/mrichter/AliRoot.git/blob - ITS/AliITSQASDDChecker.cxx
Update of the QA code of the SDD: 1) SDD Checker: added protection in case only a...
[u/mrichter/AliRoot.git] / ITS / AliITSQASDDChecker.cxx
1 /**************************************************************************
2  * Copyright(c) 2007-2009, 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$ */
17
18 // *****************************************
19 //  Checks the quality assurance 
20 //  by comparing with reference data
21 //  P. Cerello Apr 2008
22 //  INFN Torino
23
24 // --- ROOT system ---
25 #include "TH1.h"
26 #include <TH1D.h>
27 #include <TH2.h>
28 // --- AliRoot header files ---
29 #include "AliITSQADataMakerRec.h"
30 #include "AliITSQASDDChecker.h"
31 #include "AliLog.h"
32 #include "AliCDBEntry.h"
33 #include "AliCDBManager.h"
34 #include "AliITSCalibrationSDD.h"
35 #include "AliITSgeomTGeo.h"
36
37
38 ClassImp(AliITSQASDDChecker)
39 //__________________________________________________________________
40 AliITSQASDDChecker& AliITSQASDDChecker::operator = (const AliITSQASDDChecker& qac ) 
41 {
42   // Equal operator.
43   this->~AliITSQASDDChecker();
44   new(this) AliITSQASDDChecker(qac);
45   return *this;
46 }
47
48 AliITSQASDDChecker::~AliITSQASDDChecker() 
49 {
50
51   //destructor
52   if(fStepBitSDD) 
53     {
54       delete[] fStepBitSDD ;
55       fStepBitSDD = NULL;
56     }
57   if(fLowSDDValue)
58     {
59       delete[]fLowSDDValue;
60       fLowSDDValue=NULL;
61     }
62   if(fHighSDDValue)
63     { 
64       delete[]fHighSDDValue;
65       fHighSDDValue=NULL;
66     }
67   if(fCalibration)
68     {
69       delete fCalibration;
70       fCalibration=NULL;
71     }
72 } // dtor
73
74 //__________________________________________________________________
75 Double_t AliITSQASDDChecker::Check(AliQAv1::ALITASK_t index, const TObjArray * list, const AliDetectorRecoParam * /*recoparam*/) 
76 {
77   //check histograms of the different lists  
78   AliInfo(Form("AliITSQASDDChecker called with offset: %d\n", fSubDetOffset) );
79
80   AliDebug(1,Form("AliITSQASDDChecker called with offset: %d\n", fSubDetOffset));
81
82   Double_t SDDQACheckerValue = 0.;
83   TH1 *hdata=NULL;
84   Double_t entries=0.;
85   Double_t entries2[2];
86   for(Int_t i=0;i<2;i++)entries2[i]=0.;
87
88   if(!fCalibration){
89     AliCDBEntry *calibSDD = AliCDBManager::Instance()->Get("ITS/Calib/CalibSDD");
90     Bool_t cacheStatus = AliCDBManager::Instance()->GetCacheFlag();
91     if(!calibSDD)
92       {
93         AliError("Calibration object retrieval failed! SDD will not be processed");
94         fCalibration = NULL;
95         SDDQACheckerValue= fHighSDDValue[AliQAv1::kWARNING];
96       }
97     fCalibration = (TObjArray *)calibSDD->GetObject();
98     
99     if(!cacheStatus)calibSDD->SetObject(NULL);
100     calibSDD->SetOwner(kTRUE);
101     if(!cacheStatus)
102       {
103         delete calibSDD;
104       }
105   }
106
107   AliInfo("Calib SDD Created\n ");
108
109   TIter next(list);
110
111   switch(index) {
112     case AliQAv1::kRAW:{
113       AliInfo(Form("Check on %s\n",AliQAv1::GetAliTaskName(index)));
114 //       if(fRawModulePattern) { delete fRawModulePattern; fRawModulePattern = 0; }
115 //       if(fRawL3Pattern) { delete fRawL3Pattern; fRawL3Pattern = 0; }
116 //       if(fRawL4Pattern) { delete fRawL4Pattern; fRawL4Pattern = 0; }
117       if (list->GetEntries() == 0){SDDQACheckerValue += fHighSDDValue[AliQAv1::kFATAL]; break;}
118       TH1 *hmodule=NULL;
119       TH2 *hlayer[2]; 
120       Int_t emptymodules[2], filledmodules[2],emptyladders[2],filledladders[2];
121       for(Int_t i=0;i<2;i++){emptymodules[i]=0; filledmodules[i]=0; emptyladders[i]=0; filledladders[i]=0; }
122       for(Int_t i=0;i<2;i++)hlayer[i]=NULL;   
123       while( (hdata = dynamic_cast<TH1* >(next())) ){
124         if (hdata){TString hname=hdata->GetName();
125           if(hname.Contains("SDDchargeMap"))continue;
126           if(hname.Contains("SDDModPattern")){
127             if(hname.Contains("NORM")) continue;
128             hmodule=(TH1*)hdata->Clone();
129             entries= hdata->GetEntries();
130             if(AliITSQADataMakerRec::AreEqual(entries,0.)){AliWarning(Form("===================>>>>>> No entries in  %s \n",hname.Data()));SDDQACheckerValue += fStepBitSDD[AliQAv1::kFATAL];}//endif entries
131             else{int modmax=hdata->GetNbinsX();
132               Int_t empty=0;
133               Int_t filled=0;
134               Double_t content=0;
135               for(Int_t i=1;i<=modmax;i++){content=hdata->GetBinContent(i);if(AliITSQADataMakerRec::AreEqual(content,0.)) empty++; else filled++; }//end for
136               AliInfo(Form(" %s : empty modules %i \t filled modules %i",hname.Data(), empty, filled));}//end else pattern entries !=0
137           }             
138           if(hname.Contains("_RelativeOccupancy")) {
139             //fRawModulePattern = (TH1F *) hdata;
140             Float_t threshold = hdata->GetMean() + 4*hdata->GetRMS();
141             if(hname.Contains("L3")) AliInfo(Form("SDD check number 1: L3 mean: %f, rms: ,%f",hdata->GetMean(),hdata->GetRMS()));
142             if(hname.Contains("L4")) AliInfo(Form("SDD check number 2: L4 mean: %f, rms: ,%f",hdata->GetMean(),hdata->GetRMS()));
143             Int_t aboveThreshold = 0;
144             for(Int_t k=0; k<= hdata->GetNbinsX(); k++) {if(hdata->GetBinLowEdge(k) > threshold) aboveThreshold += (int)(hdata->GetBinContent(k));}
145             Float_t fractionAboveThreshold = ((Float_t) aboveThreshold)/hdata->GetEntries();
146             if(hname.Contains("L3")) AliInfo(Form("SDD check number 1, L3: Raw fractionAboveThreshold: %f",fractionAboveThreshold));
147             if(hname.Contains("L4")) AliInfo(Form("SDD check number 2, L4: Raw fractionAboveThreshold: %f",fractionAboveThreshold));
148             if(fractionAboveThreshold > fThresholdForRelativeOccupancy) {SDDQACheckerValue=fHighSDDValue[AliQAv1::kWARNING];
149               if(hname.Contains("L3")) AliInfo(Form("SDD check number 1: Set Warning (L3 Raw)"));
150               if(hname.Contains("L4")) AliInfo(Form("SDD check number 2: Set Warning (L4 Raw)")); } }
151           if(hname.Contains("SDDphizL3") || hname.Contains("SDDphizL4")){if(hname.Contains("NORM"))continue;
152             //if(hname.Contains("L3")) {fRawL3Pattern = (TH2F *) hdata;}
153             //if(hname.Contains("L4")) {fRawL4Pattern = (TH2F *) hdata;}
154             Int_t layer=0;
155             if(hname.Contains("3"))layer=0;
156             else  if(hname.Contains("4"))layer=1;
157             entries2[layer]=hdata->GetEntries();
158             if(entries2[layer]==0){AliWarning(Form("===================>>>>>> No entries in  %s \n",hname.Data()));
159               SDDQACheckerValue += fStepBitSDD[AliQAv1::kFATAL];}//end if getentries
160             else{
161               Int_t layer1=0;
162               if(hname.Contains("3"))layer1=0;
163               else  if(hname.Contains("4"))layer1=1;
164               TH2* htemp=dynamic_cast<TH2*>(hdata);
165               hlayer[layer1]=(TH2*)htemp->Clone();
166               char newname[50];
167               sprintf(newname,"%s_copy",hname.Data());
168               hlayer[layer1]->SetName(newname);
169               hlayer[layer1]->RebinX(2);
170               int modmay=hlayer[layer1]->GetNbinsY();
171               TH1D* hproj= hlayer[layer1]->ProjectionY();
172               Double_t ladcontent=0;
173               for(Int_t i=1;i<=modmay;i++) {//loop on the ladders
174                 ladcontent=hproj->GetBinContent(i);
175                 if(AliITSQADataMakerRec::AreEqual(ladcontent,0.)) emptyladders[layer1]++;
176                 else filledladders[layer1]++;}//end for
177               AliInfo(Form(" %s : empty ladders %i \t filled ladders %i\n",hname.Data(), emptyladders[layer], filledladders[layer]));//end else layer 3
178               delete hproj;
179               hproj=NULL;}//end else entries !=0
180           }//end check on phiz        
181         }//end if hdata 
182       }//end while
183       if(AliITSQADataMakerRec::AreEqual(entries,0.)&&AliITSQADataMakerRec::AreEqual(entries2[0],0.)&&AliITSQADataMakerRec::AreEqual(entries2[1],0.)) break;
184       //else{
185       if(hmodule || (hlayer[0] && hlayer[1])){
186         Int_t excluded=0;
187         Int_t active=0;
188         Int_t exactive=0;//excluded but taking data
189         for(Int_t imod=0;imod<fgknSDDmodules;imod++){
190           Int_t lay=0;
191           Int_t lad=0;
192           Int_t det=0;
193           Int_t module=0;
194           module=imod+fgkmodoffset;
195           AliITSCalibrationSDD * cal=(AliITSCalibrationSDD*)fCalibration->At(imod);
196           if(cal==0) { delete cal; continue;}
197           AliITSgeomTGeo::GetModuleId(module,lay,lad,det);
198           if (cal->IsBad()){
199             excluded++;
200             Double_t content=0.;
201             Double_t contentlayer[2];
202             for(Int_t i=0;i<2;i++)contentlayer[i]=0.;
203             if(hmodule)content=hmodule->GetBinContent(imod+1);//if expert bit is active the histogram has been created 
204             if(hlayer[lay-3]) contentlayer[lay-3]=hlayer[lay-3]->GetBinContent(det,lad);
205             if(AliITSQADataMakerRec::AreEqual(content,0.)== kFALSE || AliITSQADataMakerRec::AreEqual(contentlayer[lay-3],0.)==kFALSE) {
206               filledmodules[lay-3]++;
207               AliWarning(Form("The module %d (layer %i, ladder %i det %i ) excluded from the acquisition, took data \n ",module,lay,lad,det));
208               exactive++;
209             } else if(AliITSQADataMakerRec::AreEqual(content,0.) && AliITSQADataMakerRec::AreEqual(contentlayer[lay-3],0.)) 
210               emptymodules[lay-3]++;
211           } else {
212             Double_t contentgood=0.;
213             active++;
214             if(hlayer[lay-3]) contentgood=hlayer[lay-3]->GetBinContent(det,lad);
215             if(AliITSQADataMakerRec::AreEqual(contentgood,0.)) 
216               emptymodules[lay-3]++;
217             else 
218               filledmodules[lay-3]++;
219           }
220         }//end for
221         for(Int_t i=0;i<2;i++){AliInfo(Form("Layer %i \tempty modules %i \t filled modules %i\n", i+3,emptymodules[i], filledmodules[i]));}//end else layers
222         if(exactive==0){
223           AliInfo(Form("All the active modules (%i) are in acquisition. The number of excluded modules are %i \n",active,excluded));
224           SDDQACheckerValue=fHighSDDValue[AliQAv1::kINFO];
225         }
226         if(exactive!=0){
227           AliWarning(Form("%i modules excluded from the acquisition took data. Active modules%i \n ",exactive,active));
228           SDDQACheckerValue=fHighSDDValue[AliQAv1::kWARNING];
229         }
230         if(excluded==exactive){
231           AliWarning(Form("All the modules excluded from the acquisition (%d) took data!  Active modules %i\n",excluded,active));
232           SDDQACheckerValue=fHighSDDValue[AliQAv1::kWARNING];
233         }
234         if(active==0){
235           AliWarning(Form("No modules took data: excluded %i \t exactive %i \n", excluded, exactive)); 
236           SDDQACheckerValue=fHighSDDValue[AliQAv1::kFATAL];
237         }
238         
239       }//end else 
240       delete hmodule;
241       hmodule=NULL;
242       for(Int_t i=0;i<2;i++) {
243         delete hlayer[i];
244         hlayer[i]=NULL;
245       }
246
247     }
248       
249       break;
250       
251   case AliQAv1::kNULLTASK:{
252     AliInfo(Form("No Check on %s\n",AliQAv1::GetAliTaskName(index))); 
253     SDDQACheckerValue=1.;
254   }
255     break;
256     
257   case AliQAv1::kREC:
258     {
259       
260       AliInfo(Form("Check on %s\n",AliQAv1::GetAliTaskName(index))); 
261
262       if (list->GetEntries() == 0){ //check if the list is empty
263         //printf("SDDQACheckerValue = %f \t value %f\n",SDDQACheckerValue,fHighSDDValue[AliQAv1::kFATAL]);
264         SDDQACheckerValue=fHighSDDValue[AliQAv1::kFATAL]; 
265         break;                  
266       }//end if getentries
267       
268       while((hdata=dynamic_cast<TH1* >(next()))){
269         if (hdata){
270           TString hname=hdata->GetName();
271           if(hname.Contains("_RelativeOccupancy")) {
272             Float_t threshold = hdata->GetMean() + 4*hdata->GetRMS();
273             if(hname.Contains("L3")) AliInfo(Form("SDD check number 3: L3 mean: %f, rms: ,%f",hdata->GetMean(),hdata->GetRMS()));
274             if(hname.Contains("L4")) AliInfo(Form("SDD check number 4: L4 mean: %f, rms: ,%f",hdata->GetMean(),hdata->GetRMS()));
275             Int_t aboveThreshold = 0;
276             for(Int_t k=0; k<= ((Int_t)hdata->GetNbinsX()); k++) {
277               if(hdata->GetBinLowEdge(k) > threshold) aboveThreshold += (Int_t)(hdata->GetBinContent(k));
278             }
279             Float_t fractionAboveThreshold = ((Float_t) aboveThreshold)/hdata->GetEntries();
280             if(hname.Contains("L3")) AliInfo(Form("SDD check number 3, L3: RecPoints fractionAboveThreshold: %f",fractionAboveThreshold));
281             if(hname.Contains("L4")) AliInfo(Form("SDD check number 4, L4: RecPoints fractionAboveThreshold: %f",fractionAboveThreshold));
282             if(fractionAboveThreshold > fThresholdForRelativeOccupancy) { 
283               SDDQACheckerValue=fHighSDDValue[AliQAv1::kWARNING];
284               if(hname.Contains("L3")) AliInfo(Form("SDD check number 3: Set Warning (L3 RecPoints)"));
285               if(hname.Contains("L4")) AliInfo(Form("SDD check number 4: Set Warning (L4 RecPoints)"));
286             }
287           }
288           if(hname.Contains("Rec2Raw") && !hname.Contains("2D")) {
289             //Float_t threshold = 0.;
290             if(hname.Contains("L3")) AliInfo(Form("SDD check number 5: L3 R2R mean: %f, rms: ,%f",((TH1F *) hdata)->GetMean(),((TH1F *) hdata)->GetRMS()));
291             if(hname.Contains("L4")) AliInfo(Form("SDD check number 6: L4 R2R mean: %f, rms: ,%f",((TH1F *) hdata)->GetMean(),((TH1F *) hdata)->GetRMS()));
292             Int_t belowThreshold = 0;
293             for(Int_t k=0; k<=((TH1F *)hdata)->GetNbinsX(); k++) {
294               if(((TH1F *) hdata)->GetBinLowEdge(k) < fThresholdForRecToRawRatio) belowThreshold += ((Int_t)((TH1F *) hdata)->GetBinContent(k));
295             }
296             Double_t fractionBelowThreshold =0.;
297             Double_t entries3=((TH1F *)hdata)->GetEntries();
298             if(entries3>0.001)fractionBelowThreshold = ((Double_t)(belowThreshold))/entries3;
299             else{ AliWarning(Form("No entries on %s. The check will retuns zero.\n",hdata->GetName() )); }
300             if(hname.Contains("L3")) AliInfo(Form("SDD check number 5, L3: RecPoints2Raws fractionBelowThreshold: %f",fractionBelowThreshold));
301             if(hname.Contains("L4")) AliInfo(Form("SDD check number 6, L4: RecPoints2Raws fractionBelowThreshold: %f",fractionBelowThreshold));
302             if(fractionBelowThreshold > fThresholdForRelativeOccupancy) { 
303               SDDQACheckerValue=fHighSDDValue[AliQAv1::kWARNING];
304               if(hname.Contains("L3")) AliInfo(Form("SDD check number 5: Set Warning (L3 RecPoints2Raws)"));
305               if(hname.Contains("L4")) AliInfo(Form("SDD check number 6: Set Warning (L4 RecPoints2Raws)"));
306             }
307           }
308           if(hname.Contains("dedx")) {
309             if(hname.Contains("L3")) AliInfo(Form("SDD check number 7: L3 average charge: %f, rms: ,%f",hdata->GetMean(),hdata->GetRMS()));
310             if(hname.Contains("L4")) AliInfo(Form("SDD check number 8: L4 average charge: %f, rms: ,%f",hdata->GetMean(),hdata->GetRMS()));
311           }
312         }
313       }                         
314       
315       SDDQACheckerValue=1.;
316     }
317     break;
318   case AliQAv1::kANA:
319     {
320       AliInfo(Form("===================> No Check on %s\n",AliQAv1::GetAliTaskName(index)));
321       SDDQACheckerValue=1.; 
322     }
323     break;
324   case AliQAv1::kESD:
325     {
326       AliInfo(Form("==================>  No Check on %s\n",AliQAv1::GetAliTaskName(index)));
327       SDDQACheckerValue=1.;
328     } 
329     break;
330   case AliQAv1::kNTASK:{
331     AliInfo(Form("==================>  No Check on %s\n",AliQAv1::GetAliTaskName(index))); 
332     SDDQACheckerValue=1.;
333   }
334     break;
335   case AliQAv1::kSIM:{
336     AliInfo(Form("Check on %s\n",AliQAv1::GetAliTaskName(index))); 
337     Int_t uid=list->GetUniqueID();
338     if(uid==60) {
339       //digits
340       if (list->GetEntries() == 0){ 
341         SDDQACheckerValue=fHighSDDValue[AliQAv1::kFATAL];
342         break;
343       } else{
344         
345         while( (hdata = dynamic_cast<TH1* >(next())) ){
346           if (hdata){
347             if(hdata->GetEntries()==0)SDDQACheckerValue += fStepBitSDD[AliQAv1::kFATAL];
348             else {
349               TString hname=hdata->GetName();
350               if(hname.Contains("SDDDIGITSModulePattern")) {
351                 //see raws
352                 
353                 SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
354               } else if(hname.Contains("SDDAnodeDistribution")) {
355                 SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
356               } else if(hname.Contains("SDDTbinDistribution")) {
357                 //to do as rp
358                 SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
359               } else if(hname.Contains("SDDADCCountsDistribution")) {
360                 SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
361               }//end adc counts
362               
363             }//end entries !=0
364           }//end hdata
365         }//end while
366       }//end else
367     } else if(uid==50) 
368       {
369         //hits
370         if (list->GetEntries() == 0){ 
371           SDDQACheckerValue=fHighSDDValue[AliQAv1::kFATAL];
372           break;
373         } 
374         else{
375           
376           while( (hdata = dynamic_cast<TH1* >(next())) ){
377             if (hdata){
378               if(hdata->GetEntries()==0)SDDQACheckerValue += fStepBitSDD[AliQAv1::kFATAL];
379               else {
380                 TString hname=hdata->GetName();
381                 if(hname.Contains("SDDHITSModulePattern")) {
382                   //to do as raws
383                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
384                 } else if(hname.Contains("SDDHITlenghtalonglocalYCoord")) {
385                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
386                 } else if(hname.Contains("SDDHITlenghtalonglocalYCoordZoom")) {
387                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
388                 } else if(hname.Contains("SDDDepositedEnergyDistribution")) {
389                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
390                 }//end deposited energy
391                 
392               }//end entries !=0
393             }//end hdata
394           }//end while
395         }//end else
396       } else if(uid==70) 
397       {
398         //sdigits
399         if (list->GetEntries() == 0){ 
400           SDDQACheckerValue=fHighSDDValue[AliQAv1::kFATAL];
401           break;
402         } else{
403           
404           while( (hdata = dynamic_cast<TH1* >(next())) ){
405             if (hdata){
406               if(hdata->GetEntries()==0)SDDQACheckerValue += fStepBitSDD[AliQAv1::kFATAL];
407               else {
408                 TString hname=hdata->GetName();
409                 if(hname.Contains("SDDSDIGITSModulePattern")) {
410                   //to do as raws
411                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
412                 } else if(hname.Contains("SDDAnodeDistribution")) {
413                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
414                 } else if(hname.Contains("SDDTbinDistribution")) {
415                   //to do as rp
416                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
417                 } else if(hname.Contains("SDDADCCountsDistribution")) {
418                   SDDQACheckerValue += fStepBitSDD[AliQAv1::kINFO];    
419                 }//end adc counts bindistribution
420               }//end entries !=0
421             }//end hdata
422           }//end while
423         }//end else
424       }//end sdigits
425     SDDQACheckerValue=1.;
426   }
427     break;
428     
429   }//end switch
430   
431   fCalibration=NULL;
432   delete hdata;
433
434
435   return SDDQACheckerValue;     
436 }
437
438 //__________________________________________________________________
439 void AliITSQASDDChecker::SetTaskOffset(Int_t taskoffset)
440 {
441   //set the number of the histograms already present in the list before the SDD histograms
442   fSubDetOffset = taskoffset;
443 }
444
445
446 //__________________________________________________________________
447 void AliITSQASDDChecker::SetStepBit(const Double_t *steprange)
448 {
449   //set the values of the step bit for each QA bit range calculated in the AliITSQAChecker class
450   fStepBitSDD = new Double_t[AliQAv1::kNBIT];
451   for(Int_t bit=0;bit<AliQAv1::kNBIT;bit++)
452     {
453       fStepBitSDD[bit]=steprange[bit];
454     }
455 }
456
457 //__________________________________________________________________
458 void  AliITSQASDDChecker::SetSDDLimits(const Float_t *lowvalue, const Float_t * highvalue)
459 {
460   //set the low and high values in for each QA bit range calculated in the AliITSQAChecker class
461   fLowSDDValue = new Float_t[AliQAv1::kNBIT];
462   fHighSDDValue= new Float_t[AliQAv1::kNBIT];
463
464   for(Int_t bit=0;bit<AliQAv1::kNBIT;bit++)
465     {
466       fLowSDDValue[bit]=lowvalue[bit];
467       fHighSDDValue[bit]= highvalue[bit];
468     }
469
470 }
471