1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // Class providing the calculation of derived quantities (mean,rms,fits,...) //
20 // of calibration entries //
25 ////////////////////////////////////////////////////////////////////////////////
29 #include <TObjArray.h>
32 #include <TDirectory.h>
34 #include <AliDCSSensorArray.h>
35 #include <AliDCSSensor.h>
36 #include "AliTPCcalibDB.h"
37 #include "AliTPCCalPad.h"
38 #include "AliTPCCalROC.h"
39 #include "AliTPCROC.h"
40 #include "AliTPCmapper.h"
41 #include "AliTPCParam.h"
42 #include "AliTPCCalibRaw.h"
43 #include "TGraphErrors.h"
45 #include "AliTPCcalibDButil.h"
46 #include "AliTPCPreprocessorOnline.h"
48 ClassImp(AliTPCcalibDButil)
49 AliTPCcalibDButil::AliTPCcalibDButil() :
51 fCalibDB(AliTPCcalibDB::Instance()),
57 fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")),
68 fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")),
75 fMapper(new AliTPCmapper(0x0)),
79 fPulTmaxLimitAbs(1.5),
87 //_____________________________________________________________________________________
88 AliTPCcalibDButil::~AliTPCcalibDButil()
93 delete fPulserOutlier;
94 delete fRefPulserOutlier;
96 if (fRefPadNoise) delete fRefPadNoise;
97 if (fRefPedestals) delete fRefPedestals;
98 if (fRefPulserTmean) delete fRefPulserTmean;
99 if (fRefPulserTrms) delete fRefPulserTrms;
100 if (fRefPulserQmean) delete fRefPulserQmean;
101 if (fRefCETmean) delete fRefCETmean;
102 if (fRefCETrms) delete fRefCETrms;
103 if (fRefCEQmean) delete fRefCEQmean;
104 if (fRefALTROMasked) delete fRefALTROMasked;
105 if (fRefCalibRaw) delete fRefCalibRaw;
108 //_____________________________________________________________________________________
109 void AliTPCcalibDButil::UpdateFromCalibDB()
112 // Update pointers from calibDB
114 fPadNoise=fCalibDB->GetPadNoise();
115 fPedestals=fCalibDB->GetPedestals();
116 fPulserTmean=fCalibDB->GetPulserTmean();
117 fPulserTrms=fCalibDB->GetPulserTrms();
118 fPulserQmean=fCalibDB->GetPulserQmean();
119 fCETmean=fCalibDB->GetCETmean();
120 fCETrms=fCalibDB->GetCETrms();
121 fCEQmean=fCalibDB->GetCEQmean();
122 fALTROMasked=fCalibDB->GetALTROMasked();
123 fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
124 fCalibRaw=fCalibDB->GetCalibRaw();
125 UpdatePulserOutlierMap();
127 //_____________________________________________________________________________________
128 void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
129 Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad *outCE)
132 // Process the CE data for this run
133 // the return TVectorD arrays contian the results of the fit
134 // noutliersCE contains the number of pads marked as outliers,
135 // not including masked and edge pads
138 //retrieve CE and ALTRO data
140 TString fitString(fitFormula);
141 fitString.ReplaceAll("++","#");
142 Int_t ndim=fitString.CountChar('#')+2;
143 fitResultsA.ResizeTo(ndim);
144 fitResultsC.ResizeTo(ndim);
153 if (outCE) out=outCE;
154 else out=new AliTPCCalPad("outCE","outCE");
155 AliTPCCalROC *rocMasked=0x0;
156 //loop over all channels
157 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
158 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
159 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc);
160 AliTPCCalROC *rocOut=out->GetCalROC(iroc);
162 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
166 //add time offset to IROCs
167 if (iroc<AliTPCROC::Instance()->GetNInnerSector())
168 rocData->Add(fIrocTimeOffset);
170 UInt_t nrows=rocData->GetNrows();
171 for (UInt_t irow=0;irow<nrows;++irow){
172 UInt_t npads=rocData->GetNPads(irow);
173 for (UInt_t ipad=0;ipad<npads;++ipad){
174 rocOut->SetValue(irow,ipad,0);
175 //exclude masked pads
176 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
177 rocOut->SetValue(irow,ipad,1);
180 //exclude first two rows in IROC and last two rows in OROC
182 if (irow<2) rocOut->SetValue(irow,ipad,1);
184 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
187 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
188 Float_t valTmean=rocData->GetValue(irow,ipad);
189 //exclude values that are exactly 0
191 rocOut->SetValue(irow,ipad,1);
194 // exclude channels with too large variations
195 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
196 rocOut->SetValue(irow,ipad,1);
204 Float_t chi2Af,chi2Cf;
205 fCETmean->GlobalSidesFit(out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2Af,chi2Cf);
208 if (!outCE) delete out;
210 //_____________________________________________________________________________________
211 void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian,
212 TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian,
213 Float_t &driftTimeA, Float_t &driftTimeC )
216 // Calculate statistical information from the CE graphs for drift time and charge
220 vecTEntries.ResizeTo(72);
221 vecTMean.ResizeTo(72);
222 vecTRMS.ResizeTo(72);
223 vecTMedian.ResizeTo(72);
224 vecQEntries.ResizeTo(72);
225 vecQMean.ResizeTo(72);
226 vecQRMS.ResizeTo(72);
227 vecQMedian.ResizeTo(72);
238 TObjArray *arrT=fCalibDB->GetCErocTtime();
239 TObjArray *arrQ=fCalibDB->GetCErocQtime();
241 for (Int_t isec=0;isec<74;++isec){
242 TGraph *gr=(TGraph*)arrT->At(isec);
245 Int_t npoints = gr->GetN();
246 values.ResizeTo(npoints);
248 //skip first points, theres always some problems with finding the CE position
249 for (Int_t ipoint=4; ipoint<npoints; ipoint++){
250 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1020 ){
251 values[nused]=gr->GetY()[ipoint];
256 if (isec<72) vecTEntries[isec]= nused;
259 vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
260 vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
261 vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
262 } else if (isec==72){
263 driftTimeA=TMath::Median(nused,values.GetMatrixArray());
264 } else if (isec==73){
265 driftTimeC=TMath::Median(nused,values.GetMatrixArray());
271 for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){
272 TGraph *gr=(TGraph*)arrQ->At(isec);
275 Int_t npoints = gr->GetN();
276 values.ResizeTo(npoints);
278 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
279 if (gr->GetY()[ipoint]>10 && gr->GetY()[ipoint]<500 ){
280 values[nused]=gr->GetY()[ipoint];
285 vecQEntries[isec]= nused;
287 vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
288 vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
289 vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
295 //_____________________________________________________________________________________
296 void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
297 TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
298 Int_t &nonMaskedZero)
301 // process noise data
302 // vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1],
303 // OROCs small pads [2] and OROCs large pads [3]
304 // vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot)
305 // nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error
308 //set proper size and reset
309 const UInt_t infoSize=4;
310 vNoiseMean.ResizeTo(infoSize);
311 vNoiseMeanSenRegions.ResizeTo(infoSize);
312 vNoiseRMS.ResizeTo(infoSize);
313 vNoiseRMSSenRegions.ResizeTo(infoSize);
315 vNoiseMeanSenRegions.Zero();
317 vNoiseRMSSenRegions.Zero();
320 TVectorD c(infoSize);
321 TVectorD cs(infoSize);
325 //retrieve noise and ALTRO data
326 if (!fPadNoise) return;
327 AliTPCCalROC *rocMasked=0x0;
328 //create IROC, OROC1, OROC2 and sensitive region masks
329 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
330 AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec);
331 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
332 UInt_t nrows=noiseROC->GetNrows();
333 for (UInt_t irow=0;irow<nrows;++irow){
334 UInt_t npads=noiseROC->GetNPads(irow);
335 for (UInt_t ipad=0;ipad<npads;++ipad){
336 //don't use masked channels;
337 if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
338 Float_t noiseVal=noiseROC->GetValue(irow,ipad);
345 if ( !(noiseVal<10000000) ){
346 printf ("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal);
349 Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
350 Int_t masksen=1; // sensitive pards are not masked (0)
351 if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive)
352 if (isec<AliTPCROC::Instance()->GetNInnerSector()){
354 if (irow>19&&irow<46){
355 if (TMath::Abs(cpad)<7) masksen=0; //IROC spot
358 vNoiseMean[type]+=noiseVal;
359 vNoiseRMS[type]+=noiseVal*noiseVal;
362 vNoiseMeanSenRegions[type]+=noiseVal;
363 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
368 //define sensive regions
369 if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive
371 Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad);
372 if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive
374 if ((Int_t)irow<par.GetNRowUp1()){
377 vNoiseMean[type]+=noiseVal;
378 vNoiseRMS[type]+=noiseVal*noiseVal;
381 vNoiseMeanSenRegions[type]+=noiseVal;
382 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
388 vNoiseMean[type]+=noiseVal;
389 vNoiseRMS[type]+=noiseVal*noiseVal;
392 vNoiseMeanSenRegions[type]+=noiseVal;
393 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
400 vNoiseMean[type]+=noiseVal;
401 vNoiseRMS[type]+=noiseVal*noiseVal;
404 vNoiseMeanSenRegions[type]+=noiseVal;
405 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
410 }//end loop sectors (rocs)
412 //calculate mean and RMS
413 const Double_t verySmall=0.0000000001;
414 for (UInt_t i=0;i<infoSize;++i){
421 // printf ("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]);
422 mean=vNoiseMean[i]/c[i];
424 rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
429 if (cs[i]>verySmall){
430 meanSen=vNoiseMeanSenRegions[i]/cs[i];
431 rmsSen=vNoiseRMSSenRegions[i];
432 rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen));
434 vNoiseMeanSenRegions[i]=meanSen;
435 vNoiseRMSSenRegions[i]=rmsSen;
439 //_____________________________________________________________________________________
440 void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
443 // Process the Pulser information
444 // vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C
447 const UInt_t infoSize=4;
448 //reset counters to error number
449 vMeanTime.ResizeTo(infoSize);
452 TVectorD c(infoSize);
453 //retrieve pulser and ALTRO data
454 if (!fPulserTmean) return;
457 AliTPCCalROC *rocOut=0x0;
458 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
459 AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
460 if (!tmeanROC) continue;
461 rocOut=fPulserOutlier->GetCalROC(isec);
462 UInt_t nchannels=tmeanROC->GetNchannels();
463 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
464 if (rocOut && rocOut->GetValue(ichannel)) continue;
465 Float_t val=tmeanROC->GetValue(ichannel);
467 vMeanTime[type]+=val;
472 for (UInt_t itype=0; itype<infoSize; ++itype){
473 if (c[itype]>0) vMeanTime[itype]/=c[itype];
474 else vMeanTime[itype]=0;
477 //_____________________________________________________________________________________
478 void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked)
481 // Get Values from ALTRO configuration data
484 if (!fALTROMasked) return;
486 for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){
487 AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec);
488 for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){
489 if (rocMasked->GetValue(ichannel)) ++nMasked;
493 //_____________________________________________________________________________________
494 void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS)
497 // Proces Goofie values, return statistical information of the currently set goofieArray
498 // The meaning of the entries are given below
500 1 TPC_ANODE_I_A00_STAT
502 3 TPC_DVM_DriftVelocity
507 8 TPC_DVM_NumberOfSparks
508 9 TPC_DVM_PeakAreaFar
509 10 TPC_DVM_PeakAreaNear
510 11 TPC_DVM_PeakPosFar
511 12 TPC_DVM_PeakPosNear
517 18 TPC_DVM_TemperatureS1
521 vecEntries.ResizeTo(nsensors);
522 vecMedian.ResizeTo(nsensors);
523 vecMean.ResizeTo(nsensors);
524 vecRMS.ResizeTo(nsensors);
531 Double_t kEpsilon=0.0000000001;
532 Double_t kBig=100000000000.;
533 Int_t nsensors = fGoofieArray->NumSensors();
534 vecEntries.ResizeTo(nsensors);
535 vecMedian.ResizeTo(nsensors);
536 vecMean.ResizeTo(nsensors);
537 vecRMS.ResizeTo(nsensors);
539 for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){
540 AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor);
541 if (gsensor && gsensor->GetGraph()){
542 Int_t npoints = gsensor->GetGraph()->GetN();
544 values.ResizeTo(npoints);
546 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
547 if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon &&
548 TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){
549 values[nused]=gsensor->GetGraph()->GetY()[ipoint];
554 vecEntries[isensor]= nused;
556 vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray());
557 vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray());
558 vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray());
563 //_____________________________________________________________________________________
564 void AliTPCcalibDButil::ProcessPedestalVariations(TVectorF &pedestalDeviations)
567 // check the variations of the pedestal data to the reference pedestal data
568 // thresholds are 0.5, 1.0, 1.5 and 2 timebins respectively.
571 TVectorF vThres(npar); //thresholds
572 Int_t nActive=0; //number of active channels
574 //reset and set thresholds
575 pedestalDeviations.ResizeTo(npar);
576 for (Int_t i=0;i<npar;++i){
577 pedestalDeviations.GetMatrixArray()[i]=0;
578 vThres.GetMatrixArray()[i]=(i+1)*.5;
580 //check all needed data is available
581 if (!fRefPedestals || !fPedestals || !fALTROMasked || !fRefALTROMasked) return;
582 //loop over all channels
583 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
584 AliTPCCalROC *pROC=fPedestals->GetCalROC(isec);
585 AliTPCCalROC *pRefROC=fRefPedestals->GetCalROC(isec);
586 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
587 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
588 UInt_t nrows=mROC->GetNrows();
589 for (UInt_t irow=0;irow<nrows;++irow){
590 UInt_t npads=mROC->GetNPads(irow);
591 for (UInt_t ipad=0;ipad<npads;++ipad){
592 //don't use masked channels;
593 if (mROC ->GetValue(irow,ipad)) continue;
594 if (mRefROC->GetValue(irow,ipad)) continue;
595 Float_t deviation=TMath::Abs(pROC->GetValue(irow,ipad)-pRefROC->GetValue(irow,ipad));
596 for (Int_t i=0;i<npar;++i){
597 if (deviation>vThres[i])
598 ++pedestalDeviations.GetMatrixArray()[i];
605 for (Int_t i=0;i<npar;++i){
606 pedestalDeviations.GetMatrixArray()[i]/=nActive;
610 //_____________________________________________________________________________________
611 void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations)
614 // check the variations of the noise data to the reference noise data
615 // thresholds are 5, 10, 15 and 20 percent respectively.
618 TVectorF vThres(npar); //thresholds
619 Int_t nActive=0; //number of active channels
621 //reset and set thresholds
622 noiseDeviations.ResizeTo(npar);
623 for (Int_t i=0;i<npar;++i){
624 noiseDeviations.GetMatrixArray()[i]=0;
625 vThres.GetMatrixArray()[i]=(i+1)*.05;
627 //check all needed data is available
628 if (!fRefPadNoise || !fPadNoise || !fALTROMasked || !fRefALTROMasked) return;
629 //loop over all channels
630 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
631 AliTPCCalROC *nROC=fPadNoise->GetCalROC(isec);
632 AliTPCCalROC *nRefROC=fRefPadNoise->GetCalROC(isec);
633 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
634 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
635 UInt_t nrows=mROC->GetNrows();
636 for (UInt_t irow=0;irow<nrows;++irow){
637 UInt_t npads=mROC->GetNPads(irow);
638 for (UInt_t ipad=0;ipad<npads;++ipad){
639 //don't use masked channels;
640 if (mROC ->GetValue(irow,ipad)) continue;
641 if (mRefROC->GetValue(irow,ipad)) continue;
642 Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
643 for (Int_t i=0;i<npar;++i){
644 if (deviation>vThres[i])
645 ++noiseDeviations.GetMatrixArray()[i];
652 for (Int_t i=0;i<npar;++i){
653 noiseDeviations.GetMatrixArray()[i]/=nActive;
657 //_____________________________________________________________________________________
658 void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Float_t &varQMean,
659 Int_t &npadsOutOneTB, Int_t &npadsOffAdd)
662 // check the variations of the pulserQmean data to the reference pulserQmean data: pulserQdeviations
663 // thresholds are .5, 1, 5 and 10 percent respectively.
667 TVectorF vThres(npar); //thresholds
668 Int_t nActive=0; //number of active channels
670 //reset and set thresholds
671 pulserQdeviations.ResizeTo(npar);
672 for (Int_t i=0;i<npar;++i){
673 pulserQdeviations.GetMatrixArray()[i]=0;
678 vThres.GetMatrixArray()[0]=.005;
679 vThres.GetMatrixArray()[1]=.01;
680 vThres.GetMatrixArray()[2]=.05;
681 vThres.GetMatrixArray()[3]=.1;
682 //check all needed data is available
683 if (!fRefPulserTmean || !fPulserTmean || !fPulserQmean || !fRefPulserQmean || !fALTROMasked || !fRefALTROMasked) return;
685 UpdateRefPulserOutlierMap();
686 //loop over all channels
687 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
688 AliTPCCalROC *pqROC=fPulserQmean->GetCalROC(isec);
689 AliTPCCalROC *pqRefROC=fRefPulserQmean->GetCalROC(isec);
690 AliTPCCalROC *ptROC=fPulserTmean->GetCalROC(isec);
691 // AliTPCCalROC *ptRefROC=fRefPulserTmean->GetCalROC(isec);
692 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
693 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
694 AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
695 Float_t pt_mean=ptROC->GetMean(oROC);
696 UInt_t nrows=mROC->GetNrows();
697 for (UInt_t irow=0;irow<nrows;++irow){
698 UInt_t npads=mROC->GetNPads(irow);
699 for (UInt_t ipad=0;ipad<npads;++ipad){
700 //don't use masked channels;
701 if (mROC ->GetValue(irow,ipad)) continue;
702 if (mRefROC->GetValue(irow,ipad)) continue;
703 //don't user edge pads
704 if (ipad==0||ipad==npads-1) continue;
706 Float_t pq=pqROC->GetValue(irow,ipad);
707 Float_t pqRef=pqRefROC->GetValue(irow,ipad);
708 Float_t pt=ptROC->GetValue(irow,ipad);
709 // Float_t ptRef=ptRefROC->GetValue(irow,ipad);
711 Float_t deviation=TMath::Abs(pq/pqRef-1);
712 for (Int_t i=0;i<npar;++i){
713 if (deviation>vThres[i])
714 ++pulserQdeviations.GetMatrixArray()[i];
716 if (pqRef>11&&pq<11) ++npadsOffAdd;
719 if (TMath::Abs(pt-pt_mean)>1) ++npadsOutOneTB;
725 for (Int_t i=0;i<npar;++i){
726 pulserQdeviations.GetMatrixArray()[i]/=nActive;
731 //_____________________________________________________________________________________
732 void AliTPCcalibDButil::UpdatePulserOutlierMap()
737 PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
739 //_____________________________________________________________________________________
740 void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
745 PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
747 //_____________________________________________________________________________________
748 void AliTPCcalibDButil::PulserOutlierMap(AliTPCCalPad *pulOut, const AliTPCCalPad *pulT, const AliTPCCalPad *pulQ)
751 // Create a map that contains outliers from the Pulser calibration data.
752 // The outliers include masked channels, edge pads and pads with
753 // too large timing and charge variations.
754 // fNpulserOutliers is the number of outliers in the Pulser calibration data.
755 // those do not contain masked and edge pads
759 pulOut->Multiply(0.);
763 AliTPCCalROC *rocMasked=0x0;
767 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
768 AliTPCCalROC *tmeanROC=pulT->GetCalROC(isec);
769 AliTPCCalROC *qmeanROC=pulQ->GetCalROC(isec);
770 AliTPCCalROC *outROC=pulOut->GetCalROC(isec);
771 if (!tmeanROC||!qmeanROC) {
772 //reset outliers in this ROC
773 outROC->Multiply(0.);
776 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
778 // Float_t qmedian=qmeanROC->GetLTM(&dummy,.5);
779 // Float_t tmedian=tmeanROC->GetLTM(&dummy,.5);
780 UInt_t nrows=tmeanROC->GetNrows();
781 for (UInt_t irow=0;irow<nrows;++irow){
782 UInt_t npads=tmeanROC->GetNPads(irow);
783 for (UInt_t ipad=0;ipad<npads;++ipad){
784 Int_t outlier=0,masked=0;
785 Float_t q=qmeanROC->GetValue(irow,ipad);
786 Float_t t=tmeanROC->GetValue(irow,ipad);
787 //masked channels are outliers
788 if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1;
789 //edge pads are outliers
790 if (ipad==0||ipad==npads-1) masked=1;
791 //channels with too large charge or timing deviation from the meadian are outliers
792 // if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1;
793 if (q<fPulQminLimit && !masked) outlier=1;
795 if ( !(q<10000000) || !(t<10000000)) outlier=1;
796 outROC->SetValue(irow,ipad,outlier+masked);
797 fNpulserOutliers+=outlier;
802 //_____________________________________________________________________________________
803 AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Double_t &gyC, Double_t &chi2A, Double_t &chi2C )
806 // Create pad time0 object from pulser and/or CE data, depending on the selected model
807 // Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser
808 // Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser
809 // Model 2: use CE data and a combination CE fit + pulser in the outlier regions.
811 // In case model 2 is invoked - gy arival time gradient is also returned
815 AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model));
816 // decide between different models
817 if (model==0||model==1){
819 if (model==1) ProcessPulser(vMean);
820 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
821 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
822 if (!rocPulTmean) continue;
823 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
824 AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
825 Float_t mean=rocPulTmean->GetMean(rocOut);
826 //treat case where a whole partition is masked
827 if (mean==0) mean=rocPulTmean->GetMean();
832 UInt_t nrows=rocTime0->GetNrows();
833 for (UInt_t irow=0;irow<nrows;++irow){
834 UInt_t npads=rocTime0->GetNPads(irow);
835 for (UInt_t ipad=0;ipad<npads;++ipad){
836 Float_t time=rocPulTmean->GetValue(irow,ipad);
837 //in case of an outlier pad use the mean of the altro values.
838 //This should be the most precise guess in that case.
839 if (rocOut->GetValue(irow,ipad)) {
840 time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
841 if (time==0) time=mean;
843 Float_t val=time-mean;
844 rocTime0->SetValue(irow,ipad,val);
848 } else if (model==2){
849 Double_t pgya,pgyc,pchi2a,pchi2c;
850 AliTPCCalPad * padPulser = CreatePadTime0(1,pgya,pgyc,pchi2a,pchi2c);
851 fCETmean->Add(padPulser,-1.);
853 AliTPCCalPad outCE("outCE","outCE");
855 ProcessCEdata("(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)++(ly/lx)^2",vA,vC,nOut,chi2A, chi2C,&outCE);
856 AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++0++gy++0++(lx-134)++0++0",vA,vC);
857 // AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC);
858 if (!padFit) { delete padPulser; return 0;}
861 fCETmean->Add(padPulser,1.);
862 padTime0->Add(fCETmean);
863 padTime0->Add(padFit,-1);
868 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
869 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
870 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
871 AliTPCCalROC *rocOutPul=fPulserOutlier->GetCalROC(isec);
872 AliTPCCalROC *rocOutCE=outCE.GetCalROC(isec);
873 rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
874 AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
875 Float_t mean=rocPulTmean->GetMean(rocOutPul);
876 if (mean==0) mean=rocPulTmean->GetMean();
877 UInt_t nrows=rocTime0->GetNrows();
878 for (UInt_t irow=0;irow<nrows;++irow){
879 UInt_t npads=rocTime0->GetNPads(irow);
880 for (UInt_t ipad=0;ipad<npads;++ipad){
881 Float_t timePulser=rocPulTmean->GetValue(irow,ipad)-mean;
882 if (rocOutCE->GetValue(irow,ipad)){
883 Float_t valOut=rocCEfit->GetValue(irow,ipad);
884 if (!rocOutPul->GetValue(irow,ipad)) valOut+=timePulser;
885 rocTime0->SetValue(irow,ipad,valOut);
893 Double_t median = padTime0->GetMedian();
894 padTime0->Add(-median); // normalize to median
897 //_____________________________________________________________________________________
898 Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *rocOut)
900 if (roc==0) return 0.;
901 const Int_t sector=roc->GetSector();
902 AliTPCROC *tpcRoc=AliTPCROC::Instance();
903 const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad);
907 //loop over a small range around the requested pad (+-10 rows/pads)
908 for (Int_t irow=row-10;irow<row+10;++irow){
909 if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue;
910 for (Int_t ipad=pad-10; ipad<pad+10;++ipad){
911 if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue;
912 const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad);
913 if (altroRoc!=altroCurr) continue;
914 if ( rocOut && rocOut->GetValue(irow,ipad) ) continue;
915 Float_t val=roc->GetValue(irow,ipad);
923 //_____________________________________________________________________________________
924 void AliTPCcalibDButil::SetRefFile(const char* filename)
927 // load cal pad objects form the reference file
929 TDirectory *currDir=gDirectory;
931 fRefPedestals=(AliTPCCalPad*)f.Get("Pedestals");
932 fRefPadNoise=(AliTPCCalPad*)f.Get("PadNoise");
934 fRefPulserTmean=(AliTPCCalPad*)f.Get("PulserTmean");
935 fRefPulserTrms=(AliTPCCalPad*)f.Get("PulserTrms");
936 fRefPulserQmean=(AliTPCCalPad*)f.Get("PulserQmean");
938 fRefCETmean=(AliTPCCalPad*)f.Get("CETmean");
939 fRefCETrms=(AliTPCCalPad*)f.Get("CETrms");
940 fRefCEQmean=(AliTPCCalPad*)f.Get("CEQmean");
942 // fRefALTROAcqStart=(AliTPCCalPad*)f.Get("ALTROAcqStart");
943 // fRefALTROZsThr=(AliTPCCalPad*)f.Get("ALTROZsThr");
944 // fRefALTROFPED=(AliTPCCalPad*)f.Get("ALTROFPED");
945 // fRefALTROAcqStop=(AliTPCCalPad*)f.Get("ALTROAcqStop");
946 fRefALTROMasked=(AliTPCCalPad*)f.Get("ALTROMasked");
954 AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad *ceOut, Float_t minSignal, Float_t cutTrmsMin, Float_t cutTrmsMax, Float_t cutMaxDistT){
956 // Author: marian.ivanov@cern.ch
958 // Create outlier map for CE study
960 // Return value - outlyer map
961 // noutlyersCE - number of outlyers
962 // minSignal - minimal total Q signal
963 // cutRMSMin - minimal width of the signal in respect to the median
964 // cutRMSMax - maximal width of the signal in respect to the median
965 // cutMaxDistT - maximal deviation from time median per chamber
967 // Outlyers criteria:
968 // 0. Exclude masked pads
969 // 1. Exclude first two rows in IROC and last two rows in OROC
970 // 2. Exclude edge pads
971 // 3. Exclude channels with too large variations
972 // 4. Exclude pads with too small signal
973 // 5. Exclude signal with outlyers RMS
974 // 6. Exclude channels to far from the chamber median
977 AliTPCCalPad *out=ceOut;
978 if (!out) out= new AliTPCCalPad("outCE","outCE");
979 AliTPCCalROC *rocMasked=0x0;
980 if (!fCETmean) return 0;
981 if (!fCETrms) return 0;
982 if (!fCEQmean) return 0;
984 //loop over all channels
986 Double_t rmsMedian = fCETrms->GetMedian();
987 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
988 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
989 if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
990 AliTPCCalROC *rocOut = out->GetCalROC(iroc);
991 AliTPCCalROC *rocCEQ = fCEQmean->GetCalROC(iroc);
992 AliTPCCalROC *rocCETrms = fCETrms->GetCalROC(iroc);
993 Double_t trocMedian = rocData->GetMedian();
996 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
1002 UInt_t nrows=rocData->GetNrows();
1003 for (UInt_t irow=0;irow<nrows;++irow){
1004 UInt_t npads=rocData->GetNPads(irow);
1005 for (UInt_t ipad=0;ipad<npads;++ipad){
1006 rocOut->SetValue(irow,ipad,0);
1007 Float_t valTmean=rocData->GetValue(irow,ipad);
1008 Float_t valQmean=rocCEQ->GetValue(irow,ipad);
1009 Float_t valTrms =rocCETrms->GetValue(irow,ipad);
1010 //0. exclude masked pads
1011 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
1012 rocOut->SetValue(irow,ipad,1);
1015 //1. exclude first two rows in IROC and last two rows in OROC
1017 if (irow<2) rocOut->SetValue(irow,ipad,1);
1019 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
1021 //2. exclude edge pads
1022 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
1023 //exclude values that are exactly 0
1025 rocOut->SetValue(irow,ipad,1);
1028 //3. exclude channels with too large variations
1029 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
1030 rocOut->SetValue(irow,ipad,1);
1034 //4. exclude channels with too small signal
1035 if (valQmean<minSignal) {
1036 rocOut->SetValue(irow,ipad,1);
1040 //5. exclude channels with too small rms
1041 if (valTrms<cutTrmsMin*rmsMedian || valTrms>cutTrmsMax*rmsMedian){
1042 rocOut->SetValue(irow,ipad,1);
1046 //6. exclude channels to far from the chamber median
1047 if (TMath::Abs(valTmean-trocMedian)>cutMaxDistT){
1048 rocOut->SetValue(irow,ipad,1);
1059 AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad *pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
1061 // Author: marian.ivanov@cern.ch
1063 // Create outlier map for Pulser
1065 // Return value - outlyer map
1066 // noutlyersPulser - number of outlyers
1067 // cutTime - absolute cut - distance to the median of chamber
1068 // cutnRMSQ - nsigma cut from median q distribution per chamber
1069 // cutnRMSrms - nsigma cut from median rms distribution
1070 // Outlyers criteria:
1071 // 0. Exclude masked pads
1072 // 1. Exclude time outlyers (default 3 time bins)
1073 // 2. Exclude q outlyers (default 5 sigma)
1074 // 3. Exclude rms outlyers (default 5 sigma)
1076 AliTPCCalPad *out=pulserOut;
1077 if (!out) out= new AliTPCCalPad("outPulser","outPulser");
1078 AliTPCCalROC *rocMasked=0x0;
1079 if (!fPulserTmean) return 0;
1080 if (!fPulserTrms) return 0;
1081 if (!fPulserQmean) return 0;
1083 //loop over all channels
1085 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1086 if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
1087 AliTPCCalROC *rocData = fPulserTmean->GetCalROC(iroc);
1088 AliTPCCalROC *rocOut = out->GetCalROC(iroc);
1089 AliTPCCalROC *rocPulserQ = fPulserQmean->GetCalROC(iroc);
1090 AliTPCCalROC *rocPulserTrms = fPulserTrms->GetCalROC(iroc);
1092 Double_t rocMedianT = rocData->GetMedian();
1093 Double_t rocMedianQ = rocPulserQ->GetMedian();
1094 Double_t rocRMSQ = rocPulserQ->GetRMS();
1095 Double_t rocMedianTrms = rocPulserTrms->GetMedian();
1096 Double_t rocRMSTrms = rocPulserTrms->GetRMS();
1097 for (UInt_t ichannel=0;ichannel<rocData->GetNchannels();++ichannel){
1098 rocOut->SetValue(ichannel,0);
1099 Float_t valTmean=rocData->GetValue(ichannel);
1100 Float_t valQmean=rocPulserQ->GetValue(ichannel);
1101 Float_t valTrms =rocPulserTrms->GetValue(ichannel);
1103 if (TMath::Abs(valTmean-rocMedianT)>cutTime) isOut=1;
1104 if (TMath::Abs(valQmean-rocMedianQ)>cutnRMSQ*rocRMSQ) isOut=1;
1105 if (TMath::Abs(valTrms-rocMedianTrms)>cutnRMSrms*rocRMSTrms) isOut=1;
1106 rocOut->SetValue(ichannel,isOut);
1107 if (isOut) noutliersPulser++;
1114 AliTPCCalPad *AliTPCcalibDButil::CreatePadTime0CE(TVectorD &fitResultsA, TVectorD&fitResultsC, Int_t &nOut, Double_t &chi2A, Double_t &chi2C, const char *dumpfile){
1116 // Author : Marian Ivanov
1117 // Create pad time0 correction map using information from the CE and from pulser
1120 // Return PadTime0 to be used for time0 relative alignment
1121 // if dump file specified intermediat results are dumped to the fiel and can be visualized
1122 // using $ALICE_ROOT/TPC/script/gui application
1124 // fitResultsA - fitParameters A side
1125 // fitResultsC - fitParameters C side
1126 // chi2A - chi2/ndf for A side (assuming error 1 time bin)
1127 // chi2C - chi2/ndf for C side (assuming error 1 time bin)
1131 // 1. Find outlier map for CE
1132 // 2. Find outlier map for Pulser
1133 // 3. Replace outlier by median at given sector (median without outliers)
1134 // 4. Substract from the CE data pulser
1135 // 5. Fit the CE with formula
1136 // 5.1) (IROC-OROC) offset
1140 // 5.5) (IROC-OROC)*(lx-xmid)
1142 // 6. Substract gy fit dependence from the CE data
1143 // 7. Add pulser back to CE data
1144 // 8. Replace outliers by fit value - median of diff per given chamber -GY fit
1145 // 9. return CE data
1147 // Time0 <= padCE = padCEin -padCEfitGy - if not outlier
1148 // Time0 <= padCE = padFitAll-padCEfitGy - if outlier
1151 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)";
1152 // output for fit formula
1153 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)";
1154 // gy part of formula
1155 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)";
1158 if (!fCETmean) return 0;
1159 Double_t pgya,pgyc,pchi2a,pchi2c;
1160 AliTPCCalPad * padPulserOut = CreatePulserOutlyerMap(nOut);
1161 AliTPCCalPad * padCEOut = CreateCEOutlyerMap(nOut);
1163 AliTPCCalPad * padPulser = CreatePadTime0(1,pgya,pgyc,pchi2a,pchi2c);
1164 AliTPCCalPad * padCE = new AliTPCCalPad(*fCETmean);
1165 AliTPCCalPad * padCEIn = new AliTPCCalPad(*fCETmean);
1166 AliTPCCalPad * padOut = new AliTPCCalPad("padOut","padOut");
1167 padPulser->SetName("padPulser");
1168 padPulserOut->SetName("padPulserOut");
1169 padCE->SetName("padCE");
1170 padCEIn->SetName("padCEIn");
1171 padCEOut->SetName("padCEOut");
1172 padOut->SetName("padOut");
1175 // make combined outlyers map
1176 // and replace outlyers in maps with median for chamber
1178 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1179 AliTPCCalROC * rocOut = padOut->GetCalROC(iroc);
1180 AliTPCCalROC * rocPulser = padPulser->GetCalROC(iroc);
1181 AliTPCCalROC * rocPulserOut = padPulserOut->GetCalROC(iroc);
1182 AliTPCCalROC * rocCEOut = padCEOut->GetCalROC(iroc);
1183 AliTPCCalROC * rocCE = padCE->GetCalROC(iroc);
1184 Double_t ceMedian = rocCE->GetMedian(rocCEOut);
1185 Double_t pulserMedian = rocPulser->GetMedian(rocCEOut);
1186 for (UInt_t ichannel=0;ichannel<rocOut->GetNchannels();++ichannel){
1187 if (rocPulserOut->GetValue(ichannel)>0) {
1188 rocPulser->SetValue(ichannel,pulserMedian);
1189 rocOut->SetValue(ichannel,1);
1191 if (rocCEOut->GetValue(ichannel)>0) {
1192 rocCE->SetValue(ichannel,ceMedian);
1193 rocOut->SetValue(ichannel,1);
1198 // remove pulser time 0
1200 padCE->Add(padPulser,-1);
1205 Float_t chi2Af,chi2Cf;
1206 padCE->GlobalSidesFit(padOut,formulaIn,fitResultsA,fitResultsC,dummy,dummy,chi2Af,chi2Cf);
1210 AliTPCCalPad *padCEFitGY=AliTPCCalPad::CreateCalPadFit(formulaOut,fitResultsA,fitResultsC);
1211 padCEFitGY->SetName("padCEFitGy");
1213 AliTPCCalPad *padCEFit =AliTPCCalPad::CreateCalPadFit(formulaAll,fitResultsA,fitResultsC);
1214 padCEFit->SetName("padCEFit");
1216 AliTPCCalPad* padCEDiff = new AliTPCCalPad(*padCE);
1217 padCEDiff->SetName("padCEDiff");
1218 padCEDiff->Add(padCEFit,-1.);
1221 padCE->Add(padCEFitGY,-1.);
1223 padCE->Add(padPulser,1.);
1224 Double_t padmedian = padCE->GetMedian();
1225 padCE->Add(-padmedian); // normalize to median
1227 // Replace outliers by fit value - median of diff per given chamber -GY fit
1229 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1230 AliTPCCalROC * rocOut = padOut->GetCalROC(iroc);
1231 AliTPCCalROC * rocCE = padCE->GetCalROC(iroc);
1232 AliTPCCalROC * rocCEFit = padCEFit->GetCalROC(iroc);
1233 AliTPCCalROC * rocCEFitGY = padCEFitGY->GetCalROC(iroc);
1234 AliTPCCalROC * rocCEDiff = padCEDiff->GetCalROC(iroc);
1236 Double_t diffMedian = rocCEDiff->GetMedian(rocOut);
1237 for (UInt_t ichannel=0;ichannel<rocOut->GetNchannels();++ichannel){
1238 if (rocOut->GetValue(ichannel)==0) continue;
1239 Float_t value=rocCEFit->GetValue(ichannel)-rocCEFitGY->GetValue(ichannel)-diffMedian-padmedian;
1240 rocCE->SetValue(ichannel,value);
1246 //dump to the file - result can be visualized
1247 AliTPCPreprocessorOnline preprocesor;
1248 preprocesor.AddComponent(new AliTPCCalPad(*padCE));
1249 preprocesor.AddComponent(new AliTPCCalPad(*padCEIn));
1250 preprocesor.AddComponent(new AliTPCCalPad(*padCEFit));
1251 preprocesor.AddComponent(new AliTPCCalPad(*padOut));
1253 preprocesor.AddComponent(new AliTPCCalPad(*padCEFitGY));
1254 preprocesor.AddComponent(new AliTPCCalPad(*padCEDiff));
1256 preprocesor.AddComponent(new AliTPCCalPad(*padCEOut));
1257 preprocesor.AddComponent(new AliTPCCalPad(*padPulser));
1258 preprocesor.AddComponent(new AliTPCCalPad(*padPulserOut));
1259 preprocesor.DumpToFile(dumpfile);
1262 delete padPulserOut;
1275 Int_t AliTPCcalibDButil::GetNearest(TGraph *graph, Double_t xref, Double_t &dx, Double_t &y){
1277 // find the closest point to xref in x direction
1278 // return dx and value
1280 index = TMath::BinarySearch(graph->GetN(), graph->GetX(),xref);
1281 if (index<0) index=0;
1282 if (index>=graph->GetN()-1) index=graph->GetN()-2;
1283 if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
1284 dx = xref-graph->GetX()[index];
1285 y = graph->GetY()[index];
1290 Double_t AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
1292 // Get the correction of the trigger offset
1293 // combining information from the laser track calibration
1294 // and from cosmic calibration
1297 // timeStamp - tim stamp in seconds
1298 // deltaT - integration period to calculate offset
1299 // deltaTLaser -max validity of laser data
1300 // valType - 0 - median, 1- mean
1302 // Integration vaues are just recomendation - if not possible to get points
1303 // automatically increase the validity by factor 2
1304 // (recursive algorithm until one month of data taking)
1307 const Float_t kLaserCut=0.0005;
1308 const Int_t kMaxPeriod=3600*24*30*3; // 3 month max
1309 const Int_t kMinPoints=20;
1311 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1313 AliTPCcalibDB::Instance()->UpdateRunInformations(run,kFALSE);
1315 array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1316 if (!array) return 0;
1318 TGraphErrors *laserA[3]={0,0,0};
1319 TGraphErrors *laserC[3]={0,0,0};
1320 TGraphErrors *cosmicAll=0;
1321 laserA[1]=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1322 laserC[1]=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1323 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1326 if (!cosmicAll) return 0;
1327 Int_t nmeasC=cosmicAll->GetN();
1328 Float_t *tdelta = new Float_t[nmeasC];
1330 for (Int_t i=0;i<nmeasC;i++){
1331 if (TMath::Abs(cosmicAll->GetX()[i]-timeStamp)>deltaT) continue;
1332 Float_t ccosmic=cosmicAll->GetY()[i];
1333 Double_t yA=0,yC=0,dA=0,dC=0;
1334 if (laserA[1]) GetNearest(laserA[1], cosmicAll->GetX()[i],dA,yA);
1335 if (laserC[1]) GetNearest(laserC[1], cosmicAll->GetX()[i],dC,yC);
1336 //yA=laserA[1]->Eval(cosmicAll->GetX()[i]);
1337 //yC=laserC[1]->Eval(cosmicAll->GetX()[i]);
1339 if (TMath::Sqrt(dA*dA+dC*dC)>deltaTLaser) continue;
1341 if (TMath::Abs(yA-yC)<kLaserCut) {
1344 if (i%2==0) claser=yA;
1345 if (i%2==1) claser=yC;
1347 tdelta[nused]=ccosmic-claser;
1350 if (nused<kMinPoints &&deltaT<kMaxPeriod) return AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
1351 Double_t median = TMath::Median(nused,tdelta);
1352 Double_t mean = TMath::Mean(nused,tdelta);
1354 return (valType==0) ? median:mean;
1357 Double_t AliTPCcalibDButil::GetVDriftTPC(Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
1359 // Get the correction of the drift velocity
1360 // combining information from the laser track calibration
1361 // and from cosmic calibration
1364 // timeStamp - tim stamp in seconds
1365 // deltaT - integration period to calculate time0 offset
1366 // deltaTLaser -max validity of laser data
1367 // valType - 0 - median, 1- mean
1369 // Integration vaues are just recomendation - if not possible to get points
1370 // automatically increase the validity by factor 2
1371 // (recursive algorithm until one month of data taking)
1375 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1377 AliTPCcalibDB::Instance()->UpdateRunInformations(run,kFALSE);
1379 array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1380 if (!array) return 0;
1381 TGraphErrors *cosmicAll=0;
1382 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1383 if (!cosmicAll) return 0;
1384 Double_t t0= AliTPCcalibDButil::GetTriggerOffsetTPC(run,timeStamp, deltaT, deltaTLaser,valType);
1385 Double_t vcosmic= cosmicAll->Eval(timeStamp);
1386 if (timeStamp>cosmicAll->GetX()[cosmicAll->GetN()-1]) vcosmic=timeStamp>cosmicAll->GetY()[cosmicAll->GetN()-1];
1387 if (timeStamp<cosmicAll->GetX()[0]) vcosmic=cosmicAll->GetY()[0];
1394 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1395 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1396 laserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1398 Double_t *yvd= new Double_t[cosmicAll->GetN()];
1399 Double_t *yt0= new Double_t[cosmicAll->GetN()];
1400 for (Int_t i=0; i<cosmicAll->GetN();i++) yvd[i]=AliTPCcalibDButil::GetVDriftTPC(run,cosmicAll->GetX()[i]);
1401 for (Int_t i=0; i<cosmicAll->GetN();i++) yt0[i]=AliTPCcalibDButil::GetTriggerOffsetTPC(run,cosmicAll->GetX()[i]);
1403 TGraph *pcosmicVd=new TGraph(cosmicAll->GetN(), cosmicAll->GetX(), yvd);
1404 TGraph *pcosmicT0=new TGraph(cosmicAll->GetN(), cosmicAll->GetX(), yt0);