adding libAliHLTTRD.so as dependency for libAliHLTTrigger.so
[u/mrichter/AliRoot.git] / TPC / AliTPCcalibDButil.cxx
CommitLineData
892226be 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"
6e7d7dc4 40#include "AliTPCCalibRaw.h"
892226be 41
42#include "AliTPCcalibDButil.h"
43
44ClassImp(AliTPCcalibDButil)
45AliTPCcalibDButil::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),
6e7d7dc4 58 fCalibRaw(0x0),
892226be 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//_____________________________________________________________________________________
73AliTPCcalibDButil::~AliTPCcalibDButil()
74{
75 //
76 // dtor
77 //
78 delete fPulserOutlier;
79 delete fMapper;
80}
81//_____________________________________________________________________________________
82void 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());
6e7d7dc4 97 fCalibRaw=fCalibDB->GetCalibRaw();
892226be 98 UpdatePulserOutlierMap();
99}
100//_____________________________________________________________________________________
101void 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);
6e7d7dc4 131 if (!rocData) {
132 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
133 continue;
134 }
892226be 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//_____________________________________________________________________________________
170void 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;
6e7d7dc4 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 ){
892226be 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){
6e7d7dc4 230 for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){
892226be 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 //
6e7d7dc4 244 vecQEntries[isec]= nused;
892226be 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//_____________________________________________________________________________________
255void 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//_____________________________________________________________________________________
399void 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//_____________________________________________________________________________________
437void 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//_____________________________________________________________________________________
453void 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//_____________________________________________________________________________________
524void 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//_____________________________________________________________________________________
579AliTPCCalPad* 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//_____________________________________________________________________________________
628Float_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}