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 <TGraphErrors.h>
35 #include <AliCDBStorage.h>
36 #include <AliDCSSensorArray.h>
37 #include <AliTPCSensorTempArray.h>
38 #include <AliDCSSensor.h>
40 #include <AliCDBEntry.h>
41 #include <AliCDBManager.h>
43 #include <AliSplineFit.h>
44 #include "AliTPCcalibDB.h"
45 #include "AliTPCCalPad.h"
46 #include "AliTPCCalROC.h"
47 #include "AliTPCROC.h"
48 #include "AliTPCmapper.h"
49 #include "AliTPCParam.h"
50 #include "AliTPCCalibRaw.h"
51 #include "AliTPCPreprocessorOnline.h"
52 #include "AliTPCdataQA.h"
54 #include "AliTPCcalibDButil.h"
55 #include "AliTPCCalibVdrift.h"
56 #include "AliMathBase.h"
57 #include "AliRelAlignerKalman.h"
59 const Float_t kAlmost0=1.e-30;
61 ClassImp(AliTPCcalibDButil)
62 AliTPCcalibDButil::AliTPCcalibDButil() :
70 fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")),
82 fRefPedestalMasked(0x0),
86 fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")),
87 fRefPulserMasked(0x0),
94 fRefALTROAcqStart(0x0),
95 fRefALTROAcqStop(0x0),
100 fMapper(new AliTPCmapper(0x0)),
101 fNpulserOutliers(-1),
103 fCETmaxLimitAbs(1.5),
104 fPulTmaxLimitAbs(1.5),
107 fRuns(0), // run list with OCDB info
108 fRunsStart(0), // start time for given run
109 fRunsStop(0) // stop time for given run
115 //_____________________________________________________________________________________
116 AliTPCcalibDButil::~AliTPCcalibDButil()
121 delete fPulserOutlier;
122 delete fRefPulserOutlier;
124 if (fRefPadNoise) delete fRefPadNoise;
125 if (fRefPedestals) delete fRefPedestals;
126 if (fRefPedestalMasked) delete fRefPedestalMasked;
127 if (fRefPulserTmean) delete fRefPulserTmean;
128 if (fRefPulserTrms) delete fRefPulserTrms;
129 if (fRefPulserQmean) delete fRefPulserQmean;
130 if (fRefPulserMasked) delete fRefPulserMasked;
131 if (fRefCETmean) delete fRefCETmean;
132 if (fRefCETrms) delete fRefCETrms;
133 if (fRefCEQmean) delete fRefCEQmean;
134 if (fRefCEMasked) delete fRefCEMasked;
135 if (fRefALTROFPED) delete fRefALTROFPED;
136 if (fRefALTROZsThr) delete fRefALTROZsThr;
137 if (fRefALTROAcqStart) delete fRefALTROAcqStart;
138 if (fRefALTROAcqStop) delete fRefALTROAcqStop;
139 if (fRefALTROMasked) delete fRefALTROMasked;
140 if (fRefCalibRaw) delete fRefCalibRaw;
141 if (fCurrentRefMap) delete fCurrentRefMap;
143 //_____________________________________________________________________________________
144 void AliTPCcalibDButil::UpdateFromCalibDB()
147 // Update pointers from calibDB
149 if (!fCalibDB) fCalibDB=AliTPCcalibDB::Instance();
150 fCalibDB->UpdateNonRec(); // load all infromation now
151 fPadNoise=fCalibDB->GetPadNoise();
152 fPedestals=fCalibDB->GetPedestals();
153 fPulserTmean=fCalibDB->GetPulserTmean();
154 fPulserTrms=fCalibDB->GetPulserTrms();
155 fPulserQmean=fCalibDB->GetPulserQmean();
156 fCETmean=fCalibDB->GetCETmean();
157 fCETrms=fCalibDB->GetCETrms();
158 fCEQmean=fCalibDB->GetCEQmean();
159 fALTROMasked=fCalibDB->GetALTROMasked();
160 fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
161 fCalibRaw=fCalibDB->GetCalibRaw();
162 fDataQA=fCalibDB->GetDataQA();
163 UpdatePulserOutlierMap();
164 // SetReferenceRun();
165 // UpdateRefDataFromOCDB();
167 //_____________________________________________________________________________________
168 void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
169 Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad * const outCE)
172 // Process the CE data for this run
173 // the return TVectorD arrays contian the results of the fit
174 // noutliersCE contains the number of pads marked as outliers,
175 // not including masked and edge pads
178 //retrieve CE and ALTRO data
180 TString fitString(fitFormula);
181 fitString.ReplaceAll("++","#");
182 Int_t ndim=fitString.CountChar('#')+2;
183 fitResultsA.ResizeTo(ndim);
184 fitResultsC.ResizeTo(ndim);
193 if (outCE) out=outCE;
194 else out=new AliTPCCalPad("outCE","outCE");
195 AliTPCCalROC *rocMasked=0x0;
196 //loop over all channels
197 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
198 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
199 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc);
200 AliTPCCalROC *rocOut=out->GetCalROC(iroc);
202 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
206 //add time offset to IROCs
207 if (iroc<AliTPCROC::Instance()->GetNInnerSector())
208 rocData->Add(fIrocTimeOffset);
210 UInt_t nrows=rocData->GetNrows();
211 for (UInt_t irow=0;irow<nrows;++irow){
212 UInt_t npads=rocData->GetNPads(irow);
213 for (UInt_t ipad=0;ipad<npads;++ipad){
214 rocOut->SetValue(irow,ipad,0);
215 //exclude masked pads
216 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
217 rocOut->SetValue(irow,ipad,1);
220 //exclude first two rows in IROC and last two rows in OROC
222 if (irow<2) rocOut->SetValue(irow,ipad,1);
224 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
227 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
228 Float_t valTmean=rocData->GetValue(irow,ipad);
229 //exclude values that are exactly 0
230 if ( !(TMath::Abs(valTmean)>kAlmost0) ) {
231 rocOut->SetValue(irow,ipad,1);
234 // exclude channels with too large variations
235 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
236 rocOut->SetValue(irow,ipad,1);
244 Float_t chi2Af,chi2Cf;
245 fCETmean->GlobalSidesFit(out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2Af,chi2Cf);
248 if (!outCE) delete out;
250 //_____________________________________________________________________________________
251 void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian,
252 TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian,
253 Float_t &driftTimeA, Float_t &driftTimeC )
256 // Calculate statistical information from the CE graphs for drift time and charge
260 vecTEntries.ResizeTo(72);
261 vecTMean.ResizeTo(72);
262 vecTRMS.ResizeTo(72);
263 vecTMedian.ResizeTo(72);
264 vecQEntries.ResizeTo(72);
265 vecQMean.ResizeTo(72);
266 vecQRMS.ResizeTo(72);
267 vecQMedian.ResizeTo(72);
278 TObjArray *arrT=fCalibDB->GetCErocTtime();
279 TObjArray *arrQ=fCalibDB->GetCErocQtime();
281 for (Int_t isec=0;isec<74;++isec){
282 TGraph *gr=(TGraph*)arrT->At(isec);
285 Int_t npoints = gr->GetN();
286 values.ResizeTo(npoints);
288 //skip first points, theres always some problems with finding the CE position
289 for (Int_t ipoint=4; ipoint<npoints; ipoint++){
290 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1020 ){
291 values[nused]=gr->GetY()[ipoint];
296 if (isec<72) vecTEntries[isec]= nused;
299 vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
300 vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
301 vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
302 } else if (isec==72){
303 driftTimeA=TMath::Median(nused,values.GetMatrixArray());
304 } else if (isec==73){
305 driftTimeC=TMath::Median(nused,values.GetMatrixArray());
311 for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){
312 TGraph *gr=(TGraph*)arrQ->At(isec);
315 Int_t npoints = gr->GetN();
316 values.ResizeTo(npoints);
318 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
319 if (gr->GetY()[ipoint]>10 && gr->GetY()[ipoint]<500 ){
320 values[nused]=gr->GetY()[ipoint];
325 vecQEntries[isec]= nused;
327 vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
328 vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
329 vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
335 //_____________________________________________________________________________________
336 void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
337 TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
338 Int_t &nonMaskedZero, Int_t &nNaN)
341 // process noise data
342 // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1],
343 // OROCs small pads [2] and OROCs large pads [3]
344 // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot)
345 // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error
348 //set proper size and reset
349 const UInt_t infoSize=4;
350 vNoiseMean.ResizeTo(infoSize);
351 vNoiseMeanSenRegions.ResizeTo(infoSize);
352 vNoiseRMS.ResizeTo(infoSize);
353 vNoiseRMSSenRegions.ResizeTo(infoSize);
355 vNoiseMeanSenRegions.Zero();
357 vNoiseRMSSenRegions.Zero();
361 TVectorD c(infoSize);
362 TVectorD cs(infoSize);
366 //retrieve noise and ALTRO data
367 if (!fPadNoise) return;
368 AliTPCCalROC *rocMasked=0x0;
369 //create IROC, OROC1, OROC2 and sensitive region masks
370 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
371 AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec);
372 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
373 UInt_t nrows=noiseROC->GetNrows();
374 for (UInt_t irow=0;irow<nrows;++irow){
375 UInt_t npads=noiseROC->GetNPads(irow);
376 for (UInt_t ipad=0;ipad<npads;++ipad){
377 //don't use masked channels;
378 if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
379 Float_t noiseVal=noiseROC->GetValue(irow,ipad);
381 if (noiseVal<kAlmost0) {
386 if ( !(noiseVal<10000000) ){
387 AliInfo(Form("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal));
391 Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
392 Int_t masksen=1; // sensitive pards are not masked (0)
393 if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive)
394 if (isec<AliTPCROC::Instance()->GetNInnerSector()){
396 if (irow>19&&irow<46){
397 if (TMath::Abs(cpad)<7) masksen=0; //IROC spot
400 vNoiseMean[type]+=noiseVal;
401 vNoiseRMS[type]+=noiseVal*noiseVal;
404 vNoiseMeanSenRegions[type]+=noiseVal;
405 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
410 //define sensive regions
411 if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive
413 Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad);
414 if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive
416 if ((Int_t)irow<par.GetNRowUp1()){
419 vNoiseMean[type]+=noiseVal;
420 vNoiseRMS[type]+=noiseVal*noiseVal;
423 vNoiseMeanSenRegions[type]+=noiseVal;
424 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
430 vNoiseMean[type]+=noiseVal;
431 vNoiseRMS[type]+=noiseVal*noiseVal;
434 vNoiseMeanSenRegions[type]+=noiseVal;
435 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
442 vNoiseMean[type]+=noiseVal;
443 vNoiseRMS[type]+=noiseVal*noiseVal;
446 vNoiseMeanSenRegions[type]+=noiseVal;
447 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
452 }//end loop sectors (rocs)
454 //calculate mean and RMS
455 const Double_t verySmall=0.0000000001;
456 for (UInt_t i=0;i<infoSize;++i){
463 AliInfo(Form("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]));
464 mean=vNoiseMean[i]/c[i];
466 rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
471 if (cs[i]>verySmall){
472 meanSen=vNoiseMeanSenRegions[i]/cs[i];
473 rmsSen=vNoiseRMSSenRegions[i];
474 rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen));
476 vNoiseMeanSenRegions[i]=meanSen;
477 vNoiseRMSSenRegions[i]=rmsSen;
481 //_____________________________________________________________________________________
482 void AliTPCcalibDButil::ProcessQAData(TVectorD &vQaOcc, TVectorD &vQaQtot,
488 // vQaOcc/Qtot/Qmax contains the Mean occupancy/Qtot/Qmax for each sector
492 const UInt_t infoSize = 72;
493 //reset counters to error number
494 vQaOcc.ResizeTo(infoSize);
496 vQaQtot.ResizeTo(infoSize);
498 vQaQmax.ResizeTo(infoSize);
501 //retrieve pulser and ALTRO data
505 AliInfo("No QA data");
508 if (fDataQA->GetEventCounter()<=0) {
510 AliInfo("No QA data");
511 return; // no data processed
516 TVectorD normOcc(infoSize);
517 TVectorD normQ(infoSize);
519 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
521 AliInfo(Form("Sector %d\n", isec));
522 AliTPCCalROC* occupancyROC = fDataQA->GetNoThreshold()->GetCalROC(isec);
523 AliTPCCalROC* nclusterROC = fDataQA->GetNLocalMaxima()->GetCalROC(isec);
524 AliTPCCalROC* qROC = fDataQA->GetMeanCharge()->GetCalROC(isec);
525 AliTPCCalROC* qmaxROC = fDataQA->GetMaxCharge()->GetCalROC(isec);
526 if (!occupancyROC) continue;
527 if (!nclusterROC) continue;
529 if (!qmaxROC) continue;
531 const UInt_t nchannels=occupancyROC->GetNchannels();
533 AliInfo(Form("Nchannels %d\n", nchannels));
535 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
537 vQaOcc[isec] += occupancyROC->GetValue(ichannel);
540 Float_t nClusters = nclusterROC->GetValue(ichannel);
541 normQ[isec] += nClusters;
542 vQaQtot[isec]+=nClusters*qROC->GetValue(ichannel);
543 vQaQmax[isec]+=nClusters*qmaxROC->GetValue(ichannel);
547 //calculate mean values
548 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
550 if (normOcc[isec]>0) vQaOcc[isec] /= normOcc[isec];
551 else vQaOcc[isec] = 0;
554 vQaQtot[isec] /= normQ[isec];
555 vQaQmax[isec] /= normQ[isec];
564 //_____________________________________________________________________________________
565 void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
568 // Process the Pulser information
569 // vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C
572 const UInt_t infoSize=4;
573 //reset counters to error number
574 vMeanTime.ResizeTo(infoSize);
577 TVectorD c(infoSize);
578 //retrieve pulser and ALTRO data
579 if (!fPulserTmean) return;
582 AliTPCCalROC *rocOut=0x0;
583 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
584 AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
585 if (!tmeanROC) continue;
586 rocOut=fPulserOutlier->GetCalROC(isec);
587 UInt_t nchannels=tmeanROC->GetNchannels();
588 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
589 if (rocOut && rocOut->GetValue(ichannel)) continue;
590 Float_t val=tmeanROC->GetValue(ichannel);
592 vMeanTime[type]+=val;
597 for (UInt_t itype=0; itype<infoSize; ++itype){
598 if (c[itype]>0) vMeanTime[itype]/=c[itype];
599 else vMeanTime[itype]=0;
602 //_____________________________________________________________________________________
603 void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked)
606 // Get Values from ALTRO configuration data
609 if (!fALTROMasked) return;
611 for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){
612 AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec);
613 for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){
614 if (rocMasked->GetValue(ichannel)) ++nMasked;
618 //_____________________________________________________________________________________
619 void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS)
622 // Proces Goofie values, return statistical information of the currently set goofieArray
623 // The meaning of the entries are given below
625 1 TPC_ANODE_I_A00_STAT
627 3 TPC_DVM_DriftVelocity
632 8 TPC_DVM_NumberOfSparks
633 9 TPC_DVM_PeakAreaFar
634 10 TPC_DVM_PeakAreaNear
635 11 TPC_DVM_PeakPosFar
636 12 TPC_DVM_PeakPosNear
642 18 TPC_DVM_TemperatureS1
646 vecEntries.ResizeTo(nsensors);
647 vecMedian.ResizeTo(nsensors);
648 vecMean.ResizeTo(nsensors);
649 vecRMS.ResizeTo(nsensors);
656 Double_t kEpsilon=0.0000000001;
657 Double_t kBig=100000000000.;
658 Int_t nsensors = fGoofieArray->NumSensors();
659 vecEntries.ResizeTo(nsensors);
660 vecMedian.ResizeTo(nsensors);
661 vecMean.ResizeTo(nsensors);
662 vecRMS.ResizeTo(nsensors);
664 for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){
665 AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor);
666 if (gsensor && gsensor->GetGraph()){
667 Int_t npoints = gsensor->GetGraph()->GetN();
669 values.ResizeTo(npoints);
671 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
672 if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon &&
673 TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){
674 values[nused]=gsensor->GetGraph()->GetY()[ipoint];
679 vecEntries[isensor]= nused;
681 vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray());
682 vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray());
683 vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray());
688 //_____________________________________________________________________________________
689 void AliTPCcalibDButil::ProcessPedestalVariations(TVectorF &pedestalDeviations)
692 // check the variations of the pedestal data to the reference pedestal data
693 // thresholds are 0.5, 1.0, 1.5 and 2 timebins respectively.
696 TVectorF vThres(npar); //thresholds
697 Int_t nActive=0; //number of active channels
699 //reset and set thresholds
700 pedestalDeviations.ResizeTo(npar);
701 for (Int_t i=0;i<npar;++i){
702 pedestalDeviations.GetMatrixArray()[i]=0;
703 vThres.GetMatrixArray()[i]=(i+1)*.5;
705 //check all needed data is available
706 if (!fRefPedestals || !fPedestals || !fALTROMasked || !fRefALTROMasked) return;
707 //loop over all channels
708 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
709 AliTPCCalROC *pROC=fPedestals->GetCalROC(isec);
710 AliTPCCalROC *pRefROC=fRefPedestals->GetCalROC(isec);
711 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
712 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
713 UInt_t nrows=mROC->GetNrows();
714 for (UInt_t irow=0;irow<nrows;++irow){
715 UInt_t npads=mROC->GetNPads(irow);
716 for (UInt_t ipad=0;ipad<npads;++ipad){
717 //don't use masked channels;
718 if (mROC ->GetValue(irow,ipad)) continue;
719 if (mRefROC->GetValue(irow,ipad)) continue;
720 Float_t deviation=TMath::Abs(pROC->GetValue(irow,ipad)-pRefROC->GetValue(irow,ipad));
721 for (Int_t i=0;i<npar;++i){
722 if (deviation>vThres[i])
723 ++pedestalDeviations.GetMatrixArray()[i];
730 for (Int_t i=0;i<npar;++i){
731 pedestalDeviations.GetMatrixArray()[i]/=nActive;
735 //_____________________________________________________________________________________
736 void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations)
739 // check the variations of the noise data to the reference noise data
740 // thresholds are 5, 10, 15 and 20 percent respectively.
743 TVectorF vThres(npar); //thresholds
744 Int_t nActive=0; //number of active channels
746 //reset and set thresholds
747 noiseDeviations.ResizeTo(npar);
748 for (Int_t i=0;i<npar;++i){
749 noiseDeviations.GetMatrixArray()[i]=0;
750 vThres.GetMatrixArray()[i]=(i+1)*.05;
752 //check all needed data is available
753 if (!fRefPadNoise || !fPadNoise || !fALTROMasked || !fRefALTROMasked) return;
754 //loop over all channels
755 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
756 AliTPCCalROC *nROC=fPadNoise->GetCalROC(isec);
757 AliTPCCalROC *nRefROC=fRefPadNoise->GetCalROC(isec);
758 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
759 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
760 UInt_t nrows=mROC->GetNrows();
761 for (UInt_t irow=0;irow<nrows;++irow){
762 UInt_t npads=mROC->GetNPads(irow);
763 for (UInt_t ipad=0;ipad<npads;++ipad){
764 //don't use masked channels;
765 if (mROC ->GetValue(irow,ipad)) continue;
766 if (mRefROC->GetValue(irow,ipad)) continue;
767 if (nRefROC->GetValue(irow,ipad)==0) continue;
768 Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
769 for (Int_t i=0;i<npar;++i){
770 if (deviation>vThres[i])
771 ++noiseDeviations.GetMatrixArray()[i];
778 for (Int_t i=0;i<npar;++i){
779 noiseDeviations.GetMatrixArray()[i]/=nActive;
783 //_____________________________________________________________________________________
784 void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Float_t &varQMean,
785 Int_t &npadsOutOneTB, Int_t &npadsOffAdd)
788 // check the variations of the pulserQmean data to the reference pulserQmean data: pulserQdeviations
789 // thresholds are .5, 1, 5 and 10 percent respectively.
793 TVectorF vThres(npar); //thresholds
794 Int_t nActive=0; //number of active channels
796 //reset and set thresholds
797 pulserQdeviations.ResizeTo(npar);
798 for (Int_t i=0;i<npar;++i){
799 pulserQdeviations.GetMatrixArray()[i]=0;
804 vThres.GetMatrixArray()[0]=.005;
805 vThres.GetMatrixArray()[1]=.01;
806 vThres.GetMatrixArray()[2]=.05;
807 vThres.GetMatrixArray()[3]=.1;
808 //check all needed data is available
809 if (!fRefPulserTmean || !fPulserTmean || !fPulserQmean || !fRefPulserQmean || !fALTROMasked || !fRefALTROMasked) return;
811 UpdateRefPulserOutlierMap();
812 //loop over all channels
813 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
814 AliTPCCalROC *pqROC=fPulserQmean->GetCalROC(isec);
815 AliTPCCalROC *pqRefROC=fRefPulserQmean->GetCalROC(isec);
816 AliTPCCalROC *ptROC=fPulserTmean->GetCalROC(isec);
817 // AliTPCCalROC *ptRefROC=fRefPulserTmean->GetCalROC(isec);
818 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
819 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
820 AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
821 Float_t ptmean=ptROC->GetMean(oROC);
822 UInt_t nrows=mROC->GetNrows();
823 for (UInt_t irow=0;irow<nrows;++irow){
824 UInt_t npads=mROC->GetNPads(irow);
825 for (UInt_t ipad=0;ipad<npads;++ipad){
826 //don't use masked channels;
827 if (mROC ->GetValue(irow,ipad)) continue;
828 if (mRefROC->GetValue(irow,ipad)) continue;
829 //don't user edge pads
830 if (ipad==0||ipad==npads-1) continue;
832 Float_t pq=pqROC->GetValue(irow,ipad);
833 Float_t pqRef=pqRefROC->GetValue(irow,ipad);
834 Float_t pt=ptROC->GetValue(irow,ipad);
835 // Float_t ptRef=ptRefROC->GetValue(irow,ipad);
837 Float_t deviation=TMath::Abs(pq/pqRef-1);
838 for (Int_t i=0;i<npar;++i){
839 if (deviation>vThres[i])
840 ++pulserQdeviations.GetMatrixArray()[i];
842 if (pqRef>11&&pq<11) ++npadsOffAdd;
845 if (TMath::Abs(pt-ptmean)>1) ++npadsOutOneTB;
851 for (Int_t i=0;i<npar;++i){
852 pulserQdeviations.GetMatrixArray()[i]/=nActive;
857 //_____________________________________________________________________________________
858 void AliTPCcalibDButil::UpdatePulserOutlierMap()
861 // Update the outlier map of the pulser data
863 PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
865 //_____________________________________________________________________________________
866 void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
869 // Update the outlier map of the pulser reference data
871 PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
873 //_____________________________________________________________________________________
874 void AliTPCcalibDButil::PulserOutlierMap(AliTPCCalPad *pulOut, const AliTPCCalPad *pulT, const AliTPCCalPad *pulQ)
877 // Create a map that contains outliers from the Pulser calibration data.
878 // The outliers include masked channels, edge pads and pads with
879 // too large timing and charge variations.
880 // fNpulserOutliers is the number of outliers in the Pulser calibration data.
881 // those do not contain masked and edge pads
885 pulOut->Multiply(0.);
889 AliTPCCalROC *rocMasked=0x0;
893 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
894 AliTPCCalROC *tmeanROC=pulT->GetCalROC(isec);
895 AliTPCCalROC *qmeanROC=pulQ->GetCalROC(isec);
896 AliTPCCalROC *outROC=pulOut->GetCalROC(isec);
897 if (!tmeanROC||!qmeanROC) {
898 //reset outliers in this ROC
899 outROC->Multiply(0.);
902 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
904 // Float_t qmedian=qmeanROC->GetLTM(&dummy,.5);
905 // Float_t tmedian=tmeanROC->GetLTM(&dummy,.5);
906 UInt_t nrows=tmeanROC->GetNrows();
907 for (UInt_t irow=0;irow<nrows;++irow){
908 UInt_t npads=tmeanROC->GetNPads(irow);
909 for (UInt_t ipad=0;ipad<npads;++ipad){
910 Int_t outlier=0,masked=0;
911 Float_t q=qmeanROC->GetValue(irow,ipad);
912 Float_t t=tmeanROC->GetValue(irow,ipad);
913 //masked channels are outliers
914 if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1;
915 //edge pads are outliers
916 if (ipad==0||ipad==npads-1) masked=1;
917 //channels with too large charge or timing deviation from the meadian are outliers
918 // if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1;
919 if (q<fPulQminLimit && !masked) outlier=1;
921 if ( !(q<10000000) || !(t<10000000)) outlier=1;
922 outROC->SetValue(irow,ipad,outlier+masked);
923 fNpulserOutliers+=outlier;
928 //_____________________________________________________________________________________
929 AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Double_t &gyC, Double_t &chi2A, Double_t &chi2C )
932 // Create pad time0 object from pulser and/or CE data, depending on the selected model
933 // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser
934 // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser
935 // Model 2: use CE data and a combination CE fit + pulser in the outlier regions.
937 // In case model 2 is invoked - gy arival time gradient is also returned
941 AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model));
942 // decide between different models
943 if (model==0||model==1){
945 if (model==1) ProcessPulser(vMean);
946 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
947 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
948 if (!rocPulTmean) continue;
949 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
950 AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
951 Float_t mean=rocPulTmean->GetMean(rocOut);
952 //treat case where a whole partition is masked
953 if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
958 UInt_t nrows=rocTime0->GetNrows();
959 for (UInt_t irow=0;irow<nrows;++irow){
960 UInt_t npads=rocTime0->GetNPads(irow);
961 for (UInt_t ipad=0;ipad<npads;++ipad){
962 Float_t time=rocPulTmean->GetValue(irow,ipad);
963 //in case of an outlier pad use the mean of the altro values.
964 //This should be the most precise guess in that case.
965 if (rocOut->GetValue(irow,ipad)) {
966 time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
967 if ( TMath::Abs(time)<kAlmost0 ) time=mean;
969 Float_t val=time-mean;
970 rocTime0->SetValue(irow,ipad,val);
974 } else if (model==2){
975 Double_t pgya,pgyc,pchi2a,pchi2c;
976 AliTPCCalPad * padPulser = CreatePadTime0(1,pgya,pgyc,pchi2a,pchi2c);
977 fCETmean->Add(padPulser,-1.);
979 AliTPCCalPad outCE("outCE","outCE");
981 ProcessCEdata("(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)++(ly/lx)^2",vA,vC,nOut,chi2A, chi2C,&outCE);
982 AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++0++gy++0++(lx-134)++0++0",vA,vC);
983 // AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC);
984 if (!padFit) { delete padPulser; return 0;}
987 fCETmean->Add(padPulser,1.);
988 padTime0->Add(fCETmean);
989 padTime0->Add(padFit,-1);
994 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
995 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
996 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
997 AliTPCCalROC *rocOutPul=fPulserOutlier->GetCalROC(isec);
998 AliTPCCalROC *rocOutCE=outCE.GetCalROC(isec);
999 rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
1000 AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
1001 Float_t mean=rocPulTmean->GetMean(rocOutPul);
1002 if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
1003 UInt_t nrows=rocTime0->GetNrows();
1004 for (UInt_t irow=0;irow<nrows;++irow){
1005 UInt_t npads=rocTime0->GetNPads(irow);
1006 for (UInt_t ipad=0;ipad<npads;++ipad){
1007 Float_t timePulser=rocPulTmean->GetValue(irow,ipad)-mean;
1008 if (rocOutCE->GetValue(irow,ipad)){
1009 Float_t valOut=rocCEfit->GetValue(irow,ipad);
1010 if (!rocOutPul->GetValue(irow,ipad)) valOut+=timePulser;
1011 rocTime0->SetValue(irow,ipad,valOut);
1019 Double_t median = padTime0->GetMedian();
1020 padTime0->Add(-median); // normalize to median
1023 //_____________________________________________________________________________________
1024 Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *const rocOut)
1027 // GetMeanAlto information
1029 if (roc==0) return 0.;
1030 const Int_t sector=roc->GetSector();
1031 AliTPCROC *tpcRoc=AliTPCROC::Instance();
1032 const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad);
1036 //loop over a small range around the requested pad (+-10 rows/pads)
1037 for (Int_t irow=row-10;irow<row+10;++irow){
1038 if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue;
1039 for (Int_t ipad=pad-10; ipad<pad+10;++ipad){
1040 if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue;
1041 const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad);
1042 if (altroRoc!=altroCurr) continue;
1043 if ( rocOut && rocOut->GetValue(irow,ipad) ) continue;
1044 Float_t val=roc->GetValue(irow,ipad);
1052 //_____________________________________________________________________________________
1053 void AliTPCcalibDButil::SetRefFile(const char* filename)
1056 // load cal pad objects form the reference file
1058 TDirectory *currDir=gDirectory;
1060 fRefPedestals=(AliTPCCalPad*)f.Get("Pedestals");
1061 fRefPadNoise=(AliTPCCalPad*)f.Get("PadNoise");
1063 fRefPulserTmean=(AliTPCCalPad*)f.Get("PulserTmean");
1064 fRefPulserTrms=(AliTPCCalPad*)f.Get("PulserTrms");
1065 fRefPulserQmean=(AliTPCCalPad*)f.Get("PulserQmean");
1067 fRefCETmean=(AliTPCCalPad*)f.Get("CETmean");
1068 fRefCETrms=(AliTPCCalPad*)f.Get("CETrms");
1069 fRefCEQmean=(AliTPCCalPad*)f.Get("CEQmean");
1071 // fRefALTROAcqStart=(AliTPCCalPad*)f.Get("ALTROAcqStart");
1072 // fRefALTROZsThr=(AliTPCCalPad*)f.Get("ALTROZsThr");
1073 // fRefALTROFPED=(AliTPCCalPad*)f.Get("ALTROFPED");
1074 // fRefALTROAcqStop=(AliTPCCalPad*)f.Get("ALTROAcqStop");
1075 fRefALTROMasked=(AliTPCCalPad*)f.Get("ALTROMasked");
1079 //_____________________________________________________________________________________
1080 void AliTPCcalibDButil::UpdateRefDataFromOCDB()
1083 // set reference data from OCDB Reference map
1086 AliWarning("Referenc map not set!");
1091 AliCDBEntry* entry = 0x0;
1092 Bool_t hasAnyChanged=kFALSE;
1095 cdbPath="TPC/Calib/Pedestals";
1096 if (HasRefChanged(cdbPath.Data())){
1097 hasAnyChanged=kTRUE;
1098 //delete old entries
1099 if (fRefPedestals) delete fRefPedestals;
1100 if (fRefPedestalMasked) delete fRefPedestalMasked;
1101 fRefPedestals=fRefPedestalMasked=0x0;
1103 entry=GetRefEntry(cdbPath.Data());
1105 entry->SetOwner(kTRUE);
1106 fRefPedestals=GetRefCalPad(entry);
1108 fRefPedestalMasked=GetAltroMasked(cdbPath, "MaskedPedestals");
1113 cdbPath="TPC/Calib/PadNoise";
1114 if (HasRefChanged(cdbPath.Data())){
1115 hasAnyChanged=kTRUE;
1117 if (fRefPadNoise) delete fRefPadNoise;
1120 entry=GetRefEntry(cdbPath.Data());
1122 entry->SetOwner(kTRUE);
1123 fRefPadNoise=GetRefCalPad(entry);
1129 cdbPath="TPC/Calib/Pulser";
1130 if (HasRefChanged(cdbPath.Data())){
1131 hasAnyChanged=kTRUE;
1132 //delete old entries
1133 if (fRefPulserTmean) delete fRefPulserTmean;
1134 if (fRefPulserTrms) delete fRefPulserTrms;
1135 if (fRefPulserQmean) delete fRefPulserQmean;
1136 if (fRefPulserMasked) delete fRefPulserMasked;
1137 fRefPulserTmean=fRefPulserTrms=fRefPulserQmean=fRefPulserMasked=0x0;
1139 entry=GetRefEntry(cdbPath.Data());
1141 entry->SetOwner(kTRUE);
1142 fRefPulserTmean=GetRefCalPad(entry,"PulserTmean");
1143 fRefPulserTrms=GetRefCalPad(entry,"PulserTrms");
1144 fRefPulserQmean=GetRefCalPad(entry,"PulserQmean");
1146 fRefPulserMasked=GetAltroMasked(cdbPath, "MaskedPulser");
1151 cdbPath="TPC/Calib/CE";
1152 if (HasRefChanged(cdbPath.Data())){
1153 hasAnyChanged=kTRUE;
1154 //delete old entries
1155 if (fRefCETmean) delete fRefCETmean;
1156 if (fRefCETrms) delete fRefCETrms;
1157 if (fRefCEQmean) delete fRefCEQmean;
1158 if (fRefCEMasked) delete fRefCEMasked;
1159 fRefCETmean=fRefCETrms=fRefCEQmean=fRefCEMasked=0x0;
1161 entry=GetRefEntry(cdbPath.Data());
1163 entry->SetOwner(kTRUE);
1164 fRefCETmean=GetRefCalPad(entry,"CETmean");
1165 fRefCETrms=GetRefCalPad(entry,"CETrms");
1166 fRefCEQmean=GetRefCalPad(entry,"CEQmean");
1168 fRefCEMasked=GetAltroMasked(cdbPath, "MaskedCE");
1173 cdbPath="TPC/Calib/AltroConfig";
1174 if (HasRefChanged(cdbPath.Data())){
1175 hasAnyChanged=kTRUE;
1176 //delete old entries
1177 if (fRefALTROFPED) delete fRefALTROFPED;
1178 if (fRefALTROZsThr) delete fRefALTROZsThr;
1179 if (fRefALTROAcqStart) delete fRefALTROAcqStart;
1180 if (fRefALTROAcqStop) delete fRefALTROAcqStop;
1181 if (fRefALTROMasked) delete fRefALTROMasked;
1182 fRefALTROFPED=fRefALTROZsThr=fRefALTROAcqStart=fRefALTROAcqStop=fRefALTROMasked=0x0;
1184 entry=GetRefEntry(cdbPath.Data());
1186 entry->SetOwner(kTRUE);
1187 fRefALTROFPED=GetRefCalPad(entry,"FPED");
1188 fRefALTROZsThr=GetRefCalPad(entry,"ZsThr");
1189 fRefALTROAcqStart=GetRefCalPad(entry,"AcqStart");
1190 fRefALTROAcqStop=GetRefCalPad(entry,"AcqStop");
1191 fRefALTROMasked=GetRefCalPad(entry,"Masked");
1198 cdbPath="TPC/Calib/Raw";
1199 if (HasRefChanged(cdbPath.Data())){
1200 hasAnyChanged=kTRUE;
1202 if (fRefCalibRaw) delete fRefCalibRaw;
1204 entry=GetRefEntry(cdbPath.Data());
1206 entry->SetOwner(kTRUE);
1207 TObjArray *arr=(TObjArray*)entry->GetObject();
1209 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
1211 fRefCalibRaw=(AliTPCCalibRaw*)arr->At(0)->Clone();
1218 cdbPath="TPC/Calib/QA";
1219 if (HasRefChanged(cdbPath.Data())){
1220 hasAnyChanged=kTRUE;
1222 if (fRefDataQA) delete fRefDataQA;
1224 entry=GetRefEntry(cdbPath.Data());
1226 entry->SetOwner(kTRUE);
1227 fRefDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
1229 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
1231 fRefDataQA=(AliTPCdataQA*)fRefDataQA->Clone();
1238 //update current reference maps
1240 if (fCurrentRefMap) delete fCurrentRefMap;
1241 fCurrentRefMap=(TMap*)fRefMap->Clone();
1244 //_____________________________________________________________________________________
1245 AliTPCCalPad* AliTPCcalibDButil::GetRefCalPad(AliCDBEntry *entry, const char* objName)
1248 // TObjArray object type case
1249 // find 'objName' in 'arr' cast is to a calPad and store it in 'pad'
1251 AliTPCCalPad *pad=0x0;
1252 TObjArray *arr=(TObjArray*)entry->GetObject();
1254 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
1257 pad=(AliTPCCalPad*)arr->FindObject(objName);
1259 AliError(Form("Could not get '%s' from TObjArray in entry '%s'\nPlease check!!!",objName,entry->GetId().GetPath().Data()));
1262 return (AliTPCCalPad*)pad->Clone();
1264 //_____________________________________________________________________________________
1265 AliTPCCalPad* AliTPCcalibDButil::GetRefCalPad(AliCDBEntry *entry)
1268 // AliTPCCalPad object type case
1269 // cast object to a calPad and store it in 'pad'
1271 AliTPCCalPad *pad=(AliTPCCalPad*)entry->GetObject();
1273 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
1276 pad=(AliTPCCalPad*)pad->Clone();
1279 //_____________________________________________________________________________________
1280 AliTPCCalPad* AliTPCcalibDButil::GetAltroMasked(const char* cdbPath, const char* name)
1283 // set altro masked channel map for 'cdbPath'
1285 AliTPCCalPad* pad=0x0;
1286 const Int_t run=GetReferenceRun(cdbPath);
1288 AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
1291 AliCDBEntry *entry=AliCDBManager::Instance()->Get("TPC/Calib/AltroConfig", run);
1293 AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
1296 pad=GetRefCalPad(entry,"Masked");
1297 if (pad) pad->SetNameTitle(name,name);
1298 entry->SetOwner(kTRUE);
1302 //_____________________________________________________________________________________
1303 void AliTPCcalibDButil::SetReferenceRun(Int_t run){
1305 // Get Reference map
1307 if (run<0) run=fCalibDB->GetRun();
1308 TString cdbPath="TPC/Calib/Ref";
1309 AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath.Data(), run);
1311 AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath.Data()));
1315 entry->SetOwner(kTRUE);
1316 fRefMap=(TMap*)(entry->GetObject());
1317 AliCDBId &id=entry->GetId();
1318 fRefValidity.Form("%d_%d_v%d_s%d",id.GetFirstRun(),id.GetLastRun(),id.GetVersion(),id.GetSubVersion());
1320 //_____________________________________________________________________________________
1321 Bool_t AliTPCcalibDButil::HasRefChanged(const char *cdbPath)
1324 // check whether a reference cdb entry has changed
1326 if (!fCurrentRefMap) return kTRUE;
1327 if (GetReferenceRun(cdbPath)!=GetCurrentReferenceRun(cdbPath)) return kTRUE;
1330 //_____________________________________________________________________________________
1331 AliCDBEntry* AliTPCcalibDButil::GetRefEntry(const char* cdbPath)
1334 // get the reference AliCDBEntry for 'cdbPath'
1336 const Int_t run=GetReferenceRun(cdbPath);
1338 AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
1341 AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath, run);
1343 AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
1348 //_____________________________________________________________________________________
1349 Int_t AliTPCcalibDButil::GetCurrentReferenceRun(const char* type) const {
1351 // Get reference run number for the specified OCDB path
1353 if (!fCurrentRefMap) return -2;
1354 TObjString *str=dynamic_cast<TObjString*>(fCurrentRefMap->GetValue(type));
1355 if (!str) return -2;
1356 return (Int_t)str->GetString().Atoi();
1358 //_____________________________________________________________________________________
1359 Int_t AliTPCcalibDButil::GetReferenceRun(const char* type) const{
1361 // Get reference run number for the specified OCDB path
1363 if (!fRefMap) return -1;
1364 TObjString *str=dynamic_cast<TObjString*>(fRefMap->GetValue(type));
1365 if (!str) return -1;
1366 return (Int_t)str->GetString().Atoi();
1368 //_____________________________________________________________________________________
1369 AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad * const ceOut, Float_t minSignal, Float_t cutTrmsMin, Float_t cutTrmsMax, Float_t cutMaxDistT){
1371 // Author: marian.ivanov@cern.ch
1373 // Create outlier map for CE study
1375 // Return value - outlyer map
1376 // noutlyersCE - number of outlyers
1377 // minSignal - minimal total Q signal
1378 // cutRMSMin - minimal width of the signal in respect to the median
1379 // cutRMSMax - maximal width of the signal in respect to the median
1380 // cutMaxDistT - maximal deviation from time median per chamber
1382 // Outlyers criteria:
1383 // 0. Exclude masked pads
1384 // 1. Exclude first two rows in IROC and last two rows in OROC
1385 // 2. Exclude edge pads
1386 // 3. Exclude channels with too large variations
1387 // 4. Exclude pads with too small signal
1388 // 5. Exclude signal with outlyers RMS
1389 // 6. Exclude channels to far from the chamber median
1391 //create outlier map
1392 AliTPCCalPad *out=ceOut;
1393 if (!out) out= new AliTPCCalPad("outCE","outCE");
1394 AliTPCCalROC *rocMasked=0x0;
1395 if (!fCETmean) return 0;
1396 if (!fCETrms) return 0;
1397 if (!fCEQmean) return 0;
1399 //loop over all channels
1401 Double_t rmsMedian = fCETrms->GetMedian();
1402 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1403 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
1404 if (!rocData) continue;
1405 if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
1406 AliTPCCalROC *rocOut = out->GetCalROC(iroc);
1407 AliTPCCalROC *rocCEQ = fCEQmean->GetCalROC(iroc);
1408 AliTPCCalROC *rocCETrms = fCETrms->GetCalROC(iroc);
1409 Double_t trocMedian = rocData->GetMedian();
1411 if (!rocData || !rocCEQ || !rocCETrms || !rocData) {
1412 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
1418 UInt_t nrows=rocData->GetNrows();
1419 for (UInt_t irow=0;irow<nrows;++irow){
1420 UInt_t npads=rocData->GetNPads(irow);
1421 for (UInt_t ipad=0;ipad<npads;++ipad){
1422 rocOut->SetValue(irow,ipad,0);
1423 Float_t valTmean=rocData->GetValue(irow,ipad);
1424 Float_t valQmean=rocCEQ->GetValue(irow,ipad);
1425 Float_t valTrms =rocCETrms->GetValue(irow,ipad);
1426 //0. exclude masked pads
1427 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
1428 rocOut->SetValue(irow,ipad,1);
1431 //1. exclude first two rows in IROC and last two rows in OROC
1433 if (irow<2) rocOut->SetValue(irow,ipad,1);
1435 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
1437 //2. exclude edge pads
1438 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
1439 //exclude values that are exactly 0
1440 if ( TMath::Abs(valTmean)<kAlmost0) {
1441 rocOut->SetValue(irow,ipad,1);
1444 //3. exclude channels with too large variations
1445 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
1446 rocOut->SetValue(irow,ipad,1);
1450 //4. exclude channels with too small signal
1451 if (valQmean<minSignal) {
1452 rocOut->SetValue(irow,ipad,1);
1456 //5. exclude channels with too small rms
1457 if (valTrms<cutTrmsMin*rmsMedian || valTrms>cutTrmsMax*rmsMedian){
1458 rocOut->SetValue(irow,ipad,1);
1462 //6. exclude channels to far from the chamber median
1463 if (TMath::Abs(valTmean-trocMedian)>cutMaxDistT){
1464 rocOut->SetValue(irow,ipad,1);
1475 AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad * const pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
1477 // Author: marian.ivanov@cern.ch
1479 // Create outlier map for Pulser
1481 // Return value - outlyer map
1482 // noutlyersPulser - number of outlyers
1483 // cutTime - absolute cut - distance to the median of chamber
1484 // cutnRMSQ - nsigma cut from median q distribution per chamber
1485 // cutnRMSrms - nsigma cut from median rms distribution
1486 // Outlyers criteria:
1487 // 0. Exclude masked pads
1488 // 1. Exclude time outlyers (default 3 time bins)
1489 // 2. Exclude q outlyers (default 5 sigma)
1490 // 3. Exclude rms outlyers (default 5 sigma)
1492 AliTPCCalPad *out=pulserOut;
1493 if (!out) out= new AliTPCCalPad("outPulser","outPulser");
1494 AliTPCCalROC *rocMasked=0x0;
1495 if (!fPulserTmean) return 0;
1496 if (!fPulserTrms) return 0;
1497 if (!fPulserQmean) return 0;
1499 //loop over all channels
1501 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1502 if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
1503 AliTPCCalROC *rocData = fPulserTmean->GetCalROC(iroc);
1504 AliTPCCalROC *rocOut = out->GetCalROC(iroc);
1505 AliTPCCalROC *rocPulserQ = fPulserQmean->GetCalROC(iroc);
1506 AliTPCCalROC *rocPulserTrms = fPulserTrms->GetCalROC(iroc);
1508 Double_t rocMedianT = rocData->GetMedian();
1509 Double_t rocMedianQ = rocPulserQ->GetMedian();
1510 Double_t rocRMSQ = rocPulserQ->GetRMS();
1511 Double_t rocMedianTrms = rocPulserTrms->GetMedian();
1512 Double_t rocRMSTrms = rocPulserTrms->GetRMS();
1513 for (UInt_t ichannel=0;ichannel<rocData->GetNchannels();++ichannel){
1514 rocOut->SetValue(ichannel,0);
1515 Float_t valTmean=rocData->GetValue(ichannel);
1516 Float_t valQmean=rocPulserQ->GetValue(ichannel);
1517 Float_t valTrms =rocPulserTrms->GetValue(ichannel);
1518 Float_t valMasked =0;
1519 if (rocMasked) valMasked = rocMasked->GetValue(ichannel);
1521 if (valMasked>0.5) isOut=1;
1522 if (TMath::Abs(valTmean-rocMedianT)>cutTime) isOut=1;
1523 if (TMath::Abs(valQmean-rocMedianQ)>cutnRMSQ*rocRMSQ) isOut=1;
1524 if (TMath::Abs(valTrms-rocMedianTrms)>cutnRMSrms*rocRMSTrms) isOut=1;
1525 rocOut->SetValue(ichannel,isOut);
1526 if (isOut) noutliersPulser++;
1533 AliTPCCalPad *AliTPCcalibDButil::CreatePadTime0CE(TVectorD &fitResultsA, TVectorD&fitResultsC, Int_t &nOut, Double_t &chi2A, Double_t &chi2C, const char *dumpfile){
1535 // Author : Marian Ivanov
1536 // Create pad time0 correction map using information from the CE and from pulser
1539 // Return PadTime0 to be used for time0 relative alignment
1540 // if dump file specified intermediat results are dumped to the fiel and can be visualized
1541 // using $ALICE_ROOT/TPC/script/gui application
1543 // fitResultsA - fitParameters A side
1544 // fitResultsC - fitParameters C side
1545 // chi2A - chi2/ndf for A side (assuming error 1 time bin)
1546 // chi2C - chi2/ndf for C side (assuming error 1 time bin)
1550 // 1. Find outlier map for CE
1551 // 2. Find outlier map for Pulser
1552 // 3. Replace outlier by median at given sector (median without outliers)
1553 // 4. Substract from the CE data pulser
1554 // 5. Fit the CE with formula
1555 // 5.1) (IROC-OROC) offset
1559 // 5.5) (IROC-OROC)*(lx-xmid)
1561 // 6. Substract gy fit dependence from the CE data
1562 // 7. Add pulser back to CE data
1563 // 8. Replace outliers by fit value - median of diff per given chamber -GY fit
1564 // 9. return CE data
1566 // Time0 <= padCE = padCEin -padCEfitGy - if not outlier
1567 // Time0 <= padCE = padFitAll-padCEfitGy - if outlier
1570 const char *formulaIn="(-1.+2.*(sector<36))*0.5++gx++gy++(lx-134.)++(-1.+2.*(sector<36))*0.5*(lx-134)++((ly/lx)^2/(0.1763)^2)";
1571 // output for fit formula
1572 const char *formulaAll="1++(-1.+2.*(sector<36))*0.5++gx++gy++(lx-134.)++(-1.+2.*(sector<36))*0.5*(lx-134)++((ly/lx)^2/(0.1763)^2)";
1573 // gy part of formula
1574 const char *formulaOut="0++0*(-1.+2.*(sector<36))*0.5++0*gx++gy++0*(lx-134.)++0*(-1.+2.*(sector<36))*0.5*(lx-134)++0*((ly/lx)^2/(0.1763)^2)";
1577 if (!fCETmean) return 0;
1578 Double_t pgya,pgyc,pchi2a,pchi2c;
1579 AliTPCCalPad * padPulserOut = CreatePulserOutlyerMap(nOut);
1580 AliTPCCalPad * padCEOut = CreateCEOutlyerMap(nOut);
1582 AliTPCCalPad * padPulser = CreatePadTime0(1,pgya,pgyc,pchi2a,pchi2c);
1583 AliTPCCalPad * padCE = new AliTPCCalPad(*fCETmean);
1584 AliTPCCalPad * padCEIn = new AliTPCCalPad(*fCETmean);
1585 AliTPCCalPad * padOut = new AliTPCCalPad("padOut","padOut");
1586 padPulser->SetName("padPulser");
1587 padPulserOut->SetName("padPulserOut");
1588 padCE->SetName("padCE");
1589 padCEIn->SetName("padCEIn");
1590 padCEOut->SetName("padCEOut");
1591 padOut->SetName("padOut");
1594 // make combined outlyers map
1595 // and replace outlyers in maps with median for chamber
1597 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1598 AliTPCCalROC * rocOut = padOut->GetCalROC(iroc);
1599 AliTPCCalROC * rocPulser = padPulser->GetCalROC(iroc);
1600 AliTPCCalROC * rocPulserOut = padPulserOut->GetCalROC(iroc);
1601 AliTPCCalROC * rocCEOut = padCEOut->GetCalROC(iroc);
1602 AliTPCCalROC * rocCE = padCE->GetCalROC(iroc);
1603 Double_t ceMedian = rocCE->GetMedian(rocCEOut);
1604 Double_t pulserMedian = rocPulser->GetMedian(rocCEOut);
1605 for (UInt_t ichannel=0;ichannel<rocOut->GetNchannels();++ichannel){
1606 if (rocPulserOut->GetValue(ichannel)>0) {
1607 rocPulser->SetValue(ichannel,pulserMedian);
1608 rocOut->SetValue(ichannel,1);
1610 if (rocCEOut->GetValue(ichannel)>0) {
1611 rocCE->SetValue(ichannel,ceMedian);
1612 rocOut->SetValue(ichannel,1);
1617 // remove pulser time 0
1619 padCE->Add(padPulser,-1);
1624 Float_t chi2Af,chi2Cf;
1625 padCE->GlobalSidesFit(padOut,formulaIn,fitResultsA,fitResultsC,dummy,dummy,chi2Af,chi2Cf);
1629 AliTPCCalPad *padCEFitGY=AliTPCCalPad::CreateCalPadFit(formulaOut,fitResultsA,fitResultsC);
1630 padCEFitGY->SetName("padCEFitGy");
1632 AliTPCCalPad *padCEFit =AliTPCCalPad::CreateCalPadFit(formulaAll,fitResultsA,fitResultsC);
1633 padCEFit->SetName("padCEFit");
1635 AliTPCCalPad* padCEDiff = new AliTPCCalPad(*padCE);
1636 padCEDiff->SetName("padCEDiff");
1637 padCEDiff->Add(padCEFit,-1.);
1640 padCE->Add(padCEFitGY,-1.);
1642 padCE->Add(padPulser,1.);
1643 Double_t padmedian = padCE->GetMedian();
1644 padCE->Add(-padmedian); // normalize to median
1646 // Replace outliers by fit value - median of diff per given chamber -GY fit
1648 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1649 AliTPCCalROC * rocOut = padOut->GetCalROC(iroc);
1650 AliTPCCalROC * rocCE = padCE->GetCalROC(iroc);
1651 AliTPCCalROC * rocCEFit = padCEFit->GetCalROC(iroc);
1652 AliTPCCalROC * rocCEFitGY = padCEFitGY->GetCalROC(iroc);
1653 AliTPCCalROC * rocCEDiff = padCEDiff->GetCalROC(iroc);
1655 Double_t diffMedian = rocCEDiff->GetMedian(rocOut);
1656 for (UInt_t ichannel=0;ichannel<rocOut->GetNchannels();++ichannel){
1657 if (rocOut->GetValue(ichannel)==0) continue;
1658 Float_t value=rocCEFit->GetValue(ichannel)-rocCEFitGY->GetValue(ichannel)-diffMedian-padmedian;
1659 rocCE->SetValue(ichannel,value);
1665 //dump to the file - result can be visualized
1666 AliTPCPreprocessorOnline preprocesor;
1667 preprocesor.AddComponent(new AliTPCCalPad(*padCE));
1668 preprocesor.AddComponent(new AliTPCCalPad(*padCEIn));
1669 preprocesor.AddComponent(new AliTPCCalPad(*padCEFit));
1670 preprocesor.AddComponent(new AliTPCCalPad(*padOut));
1672 preprocesor.AddComponent(new AliTPCCalPad(*padCEFitGY));
1673 preprocesor.AddComponent(new AliTPCCalPad(*padCEDiff));
1675 preprocesor.AddComponent(new AliTPCCalPad(*padCEOut));
1676 preprocesor.AddComponent(new AliTPCCalPad(*padPulser));
1677 preprocesor.AddComponent(new AliTPCCalPad(*padPulserOut));
1678 preprocesor.DumpToFile(dumpfile);
1681 delete padPulserOut;
1694 Int_t AliTPCcalibDButil::GetNearest(TGraph *graph, Double_t xref, Double_t &dx, Double_t &y){
1696 // find the closest point to xref in x direction
1697 // return dx and value
1701 if(!graph) return 0;
1702 if(graph->GetN() < 1) return 0;
1705 index = TMath::BinarySearch(graph->GetN(), graph->GetX(),xref);
1706 if (index<0) index=0;
1707 if(graph->GetN()==1) {
1708 dx = xref-graph->GetX()[index];
1711 if (index>=graph->GetN()-1) index=graph->GetN()-2;
1712 if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
1713 dx = xref-graph->GetX()[index];
1715 y = graph->GetY()[index];
1719 Double_t AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
1721 // Get the correction of the trigger offset
1722 // combining information from the laser track calibration
1723 // and from cosmic calibration
1726 // timeStamp - tim stamp in seconds
1727 // deltaT - integration period to calculate offset
1728 // deltaTLaser -max validity of laser data
1729 // valType - 0 - median, 1- mean
1731 // Integration vaues are just recomendation - if not possible to get points
1732 // automatically increase the validity by factor 2
1733 // (recursive algorithm until one month of data taking)
1736 const Float_t kLaserCut=0.0005;
1737 const Int_t kMaxPeriod=3600*24*30*12; // one year max
1738 const Int_t kMinPoints=20;
1740 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1742 AliTPCcalibDB::Instance()->UpdateRunInformations(run,kFALSE);
1744 array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1745 if (!array) return 0;
1747 TGraphErrors *laserA[3]={0,0,0};
1748 TGraphErrors *laserC[3]={0,0,0};
1749 TGraphErrors *cosmicAll=0;
1750 laserA[1]=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1751 laserC[1]=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1752 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1755 if (!cosmicAll) return 0;
1756 Int_t nmeasC=cosmicAll->GetN();
1757 Float_t *tdelta = new Float_t[nmeasC];
1759 for (Int_t i=0;i<nmeasC;i++){
1760 if (TMath::Abs(cosmicAll->GetX()[i]-timeStamp)>deltaT) continue;
1761 Float_t ccosmic=cosmicAll->GetY()[i];
1762 Double_t yA=0,yC=0,dA=0,dC=0;
1763 if (laserA[1]) GetNearest(laserA[1], cosmicAll->GetX()[i],dA,yA);
1764 if (laserC[1]) GetNearest(laserC[1], cosmicAll->GetX()[i],dC,yC);
1765 //yA=laserA[1]->Eval(cosmicAll->GetX()[i]);
1766 //yC=laserC[1]->Eval(cosmicAll->GetX()[i]);
1768 if (TMath::Sqrt(dA*dA+dC*dC)>deltaTLaser) continue;
1770 if (TMath::Abs(yA-yC)<kLaserCut) {
1773 if (i%2==0) claser=yA;
1774 if (i%2==1) claser=yC;
1776 tdelta[nused]=ccosmic-claser;
1779 if (nused<kMinPoints &&deltaT<kMaxPeriod) {
1781 return AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
1783 if (nused<kMinPoints) {
1785 //AliWarning("AliFatal: No time offset calibration available\n");
1788 Double_t median = TMath::Median(nused,tdelta);
1789 Double_t mean = TMath::Mean(nused,tdelta);
1791 return (valType==0) ? median:mean;
1794 Double_t AliTPCcalibDButil::GetVDriftTPC(Double_t &dist, Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
1796 // Get the correction of the drift velocity
1797 // combining information from the laser track calibration
1798 // and from cosmic calibration
1800 // dist - return value - distance to closest point in graph
1802 // timeStamp - tim stamp in seconds
1803 // deltaT - integration period to calculate time0 offset
1804 // deltaTLaser -max validity of laser data
1805 // valType - 0 - median, 1- mean
1807 // Integration vaues are just recomendation - if not possible to get points
1808 // automatically increase the validity by factor 2
1809 // (recursive algorithm until one month of data taking)
1813 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1815 AliTPCcalibDB::Instance()->UpdateRunInformations(run,kFALSE);
1817 array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1818 if (!array) return 0;
1819 TGraphErrors *cosmicAll=0;
1820 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1821 if (!cosmicAll) return 0;
1823 AliTPCcalibDButil::GetNearest(cosmicAll,timeStamp,dist,grY);
1825 Double_t t0= AliTPCcalibDButil::GetTriggerOffsetTPC(run,timeStamp, deltaT, deltaTLaser,valType);
1826 Double_t vcosmic = AliTPCcalibDButil::EvalGraphConst(cosmicAll, timeStamp);
1827 if (timeStamp>cosmicAll->GetX()[cosmicAll->GetN()-1]) vcosmic=cosmicAll->GetY()[cosmicAll->GetN()-1];
1828 if (timeStamp<cosmicAll->GetX()[0]) vcosmic=cosmicAll->GetY()[0];
1835 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1836 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1837 laserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1839 Double_t *yvd= new Double_t[cosmicAll->GetN()];
1840 Double_t *yt0= new Double_t[cosmicAll->GetN()];
1841 for (Int_t i=0; i<cosmicAll->GetN();i++) yvd[i]=AliTPCcalibDButil::GetVDriftTPC(run,cosmicAll->GetX()[i]);
1842 for (Int_t i=0; i<cosmicAll->GetN();i++) yt0[i]=AliTPCcalibDButil::GetTriggerOffsetTPC(run,cosmicAll->GetX()[i]);
1844 TGraph *pcosmicVd=new TGraph(cosmicAll->GetN(), cosmicAll->GetX(), yvd);
1845 TGraph *pcosmicT0=new TGraph(cosmicAll->GetN(), cosmicAll->GetX(), yt0);
1851 const char* AliTPCcalibDButil::GetGUIRefTreeDefaultName()
1854 // Create a default name for the gui file
1857 return Form("guiRefTreeRun%s.root",GetRefValidity());
1860 Bool_t AliTPCcalibDButil::CreateGUIRefTree(const char* filename)
1863 // Create a gui reference tree
1864 // if dirname and filename are empty default values will be used
1865 // this is the recommended way of using this function
1866 // it allows to check whether a file with the given run validity alredy exists
1868 if (!AliCDBManager::Instance()->GetDefaultStorage()){
1869 AliError("Default Storage not set. Cannot create reference calibration Tree!");
1873 TString file=filename;
1874 if (file.IsNull()) file=GetGUIRefTreeDefaultName();
1876 AliTPCPreprocessorOnline prep;
1877 //noise and pedestals
1878 if (fRefPedestals) prep.AddComponent(new AliTPCCalPad(*(fRefPedestals)));
1879 if (fRefPadNoise ) prep.AddComponent(new AliTPCCalPad(*(fRefPadNoise)));
1880 if (fRefPedestalMasked) prep.AddComponent(new AliTPCCalPad(*fRefPedestalMasked));
1882 if (fRefPulserTmean) prep.AddComponent(new AliTPCCalPad(*(fRefPulserTmean)));
1883 if (fRefPulserTrms ) prep.AddComponent(new AliTPCCalPad(*(fRefPulserTrms)));
1884 if (fRefPulserQmean) prep.AddComponent(new AliTPCCalPad(*(fRefPulserQmean)));
1885 if (fRefPulserMasked) prep.AddComponent(new AliTPCCalPad(*fRefPulserMasked));
1887 if (fRefCETmean) prep.AddComponent(new AliTPCCalPad(*(fRefCETmean)));
1888 if (fRefCETrms ) prep.AddComponent(new AliTPCCalPad(*(fRefCETrms)));
1889 if (fRefCEQmean) prep.AddComponent(new AliTPCCalPad(*(fRefCEQmean)));
1890 if (fRefCEMasked) prep.AddComponent(new AliTPCCalPad(*fRefCEMasked));
1892 if (fRefALTROAcqStart ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROAcqStart )));
1893 if (fRefALTROZsThr ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROZsThr )));
1894 if (fRefALTROFPED ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROFPED )));
1895 if (fRefALTROAcqStop ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROAcqStop )));
1896 if (fRefALTROMasked ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROMasked )));
1898 AliTPCdataQA *dataQA=fRefDataQA;
1900 if (dataQA->GetNLocalMaxima())
1901 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
1902 if (dataQA->GetMaxCharge())
1903 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
1904 if (dataQA->GetMeanCharge())
1905 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
1906 if (dataQA->GetNoThreshold())
1907 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
1908 if (dataQA->GetNTimeBins())
1909 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
1910 if (dataQA->GetNPads())
1911 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
1912 if (dataQA->GetTimePosition())
1913 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
1915 prep.DumpToFile(file.Data());
1919 Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracks(Double_t &dist, Int_t run, Int_t timeStamp, Double_t deltaT, Int_t side){
1921 // Get the correction of the drift velocity using the offline laser tracks calbration
1924 // timeStamp - tim stamp in seconds
1925 // deltaT - integration period to calculate time0 offset
1926 // side - 0 - A side, 1 - C side, 2 - mean from both sides
1927 // Note in case no data form both A and C side - the value from active side used
1928 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1930 return GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
1933 Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracksOnline(Double_t &dist, Int_t /*run*/, Int_t timeStamp, Double_t deltaT, Int_t side){
1935 // Get the correction of the drift velocity using the online laser tracks calbration
1938 // timeStamp - tim stamp in seconds
1939 // deltaT - integration period to calculate time0 offset
1940 // side - 0 - A side, 1 - C side, 2 - mean from both sides
1941 // Note in case no data form both A and C side - the value from active side used
1942 TObjArray *array =AliTPCcalibDB::Instance()->GetCEfitsDrift();
1944 Double_t dv = GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
1945 AliTPCParam *param =AliTPCcalibDB::Instance()->GetParameters();
1946 if (!param) return 0;
1948 //the drift velocity is hard wired in the AliTPCCalibCE class, since online there is no access to OCDB
1949 dv*=param->GetDriftV()/2.61301900000000000e+06;
1950 if (dv>1e-20) dv=1/dv-1;
1953 TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
1955 AliTPCSensorTempArray *temp = (AliTPCSensorTempArray*)cearray->FindObject("TempMap");
1956 AliDCSSensor *press = (AliDCSSensor*)cearray->FindObject("CavernAtmosPressure");
1962 AliTPCCalibVdrift corr(temp,press,0);
1963 corrPTA=corr.GetPTRelative(timeStamp,0);
1964 corrPTC=corr.GetPTRelative(timeStamp,1);
1967 if (side==0) dv -= corrPTA;
1968 if (side==1) dv -= corrPTC;
1969 if (side==2) dv -= (corrPTA+corrPTC)/2;
1974 Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracksCommon(Double_t &dist, Int_t timeStamp, Double_t deltaT,
1975 Int_t side, TObjArray * const array){
1977 // common drift velocity retrieval for online and offline method
1979 TGraphErrors *grlaserA=0;
1980 TGraphErrors *grlaserC=0;
1981 Double_t vlaserA=0, vlaserC=0;
1982 if (!array) return 0;
1983 grlaserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1984 grlaserC=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1986 if (grlaserA && grlaserA->GetN()>0) {
1987 AliTPCcalibDButil::GetNearest(grlaserA,timeStamp,dist,deltaY);
1988 if (TMath::Abs(dist)>deltaT) vlaserA= deltaY;
1989 else vlaserA = AliTPCcalibDButil::EvalGraphConst(grlaserA,timeStamp);
1991 if (grlaserC && grlaserC->GetN()>0) {
1992 AliTPCcalibDButil::GetNearest(grlaserC,timeStamp,dist,deltaY);
1993 if (TMath::Abs(dist)>deltaT) vlaserC= deltaY;
1994 else vlaserC = AliTPCcalibDButil::EvalGraphConst(grlaserC,timeStamp);
1996 if (side==0) return vlaserA;
1997 if (side==1) return vlaserC;
1998 Double_t mdrift=(vlaserA+vlaserC)*0.5;
1999 if (!grlaserA) return vlaserC;
2000 if (!grlaserC) return vlaserA;
2005 Double_t AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t timeStamp, Double_t deltaT, Int_t side){
2007 // Get the correction of the drift velocity using the CE laser data
2008 // combining information from the CE, laser track calibration
2009 // and P/T calibration
2012 // timeStamp - tim stamp in seconds
2013 // deltaT - integration period to calculate time0 offset
2014 // side - 0 - A side, 1 - C side, 2 - mean from both sides
2015 TObjArray *arrT =AliTPCcalibDB::Instance()->GetCErocTtime();
2016 if (!arrT) return 0;
2017 AliTPCParam *param =AliTPCcalibDB::Instance()->GetParameters();
2018 TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
2019 AliTPCCalibVdrift * driftCalib = (AliTPCCalibVdrift *)cearray->FindObject("driftPTCE");
2022 Double_t corrPTA = 0, corrPTC=0;
2023 Double_t ltime0A = 0, ltime0C=0;
2025 Double_t corrA=0, corrC=0;
2026 Double_t timeA=0, timeC=0;
2027 const Double_t kEpsilon = 0.00001;
2028 TGraph *graphA = (TGraph*)arrT->At(72);
2029 TGraph *graphC = (TGraph*)arrT->At(73);
2030 if (!graphA && !graphC) return 0.;
2031 if (graphA &&graphA->GetN()>0) {
2032 AliTPCcalibDButil::GetNearest(graphA,timeStamp,dist,gry);
2033 timeA = AliTPCcalibDButil::EvalGraphConst(graphA,timeStamp);
2034 Int_t mtime =TMath::Nint((graphA->GetX()[0]+graphA->GetX()[graphA->GetN()-1])*0.5);
2035 ltime0A = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
2036 if(ltime0A < kEpsilon) return 0;
2037 if (driftCalib) corrPTA = driftCalib->GetPTRelative(timeStamp,0);
2038 corrA = (param->GetZLength(36)/(timeA*param->GetTSample()*(1.-ltime0A)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
2041 if (graphC&&graphC->GetN()>0){
2042 AliTPCcalibDButil::GetNearest(graphC,timeStamp,dist,gry);
2043 timeC=AliTPCcalibDButil::EvalGraphConst(graphC,timeStamp);
2044 Int_t mtime=TMath::Nint((graphC->GetX()[0]+graphC->GetX()[graphC->GetN()-1])*0.5);
2045 ltime0C = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
2046 if(ltime0C < kEpsilon) return 0;
2047 if (driftCalib) corrPTC = driftCalib->GetPTRelative(timeStamp,0);
2048 corrC = (param->GetZLength(54)/(timeC*param->GetTSample()*(1.-ltime0C)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
2052 if (side ==0 ) return corrA;
2053 if (side ==1 ) return corrC;
2054 Double_t corrM= (corrA+corrC)*0.5;
2055 if (!graphA) corrM=corrC;
2056 if (!graphC) corrM=corrA;
2060 Double_t AliTPCcalibDButil::GetVDriftTPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
2062 // return drift velocity using the TPC-ITS matchin method
2063 // return also distance to the closest point
2065 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2066 TGraphErrors *graph=0;
2068 if (!array) return 0;
2070 graph = (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DRIFTVD");
2071 if (!graph) return 0;
2073 AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY);
2074 Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
2078 Double_t AliTPCcalibDButil::GetTime0TPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
2080 // Get time dependent time 0 (trigger delay in cm) correction
2082 // timestamp - timestamp
2085 // Notice - Extrapolation outside of calibration range - using constant function
2087 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2088 TGraphErrors *graph=0;
2090 if (!array) return 0;
2091 graph = (TGraphErrors*)array->FindObject("ALIGN_ITSM_TPC_T0");
2092 if (!graph) return 0;
2094 AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY);
2095 Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
2103 Int_t AliTPCcalibDButil::MakeRunList(Int_t startRun, Int_t stopRun){
2105 // VERY obscure method - we need something in framework
2106 // Find the TPC runs with temperature OCDB entry
2107 // cache the start and end of the run
2109 AliCDBStorage* storage = AliCDBManager::Instance()->GetSpecificStorage("TPC/Calib/Temperature");
2110 if (!storage) storage = AliCDBManager::Instance()->GetDefaultStorage();
2111 if (!storage) return 0;
2112 TString path=storage->GetURI();
2116 if (path.Contains("local")){ // find the list if local system
2117 path.ReplaceAll("local://","");
2118 path+="TPC/Calib/Temperature";
2119 command=Form("ls %s | sed s/_/\\ /g | awk '{print \"r\"$2}' ",path.Data());
2121 runsT=gSystem->GetFromPipe(command);
2123 TObjArray *arr= runsT.Tokenize("r");
2126 TArrayI indexes(arr->GetEntries());
2127 TArrayI runs(arr->GetEntries());
2129 {for (Int_t irun=0;irun<arr->GetEntries();irun++){
2130 Int_t irunN = atoi(arr->At(irun)->GetName());
2131 if (irunN<startRun) continue;
2132 if (irunN>stopRun) continue;
2133 runs[naccept]=irunN;
2137 fRunsStart.Set(fRuns.fN);
2138 fRunsStop.Set(fRuns.fN);
2139 TMath::Sort(fRuns.fN, runs.fArray, indexes.fArray,kFALSE);
2140 for (Int_t irun=0; irun<fRuns.fN; irun++) fRuns[irun]=runs[indexes[irun]];
2143 AliCDBEntry * entry = 0;
2144 {for (Int_t irun=0;irun<fRuns.fN; irun++){
2145 entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",fRuns[irun]);
2146 if (!entry) continue;
2147 AliTPCSensorTempArray * tmpRun = dynamic_cast<AliTPCSensorTempArray*>(entry->GetObject());
2148 if (!tmpRun) continue;
2149 fRunsStart[irun]=tmpRun->GetStartTime().GetSec();
2150 fRunsStop[irun]=tmpRun->GetEndTime().GetSec();
2151 //AliInfo(Form("irun\t%d\tRun\t%d\t%d\t%d\n",irun,fRuns[irun],tmpRun->GetStartTime().GetSec(),tmpRun->GetEndTime().GetSec()));
2157 Int_t AliTPCcalibDButil::FindRunTPC(Int_t itime, Bool_t debug){
2159 // binary search - find the run for given time stamp
2161 Int_t index0 = TMath::BinarySearch(fRuns.fN, fRunsStop.fArray,itime);
2162 Int_t index1 = TMath::BinarySearch(fRuns.fN, fRunsStart.fArray,itime);
2164 for (Int_t index=index0; index<=index1; index++){
2165 if (fRunsStart[index]<=itime && fRunsStop[index]>=itime) cindex=index;
2167 AliInfo(Form("%d\t%d\t%d\n",fRuns[index], fRunsStart[index]-itime, fRunsStop[index]-itime));
2170 if (cindex<0) cindex =(index0+index1)/2;
2174 return fRuns[cindex];
2181 TGraph* AliTPCcalibDButil::FilterGraphMedian(TGraph * graph, Float_t sigmaCut,Double_t &medianY){
2183 // filter outlyer measurement
2184 // Only points around median +- sigmaCut filtered
2185 if (!graph) return 0;
2187 Int_t npoints0 = graph->GetN();
2192 if (npoints0<kMinPoints) return 0;
2194 Double_t *outx=new Double_t[npoints0];
2195 Double_t *outy=new Double_t[npoints0];
2196 for (Int_t iter=0; iter<3; iter++){
2198 for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
2199 if (graph->GetY()[ipoint]==0) continue;
2200 if (iter>0 &&TMath::Abs(graph->GetY()[ipoint]-medianY)>sigmaCut*rmsY) continue;
2201 outx[npoints] = graph->GetX()[ipoint];
2202 outy[npoints] = graph->GetY()[ipoint];
2205 if (npoints<=1) break;
2206 medianY =TMath::Median(npoints,outy);
2207 rmsY =TMath::RMS(npoints,outy);
2210 if (npoints>1) graphOut= new TGraph(npoints,outx,outy);
2217 TGraph* AliTPCcalibDButil::FilterGraphMedianAbs(TGraph * graph, Float_t cut,Double_t &medianY){
2219 // filter outlyer measurement
2220 // Only points around median +- cut filtered
2221 if (!graph) return 0;
2223 Int_t npoints0 = graph->GetN();
2228 if (npoints0<kMinPoints) return 0;
2230 Double_t *outx=new Double_t[npoints0];
2231 Double_t *outy=new Double_t[npoints0];
2232 for (Int_t iter=0; iter<3; iter++){
2234 for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
2235 if (graph->GetY()[ipoint]==0) continue;
2236 if (iter>0 &&TMath::Abs(graph->GetY()[ipoint]-medianY)>cut) continue;
2237 outx[npoints] = graph->GetX()[ipoint];
2238 outy[npoints] = graph->GetY()[ipoint];
2241 if (npoints<=1) break;
2242 medianY =TMath::Median(npoints,outy);
2243 rmsY =TMath::RMS(npoints,outy);
2246 if (npoints>1) graphOut= new TGraph(npoints,outx,outy);
2254 TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * const graph, Float_t sigmaCut,Double_t &medianY){
2256 // filter outlyer measurement
2257 // Only points with normalized errors median +- sigmaCut filtered
2259 Int_t kMinPoints=10;
2260 Int_t npoints0 = graph->GetN();
2262 Float_t medianErr=0, rmsErr=0;
2265 if (npoints0<kMinPoints) return 0;
2267 Double_t *outx=new Double_t[npoints0];
2268 Double_t *outy=new Double_t[npoints0];
2269 Double_t *erry=new Double_t[npoints0];
2270 Double_t *nerry=new Double_t[npoints0];
2271 Double_t *errx=new Double_t[npoints0];
2273 for (Int_t iter=0; iter<3; iter++){
2275 for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
2276 nerry[npoints] = graph->GetErrorY(ipoint);
2277 if (iter>0 &&TMath::Abs(nerry[npoints]-medianErr)>sigmaCut*rmsErr) continue;
2278 erry[npoints] = graph->GetErrorY(ipoint);
2279 outx[npoints] = graph->GetX()[ipoint];
2280 outy[npoints] = graph->GetY()[ipoint];
2281 errx[npoints] = graph->GetErrorY(ipoint);
2284 if (npoints==0) break;
2285 medianErr=TMath::Median(npoints,erry);
2286 medianY =TMath::Median(npoints,outy);
2287 rmsErr =TMath::RMS(npoints,erry);
2289 TGraphErrors *graphOut=0;
2290 if (npoints>1) graphOut= new TGraphErrors(npoints,outx,outy,errx,erry);
2300 void AliTPCcalibDButil::Sort(TGraph *graph){
2302 // sort array - neccessay for approx
2304 Int_t npoints = graph->GetN();
2305 Int_t *indexes=new Int_t[npoints];
2306 Double_t *outx=new Double_t[npoints];
2307 Double_t *outy=new Double_t[npoints];
2308 TMath::Sort(npoints, graph->GetX(),indexes,kFALSE);
2309 for (Int_t i=0;i<npoints;i++) outx[i]=graph->GetX()[indexes[i]];
2310 for (Int_t i=0;i<npoints;i++) outy[i]=graph->GetY()[indexes[i]];
2311 for (Int_t i=0;i<npoints;i++) graph->GetX()[i]=outx[i];
2312 for (Int_t i=0;i<npoints;i++) graph->GetY()[i]=outy[i];
2318 void AliTPCcalibDButil::SmoothGraph(TGraph *graph, Double_t delta){
2320 // smmoth graph - mean on the interval
2323 Int_t npoints = graph->GetN();
2324 Double_t *outy=new Double_t[npoints];
2326 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
2327 Double_t lx=graph->GetX()[ipoint];
2328 Int_t index0=TMath::BinarySearch(npoints, graph->GetX(),lx-delta);
2329 Int_t index1=TMath::BinarySearch(npoints, graph->GetX(),lx+delta);
2330 if (index0<0) index0=0;
2331 if (index1>=npoints-1) index1=npoints-1;
2332 if ((index1-index0)>1){
2333 outy[ipoint] = TMath::Mean(index1-index0, &(graph->GetY()[index0]));
2335 outy[ipoint]=graph->GetY()[ipoint];
2338 // TLinearFitter fitter(3,"pol2");
2339 // for (Int_t ipoint=0; ipoint<npoints; ipoint++){
2340 // Double_t lx=graph->GetX()[ipoint];
2341 // Int_t index0=TMath::BinarySearch(npoints, graph->GetX(),lx-delta);
2342 // Int_t index1=TMath::BinarySearch(npoints, graph->GetX(),lx+delta);
2343 // if (index0<0) index0=0;
2344 // if (index1>=npoints-1) index1=npoints-1;
2345 // fitter.ClearPoints();
2346 // for (Int_t jpoint=0;jpoint<index1-index0; jpoint++)
2347 // if ((index1-index0)>1){
2348 // outy[ipoint] = TMath::Mean(index1-index0, &(graph->GetY()[index0]));
2350 // outy[ipoint]=graph->GetY()[ipoint];
2356 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
2357 graph->GetY()[ipoint] = outy[ipoint];
2362 Double_t AliTPCcalibDButil::EvalGraphConst(TGraph * const graph, Double_t xref){
2364 // Use constant interpolation outside of range
2367 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
2371 if (graph->GetN()<1){
2372 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph \n");
2377 if (xref<graph->GetX()[0]) return graph->GetY()[0];
2378 if (xref>graph->GetX()[graph->GetN()-1]) return graph->GetY()[graph->GetN()-1];
2380 // AliInfo(Form("graph->Eval(graph->GetX()[0]) %f, graph->Eval(xref) %f \n",graph->Eval(graph->GetX()[0]), graph->Eval(xref)));
2382 if(graph->GetN()==1)
2383 return graph->Eval(graph->GetX()[0]);
2386 return graph->Eval(xref);
2389 Double_t AliTPCcalibDButil::EvalGraphConst(AliSplineFit *graph, Double_t xref){
2391 // Use constant interpolation outside of range also for spline fits
2394 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
2397 if (graph->GetKnots()<1){
2398 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph");
2401 if (xref<graph->GetX()[0]) return graph->GetY0()[0];
2402 if (xref>graph->GetX()[graph->GetKnots()-1]) return graph->GetY0()[graph->GetKnots()-1];
2403 return graph->Eval( xref);
2406 Float_t AliTPCcalibDButil::FilterSensor(AliDCSSensor * sensor, Double_t ymin, Double_t ymax, Double_t maxdy, Double_t sigmaCut){
2408 // Filter DCS sensor information
2409 // ymin - minimal value
2411 // maxdy - maximal deirivative
2412 // sigmaCut - cut on values and derivative in terms of RMS distribution
2413 // Return value - accepted fraction
2417 // 0. Calculate median and rms of values in specified range
2418 // 1. Filter out outliers - median+-sigmaCut*rms
2419 // values replaced by median
2421 AliSplineFit * fit = sensor->GetFit();
2422 if (!fit) return 0.;
2423 Int_t nknots = fit->GetKnots();
2430 Double_t *yin0 = new Double_t[nknots];
2431 Double_t *yin1 = new Double_t[nknots];
2434 for (Int_t iknot=0; iknot< nknots; iknot++){
2435 if (fit->GetY0()[iknot]>ymin && fit->GetY0()[iknot]<ymax){
2436 yin0[naccept] = fit->GetY0()[iknot];
2437 yin1[naccept] = fit->GetY1()[iknot];
2438 if (TMath::Abs(fit->GetY1()[iknot])>maxdy) yin1[naccept]=0;
2450 Double_t medianY0=0, medianY1=0;
2451 Double_t rmsY0 =0, rmsY1=0;
2452 medianY0 = TMath::Median(naccept, yin0);
2453 medianY1 = TMath::Median(naccept, yin1);
2454 rmsY0 = TMath::RMS(naccept, yin0);
2455 rmsY1 = TMath::RMS(naccept, yin1);
2458 // 1. Filter out outliers - median+-sigmaCut*rms
2459 // values replaced by median
2460 // if replaced the derivative set to 0
2462 for (Int_t iknot=0; iknot< nknots; iknot++){
2464 if (TMath::Abs(fit->GetY0()[iknot]-medianY0)>sigmaCut*rmsY0) isOK=kFALSE;
2465 if (TMath::Abs(fit->GetY1()[iknot]-medianY1)>sigmaCut*rmsY1) isOK=kFALSE;
2466 if (nknots<2) fit->GetY1()[iknot]=0;
2467 if (TMath::Abs(fit->GetY1()[iknot])>maxdy) fit->GetY1()[iknot]=0;
2469 fit->GetY0()[iknot]=medianY0;
2470 fit->GetY1()[iknot]=0;
2477 return Float_t(naccept)/Float_t(nknots);
2480 Float_t AliTPCcalibDButil::FilterTemperature(AliTPCSensorTempArray *tempArray, Double_t ymin, Double_t ymax, Double_t sigmaCut){
2482 // Filter temperature array
2483 // tempArray - array of temperatures -
2484 // ymin - minimal accepted temperature - default 15
2485 // ymax - maximal accepted temperature - default 22
2486 // sigmaCut - values filtered on interval median+-sigmaCut*rms - defaut 5
2487 // return value - fraction of filtered sensors
2488 const Double_t kMaxDy=0.1;
2489 Int_t nsensors=tempArray->NumSensors();
2490 if (nsensors==0) return 0.;
2492 for (Int_t isensor=0; isensor<nsensors; isensor++){
2493 AliDCSSensor *sensor = tempArray->GetSensorNum(isensor);
2494 if (!sensor) continue;
2495 FilterSensor(sensor,ymin,ymax,kMaxDy, sigmaCut);
2496 if (sensor->GetFit()==0){
2498 tempArray->RemoveSensorNum(isensor);
2503 return Float_t(naccept)/Float_t(nsensors);
2507 void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutSigma, TTreeSRedirector * const pcstream){
2510 // Input parameters:
2511 // deltaT - smoothing window (in seconds)
2512 // cutAbs - max distance of the time info to the median (in time bins)
2513 // cutSigma - max distance (in the RMS)
2514 // pcstream - optional debug streamer to store original and filtered info
2515 // Hardwired parameters:
2516 // kMinPoints =10; // minimal number of points to define the CE
2517 // kMinSectors=12; // minimal number of sectors to define sideCE
2519 // 0. Filter almost emty graphs (kMinPoints=10)
2520 // 1. calculate median and RMS per side
2521 // 2. Filter graphs - in respect with side medians
2522 // - cutAbs and cutDelta used
2523 // 3. Cut in respect wit the graph median - cutAbs and cutRMS used
2524 // 4. Calculate mean for A side and C side
2526 const Int_t kMinPoints =10; // minimal number of points to define the CE
2527 const Int_t kMinSectors=12; // minimal number of sectors to define sideCE
2528 const Int_t kMinTime =400; // minimal arrival time of CE
2529 TObjArray *arrT=AliTPCcalibDB::Instance()->GetCErocTtime();
2531 TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
2532 if (!cearray) return;
2537 AliTPCSensorTempArray *tempMapCE = (AliTPCSensorTempArray *)cearray->FindObject("TempMap");
2538 AliDCSSensor * cavernPressureCE = (AliDCSSensor *) cearray->FindObject("CavernAtmosPressure");
2539 if ( tempMapCE && cavernPressureCE){
2541 // Bool_t isOK = FilterTemperature(tempMapCE)>0.1;
2542 // FilterSensor(cavernPressureCE,960,1050,10, 5.);
2543 // if (cavernPressureCE->GetFit()==0) isOK=kFALSE;
2546 // recalculate P/T correction map for time of the CE
2547 AliTPCCalibVdrift * driftCalib = new AliTPCCalibVdrift(tempMapCE,cavernPressureCE ,0);
2548 driftCalib->SetName("driftPTCE");
2549 driftCalib->SetTitle("driftPTCE");
2550 cearray->AddLast(driftCalib);
2554 // 0. Filter almost emty graphs
2557 for (Int_t i=0; i<72;i++){
2558 TGraph *graph= (TGraph*)arrT->At(i);
2559 if (!graph) continue;
2561 if (graph->GetN()<kMinPoints){
2563 delete graph; // delete empty graph
2566 if (tmin<0) tmin = graph->GetX()[0];
2567 if (tmax<0) tmax = graph->GetX()[graph->GetN()-1];
2569 if (tmin>graph->GetX()[0]) tmin=graph->GetX()[0];
2570 if (tmax<graph->GetX()[graph->GetN()-1]) tmax=graph->GetX()[graph->GetN()-1];
2573 // 1. calculate median and RMS per side
2575 TArrayF arrA(100000), arrC(100000);
2577 Double_t medianA=0, medianC=0;
2578 Double_t rmsA=0, rmsC=0;
2579 for (Int_t isec=0; isec<72;isec++){
2580 TGraph *graph= (TGraph*)arrT->At(isec);
2581 if (!graph) continue;
2582 for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){
2583 if (graph->GetY()[ipoint]<kMinTime) continue;
2584 if (nA>=arrA.fN) arrA.Set(nA*2);
2585 if (nC>=arrC.fN) arrC.Set(nC*2);
2586 if (isec%36<18) arrA[nA++]= graph->GetY()[ipoint];
2587 if (isec%36>=18) arrC[nC++]= graph->GetY()[ipoint];
2591 medianA=TMath::Median(nA,arrA.fArray);
2592 rmsA =TMath::RMS(nA,arrA.fArray);
2595 medianC=TMath::Median(nC,arrC.fArray);
2596 rmsC =TMath::RMS(nC,arrC.fArray);
2599 // 2. Filter graphs - in respect with side medians
2601 TArrayD vecX(100000), vecY(100000);
2602 for (Int_t isec=0; isec<72;isec++){
2603 TGraph *graph= (TGraph*)arrT->At(isec);
2604 if (!graph) continue;
2605 Double_t median = (isec%36<18) ? medianA: medianC;
2606 Double_t rms = (isec%36<18) ? rmsA: rmsC;
2608 // for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){ //not neccessary to remove first points
2609 for (Int_t ipoint=0; ipoint<graph->GetN();ipoint++){
2610 if (TMath::Abs(graph->GetY()[ipoint]-median)>cutAbs) continue;
2611 if (TMath::Abs(graph->GetY()[ipoint]-median)>cutSigma*rms) continue;
2612 vecX[naccept]= graph->GetX()[ipoint];
2613 vecY[naccept]= graph->GetY()[ipoint];
2616 if (naccept<kMinPoints){
2617 arrT->AddAt(0,isec);
2618 delete graph; // delete empty graph
2621 TGraph *graph2 = new TGraph(naccept, vecX.fArray, vecY.fArray);
2623 arrT->AddAt(graph2,isec);
2626 // 3. Cut in respect wit the graph median
2628 for (Int_t i=0; i<72;i++){
2629 TGraph *graph= (TGraph*)arrT->At(i);
2630 if (!graph) continue;
2634 TGraph* graphTS0= FilterGraphMedianAbs(graph,cutAbs,medianY);
2635 if (!graphTS0) continue;
2636 if (graphTS0->GetN()<kMinPoints) {
2642 TGraph* graphTS= FilterGraphMedian(graphTS0,cutSigma,medianY);
2643 if (!graphTS) continue;
2645 AliTPCcalibDButil::SmoothGraph(graphTS,deltaT);
2647 Int_t run = AliTPCcalibDB::Instance()->GetRun();
2648 (*pcstream)<<"filterCE"<<
2653 "graphTS0.="<<graphTS0<<
2654 "graphTS.="<<graphTS<<
2658 arrT->AddAt(graphTS,i);
2662 // Recalculate the mean time A side C side
2664 TArrayF xA(200), yA(200), eA(200), xC(200),yC(200), eC(200);
2665 Int_t meanPoints=(nA+nC)/72; // mean number of points
2666 for (Int_t itime=0; itime<200; itime++){
2668 Double_t time=tmin+(tmax-tmin)*Float_t(itime)/200.;
2669 for (Int_t i=0; i<72;i++){
2670 TGraph *graph= (TGraph*)arrT->At(i);
2671 if (!graph) continue;
2672 if (graph->GetN()<(meanPoints/4)) continue;
2673 if ( (i%36)<18 ) arrA[nA++]=graph->Eval(time);
2674 if ( (i%36)>=18 ) arrC[nC++]=graph->Eval(time);
2678 yA[itime]=(nA>0)? TMath::Mean(nA,arrA.fArray):0;
2679 yC[itime]=(nC>0)? TMath::Mean(nC,arrC.fArray):0;
2680 eA[itime]=(nA>0)? TMath::RMS(nA,arrA.fArray):0;
2681 eC[itime]=(nC>0)? TMath::RMS(nC,arrC.fArray):0;
2684 Double_t rmsTA = TMath::RMS(200,yA.fArray)+TMath::Mean(200,eA.fArray);
2685 Double_t rmsTC = TMath::RMS(200,yC.fArray)+TMath::Mean(200,eC.fArray);
2687 Int_t run = AliTPCcalibDB::Instance()->GetRun();
2688 (*pcstream)<<"filterAC"<<
2697 TGraphErrors *grA = new TGraphErrors(200,xA.fArray,yA.fArray,0, eA.fArray);
2698 TGraphErrors *grC = new TGraphErrors(200,xC.fArray,yC.fArray,0, eC.fArray);
2699 TGraph* graphTSA= FilterGraphMedian(grA,cutSigma,medianY);
2700 if (graphTSA&&graphTSA->GetN()) SmoothGraph(graphTSA,deltaT);
2701 TGraph* graphTSC= FilterGraphMedian(grC,cutSigma,medianY);
2702 if (graphTSC&&graphTSC->GetN()>0) SmoothGraph(graphTSC,deltaT);
2705 if (nA<kMinSectors) arrT->AddAt(0,72);
2706 else arrT->AddAt(graphTSA,72);
2707 if (nC<kMinSectors) arrT->AddAt(0,73);
2708 else arrT->AddAt(graphTSC,73);
2712 void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirector * const pcstream){
2714 // Filter Drift velocity measurement using the tracks
2715 // 0. remove outlyers - error based
2719 const Int_t kMinPoints=1; // minimal number of points to define value
2720 TObjArray *arrT=AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2723 for (Int_t i=0; i<arrT->GetEntries();i++){
2724 TGraphErrors *graph= dynamic_cast<TGraphErrors*>(arrT->At(i));
2725 if (!graph) continue;
2726 if (graph->GetN()<kMinPoints){
2731 TGraphErrors *graph2 = NULL;
2732 if(graph->GetN()<10) {
2733 graph2 = new TGraphErrors(graph->GetN(),graph->GetX(),graph->GetY(),graph->GetEX(),graph->GetEY());
2735 delete graph; arrT->AddAt(0,i); continue;
2739 graph2= FilterGraphMedianErr(graph,cutSigma,medianY);
2741 delete graph; arrT->AddAt(0,i); continue;
2744 if (graph2->GetN()<1) {
2745 delete graph; arrT->AddAt(0,i); continue;
2747 graph2->SetName(graph->GetName());
2748 graph2->SetTitle(graph->GetTitle());
2749 arrT->AddAt(graph2,i);
2751 (*pcstream)<<"filterTracks"<<
2756 "graph2.="<<graph2<<
2767 Double_t AliTPCcalibDButil::GetLaserTime0(Int_t run, Int_t timeStamp, Int_t deltaT, Int_t side){
2770 // get laser time offset
2771 // median around timeStamp+-deltaT
2772 // QA - chi2 needed for later usage - to be added
2773 // - currently cut on error
2776 Double_t kMinDelay=0.01;
2777 Double_t kMinDelayErr=0.0001;
2779 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2780 if (!array) return 0;
2781 TGraphErrors *tlaser=0;
2783 if (side==0) tlaser=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DELAY_LASER_ALL_A");
2784 if (side==1) tlaser=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DELAY_LASER_ALL_C");
2786 if (!tlaser) return 0;
2787 Int_t npoints0= tlaser->GetN();
2788 if (npoints0==0) return 0;
2789 Double_t *xlaser = new Double_t[npoints0];
2790 Double_t *ylaser = new Double_t[npoints0];
2792 for (Int_t i=0;i<npoints0;i++){
2794 if (tlaser->GetY()[i]<=kMinDelay) continue; // filter zeros
2795 if (tlaser->GetErrorY(i)>TMath::Abs(kMinDelayErr)) continue;
2796 xlaser[npoints]=tlaser->GetX()[npoints];
2797 ylaser[npoints]=tlaser->GetY()[npoints];
2802 Int_t index0=TMath::BinarySearch(npoints, xlaser, Double_t(timeStamp-deltaT))-1;
2803 Int_t index1=TMath::BinarySearch(npoints, xlaser, Double_t(timeStamp+deltaT))+1;
2804 //if (index1-index0 <kMinPoints) { index1+=kMinPoints; index0-=kMinPoints;}
2805 if (index0<0) index0=0;
2806 if (index1>=npoints-1) index1=npoints-1;
2807 if (index1-index0<kMinPoints) {
2813 //Double_t median = TMath::Median(index1-index0, &(ylaser[index0]));
2814 Double_t mean = TMath::Mean(index1-index0, &(ylaser[index0]));
2823 void AliTPCcalibDButil::FilterGoofie(AliDCSSensorArray * goofieArray, Double_t deltaT, Double_t cutSigma, Double_t minVd, Double_t maxVd, TTreeSRedirector * const pcstream){
2825 // Filter Goofie data
2826 // goofieArray - points will be filtered
2827 // deltaT - smmothing time window
2828 // cutSigma - outler sigma cut in rms
2829 // minVn, maxVd- range absolute cut for variable vd/pt
2832 // Ignore goofie if not enough points
2834 const Int_t kMinPoints = 3;
2837 TGraph *graphvd = goofieArray->GetSensorNum(2)->GetGraph();
2838 TGraph *graphan = goofieArray->GetSensorNum(8)->GetGraph();
2839 TGraph *graphaf = goofieArray->GetSensorNum(9)->GetGraph();
2840 TGraph *graphpt = goofieArray->GetSensorNum(15)->GetGraph();
2841 if (!graphvd) return;
2842 if (graphvd->GetN()<kMinPoints){
2844 goofieArray->GetSensorNum(2)->SetGraph(0);
2848 // 1. Caluclate medians of critical variables
2854 Double_t medianpt=0;
2855 Double_t medianvd=0, sigmavd=0;
2856 Double_t medianan=0;
2857 Double_t medianaf=0;
2858 Int_t entries=graphvd->GetN();
2859 Double_t yvdn[10000];
2862 for (Int_t ipoint=0; ipoint<entries; ipoint++){
2863 if (graphpt->GetY()[ipoint]<=0.0000001) continue;
2864 if (graphvd->GetY()[ipoint]/graphpt->GetY()[ipoint]<minVd) continue;
2865 if (graphvd->GetY()[ipoint]/graphpt->GetY()[ipoint]>maxVd) continue;
2866 yvdn[nvd++]=graphvd->GetY()[ipoint];
2868 if (nvd<kMinPoints){
2870 goofieArray->GetSensorNum(2)->SetGraph(0);
2874 Int_t nuni = TMath::Min(TMath::Nint(nvd*0.4+2), nvd-1);
2875 if (nuni>=kMinPoints){
2876 AliMathBase::EvaluateUni(nvd, yvdn, medianvd,sigmavd,nuni);
2878 medianvd = TMath::Median(nvd, yvdn);
2881 TGraph * graphpt0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphpt,10,medianpt);
2882 TGraph * graphpt1 = AliTPCcalibDButil::FilterGraphMedian(graphpt0,2,medianpt);
2883 TGraph * graphan0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphan,10,medianan);
2884 TGraph * graphan1 = AliTPCcalibDButil::FilterGraphMedian(graphan0,2,medianan);
2885 TGraph * graphaf0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphaf,10,medianaf);
2886 TGraph * graphaf1 = AliTPCcalibDButil::FilterGraphMedian(graphaf0,2,medianaf);
2894 // 2. Make outlyer graph
2897 TGraph graphOut(*graphvd);
2898 for (Int_t i=0; i<entries;i++){
2900 Bool_t isOut=kFALSE;
2901 if (graphpt->GetY()[i]<=0.0000001) { graphOut.GetY()[i]=1; continue;}
2902 if (graphvd->GetY()[i]/graphpt->GetY()[i]<minVd || graphvd->GetY()[i]/graphpt->GetY()[i]>maxVd) { graphOut.GetY()[i]=1; continue;}
2904 if (TMath::Abs((graphvd->GetY()[i]/graphpt->GetY()[i])/medianvd-1.)<0.05)
2906 if (TMath::Abs(graphpt->GetY()[i]/medianpt-1.)>0.02) isOut|=kTRUE;
2907 if (TMath::Abs(graphan->GetY()[i]/medianan-1.)>0.2) isOut|=kTRUE;
2908 if (TMath::Abs(graphaf->GetY()[i]/medianaf-1.)>0.2) isOut|=kTRUE;
2909 graphOut.GetY()[i]= (isOut)?1:0;
2912 if (nOK<kMinPoints) {
2914 goofieArray->GetSensorNum(2)->SetGraph(0);
2918 // 3. Filter out outlyers - and smooth
2920 TVectorF vmedianArray(goofieArray->NumSensors());
2921 TVectorF vrmsArray(goofieArray->NumSensors());
2922 Double_t xnew[10000];
2923 Double_t ynew[10000];
2925 junk.SetOwner(kTRUE);
2929 for (Int_t isensor=0; isensor<goofieArray->NumSensors();isensor++){
2931 AliDCSSensor *sensor = goofieArray->GetSensorNum(isensor);
2932 TGraph *graphOld=0, *graphNew=0, * graphNew0=0,*graphNew1=0,*graphNew2=0;
2934 if (!sensor) continue;
2935 graphOld = sensor->GetGraph();
2937 sensor->SetGraph(0);
2939 for (Int_t i=0;i<entries;i++){
2940 if (graphOut.GetY()[i]>0.5) continue;
2941 xnew[nused]=graphOld->GetX()[i];
2942 ynew[nused]=graphOld->GetY()[i];
2945 graphNew = new TGraph(nused,xnew,ynew);
2946 junk.AddLast(graphNew);
2947 junk.AddLast(graphOld);
2949 graphNew0 = AliTPCcalibDButil::FilterGraphMedian(graphNew,cutSigma,median);
2951 junk.AddLast(graphNew0);
2952 graphNew1 = AliTPCcalibDButil::FilterGraphMedian(graphNew0,cutSigma,median);
2954 junk.AddLast(graphNew1);
2955 graphNew2 = AliTPCcalibDButil::FilterGraphMedian(graphNew1,cutSigma,median);
2957 vrmsArray[isensor] =TMath::RMS(graphNew2->GetN(),graphNew2->GetY());
2958 AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
2959 AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
2960 AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
2961 // AliInfo(Form("%d\t%f\t%f\n",isensor, median,vrmsArray[isensor]));
2962 vmedianArray[isensor]=median;
2968 if (!graphOld) { isOK=kFALSE; graphOld =&graphOut;}
2969 if (!graphNew0) { isOK=kFALSE; graphNew0=graphOld;}
2970 if (!graphNew1) { isOK=kFALSE; graphNew1=graphOld;}
2971 if (!graphNew2) { isOK=kFALSE; graphNew2=graphOld;}
2972 (*pcstream)<<"goofieA"<<
2973 Form("isOK_%d.=",isensor)<<isOK<<
2974 Form("s_%d.=",isensor)<<sensor<<
2975 Form("gr_%d.=",isensor)<<graphOld<<
2976 Form("gr0_%d.=",isensor)<<graphNew0<<
2977 Form("gr1_%d.=",isensor)<<graphNew1<<
2978 Form("gr2_%d.=",isensor)<<graphNew2;
2979 if (isOK) sensor->SetGraph(graphNew2);
2981 (*pcstream)<<"goofieA"<<
2982 "vmed.="<<&vmedianArray<<
2983 "vrms.="<<&vrmsArray<<
2985 junk.Delete(); // delete temoprary graphs
2993 TMatrixD* AliTPCcalibDButil::MakeStatRelKalman(TObjArray * const array, Float_t minFraction, Int_t minStat, Float_t maxvd){
2995 // Make a statistic matrix
2996 // Input parameters:
2997 // array - TObjArray of AliRelKalmanAlign
2998 // minFraction - minimal ration of accepted tracks
2999 // minStat - minimal statistic (number of accepted tracks)
3000 // maxvd - maximal deviation for the 1
3002 // columns - Mean, Median, RMS
3003 // row - parameter type (rotation[3], translation[3], drift[3])
3004 if (!array) return 0;
3005 if (array->GetEntries()<=0) return 0;
3006 // Int_t entries = array->GetEntries();
3007 Int_t entriesFast = array->GetEntriesFast();
3009 TVectorD *valArray[9];
3010 for (Int_t i=0; i<9; i++){
3011 valArray[i] = new TVectorD(entriesFast);
3014 for (Int_t ikalman=0; ikalman<entriesFast; ikalman++){
3015 AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(ikalman);
3016 if (!kalman) continue;
3017 if (TMath::Abs(kalman->GetTPCvdCorr()-1)>maxvd) continue;
3018 if (kalman->GetNUpdates()<minStat) continue;
3019 if (Float_t(kalman->GetNUpdates())/Float_t(kalman->GetNTracks())<minFraction) continue;
3020 kalman->GetState(state);
3021 for (Int_t ipar=0; ipar<9; ipar++)
3022 (*valArray[ipar])[naccept]=state[ipar];
3025 //if (naccept<2) return 0;
3026 if (naccept<1) return 0;
3027 TMatrixD *pstat=new TMatrixD(9,3);
3028 TMatrixD &stat=*pstat;
3029 for (Int_t ipar=0; ipar<9; ipar++){
3030 stat(ipar,0)=TMath::Mean(naccept, valArray[ipar]->GetMatrixArray());
3031 stat(ipar,1)=TMath::Median(naccept, valArray[ipar]->GetMatrixArray());
3032 stat(ipar,2)=TMath::RMS(naccept, valArray[ipar]->GetMatrixArray());
3038 TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const array, const TMatrixD & stat, Bool_t direction, Float_t sigmaCut){
3040 // Smooth the array of AliRelKalmanAlign - detector alignment and drift calibration)
3042 // array - input array
3043 // stat - mean parameters statistic
3045 // sigmaCut - maximal allowed deviation from mean in terms of RMS
3046 if (!array) return 0;
3047 if (array->GetEntries()<=0) return 0;
3048 if (!(&stat)) return 0;
3049 // error increase in 1 hour
3050 const Double_t kerrsTime[9]={
3051 0.00001, 0.00001, 0.00001,
3052 0.001, 0.001, 0.001,
3053 0.002, 0.01, 0.001};
3056 Int_t entries = array->GetEntriesFast();
3057 TObjArray *sArray= new TObjArray(entries);
3058 AliRelAlignerKalman * sKalman =0;
3060 for (Int_t i=0; i<entries; i++){
3061 Int_t index=(direction)? entries-i-1:i;
3062 AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(index);
3063 if (!kalman) continue;
3065 kalman->GetState(state);
3066 for (Int_t ipar=0; ipar<9; ipar++){
3067 if (TMath::Abs(state[ipar]-stat(ipar,1))>sigmaCut*stat(ipar,2)) isOK=kFALSE;
3069 if (!sKalman &&isOK) {
3070 sKalman=new AliRelAlignerKalman(*kalman);
3071 sKalman->SetRejectOutliers(kFALSE);
3072 sKalman->SetRunNumber(kalman->GetRunNumber());
3073 sKalman->SetTimeStamp(kalman->GetTimeStamp());
3075 if (!sKalman) continue;
3076 Double_t deltaT=TMath::Abs(Int_t(kalman->GetTimeStamp())-Int_t(sKalman->GetTimeStamp()))/3600.;
3077 for (Int_t ipar=0; ipar<9; ipar++){
3078 // (*(sKalman->GetStateCov()))(6,6)+=deltaT*errvd*errvd;
3079 // (*(sKalman->GetStateCov()))(7,7)+=deltaT*errt0*errt0;
3080 // (*(sKalman->GetStateCov()))(8,8)+=deltaT*errvy*errvy;
3081 (*(sKalman->GetStateCov()))(ipar,ipar)+=deltaT*kerrsTime[ipar]*kerrsTime[ipar];
3083 sKalman->SetRunNumber(kalman->GetRunNumber());
3084 if (!isOK) sKalman->SetRunNumber(0);
3085 sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
3086 if (!isOK) continue;
3087 sKalman->SetRejectOutliers(kFALSE);
3088 sKalman->SetRunNumber(kalman->GetRunNumber());
3089 sKalman->SetTimeStamp(kalman->GetTimeStamp());
3090 sKalman->Merge(kalman);
3091 sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
3097 TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const arrayP, TObjArray * const arrayM){
3099 // Merge 2 RelKalman arrays
3101 // arrayP - rel kalman in direction plus
3102 // arrayM - rel kalman in direction minus
3103 if (!arrayP) return 0;
3104 if (arrayP->GetEntries()<=0) return 0;
3105 if (!arrayM) return 0;
3106 if (arrayM->GetEntries()<=0) return 0;
3108 Int_t entries = arrayP->GetEntriesFast();
3109 TObjArray *array = new TObjArray(arrayP->GetEntriesFast());
3111 for (Int_t i=0; i<entries; i++){
3112 AliRelAlignerKalman * kalmanP = (AliRelAlignerKalman *) arrayP->UncheckedAt(i);
3113 AliRelAlignerKalman * kalmanM = (AliRelAlignerKalman *) arrayM->UncheckedAt(i);
3114 if (!kalmanP) continue;
3115 if (!kalmanM) continue;
3117 AliRelAlignerKalman *kalman = NULL;
3118 if(kalmanP->GetRunNumber() != 0 && kalmanM->GetRunNumber() != 0) {
3119 kalman = new AliRelAlignerKalman(*kalmanP);
3120 kalman->Merge(kalmanM);
3122 else if (kalmanP->GetRunNumber() == 0) {
3123 kalman = new AliRelAlignerKalman(*kalmanM);
3125 else if (kalmanM->GetRunNumber() == 0) {
3126 kalman = new AliRelAlignerKalman(*kalmanP);
3131 array->AddAt(kalman,i);