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