1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // Class providing the calculation of derived quantities (mean,rms,fits,...) //
20 // of calibration entries //
25 ////////////////////////////////////////////////////////////////////////////////
29 #include <TObjArray.h>
32 #include <TDirectory.h>
34 #include <AliDCSSensorArray.h>
35 #include <AliDCSSensor.h>
36 #include "AliTPCcalibDB.h"
37 #include "AliTPCCalPad.h"
38 #include "AliTPCCalROC.h"
39 #include "AliTPCROC.h"
40 #include "AliTPCmapper.h"
41 #include "AliTPCParam.h"
42 #include "AliTPCCalibRaw.h"
44 #include "AliTPCcalibDButil.h"
46 ClassImp(AliTPCcalibDButil)
47 AliTPCcalibDButil::AliTPCcalibDButil() :
49 fCalibDB(AliTPCcalibDB::Instance()),
55 fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")),
66 fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")),
73 fMapper(new AliTPCmapper(0x0)),
77 fPulTmaxLimitAbs(1.5),
85 //_____________________________________________________________________________________
86 AliTPCcalibDButil::~AliTPCcalibDButil()
91 delete fPulserOutlier;
92 delete fRefPulserOutlier;
94 if (fRefPadNoise) delete fRefPadNoise;
95 if (fRefPedestals) delete fRefPedestals;
96 if (fRefPulserTmean) delete fRefPulserTmean;
97 if (fRefPulserTrms) delete fRefPulserTrms;
98 if (fRefPulserQmean) delete fRefPulserQmean;
99 if (fRefCETmean) delete fRefCETmean;
100 if (fRefCETrms) delete fRefCETrms;
101 if (fRefCEQmean) delete fRefCEQmean;
102 if (fRefALTROMasked) delete fRefALTROMasked;
103 if (fRefCalibRaw) delete fRefCalibRaw;
106 //_____________________________________________________________________________________
107 void AliTPCcalibDButil::UpdateFromCalibDB()
110 // Update pointers from calibDB
112 fPadNoise=fCalibDB->GetPadNoise();
113 fPedestals=fCalibDB->GetPedestals();
114 fPulserTmean=fCalibDB->GetPulserTmean();
115 fPulserTrms=fCalibDB->GetPulserTrms();
116 fPulserQmean=fCalibDB->GetPulserQmean();
117 fCETmean=fCalibDB->GetCETmean();
118 fCETrms=fCalibDB->GetCETrms();
119 fCEQmean=fCalibDB->GetCEQmean();
120 fALTROMasked=fCalibDB->GetALTROMasked();
121 fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
122 fCalibRaw=fCalibDB->GetCalibRaw();
123 UpdatePulserOutlierMap();
125 //_____________________________________________________________________________________
126 void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
127 Int_t &noutliersCE, AliTPCCalPad *outCE)
130 // Process the CE data for this run
131 // the return TVectorD arrays contian the results of the fit
132 // noutliersCE contains the number of pads marked as outliers,
133 // not including masked and edge pads
136 //retrieve CE and ALTRO data
138 TString fitString(fitFormula);
139 fitString.ReplaceAll("++","#");
140 Int_t ndim=fitString.CountChar('#')+2;
141 fitResultsA.ResizeTo(ndim);
142 fitResultsC.ResizeTo(ndim);
151 if (outCE) out=outCE;
152 else out=new AliTPCCalPad("outCE","outCE");
153 AliTPCCalROC *rocMasked=0x0;
154 //loop over all channels
155 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
156 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
157 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc);
158 AliTPCCalROC *rocOut=out->GetCalROC(iroc);
160 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
164 //add time offset to IROCs
165 if (iroc<AliTPCROC::Instance()->GetNInnerSector())
166 rocData->Add(fIrocTimeOffset);
168 UInt_t nrows=rocData->GetNrows();
169 for (UInt_t irow=0;irow<nrows;++irow){
170 UInt_t npads=rocData->GetNPads(irow);
171 for (UInt_t ipad=0;ipad<npads;++ipad){
172 rocOut->SetValue(irow,ipad,0);
173 //exclude masked pads
174 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
175 rocOut->SetValue(irow,ipad,1);
178 //exclude first two rows in IROC and last two rows in OROC
180 if (irow<2) rocOut->SetValue(irow,ipad,1);
182 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
185 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
186 Float_t valTmean=rocData->GetValue(irow,ipad);
187 //exclude values that are exactly 0
189 rocOut->SetValue(irow,ipad,1);
192 // exclude channels with too large variations
193 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
194 rocOut->SetValue(irow,ipad,1);
203 fCETmean->GlobalSidesFit(out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2A,chi2C);
204 if (!outCE) delete out;
206 //_____________________________________________________________________________________
207 void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian,
208 TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian,
209 Float_t &driftTimeA, Float_t &driftTimeC )
212 // Calculate statistical information from the CE graphs for drift time and charge
216 vecTEntries.ResizeTo(72);
217 vecTMean.ResizeTo(72);
218 vecTRMS.ResizeTo(72);
219 vecTMedian.ResizeTo(72);
220 vecQEntries.ResizeTo(72);
221 vecQMean.ResizeTo(72);
222 vecQRMS.ResizeTo(72);
223 vecQMedian.ResizeTo(72);
234 TObjArray *arrT=fCalibDB->GetCErocTtime();
235 TObjArray *arrQ=fCalibDB->GetCErocQtime();
237 for (Int_t isec=0;isec<74;++isec){
238 TGraph *gr=(TGraph*)arrT->At(isec);
241 Int_t npoints = gr->GetN();
242 values.ResizeTo(npoints);
244 //skip first points, theres always some problems with finding the CE position
245 for (Int_t ipoint=4; ipoint<npoints; ipoint++){
246 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1020 ){
247 values[nused]=gr->GetY()[ipoint];
252 if (isec<72) vecTEntries[isec]= nused;
255 vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
256 vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
257 vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
258 } else if (isec==72){
259 driftTimeA=TMath::Median(nused,values.GetMatrixArray());
260 } else if (isec==73){
261 driftTimeC=TMath::Median(nused,values.GetMatrixArray());
267 for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){
268 TGraph *gr=(TGraph*)arrQ->At(isec);
271 Int_t npoints = gr->GetN();
272 values.ResizeTo(npoints);
274 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
275 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1000 ){
276 values[nused]=gr->GetY()[ipoint];
281 vecQEntries[isec]= nused;
283 vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
284 vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
285 vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
291 //_____________________________________________________________________________________
292 void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
293 TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
294 Int_t &nonMaskedZero)
297 // process noise data
298 // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1],
299 // OROCs small pads [2] and OROCs large pads [3]
300 // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot)
301 // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error
304 //set proper size and reset
305 const UInt_t infoSize=4;
306 vNoiseMean.ResizeTo(infoSize);
307 vNoiseMeanSenRegions.ResizeTo(infoSize);
308 vNoiseRMS.ResizeTo(infoSize);
309 vNoiseRMSSenRegions.ResizeTo(infoSize);
311 vNoiseMeanSenRegions.Zero();
313 vNoiseRMSSenRegions.Zero();
316 TVectorD c(infoSize);
317 TVectorD cs(infoSize);
321 //retrieve noise and ALTRO data
322 if (!fPadNoise) return;
323 AliTPCCalROC *rocMasked=0x0;
324 //create IROC, OROC1, OROC2 and sensitive region masks
325 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
326 AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec);
327 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
328 UInt_t nrows=noiseROC->GetNrows();
329 for (UInt_t irow=0;irow<nrows;++irow){
330 UInt_t npads=noiseROC->GetNPads(irow);
331 for (UInt_t ipad=0;ipad<npads;++ipad){
332 //don't use masked channels;
333 if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
334 Float_t noiseVal=noiseROC->GetValue(irow,ipad);
341 if ( !(noiseVal<10000000) ){
342 printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal);
345 Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
346 Int_t masksen=1; // sensitive pards are not masked (0)
347 if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive)
348 if (isec<AliTPCROC::Instance()->GetNInnerSector()){
350 if (irow>19&&irow<46){
351 if (TMath::Abs(cpad)<7) masksen=0; //IROC spot
354 vNoiseMean[type]+=noiseVal;
355 vNoiseRMS[type]+=noiseVal*noiseVal;
358 vNoiseMeanSenRegions[type]+=noiseVal;
359 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
364 //define sensive regions
365 if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive
367 Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad);
368 if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive
370 if ((Int_t)irow<par.GetNRowUp1()){
373 vNoiseMean[type]+=noiseVal;
374 vNoiseRMS[type]+=noiseVal*noiseVal;
377 vNoiseMeanSenRegions[type]+=noiseVal;
378 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
384 vNoiseMean[type]+=noiseVal;
385 vNoiseRMS[type]+=noiseVal*noiseVal;
388 vNoiseMeanSenRegions[type]+=noiseVal;
389 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
396 vNoiseMean[type]+=noiseVal;
397 vNoiseRMS[type]+=noiseVal*noiseVal;
400 vNoiseMeanSenRegions[type]+=noiseVal;
401 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
406 }//end loop sectors (rocs)
408 //calculate mean and RMS
409 const Double_t verySmall=0.0000000001;
410 for (UInt_t i=0;i<infoSize;++i){
417 // printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]);
418 mean=vNoiseMean[i]/c[i];
420 rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
425 if (cs[i]>verySmall){
426 meanSen=vNoiseMeanSenRegions[i]/cs[i];
427 rmsSen=vNoiseRMSSenRegions[i];
428 rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen));
430 vNoiseMeanSenRegions[i]=meanSen;
431 vNoiseRMSSenRegions[i]=rmsSen;
435 //_____________________________________________________________________________________
436 void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
439 // Process the Pulser information
440 // vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C
443 const UInt_t infoSize=4;
444 //reset counters to error number
445 vMeanTime.ResizeTo(infoSize);
448 TVectorD c(infoSize);
449 //retrieve pulser and ALTRO data
450 if (!fPulserTmean) return;
453 AliTPCCalROC *rocOut=0x0;
454 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
455 AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
456 if (!tmeanROC) continue;
457 rocOut=fPulserOutlier->GetCalROC(isec);
458 UInt_t nchannels=tmeanROC->GetNchannels();
459 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
460 if (rocOut && rocOut->GetValue(ichannel)) continue;
461 Float_t val=tmeanROC->GetValue(ichannel);
463 vMeanTime[type]+=val;
468 for (UInt_t itype=0; itype<infoSize; ++itype){
469 if (c[itype]>0) vMeanTime[itype]/=c[itype];
470 else vMeanTime[itype]=0;
473 //_____________________________________________________________________________________
474 void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked)
477 // Get Values from ALTRO configuration data
480 if (!fALTROMasked) return;
482 for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){
483 AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec);
484 for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){
485 if (rocMasked->GetValue(ichannel)) ++nMasked;
489 //_____________________________________________________________________________________
490 void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS)
493 // Proces Goofie values, return statistical information of the currently set goofieArray
494 // The meaning of the entries are given below
496 1 TPC_ANODE_I_A00_STAT
498 3 TPC_DVM_DriftVelocity
503 8 TPC_DVM_NumberOfSparks
504 9 TPC_DVM_PeakAreaFar
505 10 TPC_DVM_PeakAreaNear
506 11 TPC_DVM_PeakPosFar
507 12 TPC_DVM_PeakPosNear
513 18 TPC_DVM_TemperatureS1
517 vecEntries.ResizeTo(nsensors);
518 vecMedian.ResizeTo(nsensors);
519 vecMean.ResizeTo(nsensors);
520 vecRMS.ResizeTo(nsensors);
527 Double_t kEpsilon=0.0000000001;
528 Double_t kBig=100000000000.;
529 Int_t nsensors = fGoofieArray->NumSensors();
530 vecEntries.ResizeTo(nsensors);
531 vecMedian.ResizeTo(nsensors);
532 vecMean.ResizeTo(nsensors);
533 vecRMS.ResizeTo(nsensors);
535 for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){
536 AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor);
537 if (gsensor && gsensor->GetGraph()){
538 Int_t npoints = gsensor->GetGraph()->GetN();
540 values.ResizeTo(npoints);
542 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
543 if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon &&
544 TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){
545 values[nused]=gsensor->GetGraph()->GetY()[ipoint];
550 vecEntries[isensor]= nused;
552 vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray());
553 vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray());
554 vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray());
559 //_____________________________________________________________________________________
560 void AliTPCcalibDButil::ProcessPedestalVariations(TVectorF &pedestalDeviations)
563 // check the variations of the pedestal data to the reference pedestal data
564 // thresholds are 0.5, 1.0, 1.5 and 2 timebins respectively.
567 TVectorF vThres(npar); //thresholds
568 Int_t nActive=0; //number of active channels
570 //reset and set thresholds
571 pedestalDeviations.ResizeTo(npar);
572 for (Int_t i=0;i<npar;++i){
573 pedestalDeviations.GetMatrixArray()[i]=0;
574 vThres.GetMatrixArray()[i]=(i+1)*.5;
576 //check all needed data is available
577 if (!fRefPedestals || !fPedestals || !fALTROMasked || !fRefALTROMasked) return;
578 //loop over all channels
579 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
580 AliTPCCalROC *pROC=fPedestals->GetCalROC(isec);
581 AliTPCCalROC *pRefROC=fRefPedestals->GetCalROC(isec);
582 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
583 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
584 UInt_t nrows=mROC->GetNrows();
585 for (UInt_t irow=0;irow<nrows;++irow){
586 UInt_t npads=mROC->GetNPads(irow);
587 for (UInt_t ipad=0;ipad<npads;++ipad){
588 //don't use masked channels;
589 if (mROC ->GetValue(irow,ipad)) continue;
590 if (mRefROC->GetValue(irow,ipad)) continue;
591 Float_t deviation=TMath::Abs(pROC->GetValue(irow,ipad)-pRefROC->GetValue(irow,ipad));
592 for (Int_t i=0;i<npar;++i){
593 if (deviation>vThres[i])
594 ++pedestalDeviations.GetMatrixArray()[i];
601 for (Int_t i=0;i<npar;++i){
602 pedestalDeviations.GetMatrixArray()[i]/=nActive;
606 //_____________________________________________________________________________________
607 void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations)
610 // check the variations of the noise data to the reference noise data
611 // thresholds are 5, 10, 15 and 20 percent respectively.
614 TVectorF vThres(npar); //thresholds
615 Int_t nActive=0; //number of active channels
617 //reset and set thresholds
618 noiseDeviations.ResizeTo(npar);
619 for (Int_t i=0;i<npar;++i){
620 noiseDeviations.GetMatrixArray()[i]=0;
621 vThres.GetMatrixArray()[i]=(i+1)*.05;
623 //check all needed data is available
624 if (!fRefPadNoise || !fPadNoise || !fALTROMasked || !fRefALTROMasked) return;
625 //loop over all channels
626 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
627 AliTPCCalROC *nROC=fPadNoise->GetCalROC(isec);
628 AliTPCCalROC *nRefROC=fRefPadNoise->GetCalROC(isec);
629 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
630 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
631 UInt_t nrows=mROC->GetNrows();
632 for (UInt_t irow=0;irow<nrows;++irow){
633 UInt_t npads=mROC->GetNPads(irow);
634 for (UInt_t ipad=0;ipad<npads;++ipad){
635 //don't use masked channels;
636 if (mROC ->GetValue(irow,ipad)) continue;
637 if (mRefROC->GetValue(irow,ipad)) continue;
638 Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
639 for (Int_t i=0;i<npar;++i){
640 if (deviation>vThres[i])
641 ++noiseDeviations.GetMatrixArray()[i];
648 for (Int_t i=0;i<npar;++i){
649 noiseDeviations.GetMatrixArray()[i]/=nActive;
653 //_____________________________________________________________________________________
654 void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Float_t &varQMean,
655 Int_t &npadsOutOneTB, Int_t &npadsOffAdd)
658 // check the variations of the pulserQmean data to the reference pulserQmean data: pulserQdeviations
659 // thresholds are .5, 1, 5 and 10 percent respectively.
663 TVectorF vThres(npar); //thresholds
664 Int_t nActive=0; //number of active channels
666 //reset and set thresholds
667 pulserQdeviations.ResizeTo(npar);
668 for (Int_t i=0;i<npar;++i){
669 pulserQdeviations.GetMatrixArray()[i]=0;
674 vThres.GetMatrixArray()[0]=.005;
675 vThres.GetMatrixArray()[1]=.01;
676 vThres.GetMatrixArray()[2]=.05;
677 vThres.GetMatrixArray()[3]=.1;
678 //check all needed data is available
679 if (!fRefPulserTmean || !fPulserTmean || !fPulserQmean || !fRefPulserQmean || !fALTROMasked || !fRefALTROMasked) return;
681 UpdateRefPulserOutlierMap();
682 //loop over all channels
683 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
684 AliTPCCalROC *pqROC=fPulserQmean->GetCalROC(isec);
685 AliTPCCalROC *pqRefROC=fRefPulserQmean->GetCalROC(isec);
686 AliTPCCalROC *ptROC=fPulserTmean->GetCalROC(isec);
687 // AliTPCCalROC *ptRefROC=fRefPulserTmean->GetCalROC(isec);
688 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
689 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
690 AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
691 Float_t pt_mean=ptROC->GetMean(oROC);
692 UInt_t nrows=mROC->GetNrows();
693 for (UInt_t irow=0;irow<nrows;++irow){
694 UInt_t npads=mROC->GetNPads(irow);
695 for (UInt_t ipad=0;ipad<npads;++ipad){
696 //don't use masked channels;
697 if (mROC ->GetValue(irow,ipad)) continue;
698 if (mRefROC->GetValue(irow,ipad)) continue;
699 //don't user edge pads
700 if (ipad==0||ipad==npads-1) continue;
702 Float_t pq=pqROC->GetValue(irow,ipad);
703 Float_t pqRef=pqRefROC->GetValue(irow,ipad);
704 Float_t pt=ptROC->GetValue(irow,ipad);
705 // Float_t ptRef=ptRefROC->GetValue(irow,ipad);
707 Float_t deviation=TMath::Abs(pq/pqRef-1);
708 for (Int_t i=0;i<npar;++i){
709 if (deviation>vThres[i])
710 ++pulserQdeviations.GetMatrixArray()[i];
712 if (pqRef>11&&pq<11) ++npadsOffAdd;
715 if (TMath::Abs(pt-pt_mean)>1) ++npadsOutOneTB;
721 for (Int_t i=0;i<npar;++i){
722 pulserQdeviations.GetMatrixArray()[i]/=nActive;
727 //_____________________________________________________________________________________
728 void AliTPCcalibDButil::UpdatePulserOutlierMap()
733 PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
735 //_____________________________________________________________________________________
736 void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
741 PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
743 //_____________________________________________________________________________________
744 void AliTPCcalibDButil::PulserOutlierMap(AliTPCCalPad *pulOut, const AliTPCCalPad *pulT, const AliTPCCalPad *pulQ)
747 // Create a map that contains outliers from the Pulser calibration data.
748 // The outliers include masked channels, edge pads and pads with
749 // too large timing and charge variations.
750 // fNpulserOutliers is the number of outliers in the Pulser calibration data.
751 // those do not contain masked and edge pads
755 pulOut->Multiply(0.);
759 AliTPCCalROC *rocMasked=0x0;
763 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
764 AliTPCCalROC *tmeanROC=pulT->GetCalROC(isec);
765 AliTPCCalROC *qmeanROC=pulQ->GetCalROC(isec);
766 AliTPCCalROC *outROC=pulOut->GetCalROC(isec);
767 if (!tmeanROC||!qmeanROC) {
768 //reset outliers in this ROC
769 outROC->Multiply(0.);
772 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
774 // Float_t qmedian=qmeanROC->GetLTM(&dummy,.5);
775 // Float_t tmedian=tmeanROC->GetLTM(&dummy,.5);
776 UInt_t nrows=tmeanROC->GetNrows();
777 for (UInt_t irow=0;irow<nrows;++irow){
778 UInt_t npads=tmeanROC->GetNPads(irow);
779 for (UInt_t ipad=0;ipad<npads;++ipad){
780 Int_t outlier=0,masked=0;
781 Float_t q=qmeanROC->GetValue(irow,ipad);
782 Float_t t=tmeanROC->GetValue(irow,ipad);
783 //masked channels are outliers
784 if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1;
785 //edge pads are outliers
786 if (ipad==0||ipad==npads-1) masked=1;
787 //channels with too large charge or timing deviation from the meadian are outliers
788 // if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1;
789 if (q<fPulQminLimit && !masked) outlier=1;
791 if ( !(q<10000000) || !(t<10000000)) outlier=1;
792 outROC->SetValue(irow,ipad,outlier+masked);
793 fNpulserOutliers+=outlier;
798 //_____________________________________________________________________________________
799 AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model)
802 // Create pad time0 object from pulser and/or CE data, depending on the selected model
803 // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser
804 // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser
805 // Model 2: use CE data and a combination CE fit + pulser in the outlier regions.
808 AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model));
809 // decide between different models
810 if (model==0||model==1){
812 if (model==1) ProcessPulser(vMean);
813 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
814 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
815 if (!rocPulTmean) continue;
816 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
817 AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
818 Float_t mean=rocPulTmean->GetMean(rocOut);
819 //treat case where a whole partition is masked
820 if (mean==0) mean=rocPulTmean->GetMean();
825 UInt_t nrows=rocTime0->GetNrows();
826 for (UInt_t irow=0;irow<nrows;++irow){
827 UInt_t npads=rocTime0->GetNPads(irow);
828 for (UInt_t ipad=0;ipad<npads;++ipad){
829 Float_t time=rocPulTmean->GetValue(irow,ipad);
830 //in case of an outlier pad use the mean of the altro values.
831 //This should be the most precise guess in that case.
832 if (rocOut->GetValue(irow,ipad)) {
833 time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
834 if (time==0) time=mean;
836 Float_t val=time-mean;
837 rocTime0->SetValue(irow,ipad,val);
841 } else if (model==2){
843 AliTPCCalPad outCE("outCE","outCE");
845 ProcessCEdata("(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC,nOut,&outCE);
846 AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++0++gy++0++(lx-134)++0",vA,vC);
847 // AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC);
848 if (!padFit) return 0;
849 padTime0->Add(fCETmean);
850 padTime0->Add(padFit,-1);
854 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
855 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
856 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
857 AliTPCCalROC *rocOutPul=fPulserOutlier->GetCalROC(isec);
858 AliTPCCalROC *rocOutCE=outCE.GetCalROC(isec);
859 rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
860 AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
861 Float_t mean=rocPulTmean->GetMean(rocOutPul);
862 if (mean==0) mean=rocPulTmean->GetMean();
863 UInt_t nrows=rocTime0->GetNrows();
864 for (UInt_t irow=0;irow<nrows;++irow){
865 UInt_t npads=rocTime0->GetNPads(irow);
866 for (UInt_t ipad=0;ipad<npads;++ipad){
867 Float_t timePulser=rocPulTmean->GetValue(irow,ipad)-mean;
868 if (rocOutCE->GetValue(irow,ipad)){
869 Float_t valOut=rocCEfit->GetValue(irow,ipad);
870 if (!rocOutPul->GetValue(irow,ipad)) valOut+=timePulser;
871 rocTime0->SetValue(irow,ipad,valOut);
882 //_____________________________________________________________________________________
883 Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut)
885 if (roc==0) return 0.;
886 const Int_t sector=roc->GetSector();
887 AliTPCROC *tpcRoc=AliTPCROC::Instance();
888 const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad);
892 //loop over a small range around the requested pad (+-10 rows/pads)
893 for (Int_t irow=row-10;irow<row+10;++irow){
894 if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue;
895 for (Int_t ipad=pad-10; ipad<pad+10;++ipad){
896 if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue;
897 const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad);
898 if (altroRoc!=altroCurr) continue;
899 if ( rocOut && rocOut->GetValue(irow,ipad) ) continue;
900 Float_t val=roc->GetValue(irow,ipad);
908 //_____________________________________________________________________________________
909 void AliTPCcalibDButil::SetRefFile(const char* filename)
912 // load cal pad objects form the reference file
914 TDirectory *currDir=gDirectory;
916 fRefPedestals=(AliTPCCalPad*)f.Get("Pedestals");
917 fRefPadNoise=(AliTPCCalPad*)f.Get("PadNoise");
919 fRefPulserTmean=(AliTPCCalPad*)f.Get("PulserTmean");
920 fRefPulserTrms=(AliTPCCalPad*)f.Get("PulserTrms");
921 fRefPulserQmean=(AliTPCCalPad*)f.Get("PulserQmean");
923 fRefCETmean=(AliTPCCalPad*)f.Get("CETmean");
924 fRefCETrms=(AliTPCCalPad*)f.Get("CETrms");
925 fRefCEQmean=(AliTPCCalPad*)f.Get("CEQmean");
927 // fRefALTROAcqStart=(AliTPCCalPad*)f.Get("ALTROAcqStart");
928 // fRefALTROZsThr=(AliTPCCalPad*)f.Get("ALTROZsThr");
929 // fRefALTROFPED=(AliTPCCalPad*)f.Get("ALTROFPED");
930 // fRefALTROAcqStop=(AliTPCCalPad*)f.Get("ALTROAcqStop");
931 fRefALTROMasked=(AliTPCCalPad*)f.Get("ALTROMasked");