]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCcalibDButil.cxx
AliTPCcalibDB.cxx.diff Use DCS graph for HighVoltage information whenever available...
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibDButil.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 ///////////////////////////////////////////////////////////////////////////////
18 //                                                                           //
19 // Class providing the calculation of derived quantities (mean,rms,fits,...) //
20 //       of calibration entries                                              //
21 /*
22
23
24 */
25 ////////////////////////////////////////////////////////////////////////////////
26
27 #include <TMath.h>
28 #include <TVectorT.h>
29 #include <TObjArray.h>
30 #include <TGraph.h>
31
32 #include <AliDCSSensorArray.h>
33 #include <AliDCSSensor.h>
34 #include "AliTPCcalibDB.h"
35 #include "AliTPCCalPad.h"
36 #include "AliTPCCalROC.h"
37 #include "AliTPCROC.h"
38 #include "AliTPCmapper.h"
39 #include "AliTPCParam.h"
40
41 #include "AliTPCcalibDButil.h"
42
43 ClassImp(AliTPCcalibDButil)
44 AliTPCcalibDButil::AliTPCcalibDButil() :
45   TObject(),
46   fCalibDB(AliTPCcalibDB::Instance()),
47   fPadNoise(0x0),
48   fPedestals(0x0),
49   fPulserTmean(0x0),
50   fPulserTrms(0x0),
51   fPulserQmean(0x0),
52   fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")),
53   fCETmean(0x0),
54   fCETrms(0x0),
55   fCEQmean(0x0),
56   fALTROMasked(0x0),
57   fGoofieArray(0x0),
58   fMapper(new AliTPCmapper(0x0)),
59   fNpulserOutliers(-1),
60   fIrocTimeOffset(.2),
61   fCETmaxLimitAbs(1.5),
62   fPulTmaxLimitAbs(1.5),
63   fPulQmaxLimitAbs(5),
64   fPulQminLimit(11)
65 {
66   //
67   // Default ctor
68   //
69 }
70 //_____________________________________________________________________________________
71 AliTPCcalibDButil::~AliTPCcalibDButil()
72 {
73   //
74   // dtor
75   //
76   delete fPulserOutlier;
77   delete fMapper;
78 }
79 //_____________________________________________________________________________________
80 void AliTPCcalibDButil::UpdateFromCalibDB()
81 {
82   //
83   // Update pointers from calibDB
84   //
85   fPadNoise=fCalibDB->GetPadNoise();
86   fPedestals=fCalibDB->GetPedestals();
87   fPulserTmean=fCalibDB->GetPulserTmean();
88   fPulserTrms=fCalibDB->GetPulserTrms();
89   fPulserQmean=fCalibDB->GetPulserQmean();
90   fCETmean=fCalibDB->GetCETmean();
91   fCETrms=fCalibDB->GetCETrms();
92   fCEQmean=fCalibDB->GetCEQmean();
93   fALTROMasked=fCalibDB->GetALTROMasked();
94   fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
95   UpdatePulserOutlierMap();
96 }
97 //_____________________________________________________________________________________
98 void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC, Int_t &noutliersCE)
99 {
100   //
101   // Process the CE data for this run
102   // the return TVectorD arrays contian the results of the fit
103   // noutliersCE contains the number of pads marked as outliers,
104   //   not including masked and edge pads
105   //
106   
107   //retrieve CE and ALTRO data
108   if (!fCETmean){
109     TString fitString(fitFormula);
110     fitString.ReplaceAll("++","#");
111     Int_t ndim=fitString.CountChar('#')+2;
112     fitResultsA.ResizeTo(ndim);
113     fitResultsC.ResizeTo(ndim);
114     fitResultsA.Zero();
115     fitResultsC.Zero();
116     noutliersCE=-1;
117     return;
118   }
119   noutliersCE=0;
120   //create outlier map
121   AliTPCCalPad out("out","out");
122   AliTPCCalROC *rocMasked=0x0;
123   //loop over all channels
124   for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
125     AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
126     if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc);
127     AliTPCCalROC *rocOut=out.GetCalROC(iroc);
128     if (!rocData) continue;
129     //add time offset to IROCs
130     if (iroc<AliTPCROC::Instance()->GetNInnerSector())
131       rocData->Add(fIrocTimeOffset);
132     //select outliers
133     UInt_t nrows=rocData->GetNrows();
134     for (UInt_t irow=0;irow<nrows;++irow){
135       UInt_t npads=rocData->GetNPads(irow);
136       for (UInt_t ipad=0;ipad<npads;++ipad){
137         //exclude masked pads
138         if (rocMasked && rocMasked->GetValue(irow,ipad)) {
139           rocOut->SetValue(iroc,ipad,1);
140           continue;
141         }
142         //exclude edge pads
143         if (ipad==0||ipad==npads-1) rocOut->SetValue(iroc,ipad,1); 
144         Float_t valTmean=rocData->GetValue(iroc,ipad);
145         //exclude values that are exactly 0
146         if (valTmean==0) {
147           rocOut->SetValue(iroc,ipad,1);
148           ++noutliersCE;
149         }
150         // exclude channels with too large variations
151         if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
152           rocOut->SetValue(iroc,ipad,1);
153           ++noutliersCE;
154         }
155       }
156     }
157   }
158   //perform fit
159   TMatrixD dummy;
160   Float_t chi2A,chi2C;
161   fCETmean->GlobalSidesFit(&out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2A,chi2C);
162 }
163 //_____________________________________________________________________________________
164 void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian,
165                      TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian,
166                      Float_t &driftTimeA, Float_t &driftTimeC )
167 {
168   //
169   // Calculate statistical information from the CE graphs for drift time and charge
170   //
171   
172   //reset arrays
173   vecTEntries.ResizeTo(72);
174   vecTMean.ResizeTo(72);
175   vecTRMS.ResizeTo(72);
176   vecTMedian.ResizeTo(72);
177   vecQEntries.ResizeTo(72);
178   vecQMean.ResizeTo(72);
179   vecQRMS.ResizeTo(72);
180   vecQMedian.ResizeTo(72);
181   vecTEntries.Zero();
182   vecTMean.Zero();
183   vecTRMS.Zero();
184   vecTMedian.Zero();
185   vecQEntries.Zero();
186   vecQMean.Zero();
187   vecQRMS.Zero();
188   vecQMedian.Zero();
189   driftTimeA=0;
190   driftTimeC=0;
191   TObjArray *arrT=fCalibDB->GetCErocTtime();
192   TObjArray *arrQ=fCalibDB->GetCErocQtime();
193   if (arrT){
194     for (Int_t isec=0;isec<74;++isec){
195       TGraph *gr=(TGraph*)arrT->At(isec);
196       if (!gr) continue;
197       TVectorD values;
198       Int_t npoints = gr->GetN();
199       values.ResizeTo(npoints);
200       Int_t nused =0;
201       for (Int_t ipoint=0; ipoint<npoints; ipoint++){
202         if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){
203           values[nused]=gr->GetY()[ipoint];
204           nused++;
205         }
206       }
207       //
208       if (isec<72) vecTEntries[isec]= nused;
209       if (nused>1){
210         if (isec<72){
211           vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
212           vecTMean[isec]   = TMath::Mean(nused,values.GetMatrixArray());
213           vecTRMS[isec]    = TMath::RMS(nused,values.GetMatrixArray());
214         } else if (isec==72){
215           driftTimeA=TMath::Median(nused,values.GetMatrixArray());
216         } else if (isec==73){
217           driftTimeC=TMath::Median(nused,values.GetMatrixArray());
218         }
219       }
220     }
221   }
222   if (arrQ){
223     for (Int_t isec=0;isec<72;++isec){
224       TGraph *gr=(TGraph*)arrQ->At(isec);
225       if (!gr) continue;
226       TVectorD values;
227       Int_t npoints = gr->GetN();
228       values.ResizeTo(npoints);
229       Int_t nused =0;
230       for (Int_t ipoint=0; ipoint<npoints; ipoint++){
231         if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){
232           values[nused]=gr->GetY()[ipoint];
233           nused++;
234         }
235       }
236       //
237       vecTEntries[isec]= nused;
238       if (nused>1){
239         vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
240         vecQMean[isec]   = TMath::Mean(nused,values.GetMatrixArray());
241         vecQRMS[isec]    = TMath::RMS(nused,values.GetMatrixArray());
242       }
243     }
244   }
245 }
246
247 //_____________________________________________________________________________________
248 void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
249                       TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
250                       Int_t &nonMaskedZero)
251 {
252   //
253   // process noise data
254   // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1],
255   //    OROCs small pads [2] and OROCs large pads [3]
256   // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot)
257   // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error
258   //
259   
260   //set proper size and reset
261   const UInt_t infoSize=4;
262   vNoiseMean.ResizeTo(infoSize);
263   vNoiseMeanSenRegions.ResizeTo(infoSize);
264   vNoiseRMS.ResizeTo(infoSize);
265   vNoiseRMSSenRegions.ResizeTo(infoSize);
266   vNoiseMean.Zero();
267   vNoiseMeanSenRegions.Zero();
268   vNoiseRMS.Zero();
269   vNoiseRMSSenRegions.Zero();
270   nonMaskedZero=0;
271   //counters
272   TVectorD c(infoSize);
273   TVectorD cs(infoSize);
274   //tpc parameters
275   AliTPCParam par;
276   par.Update();
277   //retrieve noise and ALTRO data
278   if (!fPadNoise) return;
279   AliTPCCalROC *rocMasked=0x0;
280   //create IROC, OROC1, OROC2 and sensitive region masks
281   for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
282     AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec);
283     if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
284     UInt_t nrows=noiseROC->GetNrows();
285     for (UInt_t irow=0;irow<nrows;++irow){
286       UInt_t npads=noiseROC->GetNPads(irow);
287       for (UInt_t ipad=0;ipad<npads;++ipad){
288         //don't use masked channels;
289         if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
290         Float_t noiseVal=noiseROC->GetValue(irow,ipad);
291         //check if noise==0
292         if (noiseVal==0) {
293           ++nonMaskedZero;
294           continue;
295         }
296         //check for nan
297         if ( !(noiseVal<10000000) ){
298           printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal);
299           continue;
300         }
301         Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
302         Int_t masksen=1; // sensitive pards are not masked (0)
303         if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive)
304         if (isec<AliTPCROC::Instance()->GetNInnerSector()){
305           //IROCs
306           if (irow>19&&irow<46){
307             if (TMath::Abs(cpad)<7) masksen=0; //IROC spot
308           }
309           Int_t type=1;
310           vNoiseMean[type]+=noiseVal;
311           vNoiseRMS[type]+=noiseVal*noiseVal;
312           ++c[type];
313           if (!masksen){
314             vNoiseMeanSenRegions[type]+=noiseVal;
315             vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
316             ++cs[type];
317           }
318         } else {
319           //OROCs
320           //define sensive regions
321           if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive
322           if ( irow>75 ){
323             Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad);
324             if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive
325           }
326           if ((Int_t)irow<par.GetNRowUp1()){
327             //OROC1
328             Int_t type=2;
329             vNoiseMean[type]+=noiseVal;
330             vNoiseRMS[type]+=noiseVal*noiseVal;
331             ++c[type];
332             if (!masksen){
333               vNoiseMeanSenRegions[type]+=noiseVal;
334               vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
335               ++cs[type];
336             }
337           }else{
338             //OROC2
339             Int_t type=3;
340             vNoiseMean[type]+=noiseVal;
341             vNoiseRMS[type]+=noiseVal*noiseVal;
342             ++c[type];
343             if (!masksen){
344               vNoiseMeanSenRegions[type]+=noiseVal;
345               vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
346               ++cs[type];
347             }
348           }
349         }
350         //whole tpc
351         Int_t type=0;
352         vNoiseMean[type]+=noiseVal;
353         vNoiseRMS[type]+=noiseVal*noiseVal;
354         ++c[type];
355         if (!masksen){
356           vNoiseMeanSenRegions[type]+=noiseVal;
357           vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
358           ++cs[type];
359         }
360       }//end loop pads
361     }//end loop rows
362   }//end loop sectors (rocs)
363   
364   //calculate mean and RMS
365   const Double_t verySmall=0.0000000001;
366   for (UInt_t i=0;i<infoSize;++i){
367     Double_t mean=0;
368     Double_t rms=0;
369     Double_t meanSen=0;
370     Double_t rmsSen=0;
371     
372     if (c[i]>verySmall){
373 //       printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]);
374       mean=vNoiseMean[i]/c[i];
375       rms=vNoiseRMS[i];
376       rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
377     }
378     vNoiseMean[i]=mean;
379     vNoiseRMS[i]=rms;
380     
381     if (cs[i]>verySmall){
382       meanSen=vNoiseMeanSenRegions[i]/cs[i];
383       rmsSen=vNoiseRMSSenRegions[i];
384       rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen));
385     }
386     vNoiseMeanSenRegions[i]=meanSen;
387     vNoiseRMSSenRegions[i]=rmsSen;
388   }
389 }
390
391 //_____________________________________________________________________________________
392 void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
393 {
394   //
395   // Process the Pulser information
396   // vMeanTime:     pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C
397   //
398
399   const UInt_t infoSize=4;
400   //reset counters to error number
401   vMeanTime.ResizeTo(infoSize);
402   vMeanTime.Zero();
403   //counter
404   TVectorD c(infoSize);
405   //retrieve pulser and ALTRO data
406   if (!fPulserTmean) return;
407   //
408   //get Outliers
409   AliTPCCalROC *rocOut=0x0;
410   for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
411     AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
412     if (!tmeanROC) continue;
413     rocOut=fPulserOutlier->GetCalROC(isec);
414     UInt_t nchannels=tmeanROC->GetNchannels();
415     for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
416       if (rocOut && rocOut->GetValue(ichannel)) continue;
417       Float_t val=tmeanROC->GetValue(ichannel);
418       Int_t type=isec/18;
419       vMeanTime[type]+=val;
420       ++c[type];
421     }
422   }
423   //calculate mean
424   for (UInt_t itype=0; itype<infoSize; ++itype){
425     if (c[itype]>0) vMeanTime[itype]/=c[itype];
426     else vMeanTime[itype]=0;
427   }
428 }
429 //_____________________________________________________________________________________
430 void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked)
431 {
432   //
433   // Get Values from ALTRO configuration data
434   //
435   nMasked=-1;
436   if (!fALTROMasked) return;
437   nMasked=0;
438   for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){
439     AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec);
440     for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){
441       if (rocMasked->GetValue(ichannel)) ++nMasked;
442     }
443   }
444 }
445 //_____________________________________________________________________________________
446 void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS)
447 {
448   //
449   // Proces Goofie values, return statistical information of the currently set goofieArray
450   // The meaning of the entries are given below
451   /*
452   1       TPC_ANODE_I_A00_STAT
453   2       TPC_DVM_CO2
454   3       TPC_DVM_DriftVelocity
455   4       TPC_DVM_FCageHV
456   5       TPC_DVM_GainFar
457   6       TPC_DVM_GainNear
458   7       TPC_DVM_N2
459   8       TPC_DVM_NumberOfSparks
460   9       TPC_DVM_PeakAreaFar
461   10      TPC_DVM_PeakAreaNear
462   11      TPC_DVM_PeakPosFar
463   12      TPC_DVM_PeakPosNear
464   13      TPC_DVM_PickupHV
465   14      TPC_DVM_Pressure
466   15      TPC_DVM_T1_Over_P
467   16      TPC_DVM_T2_Over_P
468   17      TPC_DVM_T_Over_P
469   18      TPC_DVM_TemperatureS1
470    */
471   if (!fGoofieArray){
472     Int_t nsensors=19;
473     vecEntries.ResizeTo(nsensors);
474     vecMedian.ResizeTo(nsensors);
475     vecMean.ResizeTo(nsensors);
476     vecRMS.ResizeTo(nsensors);
477     vecEntries.Zero();
478     vecMedian.Zero();
479     vecMean.Zero();
480     vecRMS.Zero();
481     return;
482   }
483   Double_t kEpsilon=0.0000000001;
484   Double_t kBig=100000000000.;
485   Int_t nsensors = fGoofieArray->NumSensors();
486   vecEntries.ResizeTo(nsensors);
487   vecMedian.ResizeTo(nsensors);
488   vecMean.ResizeTo(nsensors);
489   vecRMS.ResizeTo(nsensors);
490   TVectorF values;
491   for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){
492     AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor);
493     if (gsensor &&  gsensor->GetGraph()){
494       Int_t npoints = gsensor->GetGraph()->GetN();
495       // filter zeroes
496       values.ResizeTo(npoints);
497       Int_t nused =0;
498       for (Int_t ipoint=0; ipoint<npoints; ipoint++){
499         if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon &&
500             TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){
501               values[nused]=gsensor->GetGraph()->GetY()[ipoint];
502               nused++;
503             }
504       }
505       //
506       vecEntries[isensor]= nused;
507       if (nused>1){
508         vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray());
509         vecMean[isensor]   = TMath::Mean(nused,values.GetMatrixArray());
510         vecRMS[isensor]    = TMath::RMS(nused,values.GetMatrixArray());
511       }
512     }
513   }
514 }
515
516 //_____________________________________________________________________________________
517 void AliTPCcalibDButil::UpdatePulserOutlierMap()
518 {
519   //
520   // Create a map that contains outliers from the Pulser calibration data.
521   // The outliers include masked channels, edge pads and pads with
522   //   too large timing and charge variations.
523   // nonMaskedZero is the number of outliers in the Pulser calibration data.
524   //   those do not contain masked and edge pads
525   //
526   if (!fPulserTmean||!fPulserQmean) {
527     //reset map
528     fPulserOutlier->Multiply(0.);
529     fNpulserOutliers=-1;
530     return;
531   }
532   AliTPCCalROC *rocMasked=0x0;
533   fNpulserOutliers=0;
534   
535   //Create Outlier Map
536   for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
537     AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
538     AliTPCCalROC *qmeanROC=fPulserQmean->GetCalROC(isec);
539     AliTPCCalROC *outROC=fPulserOutlier->GetCalROC(isec);
540     if (!tmeanROC||!qmeanROC) {
541       //reset outliers in this ROC
542       outROC->Multiply(0.);
543       continue;
544     }
545     if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
546 //     Double_t dummy=0;
547 //     Float_t qmedian=qmeanROC->GetLTM(&dummy,.5);
548 //     Float_t tmedian=tmeanROC->GetLTM(&dummy,.5);
549     UInt_t nrows=tmeanROC->GetNrows();
550     for (UInt_t irow=0;irow<nrows;++irow){
551       UInt_t npads=tmeanROC->GetNPads(irow);
552       for (UInt_t ipad=0;ipad<npads;++ipad){
553         Int_t outlier=0,masked=0;
554         Float_t q=qmeanROC->GetValue(irow,ipad);
555         Float_t t=tmeanROC->GetValue(irow,ipad);
556         //masked channels are outliers
557         if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1;
558         //edge pads are outliers
559         if (ipad==0||ipad==npads-1) masked=1;
560         //channels with too large charge or timing deviation from the meadian are outliers
561 //         if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1;
562         if (q<fPulQminLimit && !masked) outlier=1;
563         //check for nan
564         if ( !(q<10000000) || !(t<10000000)) outlier=1;
565         outROC->SetValue(irow,ipad,outlier+masked);
566         fNpulserOutliers+=outlier;
567       }
568     }
569   }
570 }
571 //_____________________________________________________________________________________
572 AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model)
573 {
574   //
575   // Create pad time0 object from pulser and/or CE data, depending on the selected model
576   // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser
577   // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser
578   // 
579   //
580   
581   AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model));
582   // decide between different models
583   if (model==0||model==1){
584     TVectorD vMean;
585     if (model==1) ProcessPulser(vMean);
586     for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
587       AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
588       if (!rocPulTmean) continue;
589       AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
590       AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
591       Float_t mean=rocPulTmean->GetMean(rocOut);
592       //treat case where a whole partition is masked
593       if (mean==0) mean=rocPulTmean->GetMean();
594       if (model==1) {
595         Int_t type=isec/18;
596         mean=vMean[type];
597       }
598       UInt_t nrows=rocTime0->GetNrows();
599       for (UInt_t irow=0;irow<nrows;++irow){
600         UInt_t npads=rocTime0->GetNPads(irow);
601         for (UInt_t ipad=0;ipad<npads;++ipad){
602           Float_t time=rocPulTmean->GetValue(irow,ipad);
603           //in case of an outlier pad use the mean of the altro values.
604           //This should be the most precise guess in that case.
605           if (rocOut->GetValue(irow,ipad)) {
606             time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
607             if (time==0) time=mean;
608           }
609           Float_t val=time-mean;
610           rocTime0->SetValue(irow,ipad,val);
611         }
612       }
613     }
614   }
615
616
617
618   return padTime0;
619 }
620 //_____________________________________________________________________________________
621 Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut)
622 {
623   if (roc==0) return 0.;
624   const Int_t sector=roc->GetSector();
625   AliTPCROC *tpcRoc=AliTPCROC::Instance();
626   const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad);
627   Float_t mean=0;
628   Int_t   n=0;
629   
630   //loop over a small range around the requested pad (+-10 rows/pads)
631   for (Int_t irow=row-10;irow<row+10;++irow){
632     if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue;
633     for (Int_t ipad=pad-10; ipad<pad+10;++ipad){
634       if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue;
635       const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad);
636       if (altroRoc!=altroCurr) continue;
637       if ( rocOut && rocOut->GetValue(irow,ipad) ) continue;
638       Float_t val=roc->GetValue(irow,ipad);
639       mean+=val;
640       ++n;
641     }
642   }
643   if (n>0) mean/=n;
644   return mean;
645 }