]> git.uio.no Git - u/mrichter/AliRoot.git/blame - TPC/TPCbase/AliTPCcalibDButil.cxx
Update master to aliroot
[u/mrichter/AliRoot.git] / TPC / TPCbase / AliTPCcalibDButil.cxx
CommitLineData
892226be 1/**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
3 * *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
6 * *
7 * Permission to use, copy, modify and distribute this software and its *
8 * documentation strictly for non-commercial purposes is hereby granted *
9 * without fee, provided that the above copyright notice appears in all *
10 * copies and that both the copyright notice and this permission notice *
11 * appear in the supporting documentation. The authors make no claims *
12 * about the suitability of this software for any purpose. It is *
13 * provided "as is" without express or implied warranty. *
14 **************************************************************************/
15
16
7d855b04 17/// \class AliTPCcalibDButil
18/// \brief Class providing the calculation of derived quantities (mean,rms,fits,...) of calibration entries
892226be 19
20#include <TMath.h>
21#include <TVectorT.h>
22#include <TObjArray.h>
23#include <TGraph.h>
7390f655 24#include <TFile.h>
25#include <TDirectory.h>
949d8707 26#include <TMap.h>
27#include <TGraphErrors.h>
a23ba1c3 28#include <AliCDBStorage.h>
892226be 29#include <AliDCSSensorArray.h>
a23ba1c3 30#include <AliTPCSensorTempArray.h>
892226be 31#include <AliDCSSensor.h>
949d8707 32#include <AliLog.h>
33#include <AliCDBEntry.h>
34#include <AliCDBManager.h>
35#include <AliCDBId.h>
df5d3222 36#include <AliSplineFit.h>
892226be 37#include "AliTPCcalibDB.h"
38#include "AliTPCCalPad.h"
39#include "AliTPCCalROC.h"
40#include "AliTPCROC.h"
41#include "AliTPCmapper.h"
42#include "AliTPCParam.h"
6e7d7dc4 43#include "AliTPCCalibRaw.h"
949d8707 44#include "AliTPCPreprocessorOnline.h"
45#include "AliTPCdataQA.h"
a23ba1c3 46#include "AliLog.h"
892226be 47#include "AliTPCcalibDButil.h"
a23ba1c3 48#include "AliTPCCalibVdrift.h"
1fabc823 49#include "AliMathBase.h"
a980538f 50#include "AliRelAlignerKalman.h"
c4e4498c 51#include "TTree.h"
52#include "TROOT.h"
c4f17a0d 53#include "TKey.h"
892226be 54
8166d5d7 55const Float_t kAlmost0=1.e-30;
56
7d855b04 57/// \cond CLASSIMP
892226be 58ClassImp(AliTPCcalibDButil)
7d855b04 59/// \endcond
892226be 60AliTPCcalibDButil::AliTPCcalibDButil() :
61 TObject(),
1e722a63 62 fCalibDB(0),
892226be 63 fPadNoise(0x0),
64 fPedestals(0x0),
65 fPulserTmean(0x0),
66 fPulserTrms(0x0),
67 fPulserQmean(0x0),
68 fPulserOutlier(new AliTPCCalPad("PulserOutliers","PulserOutliers")),
69 fCETmean(0x0),
70 fCETrms(0x0),
71 fCEQmean(0x0),
72 fALTROMasked(0x0),
6e7d7dc4 73 fCalibRaw(0x0),
949d8707 74 fDataQA(0x0),
75 fRefMap(0x0),
76 fCurrentRefMap(0x0),
77 fRefValidity(""),
7390f655 78 fRefPadNoise(0x0),
79 fRefPedestals(0x0),
949d8707 80 fRefPedestalMasked(0x0),
7390f655 81 fRefPulserTmean(0x0),
82 fRefPulserTrms(0x0),
83 fRefPulserQmean(0x0),
84 fRefPulserOutlier(new AliTPCCalPad("RefPulserOutliers","RefPulserOutliers")),
949d8707 85 fRefPulserMasked(0x0),
7390f655 86 fRefCETmean(0x0),
87 fRefCETrms(0x0),
88 fRefCEQmean(0x0),
949d8707 89 fRefCEMasked(0x0),
90 fRefALTROFPED(0x0),
91 fRefALTROZsThr(0x0),
92 fRefALTROAcqStart(0x0),
93 fRefALTROAcqStop(0x0),
7390f655 94 fRefALTROMasked(0x0),
95 fRefCalibRaw(0x0),
949d8707 96 fRefDataQA(0x0),
892226be 97 fGoofieArray(0x0),
98 fMapper(new AliTPCmapper(0x0)),
99 fNpulserOutliers(-1),
7390f655 100 fIrocTimeOffset(0),
892226be 101 fCETmaxLimitAbs(1.5),
102 fPulTmaxLimitAbs(1.5),
103 fPulQmaxLimitAbs(5),
a23ba1c3 104 fPulQminLimit(11),
105 fRuns(0), // run list with OCDB info
106 fRunsStart(0), // start time for given run
107 fRunsStop(0) // stop time for given run
892226be 108{
109 //
110 // Default ctor
111 //
112}
113//_____________________________________________________________________________________
114AliTPCcalibDButil::~AliTPCcalibDButil()
115{
7d855b04 116 /// dtor
117
892226be 118 delete fPulserOutlier;
7390f655 119 delete fRefPulserOutlier;
892226be 120 delete fMapper;
7390f655 121 if (fRefPadNoise) delete fRefPadNoise;
122 if (fRefPedestals) delete fRefPedestals;
949d8707 123 if (fRefPedestalMasked) delete fRefPedestalMasked;
7390f655 124 if (fRefPulserTmean) delete fRefPulserTmean;
125 if (fRefPulserTrms) delete fRefPulserTrms;
126 if (fRefPulserQmean) delete fRefPulserQmean;
949d8707 127 if (fRefPulserMasked) delete fRefPulserMasked;
7390f655 128 if (fRefCETmean) delete fRefCETmean;
129 if (fRefCETrms) delete fRefCETrms;
130 if (fRefCEQmean) delete fRefCEQmean;
949d8707 131 if (fRefCEMasked) delete fRefCEMasked;
132 if (fRefALTROFPED) delete fRefALTROFPED;
133 if (fRefALTROZsThr) delete fRefALTROZsThr;
134 if (fRefALTROAcqStart) delete fRefALTROAcqStart;
135 if (fRefALTROAcqStop) delete fRefALTROAcqStop;
7390f655 136 if (fRefALTROMasked) delete fRefALTROMasked;
137 if (fRefCalibRaw) delete fRefCalibRaw;
949d8707 138 if (fCurrentRefMap) delete fCurrentRefMap;
892226be 139}
140//_____________________________________________________________________________________
141void AliTPCcalibDButil::UpdateFromCalibDB()
142{
7d855b04 143 /// Update pointers from calibDB
144
1e722a63 145 if (!fCalibDB) fCalibDB=AliTPCcalibDB::Instance();
56ce896d 146 fCalibDB->UpdateNonRec(); // load all infromation now
892226be 147 fPadNoise=fCalibDB->GetPadNoise();
148 fPedestals=fCalibDB->GetPedestals();
149 fPulserTmean=fCalibDB->GetPulserTmean();
150 fPulserTrms=fCalibDB->GetPulserTrms();
151 fPulserQmean=fCalibDB->GetPulserQmean();
152 fCETmean=fCalibDB->GetCETmean();
153 fCETrms=fCalibDB->GetCETrms();
154 fCEQmean=fCalibDB->GetCEQmean();
155 fALTROMasked=fCalibDB->GetALTROMasked();
156 fGoofieArray=fCalibDB->GetGoofieSensors(fCalibDB->GetRun());
6e7d7dc4 157 fCalibRaw=fCalibDB->GetCalibRaw();
949d8707 158 fDataQA=fCalibDB->GetDataQA();
892226be 159 UpdatePulserOutlierMap();
22c558aa 160// SetReferenceRun();
161// UpdateRefDataFromOCDB();
892226be 162}
163//_____________________________________________________________________________________
7390f655 164void AliTPCcalibDButil::ProcessCEdata(const char* fitFormula, TVectorD &fitResultsA, TVectorD &fitResultsC,
8166d5d7 165 Int_t &noutliersCE, Double_t & chi2A, Double_t &chi2C, AliTPCCalPad * const outCE)
892226be 166{
7d855b04 167 /// Process the CE data for this run
168 /// the return TVectorD arrays contian the results of the fit
169 /// noutliersCE contains the number of pads marked as outliers,
170 /// not including masked and edge pads
171
892226be 172 //retrieve CE and ALTRO data
173 if (!fCETmean){
174 TString fitString(fitFormula);
175 fitString.ReplaceAll("++","#");
176 Int_t ndim=fitString.CountChar('#')+2;
177 fitResultsA.ResizeTo(ndim);
178 fitResultsC.ResizeTo(ndim);
179 fitResultsA.Zero();
180 fitResultsC.Zero();
181 noutliersCE=-1;
182 return;
183 }
184 noutliersCE=0;
185 //create outlier map
7390f655 186 AliTPCCalPad *out=0;
187 if (outCE) out=outCE;
188 else out=new AliTPCCalPad("outCE","outCE");
892226be 189 AliTPCCalROC *rocMasked=0x0;
190 //loop over all channels
191 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
192 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
193 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(iroc);
7390f655 194 AliTPCCalROC *rocOut=out->GetCalROC(iroc);
6e7d7dc4 195 if (!rocData) {
196 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
7390f655 197 rocOut->Add(1.);
6e7d7dc4 198 continue;
199 }
892226be 200 //add time offset to IROCs
201 if (iroc<AliTPCROC::Instance()->GetNInnerSector())
202 rocData->Add(fIrocTimeOffset);
203 //select outliers
204 UInt_t nrows=rocData->GetNrows();
205 for (UInt_t irow=0;irow<nrows;++irow){
206 UInt_t npads=rocData->GetNPads(irow);
207 for (UInt_t ipad=0;ipad<npads;++ipad){
7390f655 208 rocOut->SetValue(irow,ipad,0);
892226be 209 //exclude masked pads
210 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
7390f655 211 rocOut->SetValue(irow,ipad,1);
892226be 212 continue;
213 }
732e90a8 214 //exclude first two rows in IROC and last two rows in OROC
215 if (iroc<36){
216 if (irow<2) rocOut->SetValue(irow,ipad,1);
217 } else {
218 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
219 }
892226be 220 //exclude edge pads
7390f655 221 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
222 Float_t valTmean=rocData->GetValue(irow,ipad);
892226be 223 //exclude values that are exactly 0
8166d5d7 224 if ( !(TMath::Abs(valTmean)>kAlmost0) ) {
7390f655 225 rocOut->SetValue(irow,ipad,1);
892226be 226 ++noutliersCE;
227 }
228 // exclude channels with too large variations
229 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
7390f655 230 rocOut->SetValue(irow,ipad,1);
892226be 231 ++noutliersCE;
232 }
233 }
234 }
235 }
236 //perform fit
237 TMatrixD dummy;
2cb269df 238 Float_t chi2Af,chi2Cf;
239 fCETmean->GlobalSidesFit(out,fitFormula,fitResultsA,fitResultsC,dummy,dummy,chi2Af,chi2Cf);
240 chi2A=chi2Af;
241 chi2C=chi2Cf;
7390f655 242 if (!outCE) delete out;
892226be 243}
244//_____________________________________________________________________________________
245void AliTPCcalibDButil::ProcessCEgraphs(TVectorD &vecTEntries, TVectorD &vecTMean, TVectorD &vecTRMS, TVectorD &vecTMedian,
246 TVectorD &vecQEntries, TVectorD &vecQMean, TVectorD &vecQRMS, TVectorD &vecQMedian,
247 Float_t &driftTimeA, Float_t &driftTimeC )
248{
7d855b04 249 /// Calculate statistical information from the CE graphs for drift time and charge
250
892226be 251 //reset arrays
252 vecTEntries.ResizeTo(72);
253 vecTMean.ResizeTo(72);
254 vecTRMS.ResizeTo(72);
255 vecTMedian.ResizeTo(72);
256 vecQEntries.ResizeTo(72);
257 vecQMean.ResizeTo(72);
258 vecQRMS.ResizeTo(72);
259 vecQMedian.ResizeTo(72);
260 vecTEntries.Zero();
261 vecTMean.Zero();
262 vecTRMS.Zero();
263 vecTMedian.Zero();
264 vecQEntries.Zero();
265 vecQMean.Zero();
266 vecQRMS.Zero();
267 vecQMedian.Zero();
268 driftTimeA=0;
269 driftTimeC=0;
270 TObjArray *arrT=fCalibDB->GetCErocTtime();
271 TObjArray *arrQ=fCalibDB->GetCErocQtime();
272 if (arrT){
273 for (Int_t isec=0;isec<74;++isec){
274 TGraph *gr=(TGraph*)arrT->At(isec);
275 if (!gr) continue;
276 TVectorD values;
277 Int_t npoints = gr->GetN();
278 values.ResizeTo(npoints);
279 Int_t nused =0;
6e7d7dc4 280 //skip first points, theres always some problems with finding the CE position
281 for (Int_t ipoint=4; ipoint<npoints; ipoint++){
282 if (gr->GetY()[ipoint]>500 && gr->GetY()[ipoint]<1020 ){
892226be 283 values[nused]=gr->GetY()[ipoint];
284 nused++;
285 }
286 }
287 //
288 if (isec<72) vecTEntries[isec]= nused;
289 if (nused>1){
290 if (isec<72){
291 vecTMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
292 vecTMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
293 vecTRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
294 } else if (isec==72){
295 driftTimeA=TMath::Median(nused,values.GetMatrixArray());
296 } else if (isec==73){
297 driftTimeC=TMath::Median(nused,values.GetMatrixArray());
298 }
299 }
300 }
301 }
302 if (arrQ){
6e7d7dc4 303 for (Int_t isec=0;isec<arrQ->GetEntriesFast();++isec){
892226be 304 TGraph *gr=(TGraph*)arrQ->At(isec);
305 if (!gr) continue;
306 TVectorD values;
307 Int_t npoints = gr->GetN();
308 values.ResizeTo(npoints);
309 Int_t nused =0;
310 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
817766d5 311 if (gr->GetY()[ipoint]>10 && gr->GetY()[ipoint]<500 ){
892226be 312 values[nused]=gr->GetY()[ipoint];
313 nused++;
314 }
315 }
316 //
6e7d7dc4 317 vecQEntries[isec]= nused;
892226be 318 if (nused>1){
319 vecQMedian[isec] = TMath::Median(nused,values.GetMatrixArray());
320 vecQMean[isec] = TMath::Mean(nused,values.GetMatrixArray());
321 vecQRMS[isec] = TMath::RMS(nused,values.GetMatrixArray());
322 }
323 }
324 }
325}
326
327//_____________________________________________________________________________________
328void AliTPCcalibDButil::ProcessNoiseData(TVectorD &vNoiseMean, TVectorD &vNoiseMeanSenRegions,
329 TVectorD &vNoiseRMS, TVectorD &vNoiseRMSSenRegions,
93425263 330 Int_t &nonMaskedZero, Int_t &nNaN)
892226be 331{
7d855b04 332 /// process noise data
333 /// vNoiseMean/RMS contains the Mean/RMS noise of the complete TPC [0], IROCs only [1],
334 /// OROCs small pads [2] and OROCs large pads [3]
335 /// vNoiseMean/RMSsenRegions constains the same information, but only for the sensitive regions (edge pads, corners, IROC spot)
336 /// nonMaskedZero contains the number of pads which show zero noise and were not masked. This might indicate an error
337
892226be 338 //set proper size and reset
339 const UInt_t infoSize=4;
340 vNoiseMean.ResizeTo(infoSize);
341 vNoiseMeanSenRegions.ResizeTo(infoSize);
342 vNoiseRMS.ResizeTo(infoSize);
343 vNoiseRMSSenRegions.ResizeTo(infoSize);
344 vNoiseMean.Zero();
345 vNoiseMeanSenRegions.Zero();
346 vNoiseRMS.Zero();
347 vNoiseRMSSenRegions.Zero();
348 nonMaskedZero=0;
93425263 349 nNaN=0;
892226be 350 //counters
351 TVectorD c(infoSize);
352 TVectorD cs(infoSize);
353 //tpc parameters
354 AliTPCParam par;
355 par.Update();
356 //retrieve noise and ALTRO data
357 if (!fPadNoise) return;
358 AliTPCCalROC *rocMasked=0x0;
359 //create IROC, OROC1, OROC2 and sensitive region masks
360 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
361 AliTPCCalROC *noiseROC=fPadNoise->GetCalROC(isec);
362 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
363 UInt_t nrows=noiseROC->GetNrows();
364 for (UInt_t irow=0;irow<nrows;++irow){
365 UInt_t npads=noiseROC->GetNPads(irow);
366 for (UInt_t ipad=0;ipad<npads;++ipad){
367 //don't use masked channels;
368 if (rocMasked && rocMasked->GetValue(irow,ipad)) continue;
369 Float_t noiseVal=noiseROC->GetValue(irow,ipad);
370 //check if noise==0
8166d5d7 371 if (noiseVal<kAlmost0) {
892226be 372 ++nonMaskedZero;
373 continue;
374 }
375 //check for nan
376 if ( !(noiseVal<10000000) ){
ef1807ef 377 AliInfo(Form("Warning: nan detected in (sec,row,pad - val): %02d,%02d,%03d - %.1f\n",isec,irow,ipad,noiseVal));
93425263 378 ++nNaN;
892226be 379 continue;
380 }
381 Int_t cpad=(Int_t)ipad-(Int_t)npads/2;
382 Int_t masksen=1; // sensitive pards are not masked (0)
383 if (ipad<2||npads-ipad-1<2) masksen=0; //don't mask edge pads (sensitive)
384 if (isec<AliTPCROC::Instance()->GetNInnerSector()){
385 //IROCs
386 if (irow>19&&irow<46){
387 if (TMath::Abs(cpad)<7) masksen=0; //IROC spot
388 }
389 Int_t type=1;
390 vNoiseMean[type]+=noiseVal;
391 vNoiseRMS[type]+=noiseVal*noiseVal;
392 ++c[type];
393 if (!masksen){
394 vNoiseMeanSenRegions[type]+=noiseVal;
395 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
396 ++cs[type];
397 }
398 } else {
399 //OROCs
400 //define sensive regions
401 if ((nrows-irow-1)<3) masksen=0; //last three rows in OROCs are sensitive
402 if ( irow>75 ){
403 Int_t padEdge=(Int_t)TMath::Min(ipad,npads-ipad);
404 if (padEdge<((((Int_t)irow-76)/4+1))*2) masksen=0; //OROC outer corners are sensitive
405 }
406 if ((Int_t)irow<par.GetNRowUp1()){
407 //OROC1
408 Int_t type=2;
409 vNoiseMean[type]+=noiseVal;
410 vNoiseRMS[type]+=noiseVal*noiseVal;
411 ++c[type];
412 if (!masksen){
413 vNoiseMeanSenRegions[type]+=noiseVal;
414 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
415 ++cs[type];
416 }
417 }else{
418 //OROC2
419 Int_t type=3;
420 vNoiseMean[type]+=noiseVal;
421 vNoiseRMS[type]+=noiseVal*noiseVal;
422 ++c[type];
423 if (!masksen){
424 vNoiseMeanSenRegions[type]+=noiseVal;
425 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
426 ++cs[type];
427 }
428 }
429 }
430 //whole tpc
431 Int_t type=0;
432 vNoiseMean[type]+=noiseVal;
433 vNoiseRMS[type]+=noiseVal*noiseVal;
434 ++c[type];
435 if (!masksen){
436 vNoiseMeanSenRegions[type]+=noiseVal;
437 vNoiseRMSSenRegions[type]+=noiseVal*noiseVal;
438 ++cs[type];
439 }
440 }//end loop pads
441 }//end loop rows
442 }//end loop sectors (rocs)
443
444 //calculate mean and RMS
445 const Double_t verySmall=0.0000000001;
446 for (UInt_t i=0;i<infoSize;++i){
447 Double_t mean=0;
448 Double_t rms=0;
449 Double_t meanSen=0;
450 Double_t rmsSen=0;
451
452 if (c[i]>verySmall){
ef1807ef 453 AliInfo(Form("i: %d - m: %.3f, c: %.0f, r: %.3f\n",i,vNoiseMean[i],c[i],vNoiseRMS[i]));
892226be 454 mean=vNoiseMean[i]/c[i];
455 rms=vNoiseRMS[i];
456 rms=TMath::Sqrt(TMath::Abs(rms/c[i]-mean*mean));
457 }
458 vNoiseMean[i]=mean;
459 vNoiseRMS[i]=rms;
460
461 if (cs[i]>verySmall){
462 meanSen=vNoiseMeanSenRegions[i]/cs[i];
463 rmsSen=vNoiseRMSSenRegions[i];
464 rmsSen=TMath::Sqrt(TMath::Abs(rmsSen/cs[i]-meanSen*meanSen));
465 }
466 vNoiseMeanSenRegions[i]=meanSen;
467 vNoiseRMSSenRegions[i]=rmsSen;
468 }
469}
470
abb20887 471//_____________________________________________________________________________________
472void AliTPCcalibDButil::ProcessQAData(TVectorD &vQaOcc, TVectorD &vQaQtot,
473 TVectorD &vQaQmax)
474{
7d855b04 475 /// process QA data
476 ///
477 /// vQaOcc/Qtot/Qmax contains the Mean occupancy/Qtot/Qmax for each sector
abb20887 478
479
480 const UInt_t infoSize = 72;
481 //reset counters to error number
482 vQaOcc.ResizeTo(infoSize);
483 vQaOcc.Zero();
484 vQaQtot.ResizeTo(infoSize);
485 vQaQtot.Zero();
486 vQaQmax.ResizeTo(infoSize);
487 vQaQmax.Zero();
488 //counter
489 //retrieve pulser and ALTRO data
490
491 if (!fDataQA) {
492
493 AliInfo("No QA data");
494 return;
495 }
496 if (fDataQA->GetEventCounter()<=0) {
497
498 AliInfo("No QA data");
499 return; // no data processed
500 }
501 //
502 fDataQA->Analyse();
503
504 TVectorD normOcc(infoSize);
505 TVectorD normQ(infoSize);
506
507 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
508
ef1807ef 509 AliInfo(Form("Sector %d\n", isec));
abb20887 510 AliTPCCalROC* occupancyROC = fDataQA->GetNoThreshold()->GetCalROC(isec);
511 AliTPCCalROC* nclusterROC = fDataQA->GetNLocalMaxima()->GetCalROC(isec);
512 AliTPCCalROC* qROC = fDataQA->GetMeanCharge()->GetCalROC(isec);
513 AliTPCCalROC* qmaxROC = fDataQA->GetMaxCharge()->GetCalROC(isec);
514 if (!occupancyROC) continue;
515 if (!nclusterROC) continue;
516 if (!qROC) continue;
517 if (!qmaxROC) continue;
518
519 const UInt_t nchannels=occupancyROC->GetNchannels();
520
ef1807ef 521 AliInfo(Form("Nchannels %d\n", nchannels));
abb20887 522
523 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
524
525 vQaOcc[isec] += occupancyROC->GetValue(ichannel);
526 ++normOcc[isec];
527
528 Float_t nClusters = nclusterROC->GetValue(ichannel);
529 normQ[isec] += nClusters;
530 vQaQtot[isec]+=nClusters*qROC->GetValue(ichannel);
531 vQaQmax[isec]+=nClusters*qmaxROC->GetValue(ichannel);
532 }
533 }
534
535 //calculate mean values
536 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
537
538 if (normOcc[isec]>0) vQaOcc[isec] /= normOcc[isec];
539 else vQaOcc[isec] = 0;
540
541 if (normQ[isec]>0) {
542 vQaQtot[isec] /= normQ[isec];
543 vQaQmax[isec] /= normQ[isec];
544 }else {
545
546 vQaQtot[isec] = 0;
547 vQaQmax[isec] = 0;
548 }
549 }
550}
551
892226be 552//_____________________________________________________________________________________
553void AliTPCcalibDButil::ProcessPulser(TVectorD &vMeanTime)
554{
7d855b04 555 /// Process the Pulser information
556 /// vMeanTime: pulser mean time position in IROC-A, IROC-C, OROC-A, OROC-C
892226be 557
558 const UInt_t infoSize=4;
559 //reset counters to error number
560 vMeanTime.ResizeTo(infoSize);
561 vMeanTime.Zero();
562 //counter
563 TVectorD c(infoSize);
564 //retrieve pulser and ALTRO data
565 if (!fPulserTmean) return;
566 //
567 //get Outliers
568 AliTPCCalROC *rocOut=0x0;
569 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
570 AliTPCCalROC *tmeanROC=fPulserTmean->GetCalROC(isec);
571 if (!tmeanROC) continue;
572 rocOut=fPulserOutlier->GetCalROC(isec);
573 UInt_t nchannels=tmeanROC->GetNchannels();
574 for (UInt_t ichannel=0;ichannel<nchannels;++ichannel){
575 if (rocOut && rocOut->GetValue(ichannel)) continue;
576 Float_t val=tmeanROC->GetValue(ichannel);
577 Int_t type=isec/18;
578 vMeanTime[type]+=val;
579 ++c[type];
580 }
581 }
582 //calculate mean
583 for (UInt_t itype=0; itype<infoSize; ++itype){
584 if (c[itype]>0) vMeanTime[itype]/=c[itype];
585 else vMeanTime[itype]=0;
586 }
587}
588//_____________________________________________________________________________________
589void AliTPCcalibDButil::ProcessALTROConfig(Int_t &nMasked)
590{
7d855b04 591 /// Get Values from ALTRO configuration data
592
892226be 593 nMasked=-1;
594 if (!fALTROMasked) return;
595 nMasked=0;
596 for (Int_t isec=0;isec<fALTROMasked->kNsec; ++isec){
597 AliTPCCalROC *rocMasked=fALTROMasked->GetCalROC(isec);
598 for (UInt_t ichannel=0; ichannel<rocMasked->GetNchannels();++ichannel){
599 if (rocMasked->GetValue(ichannel)) ++nMasked;
600 }
601 }
602}
603//_____________________________________________________________________________________
604void AliTPCcalibDButil::ProcessGoofie(TVectorD & vecEntries, TVectorD & vecMedian, TVectorD &vecMean, TVectorD &vecRMS)
605{
7d855b04 606 /// Proces Goofie values, return statistical information of the currently set goofieArray
607 /// The meaning of the entries are given below
608
892226be 609 /*
610 1 TPC_ANODE_I_A00_STAT
611 2 TPC_DVM_CO2
612 3 TPC_DVM_DriftVelocity
613 4 TPC_DVM_FCageHV
614 5 TPC_DVM_GainFar
615 6 TPC_DVM_GainNear
616 7 TPC_DVM_N2
617 8 TPC_DVM_NumberOfSparks
618 9 TPC_DVM_PeakAreaFar
619 10 TPC_DVM_PeakAreaNear
620 11 TPC_DVM_PeakPosFar
621 12 TPC_DVM_PeakPosNear
622 13 TPC_DVM_PickupHV
623 14 TPC_DVM_Pressure
624 15 TPC_DVM_T1_Over_P
625 16 TPC_DVM_T2_Over_P
626 17 TPC_DVM_T_Over_P
627 18 TPC_DVM_TemperatureS1
628 */
629 if (!fGoofieArray){
630 Int_t nsensors=19;
631 vecEntries.ResizeTo(nsensors);
632 vecMedian.ResizeTo(nsensors);
633 vecMean.ResizeTo(nsensors);
634 vecRMS.ResizeTo(nsensors);
635 vecEntries.Zero();
636 vecMedian.Zero();
637 vecMean.Zero();
638 vecRMS.Zero();
639 return;
640 }
641 Double_t kEpsilon=0.0000000001;
642 Double_t kBig=100000000000.;
643 Int_t nsensors = fGoofieArray->NumSensors();
644 vecEntries.ResizeTo(nsensors);
645 vecMedian.ResizeTo(nsensors);
646 vecMean.ResizeTo(nsensors);
647 vecRMS.ResizeTo(nsensors);
648 TVectorF values;
649 for (Int_t isensor=0; isensor<fGoofieArray->NumSensors();isensor++){
650 AliDCSSensor *gsensor = fGoofieArray->GetSensor(isensor);
651 if (gsensor && gsensor->GetGraph()){
652 Int_t npoints = gsensor->GetGraph()->GetN();
653 // filter zeroes
654 values.ResizeTo(npoints);
655 Int_t nused =0;
656 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
657 if (TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])>kEpsilon &&
658 TMath::Abs(gsensor->GetGraph()->GetY()[ipoint])<kBig ){
659 values[nused]=gsensor->GetGraph()->GetY()[ipoint];
660 nused++;
661 }
662 }
663 //
664 vecEntries[isensor]= nused;
665 if (nused>1){
666 vecMedian[isensor] = TMath::Median(nused,values.GetMatrixArray());
667 vecMean[isensor] = TMath::Mean(nused,values.GetMatrixArray());
668 vecRMS[isensor] = TMath::RMS(nused,values.GetMatrixArray());
669 }
670 }
671 }
672}
7390f655 673//_____________________________________________________________________________________
674void AliTPCcalibDButil::ProcessPedestalVariations(TVectorF &pedestalDeviations)
675{
7d855b04 676 /// check the variations of the pedestal data to the reference pedestal data
677 /// thresholds are 0.5, 1.0, 1.5 and 2 timebins respectively.
678
7390f655 679 const Int_t npar=4;
680 TVectorF vThres(npar); //thresholds
681 Int_t nActive=0; //number of active channels
682
683 //reset and set thresholds
684 pedestalDeviations.ResizeTo(npar);
685 for (Int_t i=0;i<npar;++i){
686 pedestalDeviations.GetMatrixArray()[i]=0;
687 vThres.GetMatrixArray()[i]=(i+1)*.5;
688 }
689 //check all needed data is available
690 if (!fRefPedestals || !fPedestals || !fALTROMasked || !fRefALTROMasked) return;
691 //loop over all channels
692 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
693 AliTPCCalROC *pROC=fPedestals->GetCalROC(isec);
694 AliTPCCalROC *pRefROC=fRefPedestals->GetCalROC(isec);
695 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
696 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
697 UInt_t nrows=mROC->GetNrows();
698 for (UInt_t irow=0;irow<nrows;++irow){
699 UInt_t npads=mROC->GetNPads(irow);
700 for (UInt_t ipad=0;ipad<npads;++ipad){
701 //don't use masked channels;
702 if (mROC ->GetValue(irow,ipad)) continue;
703 if (mRefROC->GetValue(irow,ipad)) continue;
704 Float_t deviation=TMath::Abs(pROC->GetValue(irow,ipad)-pRefROC->GetValue(irow,ipad));
705 for (Int_t i=0;i<npar;++i){
706 if (deviation>vThres[i])
707 ++pedestalDeviations.GetMatrixArray()[i];
708 }
709 ++nActive;
710 }//end ipad
711 }//ind irow
712 }//end isec
713 if (nActive>0){
714 for (Int_t i=0;i<npar;++i){
715 pedestalDeviations.GetMatrixArray()[i]/=nActive;
716 }
717 }
718}
719//_____________________________________________________________________________________
720void AliTPCcalibDButil::ProcessNoiseVariations(TVectorF &noiseDeviations)
721{
7d855b04 722 /// check the variations of the noise data to the reference noise data
723 /// thresholds are 5, 10, 15 and 20 percent respectively.
724
7390f655 725 const Int_t npar=4;
726 TVectorF vThres(npar); //thresholds
727 Int_t nActive=0; //number of active channels
728
729 //reset and set thresholds
730 noiseDeviations.ResizeTo(npar);
731 for (Int_t i=0;i<npar;++i){
732 noiseDeviations.GetMatrixArray()[i]=0;
733 vThres.GetMatrixArray()[i]=(i+1)*.05;
734 }
735 //check all needed data is available
736 if (!fRefPadNoise || !fPadNoise || !fALTROMasked || !fRefALTROMasked) return;
737 //loop over all channels
738 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
739 AliTPCCalROC *nROC=fPadNoise->GetCalROC(isec);
740 AliTPCCalROC *nRefROC=fRefPadNoise->GetCalROC(isec);
741 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
742 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
743 UInt_t nrows=mROC->GetNrows();
744 for (UInt_t irow=0;irow<nrows;++irow){
745 UInt_t npads=mROC->GetNPads(irow);
746 for (UInt_t ipad=0;ipad<npads;++ipad){
747 //don't use masked channels;
748 if (mROC ->GetValue(irow,ipad)) continue;
749 if (mRefROC->GetValue(irow,ipad)) continue;
32100b1d 750 if (nRefROC->GetValue(irow,ipad)==0) continue;
7390f655 751 Float_t deviation=(nROC->GetValue(irow,ipad)/nRefROC->GetValue(irow,ipad))-1;
752 for (Int_t i=0;i<npar;++i){
753 if (deviation>vThres[i])
754 ++noiseDeviations.GetMatrixArray()[i];
755 }
756 ++nActive;
757 }//end ipad
758 }//ind irow
759 }//end isec
760 if (nActive>0){
761 for (Int_t i=0;i<npar;++i){
762 noiseDeviations.GetMatrixArray()[i]/=nActive;
763 }
764 }
765}
766//_____________________________________________________________________________________
767void AliTPCcalibDButil::ProcessPulserVariations(TVectorF &pulserQdeviations, Float_t &varQMean,
768 Int_t &npadsOutOneTB, Int_t &npadsOffAdd)
769{
7d855b04 770 /// check the variations of the pulserQmean data to the reference pulserQmean data: pulserQdeviations
771 /// thresholds are .5, 1, 5 and 10 percent respectively.
772
7390f655 773 const Int_t npar=4;
774 TVectorF vThres(npar); //thresholds
775 Int_t nActive=0; //number of active channels
776
777 //reset and set thresholds
778 pulserQdeviations.ResizeTo(npar);
779 for (Int_t i=0;i<npar;++i){
780 pulserQdeviations.GetMatrixArray()[i]=0;
781 }
782 npadsOutOneTB=0;
783 npadsOffAdd=0;
784 varQMean=0;
785 vThres.GetMatrixArray()[0]=.005;
786 vThres.GetMatrixArray()[1]=.01;
787 vThres.GetMatrixArray()[2]=.05;
788 vThres.GetMatrixArray()[3]=.1;
789 //check all needed data is available
790 if (!fRefPulserTmean || !fPulserTmean || !fPulserQmean || !fRefPulserQmean || !fALTROMasked || !fRefALTROMasked) return;
791 //
792 UpdateRefPulserOutlierMap();
793 //loop over all channels
732e90a8 794 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
7390f655 795 AliTPCCalROC *pqROC=fPulserQmean->GetCalROC(isec);
796 AliTPCCalROC *pqRefROC=fRefPulserQmean->GetCalROC(isec);
797 AliTPCCalROC *ptROC=fPulserTmean->GetCalROC(isec);
732e90a8 798// AliTPCCalROC *ptRefROC=fRefPulserTmean->GetCalROC(isec);
7390f655 799 AliTPCCalROC *mROC=fALTROMasked->GetCalROC(isec);
800 AliTPCCalROC *mRefROC=fRefALTROMasked->GetCalROC(isec);
801 AliTPCCalROC *oROC=fPulserOutlier->GetCalROC(isec);
d30aa177 802 Float_t ptmean=ptROC->GetMean(oROC);
7390f655 803 UInt_t nrows=mROC->GetNrows();
804 for (UInt_t irow=0;irow<nrows;++irow){
805 UInt_t npads=mROC->GetNPads(irow);
806 for (UInt_t ipad=0;ipad<npads;++ipad){
807 //don't use masked channels;
808 if (mROC ->GetValue(irow,ipad)) continue;
809 if (mRefROC->GetValue(irow,ipad)) continue;
810 //don't user edge pads
811 if (ipad==0||ipad==npads-1) continue;
812 //data
813 Float_t pq=pqROC->GetValue(irow,ipad);
814 Float_t pqRef=pqRefROC->GetValue(irow,ipad);
815 Float_t pt=ptROC->GetValue(irow,ipad);
816// Float_t ptRef=ptRefROC->GetValue(irow,ipad);
817 //comparisons q
bb22b582 818 Float_t deviation=TMath::Abs(pqRef)>1e-20?TMath::Abs(pq/pqRef-1):-999;
7390f655 819 for (Int_t i=0;i<npar;++i){
820 if (deviation>vThres[i])
821 ++pulserQdeviations.GetMatrixArray()[i];
822 }
823 if (pqRef>11&&pq<11) ++npadsOffAdd;
824 varQMean+=pq-pqRef;
825 //comparisons t
d30aa177 826 if (TMath::Abs(pt-ptmean)>1) ++npadsOutOneTB;
7390f655 827 ++nActive;
828 }//end ipad
829 }//ind irow
830 }//end isec
831 if (nActive>0){
832 for (Int_t i=0;i<npar;++i){
833 pulserQdeviations.GetMatrixArray()[i]/=nActive;
834 varQMean/=nActive;
835 }
836 }
837}
892226be 838//_____________________________________________________________________________________
839void AliTPCcalibDButil::UpdatePulserOutlierMap()
7390f655 840{
7d855b04 841 /// Update the outlier map of the pulser data
842
7390f655 843 PulserOutlierMap(fPulserOutlier,fPulserTmean, fPulserQmean);
844}
845//_____________________________________________________________________________________
846void AliTPCcalibDButil::UpdateRefPulserOutlierMap()
847{
7d855b04 848 /// Update the outlier map of the pulser reference data
849
7390f655 850 PulserOutlierMap(fRefPulserOutlier,fRefPulserTmean, fRefPulserQmean);
851}
852//_____________________________________________________________________________________
853void AliTPCcalibDButil::PulserOutlierMap(AliTPCCalPad *pulOut, const AliTPCCalPad *pulT, const AliTPCCalPad *pulQ)
892226be 854{
7d855b04 855 /// Create a map that contains outliers from the Pulser calibration data.
856 /// The outliers include masked channels, edge pads and pads with
857 /// too large timing and charge variations.
858 /// fNpulserOutliers is the number of outliers in the Pulser calibration data.
859 /// those do not contain masked and edge pads
860
7390f655 861 if (!pulT||!pulQ) {
892226be 862 //reset map
7390f655 863 pulOut->Multiply(0.);
892226be 864 fNpulserOutliers=-1;
865 return;
866 }
867 AliTPCCalROC *rocMasked=0x0;
868 fNpulserOutliers=0;
869
870 //Create Outlier Map
871 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
7390f655 872 AliTPCCalROC *tmeanROC=pulT->GetCalROC(isec);
873 AliTPCCalROC *qmeanROC=pulQ->GetCalROC(isec);
874 AliTPCCalROC *outROC=pulOut->GetCalROC(isec);
892226be 875 if (!tmeanROC||!qmeanROC) {
876 //reset outliers in this ROC
877 outROC->Multiply(0.);
878 continue;
879 }
880 if (fALTROMasked) rocMasked=fALTROMasked->GetCalROC(isec);
881// Double_t dummy=0;
882// Float_t qmedian=qmeanROC->GetLTM(&dummy,.5);
883// Float_t tmedian=tmeanROC->GetLTM(&dummy,.5);
884 UInt_t nrows=tmeanROC->GetNrows();
885 for (UInt_t irow=0;irow<nrows;++irow){
886 UInt_t npads=tmeanROC->GetNPads(irow);
887 for (UInt_t ipad=0;ipad<npads;++ipad){
888 Int_t outlier=0,masked=0;
889 Float_t q=qmeanROC->GetValue(irow,ipad);
890 Float_t t=tmeanROC->GetValue(irow,ipad);
891 //masked channels are outliers
892 if (rocMasked && rocMasked->GetValue(irow,ipad)) masked=1;
893 //edge pads are outliers
894 if (ipad==0||ipad==npads-1) masked=1;
895 //channels with too large charge or timing deviation from the meadian are outliers
896// if (TMath::Abs(q-qmedian)>fPulQmaxLimitAbs || TMath::Abs(t-tmedian)>fPulTmaxLimitAbs) outlier=1;
897 if (q<fPulQminLimit && !masked) outlier=1;
898 //check for nan
899 if ( !(q<10000000) || !(t<10000000)) outlier=1;
900 outROC->SetValue(irow,ipad,outlier+masked);
901 fNpulserOutliers+=outlier;
902 }
903 }
904 }
905}
906//_____________________________________________________________________________________
2cb269df 907AliTPCCalPad* AliTPCcalibDButil::CreatePadTime0(Int_t model, Double_t &gyA, Double_t &gyC, Double_t &chi2A, Double_t &chi2C )
892226be 908{
7d855b04 909 /// Create pad time0 object from pulser and/or CE data, depending on the selected model
910 /// Model 0: normalise each readout chamber to its mean, outlier cutted, only Pulser
911 /// Model 1: normalise IROCs/OROCs of each readout side to its mean, only Pulser
912 /// Model 2: use CE data and a combination CE fit + pulser in the outlier regions.
913 ///
914 /// In case model 2 is invoked - gy arival time gradient is also returned
915
2cb269df 916 gyA=0;
917 gyC=0;
892226be 918 AliTPCCalPad *padTime0=new AliTPCCalPad("PadTime0",Form("PadTime0-Model_%d",model));
919 // decide between different models
920 if (model==0||model==1){
921 TVectorD vMean;
922 if (model==1) ProcessPulser(vMean);
923 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
924 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
925 if (!rocPulTmean) continue;
926 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
927 AliTPCCalROC *rocOut=fPulserOutlier->GetCalROC(isec);
928 Float_t mean=rocPulTmean->GetMean(rocOut);
929 //treat case where a whole partition is masked
8166d5d7 930 if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
892226be 931 if (model==1) {
932 Int_t type=isec/18;
933 mean=vMean[type];
934 }
935 UInt_t nrows=rocTime0->GetNrows();
936 for (UInt_t irow=0;irow<nrows;++irow){
937 UInt_t npads=rocTime0->GetNPads(irow);
938 for (UInt_t ipad=0;ipad<npads;++ipad){
939 Float_t time=rocPulTmean->GetValue(irow,ipad);
940 //in case of an outlier pad use the mean of the altro values.
941 //This should be the most precise guess in that case.
942 if (rocOut->GetValue(irow,ipad)) {
943 time=GetMeanAltro(rocPulTmean,irow,ipad,rocOut);
8166d5d7 944 if ( TMath::Abs(time)<kAlmost0 ) time=mean;
892226be 945 }
946 Float_t val=time-mean;
947 rocTime0->SetValue(irow,ipad,val);
948 }
949 }
950 }
2cb269df 951 } else if (model==2){
952 Double_t pgya,pgyc,pchi2a,pchi2c;
953 AliTPCCalPad * padPulser = CreatePadTime0(1,pgya,pgyc,pchi2a,pchi2c);
954 fCETmean->Add(padPulser,-1.);
732e90a8 955 TVectorD vA,vC;
956 AliTPCCalPad outCE("outCE","outCE");
957 Int_t nOut;
2cb269df 958 ProcessCEdata("(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)++(ly/lx)^2",vA,vC,nOut,chi2A, chi2C,&outCE);
959 AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++0++gy++0++(lx-134)++0++0",vA,vC);
732e90a8 960// AliTPCCalPad *padFit=AliTPCCalPad::CreateCalPadFit("1++(sector<36)++gy++gx++(lx-134)++(sector<36)*(lx-134)",vA,vC);
2cb269df 961 if (!padFit) { delete padPulser; return 0;}
962 gyA=vA[2];
963 gyC=vC[2];
964 fCETmean->Add(padPulser,1.);
732e90a8 965 padTime0->Add(fCETmean);
2cb269df 966 padTime0->Add(padFit,-1);
967 delete padPulser;
732e90a8 968 TVectorD vFitROC;
969 TMatrixD mFitROC;
970 Float_t chi2;
971 for (UInt_t isec=0;isec<AliTPCCalPad::kNsec;++isec){
972 AliTPCCalROC *rocPulTmean=fPulserTmean->GetCalROC(isec);
973 AliTPCCalROC *rocTime0=padTime0->GetCalROC(isec);
974 AliTPCCalROC *rocOutPul=fPulserOutlier->GetCalROC(isec);
975 AliTPCCalROC *rocOutCE=outCE.GetCalROC(isec);
976 rocTime0->GlobalFit(rocOutCE,kFALSE,vFitROC,mFitROC,chi2);
977 AliTPCCalROC *rocCEfit=AliTPCCalROC::CreateGlobalFitCalROC(vFitROC, isec);
978 Float_t mean=rocPulTmean->GetMean(rocOutPul);
8166d5d7 979 if ( TMath::Abs(mean)<kAlmost0 ) mean=rocPulTmean->GetMean();
732e90a8 980 UInt_t nrows=rocTime0->GetNrows();
981 for (UInt_t irow=0;irow<nrows;++irow){
982 UInt_t npads=rocTime0->GetNPads(irow);
983 for (UInt_t ipad=0;ipad<npads;++ipad){
984 Float_t timePulser=rocPulTmean->GetValue(irow,ipad)-mean;
985 if (rocOutCE->GetValue(irow,ipad)){
986 Float_t valOut=rocCEfit->GetValue(irow,ipad);
987 if (!rocOutPul->GetValue(irow,ipad)) valOut+=timePulser;
988 rocTime0->SetValue(irow,ipad,valOut);
989 }
990 }
991 }
992 delete rocCEfit;
993 }
994 delete padFit;
892226be 995 }
2cb269df 996 Double_t median = padTime0->GetMedian();
997 padTime0->Add(-median); // normalize to median
892226be 998 return padTime0;
999}
1000//_____________________________________________________________________________________
98a4cc77 1001Float_t AliTPCcalibDButil::GetMeanAltro(const AliTPCCalROC *roc, const Int_t row, const Int_t pad, AliTPCCalROC *const rocOut)
892226be 1002{
7d855b04 1003 /// GetMeanAlto information
1004
892226be 1005 if (roc==0) return 0.;
1006 const Int_t sector=roc->GetSector();
1007 AliTPCROC *tpcRoc=AliTPCROC::Instance();
1008 const UInt_t altroRoc=fMapper->GetFEC(sector,row,pad)*8+fMapper->GetChip(sector,row,pad);
1009 Float_t mean=0;
1010 Int_t n=0;
1011
1012 //loop over a small range around the requested pad (+-10 rows/pads)
1013 for (Int_t irow=row-10;irow<row+10;++irow){
1014 if (irow<0||irow>(Int_t)tpcRoc->GetNRows(sector)-1) continue;
1015 for (Int_t ipad=pad-10; ipad<pad+10;++ipad){
1016 if (ipad<0||ipad>(Int_t)tpcRoc->GetNPads(sector,irow)-1) continue;
1017 const UInt_t altroCurr=fMapper->GetFEC(sector,irow,ipad)*8+fMapper->GetChip(sector,irow,ipad);
1018 if (altroRoc!=altroCurr) continue;
1019 if ( rocOut && rocOut->GetValue(irow,ipad) ) continue;
1020 Float_t val=roc->GetValue(irow,ipad);
1021 mean+=val;
1022 ++n;
1023 }
1024 }
1025 if (n>0) mean/=n;
1026 return mean;
1027}
7390f655 1028//_____________________________________________________________________________________
1029void AliTPCcalibDButil::SetRefFile(const char* filename)
1030{
7d855b04 1031 /// load cal pad objects form the reference file
1032
7390f655 1033 TDirectory *currDir=gDirectory;
1034 TFile f(filename);
1035 fRefPedestals=(AliTPCCalPad*)f.Get("Pedestals");
1036 fRefPadNoise=(AliTPCCalPad*)f.Get("PadNoise");
1037 //pulser data
1038 fRefPulserTmean=(AliTPCCalPad*)f.Get("PulserTmean");
1039 fRefPulserTrms=(AliTPCCalPad*)f.Get("PulserTrms");
1040 fRefPulserQmean=(AliTPCCalPad*)f.Get("PulserQmean");
1041 //CE data
1042 fRefCETmean=(AliTPCCalPad*)f.Get("CETmean");
1043 fRefCETrms=(AliTPCCalPad*)f.Get("CETrms");
1044 fRefCEQmean=(AliTPCCalPad*)f.Get("CEQmean");
1045 //Altro data
1046// fRefALTROAcqStart=(AliTPCCalPad*)f.Get("ALTROAcqStart");
1047// fRefALTROZsThr=(AliTPCCalPad*)f.Get("ALTROZsThr");
1048// fRefALTROFPED=(AliTPCCalPad*)f.Get("ALTROFPED");
1049// fRefALTROAcqStop=(AliTPCCalPad*)f.Get("ALTROAcqStop");
1050 fRefALTROMasked=(AliTPCCalPad*)f.Get("ALTROMasked");
1051 f.Close();
1052 currDir->cd();
1053}
949d8707 1054//_____________________________________________________________________________________
1055void AliTPCcalibDButil::UpdateRefDataFromOCDB()
1056{
7d855b04 1057 /// set reference data from OCDB Reference map
1058
949d8707 1059 if (!fRefMap) {
1060 AliWarning("Referenc map not set!");
1061 return;
1062 }
1063
1064 TString cdbPath;
1065 AliCDBEntry* entry = 0x0;
1066 Bool_t hasAnyChanged=kFALSE;
1067
1068 //pedestals
1069 cdbPath="TPC/Calib/Pedestals";
1070 if (HasRefChanged(cdbPath.Data())){
1071 hasAnyChanged=kTRUE;
1072 //delete old entries
1073 if (fRefPedestals) delete fRefPedestals;
1074 if (fRefPedestalMasked) delete fRefPedestalMasked;
1075 fRefPedestals=fRefPedestalMasked=0x0;
1076 //get new entries
1077 entry=GetRefEntry(cdbPath.Data());
1078 if (entry){
1079 entry->SetOwner(kTRUE);
1080 fRefPedestals=GetRefCalPad(entry);
1081 delete entry;
1082 fRefPedestalMasked=GetAltroMasked(cdbPath, "MaskedPedestals");
1083 }
1084 }
7390f655 1085
949d8707 1086 //noise
1087 cdbPath="TPC/Calib/PadNoise";
1088 if (HasRefChanged(cdbPath.Data())){
1089 hasAnyChanged=kTRUE;
1090 //delete old entry
1091 if (fRefPadNoise) delete fRefPadNoise;
1092 fRefPadNoise=0x0;
1093 //get new entry
1094 entry=GetRefEntry(cdbPath.Data());
1095 if (entry){
1096 entry->SetOwner(kTRUE);
1097 fRefPadNoise=GetRefCalPad(entry);
1098 delete entry;
1099 }
1100 }
1101
1102 //pulser
1103 cdbPath="TPC/Calib/Pulser";
1104 if (HasRefChanged(cdbPath.Data())){
1105 hasAnyChanged=kTRUE;
1106 //delete old entries
1107 if (fRefPulserTmean) delete fRefPulserTmean;
1108 if (fRefPulserTrms) delete fRefPulserTrms;
1109 if (fRefPulserQmean) delete fRefPulserQmean;
1110 if (fRefPulserMasked) delete fRefPulserMasked;
1111 fRefPulserTmean=fRefPulserTrms=fRefPulserQmean=fRefPulserMasked=0x0;
1112 //get new entries
1113 entry=GetRefEntry(cdbPath.Data());
1114 if (entry){
1115 entry->SetOwner(kTRUE);
1116 fRefPulserTmean=GetRefCalPad(entry,"PulserTmean");
1117 fRefPulserTrms=GetRefCalPad(entry,"PulserTrms");
1118 fRefPulserQmean=GetRefCalPad(entry,"PulserQmean");
1119 delete entry;
1120 fRefPulserMasked=GetAltroMasked(cdbPath, "MaskedPulser");
1121 }
1122 }
2cb269df 1123
949d8707 1124 //ce
1125 cdbPath="TPC/Calib/CE";
1126 if (HasRefChanged(cdbPath.Data())){
1127 hasAnyChanged=kTRUE;
1128 //delete old entries
1129 if (fRefCETmean) delete fRefCETmean;
1130 if (fRefCETrms) delete fRefCETrms;
1131 if (fRefCEQmean) delete fRefCEQmean;
1132 if (fRefCEMasked) delete fRefCEMasked;
1133 fRefCETmean=fRefCETrms=fRefCEQmean=fRefCEMasked=0x0;
1134 //get new entries
1135 entry=GetRefEntry(cdbPath.Data());
1136 if (entry){
1137 entry->SetOwner(kTRUE);
1138 fRefCETmean=GetRefCalPad(entry,"CETmean");
1139 fRefCETrms=GetRefCalPad(entry,"CETrms");
1140 fRefCEQmean=GetRefCalPad(entry,"CEQmean");
1141 delete entry;
1142 fRefCEMasked=GetAltroMasked(cdbPath, "MaskedCE");
1143 }
1144 }
1145
1146 //altro data
1147 cdbPath="TPC/Calib/AltroConfig";
1148 if (HasRefChanged(cdbPath.Data())){
1149 hasAnyChanged=kTRUE;
1150 //delete old entries
1151 if (fRefALTROFPED) delete fRefALTROFPED;
1152 if (fRefALTROZsThr) delete fRefALTROZsThr;
1153 if (fRefALTROAcqStart) delete fRefALTROAcqStart;
1154 if (fRefALTROAcqStop) delete fRefALTROAcqStop;
1155 if (fRefALTROMasked) delete fRefALTROMasked;
1156 fRefALTROFPED=fRefALTROZsThr=fRefALTROAcqStart=fRefALTROAcqStop=fRefALTROMasked=0x0;
1157 //get new entries
1158 entry=GetRefEntry(cdbPath.Data());
1159 if (entry){
1160 entry->SetOwner(kTRUE);
1161 fRefALTROFPED=GetRefCalPad(entry,"FPED");
1162 fRefALTROZsThr=GetRefCalPad(entry,"ZsThr");
1163 fRefALTROAcqStart=GetRefCalPad(entry,"AcqStart");
1164 fRefALTROAcqStop=GetRefCalPad(entry,"AcqStop");
1165 fRefALTROMasked=GetRefCalPad(entry,"Masked");
1166 delete entry;
1167 }
1168 }
1169
1170 //raw data
1171 /*
1172 cdbPath="TPC/Calib/Raw";
1173 if (HasRefChanged(cdbPath.Data())){
1174 hasAnyChanged=kTRUE;
1175 //delete old entry
1176 if (fRefCalibRaw) delete fRefCalibRaw;
1177 //get new entry
1178 entry=GetRefEntry(cdbPath.Data());
1179 if (entry){
1180 entry->SetOwner(kTRUE);
1181 TObjArray *arr=(TObjArray*)entry->GetObject();
1182 if (!arr){
a980538f 1183 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
949d8707 1184 } else {
1185 fRefCalibRaw=(AliTPCCalibRaw*)arr->At(0)->Clone();
1186 }
1187 }
1188 }
1189 */
2cb269df 1190
949d8707 1191 //data qa
1192 cdbPath="TPC/Calib/QA";
1193 if (HasRefChanged(cdbPath.Data())){
1194 hasAnyChanged=kTRUE;
1195 //delete old entry
1196 if (fRefDataQA) delete fRefDataQA;
1197 //get new entry
1198 entry=GetRefEntry(cdbPath.Data());
1199 if (entry){
1200 entry->SetOwner(kTRUE);
abb20887 1201 fRefDataQA=dynamic_cast<AliTPCdataQA*>(entry->GetObject());
1202 if (!fRefDataQA){
a980538f 1203 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
949d8707 1204 } else {
668e6ebb 1205 fRefDataQA=(AliTPCdataQA*)fRefDataQA->Clone();
949d8707 1206 }
1207 delete entry;
1208 }
1209 }
1210
1211
1212//update current reference maps
1213 if (hasAnyChanged){
1214 if (fCurrentRefMap) delete fCurrentRefMap;
1215 fCurrentRefMap=(TMap*)fRefMap->Clone();
1216 }
1217}
1218//_____________________________________________________________________________________
1219AliTPCCalPad* AliTPCcalibDButil::GetRefCalPad(AliCDBEntry *entry, const char* objName)
1220{
7d855b04 1221 /// TObjArray object type case
1222 /// find 'objName' in 'arr' cast is to a calPad and store it in 'pad'
1223
949d8707 1224 AliTPCCalPad *pad=0x0;
1225 TObjArray *arr=(TObjArray*)entry->GetObject();
1226 if (!arr){
a980538f 1227 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
949d8707 1228 return pad;
1229 }
1230 pad=(AliTPCCalPad*)arr->FindObject(objName);
1231 if (!pad) {
a980538f 1232 AliError(Form("Could not get '%s' from TObjArray in entry '%s'\nPlease check!!!",objName,entry->GetId().GetPath().Data()));
949d8707 1233 return pad;
1234 }
1235 return (AliTPCCalPad*)pad->Clone();
1236}
1237//_____________________________________________________________________________________
1238AliTPCCalPad* AliTPCcalibDButil::GetRefCalPad(AliCDBEntry *entry)
1239{
7d855b04 1240 /// AliTPCCalPad object type case
1241 /// cast object to a calPad and store it in 'pad'
1242
949d8707 1243 AliTPCCalPad *pad=(AliTPCCalPad*)entry->GetObject();
1244 if (!pad) {
a980538f 1245 AliError(Form("Could not get object from entry '%s'\nPlease check!!!",entry->GetId().GetPath().Data()));
949d8707 1246 return 0x0;
1247 }
1248 pad=(AliTPCCalPad*)pad->Clone();
1249 return pad;
1250}
1251//_____________________________________________________________________________________
1252AliTPCCalPad* AliTPCcalibDButil::GetAltroMasked(const char* cdbPath, const char* name)
1253{
7d855b04 1254 /// set altro masked channel map for 'cdbPath'
1255
949d8707 1256 AliTPCCalPad* pad=0x0;
1257 const Int_t run=GetReferenceRun(cdbPath);
1258 if (run<0) {
a980538f 1259 AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
949d8707 1260 return pad;
1261 }
1262 AliCDBEntry *entry=AliCDBManager::Instance()->Get("TPC/Calib/AltroConfig", run);
1263 if (!entry) {
a980538f 1264 AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
949d8707 1265 return pad;
1266 }
1267 pad=GetRefCalPad(entry,"Masked");
1268 if (pad) pad->SetNameTitle(name,name);
1269 entry->SetOwner(kTRUE);
1270 delete entry;
1271 return pad;
1272}
1273//_____________________________________________________________________________________
1274void AliTPCcalibDButil::SetReferenceRun(Int_t run){
7d855b04 1275 /// Get Reference map
1276
949d8707 1277 if (run<0) run=fCalibDB->GetRun();
1278 TString cdbPath="TPC/Calib/Ref";
1279 AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath.Data(), run);
1280 if (!entry) {
a980538f 1281 AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath.Data()));
949d8707 1282 fRefMap=0;
1283 return;
1284 }
1285 entry->SetOwner(kTRUE);
1286 fRefMap=(TMap*)(entry->GetObject());
1287 AliCDBId &id=entry->GetId();
1288 fRefValidity.Form("%d_%d_v%d_s%d",id.GetFirstRun(),id.GetLastRun(),id.GetVersion(),id.GetSubVersion());
1289}
1290//_____________________________________________________________________________________
1291Bool_t AliTPCcalibDButil::HasRefChanged(const char *cdbPath)
1292{
7d855b04 1293 /// check whether a reference cdb entry has changed
1294
949d8707 1295 if (!fCurrentRefMap) return kTRUE;
1296 if (GetReferenceRun(cdbPath)!=GetCurrentReferenceRun(cdbPath)) return kTRUE;
1297 return kFALSE;
1298}
1299//_____________________________________________________________________________________
1300AliCDBEntry* AliTPCcalibDButil::GetRefEntry(const char* cdbPath)
1301{
7d855b04 1302 /// get the reference AliCDBEntry for 'cdbPath'
1303
949d8707 1304 const Int_t run=GetReferenceRun(cdbPath);
1305 if (run<0) {
a980538f 1306 AliError(Form("Could not get reference run number for object '%s'\nPlease check availability!!!",cdbPath));
949d8707 1307 return 0;
1308 }
1309 AliCDBEntry *entry=AliCDBManager::Instance()->Get(cdbPath, run);
1310 if (!entry) {
a980538f 1311 AliError(Form("Could not get reference object '%s'\nPlease check availability!!!",cdbPath));
949d8707 1312 return 0;
1313 }
1314 return entry;
1315}
1316//_____________________________________________________________________________________
26d8859c 1317Int_t AliTPCcalibDButil::GetCurrentReferenceRun(const char* type) const {
7d855b04 1318 /// Get reference run number for the specified OCDB path
1319
949d8707 1320 if (!fCurrentRefMap) return -2;
1321 TObjString *str=dynamic_cast<TObjString*>(fCurrentRefMap->GetValue(type));
1322 if (!str) return -2;
58affc42 1323 return (Int_t)str->GetString().Atoi();
949d8707 1324}
1325//_____________________________________________________________________________________
26d8859c 1326Int_t AliTPCcalibDButil::GetReferenceRun(const char* type) const{
7d855b04 1327 /// Get reference run number for the specified OCDB path
1328
949d8707 1329 if (!fRefMap) return -1;
1330 TObjString *str=dynamic_cast<TObjString*>(fRefMap->GetValue(type));
1331 if (!str) return -1;
58affc42 1332 return (Int_t)str->GetString().Atoi();
949d8707 1333}
1334//_____________________________________________________________________________________
8166d5d7 1335AliTPCCalPad *AliTPCcalibDButil::CreateCEOutlyerMap( Int_t & noutliersCE, AliTPCCalPad * const ceOut, Float_t minSignal, Float_t cutTrmsMin, Float_t cutTrmsMax, Float_t cutMaxDistT){
7d855b04 1336 /// Author: marian.ivanov@cern.ch
1337 ///
1338 /// Create outlier map for CE study
1339 /// Parameters:
1340 /// Return value - outlyer map
1341 /// noutlyersCE - number of outlyers
1342 /// minSignal - minimal total Q signal
1343 /// cutRMSMin - minimal width of the signal in respect to the median
1344 /// cutRMSMax - maximal width of the signal in respect to the median
1345 /// cutMaxDistT - maximal deviation from time median per chamber
1346 ///
1347 /// Outlyers criteria:
1348 /// 0. Exclude masked pads
1349 /// 1. Exclude first two rows in IROC and last two rows in OROC
1350 /// 2. Exclude edge pads
1351 /// 3. Exclude channels with too large variations
1352 /// 4. Exclude pads with too small signal
1353 /// 5. Exclude signal with outlyers RMS
1354 /// 6. Exclude channels to far from the chamber median
1355
2cb269df 1356 noutliersCE=0;
1357 //create outlier map
1358 AliTPCCalPad *out=ceOut;
1359 if (!out) out= new AliTPCCalPad("outCE","outCE");
1360 AliTPCCalROC *rocMasked=0x0;
1361 if (!fCETmean) return 0;
1362 if (!fCETrms) return 0;
1363 if (!fCEQmean) return 0;
1364 //
1365 //loop over all channels
1366 //
1367 Double_t rmsMedian = fCETrms->GetMedian();
1368 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1369 AliTPCCalROC *rocData=fCETmean->GetCalROC(iroc);
9f98a33d 1370 if (!rocData) continue;
2cb269df 1371 if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
1372 AliTPCCalROC *rocOut = out->GetCalROC(iroc);
1373 AliTPCCalROC *rocCEQ = fCEQmean->GetCalROC(iroc);
1374 AliTPCCalROC *rocCETrms = fCETrms->GetCalROC(iroc);
1375 Double_t trocMedian = rocData->GetMedian();
1376 //
768e46f1 1377 if (!rocData || !rocCEQ || !rocCETrms || !rocData) {
2cb269df 1378 noutliersCE+=AliTPCROC::Instance()->GetNChannels(iroc);
1379 rocOut->Add(1.);
1380 continue;
1381 }
1382 //
1383 //select outliers
1384 UInt_t nrows=rocData->GetNrows();
1385 for (UInt_t irow=0;irow<nrows;++irow){
1386 UInt_t npads=rocData->GetNPads(irow);
1387 for (UInt_t ipad=0;ipad<npads;++ipad){
1388 rocOut->SetValue(irow,ipad,0);
1389 Float_t valTmean=rocData->GetValue(irow,ipad);
1390 Float_t valQmean=rocCEQ->GetValue(irow,ipad);
1391 Float_t valTrms =rocCETrms->GetValue(irow,ipad);
1392 //0. exclude masked pads
1393 if (rocMasked && rocMasked->GetValue(irow,ipad)) {
1394 rocOut->SetValue(irow,ipad,1);
1395 continue;
1396 }
1397 //1. exclude first two rows in IROC and last two rows in OROC
1398 if (iroc<36){
1399 if (irow<2) rocOut->SetValue(irow,ipad,1);
1400 } else {
1401 if (irow>nrows-3) rocOut->SetValue(irow,ipad,1);
1402 }
1403 //2. exclude edge pads
1404 if (ipad==0||ipad==npads-1) rocOut->SetValue(irow,ipad,1);
1405 //exclude values that are exactly 0
8166d5d7 1406 if ( TMath::Abs(valTmean)<kAlmost0) {
2cb269df 1407 rocOut->SetValue(irow,ipad,1);
1408 ++noutliersCE;
1409 }
1410 //3. exclude channels with too large variations
1411 if (TMath::Abs(valTmean)>fCETmaxLimitAbs) {
1412 rocOut->SetValue(irow,ipad,1);
1413 ++noutliersCE;
1414 }
1415 //
1416 //4. exclude channels with too small signal
1417 if (valQmean<minSignal) {
1418 rocOut->SetValue(irow,ipad,1);
1419 ++noutliersCE;
1420 }
1421 //
1422 //5. exclude channels with too small rms
1423 if (valTrms<cutTrmsMin*rmsMedian || valTrms>cutTrmsMax*rmsMedian){
1424 rocOut->SetValue(irow,ipad,1);
1425 ++noutliersCE;
1426 }
1427 //
1428 //6. exclude channels to far from the chamber median
1429 if (TMath::Abs(valTmean-trocMedian)>cutMaxDistT){
1430 rocOut->SetValue(irow,ipad,1);
1431 ++noutliersCE;
1432 }
1433 }
1434 }
1435 }
1436 //
1437 return out;
1438}
1439
1440
8166d5d7 1441AliTPCCalPad *AliTPCcalibDButil::CreatePulserOutlyerMap(Int_t &noutliersPulser, AliTPCCalPad * const pulserOut,Float_t cutTime, Float_t cutnRMSQ, Float_t cutnRMSrms){
7d855b04 1442 /// Author: marian.ivanov@cern.ch
1443 ///
1444 /// Create outlier map for Pulser
1445 /// Parameters:
1446 /// Return value - outlyer map
1447 /// noutlyersPulser - number of outlyers
1448 /// cutTime - absolute cut - distance to the median of chamber
1449 /// cutnRMSQ - nsigma cut from median q distribution per chamber
1450 /// cutnRMSrms - nsigma cut from median rms distribution
1451 /// Outlyers criteria:
1452 /// 0. Exclude masked pads
1453 /// 1. Exclude time outlyers (default 3 time bins)
1454 /// 2. Exclude q outlyers (default 5 sigma)
1455 /// 3. Exclude rms outlyers (default 5 sigma)
1456
2cb269df 1457 noutliersPulser=0;
1458 AliTPCCalPad *out=pulserOut;
1459 if (!out) out= new AliTPCCalPad("outPulser","outPulser");
1460 AliTPCCalROC *rocMasked=0x0;
1461 if (!fPulserTmean) return 0;
1462 if (!fPulserTrms) return 0;
1463 if (!fPulserQmean) return 0;
1464 //
1465 //loop over all channels
1466 //
1467 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1468 if (fALTROMasked) rocMasked= fALTROMasked->GetCalROC(iroc);
1469 AliTPCCalROC *rocData = fPulserTmean->GetCalROC(iroc);
1470 AliTPCCalROC *rocOut = out->GetCalROC(iroc);
1471 AliTPCCalROC *rocPulserQ = fPulserQmean->GetCalROC(iroc);
1472 AliTPCCalROC *rocPulserTrms = fPulserTrms->GetCalROC(iroc);
1473 //
1474 Double_t rocMedianT = rocData->GetMedian();
1475 Double_t rocMedianQ = rocPulserQ->GetMedian();
1476 Double_t rocRMSQ = rocPulserQ->GetRMS();
1477 Double_t rocMedianTrms = rocPulserTrms->GetMedian();
1478 Double_t rocRMSTrms = rocPulserTrms->GetRMS();
1479 for (UInt_t ichannel=0;ichannel<rocData->GetNchannels();++ichannel){
1480 rocOut->SetValue(ichannel,0);
1481 Float_t valTmean=rocData->GetValue(ichannel);
1482 Float_t valQmean=rocPulserQ->GetValue(ichannel);
1483 Float_t valTrms =rocPulserTrms->GetValue(ichannel);
f03e487b 1484 Float_t valMasked =0;
1485 if (rocMasked) valMasked = rocMasked->GetValue(ichannel);
2cb269df 1486 Int_t isOut=0;
f03e487b 1487 if (valMasked>0.5) isOut=1;
2cb269df 1488 if (TMath::Abs(valTmean-rocMedianT)>cutTime) isOut=1;
1489 if (TMath::Abs(valQmean-rocMedianQ)>cutnRMSQ*rocRMSQ) isOut=1;
1490 if (TMath::Abs(valTrms-rocMedianTrms)>cutnRMSrms*rocRMSTrms) isOut=1;
1491 rocOut->SetValue(ichannel,isOut);
1492 if (isOut) noutliersPulser++;
1493 }
1494 }
1495 return out;
1496}
1497
1498
1499AliTPCCalPad *AliTPCcalibDButil::CreatePadTime0CE(TVectorD &fitResultsA, TVectorD&fitResultsC, Int_t &nOut, Double_t &chi2A, Double_t &chi2C, const char *dumpfile){
7d855b04 1500 /// Author : Marian Ivanov
1501 /// Create pad time0 correction map using information from the CE and from pulser
1502 ///
1503 /// Return PadTime0 to be used for time0 relative alignment
1504 /// if dump file specified intermediat results are dumped to the fiel and can be visualized
1505 /// using $ALICE_ROOT/TPC/script/gui application
1506 ///
1507 /// fitResultsA - fitParameters A side
1508 /// fitResultsC - fitParameters C side
1509 /// chi2A - chi2/ndf for A side (assuming error 1 time bin)
1510 /// chi2C - chi2/ndf for C side (assuming error 1 time bin)
1511 ///
1512 /// Algorithm:
1513 /// 1. Find outlier map for CE
1514 /// 2. Find outlier map for Pulser
1515 /// 3. Replace outlier by median at given sector (median without outliers)
1516 /// 4. Substract from the CE data pulser
1517 /// 5. Fit the CE with formula
1518 /// 5.1) (IROC-OROC) offset
1519 /// 5.2) gx
1520 /// 5.3) gy
1521 /// 5.4) (lx-xmid)
1522 /// 5.5) (IROC-OROC)*(lx-xmid)
1523 /// 5.6) (ly/lx)^2
1524 /// 6. Substract gy fit dependence from the CE data
1525 /// 7. Add pulser back to CE data
1526 /// 8. Replace outliers by fit value - median of diff per given chamber -GY fit
1527 /// 9. return CE data
1528 ///
1529 /// Time0 <= padCE = padCEin -padCEfitGy - if not outlier
1530 /// Time0 <= padCE = padFitAll-padCEfitGy - if outlier
2cb269df 1531
1532 // fit formula
1533 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)";
1534 // output for fit formula
1535 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)";
1536 // gy part of formula
1537 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)";
1538 //
1539 //
1540 if (!fCETmean) return 0;
1541 Double_t pgya,pgyc,pchi2a,pchi2c;
1542 AliTPCCalPad * padPulserOut = CreatePulserOutlyerMap(nOut);
1543 AliTPCCalPad * padCEOut = CreateCEOutlyerMap(nOut);
1544
1545 AliTPCCalPad * padPulser = CreatePadTime0(1,pgya,pgyc,pchi2a,pchi2c);
1546 AliTPCCalPad * padCE = new AliTPCCalPad(*fCETmean);
1547 AliTPCCalPad * padCEIn = new AliTPCCalPad(*fCETmean);
1548 AliTPCCalPad * padOut = new AliTPCCalPad("padOut","padOut");
1549 padPulser->SetName("padPulser");
1550 padPulserOut->SetName("padPulserOut");
1551 padCE->SetName("padCE");
1552 padCEIn->SetName("padCEIn");
1553 padCEOut->SetName("padCEOut");
1554 padOut->SetName("padOut");
1555
1556 //
1557 // make combined outlyers map
1558 // and replace outlyers in maps with median for chamber
1559 //
1560 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1561 AliTPCCalROC * rocOut = padOut->GetCalROC(iroc);
1562 AliTPCCalROC * rocPulser = padPulser->GetCalROC(iroc);
1563 AliTPCCalROC * rocPulserOut = padPulserOut->GetCalROC(iroc);
1564 AliTPCCalROC * rocCEOut = padCEOut->GetCalROC(iroc);
1565 AliTPCCalROC * rocCE = padCE->GetCalROC(iroc);
1566 Double_t ceMedian = rocCE->GetMedian(rocCEOut);
1567 Double_t pulserMedian = rocPulser->GetMedian(rocCEOut);
1568 for (UInt_t ichannel=0;ichannel<rocOut->GetNchannels();++ichannel){
1569 if (rocPulserOut->GetValue(ichannel)>0) {
1570 rocPulser->SetValue(ichannel,pulserMedian);
1571 rocOut->SetValue(ichannel,1);
1572 }
1573 if (rocCEOut->GetValue(ichannel)>0) {
1574 rocCE->SetValue(ichannel,ceMedian);
1575 rocOut->SetValue(ichannel,1);
1576 }
1577 }
1578 }
1579 //
1580 // remove pulser time 0
1581 //
1582 padCE->Add(padPulser,-1);
1583 //
1584 // Make fits
1585 //
1586 TMatrixD dummy;
1587 Float_t chi2Af,chi2Cf;
1588 padCE->GlobalSidesFit(padOut,formulaIn,fitResultsA,fitResultsC,dummy,dummy,chi2Af,chi2Cf);
1589 chi2A=chi2Af;
1590 chi2C=chi2Cf;
1591 //
1592 AliTPCCalPad *padCEFitGY=AliTPCCalPad::CreateCalPadFit(formulaOut,fitResultsA,fitResultsC);
1593 padCEFitGY->SetName("padCEFitGy");
1594 //
1595 AliTPCCalPad *padCEFit =AliTPCCalPad::CreateCalPadFit(formulaAll,fitResultsA,fitResultsC);
1596 padCEFit->SetName("padCEFit");
1597 //
1598 AliTPCCalPad* padCEDiff = new AliTPCCalPad(*padCE);
1599 padCEDiff->SetName("padCEDiff");
1600 padCEDiff->Add(padCEFit,-1.);
1601 //
1602 //
1603 padCE->Add(padCEFitGY,-1.);
1604
1605 padCE->Add(padPulser,1.);
1606 Double_t padmedian = padCE->GetMedian();
1607 padCE->Add(-padmedian); // normalize to median
1608 //
1609 // Replace outliers by fit value - median of diff per given chamber -GY fit
1610 //
1611 for (UInt_t iroc=0;iroc<fCETmean->kNsec;++iroc){
1612 AliTPCCalROC * rocOut = padOut->GetCalROC(iroc);
1613 AliTPCCalROC * rocCE = padCE->GetCalROC(iroc);
1614 AliTPCCalROC * rocCEFit = padCEFit->GetCalROC(iroc);
1615 AliTPCCalROC * rocCEFitGY = padCEFitGY->GetCalROC(iroc);
1616 AliTPCCalROC * rocCEDiff = padCEDiff->GetCalROC(iroc);
1617 //
1618 Double_t diffMedian = rocCEDiff->GetMedian(rocOut);
1619 for (UInt_t ichannel=0;ichannel<rocOut->GetNchannels();++ichannel){
1620 if (rocOut->GetValue(ichannel)==0) continue;
1621 Float_t value=rocCEFit->GetValue(ichannel)-rocCEFitGY->GetValue(ichannel)-diffMedian-padmedian;
1622 rocCE->SetValue(ichannel,value);
1623 }
1624 }
1625 //
1626 //
1627 if (dumpfile){
1628 //dump to the file - result can be visualized
1629 AliTPCPreprocessorOnline preprocesor;
1630 preprocesor.AddComponent(new AliTPCCalPad(*padCE));
1631 preprocesor.AddComponent(new AliTPCCalPad(*padCEIn));
1632 preprocesor.AddComponent(new AliTPCCalPad(*padCEFit));
1633 preprocesor.AddComponent(new AliTPCCalPad(*padOut));
1634 //
1635 preprocesor.AddComponent(new AliTPCCalPad(*padCEFitGY));
1636 preprocesor.AddComponent(new AliTPCCalPad(*padCEDiff));
1637 //
1638 preprocesor.AddComponent(new AliTPCCalPad(*padCEOut));
1639 preprocesor.AddComponent(new AliTPCCalPad(*padPulser));
1640 preprocesor.AddComponent(new AliTPCCalPad(*padPulserOut));
1641 preprocesor.DumpToFile(dumpfile);
1642 }
1643 delete padPulser;
1644 delete padPulserOut;
1645 delete padCEIn;
1646 delete padCEOut;
1647 delete padOut;
1648 delete padCEDiff;
1649 delete padCEFitGY;
1650 return padCE;
1651}
1652
817766d5 1653
1654
1655
1656
1657Int_t AliTPCcalibDButil::GetNearest(TGraph *graph, Double_t xref, Double_t &dx, Double_t &y){
7d855b04 1658 /// find the closest point to xref in x direction
1659 /// return dx and value
1660
5647625c 1661 dx = 0;
1662 y = 0;
1663
1664 if(!graph) return 0;
1665 if(graph->GetN() < 1) return 0;
1666
817766d5 1667 Int_t index=0;
1668 index = TMath::BinarySearch(graph->GetN(), graph->GetX(),xref);
1669 if (index<0) index=0;
5647625c 1670 if(graph->GetN()==1) {
1671 dx = xref-graph->GetX()[index];
1672 }
1673 else {
1674 if (index>=graph->GetN()-1) index=graph->GetN()-2;
1675 if (xref-graph->GetX()[index]>graph->GetX()[index]-xref) index++;
1676 dx = xref-graph->GetX()[index];
1677 }
817766d5 1678 y = graph->GetY()[index];
1679 return index;
1680}
1681
817766d5 1682Double_t AliTPCcalibDButil::GetTriggerOffsetTPC(Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
7d855b04 1683 /// Get the correction of the trigger offset
1684 /// combining information from the laser track calibration
1685 /// and from cosmic calibration
1686 ///
1687 /// run - run number
1688 /// timeStamp - tim stamp in seconds
1689 /// deltaT - integration period to calculate offset
1690 /// deltaTLaser -max validity of laser data
1691 /// valType - 0 - median, 1- mean
1692 ///
1693 /// Integration vaues are just recomendation - if not possible to get points
1694 /// automatically increase the validity by factor 2
1695 /// (recursive algorithm until one month of data taking)
1696
817766d5 1697 const Float_t kLaserCut=0.0005;
aec07590 1698 const Int_t kMaxPeriod=3600*24*30*12; // one year max
817766d5 1699 const Int_t kMinPoints=20;
1700 //
1701 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1702 if (!array) {
1703 AliTPCcalibDB::Instance()->UpdateRunInformations(run,kFALSE);
1704 }
1705 array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1706 if (!array) return 0;
1707 //
1708 TGraphErrors *laserA[3]={0,0,0};
1709 TGraphErrors *laserC[3]={0,0,0};
1710 TGraphErrors *cosmicAll=0;
1711 laserA[1]=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1712 laserC[1]=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1713 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1714 //
1715 //
1716 if (!cosmicAll) return 0;
1717 Int_t nmeasC=cosmicAll->GetN();
1718 Float_t *tdelta = new Float_t[nmeasC];
1719 Int_t nused=0;
1720 for (Int_t i=0;i<nmeasC;i++){
1721 if (TMath::Abs(cosmicAll->GetX()[i]-timeStamp)>deltaT) continue;
1722 Float_t ccosmic=cosmicAll->GetY()[i];
1723 Double_t yA=0,yC=0,dA=0,dC=0;
1724 if (laserA[1]) GetNearest(laserA[1], cosmicAll->GetX()[i],dA,yA);
1725 if (laserC[1]) GetNearest(laserC[1], cosmicAll->GetX()[i],dC,yC);
1726 //yA=laserA[1]->Eval(cosmicAll->GetX()[i]);
1727 //yC=laserC[1]->Eval(cosmicAll->GetX()[i]);
1728 //
1729 if (TMath::Sqrt(dA*dA+dC*dC)>deltaTLaser) continue;
1730 Float_t claser=0;
1731 if (TMath::Abs(yA-yC)<kLaserCut) {
1732 claser=(yA-yC)*0.5;
1733 }else{
1734 if (i%2==0) claser=yA;
1735 if (i%2==1) claser=yC;
1736 }
1737 tdelta[nused]=ccosmic-claser;
1738 nused++;
1739 }
768e46f1 1740 if (nused<kMinPoints &&deltaT<kMaxPeriod) {
1741 delete [] tdelta;
1742 return AliTPCcalibDButil::GetTriggerOffsetTPC(run, timeStamp, deltaT*2,deltaTLaser);
1743 }
aec07590 1744 if (nused<kMinPoints) {
f03e487b 1745 delete [] tdelta;
6157d837 1746 //AliWarning("AliFatal: No time offset calibration available\n");
aec07590 1747 return 0;
1748 }
817766d5 1749 Double_t median = TMath::Median(nused,tdelta);
1750 Double_t mean = TMath::Mean(nused,tdelta);
a9f487a1 1751 delete [] tdelta;
817766d5 1752 return (valType==0) ? median:mean;
1753}
1754
a23ba1c3 1755Double_t AliTPCcalibDButil::GetVDriftTPC(Double_t &dist, Int_t run, Int_t timeStamp, Double_t deltaT, Double_t deltaTLaser, Int_t valType){
7d855b04 1756 /// Get the correction of the drift velocity
1757 /// combining information from the laser track calibration
1758 /// and from cosmic calibration
1759 ///
1760 /// dist - return value - distance to closest point in graph
1761 /// run - run number
1762 /// timeStamp - tim stamp in seconds
1763 /// deltaT - integration period to calculate time0 offset
1764 /// deltaTLaser -max validity of laser data
1765 /// valType - 0 - median, 1- mean
1766 ///
1767 /// Integration vaues are just recomendation - if not possible to get points
1768 /// automatically increase the validity by factor 2
1769 /// (recursive algorithm until one month of data taking)
1770
817766d5 1771 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1772 if (!array) {
1773 AliTPCcalibDB::Instance()->UpdateRunInformations(run,kFALSE);
1774 }
1775 array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1776 if (!array) return 0;
1777 TGraphErrors *cosmicAll=0;
1778 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1779 if (!cosmicAll) return 0;
a23ba1c3 1780 Double_t grY=0;
1781 AliTPCcalibDButil::GetNearest(cosmicAll,timeStamp,dist,grY);
1782
817766d5 1783 Double_t t0= AliTPCcalibDButil::GetTriggerOffsetTPC(run,timeStamp, deltaT, deltaTLaser,valType);
5647625c 1784 Double_t vcosmic = AliTPCcalibDButil::EvalGraphConst(cosmicAll, timeStamp);
1e722a63 1785 if (timeStamp>cosmicAll->GetX()[cosmicAll->GetN()-1]) vcosmic=cosmicAll->GetY()[cosmicAll->GetN()-1];
817766d5 1786 if (timeStamp<cosmicAll->GetX()[0]) vcosmic=cosmicAll->GetY()[0];
cc65e4f5 1787 return vcosmic-t0;
817766d5 1788
1789 /*
1790 Example usage:
1791
1792 Int_t run=89000
1793 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
1794 cosmicAll =(TGraphErrors*)array->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1795 laserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1796 //
1797 Double_t *yvd= new Double_t[cosmicAll->GetN()];
1798 Double_t *yt0= new Double_t[cosmicAll->GetN()];
1799 for (Int_t i=0; i<cosmicAll->GetN();i++) yvd[i]=AliTPCcalibDButil::GetVDriftTPC(run,cosmicAll->GetX()[i]);
1800 for (Int_t i=0; i<cosmicAll->GetN();i++) yt0[i]=AliTPCcalibDButil::GetTriggerOffsetTPC(run,cosmicAll->GetX()[i]);
1801
1802 TGraph *pcosmicVd=new TGraph(cosmicAll->GetN(), cosmicAll->GetX(), yvd);
1803 TGraph *pcosmicT0=new TGraph(cosmicAll->GetN(), cosmicAll->GetX(), yt0);
1804
1805 */
1806
1807}
1808
949d8707 1809const char* AliTPCcalibDButil::GetGUIRefTreeDefaultName()
1810{
7d855b04 1811 /// Create a default name for the gui file
1812
949d8707 1813 return Form("guiRefTreeRun%s.root",GetRefValidity());
1814}
1815
1816Bool_t AliTPCcalibDButil::CreateGUIRefTree(const char* filename)
1817{
7d855b04 1818 /// Create a gui reference tree
1819 /// if dirname and filename are empty default values will be used
1820 /// this is the recommended way of using this function
1821 /// it allows to check whether a file with the given run validity alredy exists
1822
949d8707 1823 if (!AliCDBManager::Instance()->GetDefaultStorage()){
1824 AliError("Default Storage not set. Cannot create reference calibration Tree!");
1825 return kFALSE;
1826 }
1827
1828 TString file=filename;
1829 if (file.IsNull()) file=GetGUIRefTreeDefaultName();
1830
1831 AliTPCPreprocessorOnline prep;
1832 //noise and pedestals
1833 if (fRefPedestals) prep.AddComponent(new AliTPCCalPad(*(fRefPedestals)));
1834 if (fRefPadNoise ) prep.AddComponent(new AliTPCCalPad(*(fRefPadNoise)));
1835 if (fRefPedestalMasked) prep.AddComponent(new AliTPCCalPad(*fRefPedestalMasked));
1836 //pulser data
1837 if (fRefPulserTmean) prep.AddComponent(new AliTPCCalPad(*(fRefPulserTmean)));
1838 if (fRefPulserTrms ) prep.AddComponent(new AliTPCCalPad(*(fRefPulserTrms)));
1839 if (fRefPulserQmean) prep.AddComponent(new AliTPCCalPad(*(fRefPulserQmean)));
1840 if (fRefPulserMasked) prep.AddComponent(new AliTPCCalPad(*fRefPulserMasked));
1841 //CE data
1842 if (fRefCETmean) prep.AddComponent(new AliTPCCalPad(*(fRefCETmean)));
1843 if (fRefCETrms ) prep.AddComponent(new AliTPCCalPad(*(fRefCETrms)));
1844 if (fRefCEQmean) prep.AddComponent(new AliTPCCalPad(*(fRefCEQmean)));
1845 if (fRefCEMasked) prep.AddComponent(new AliTPCCalPad(*fRefCEMasked));
1846 //Altro data
1847 if (fRefALTROAcqStart ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROAcqStart )));
1848 if (fRefALTROZsThr ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROZsThr )));
1849 if (fRefALTROFPED ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROFPED )));
1850 if (fRefALTROAcqStop ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROAcqStop )));
1851 if (fRefALTROMasked ) prep.AddComponent(new AliTPCCalPad(*(fRefALTROMasked )));
1852 //QA
1853 AliTPCdataQA *dataQA=fRefDataQA;
1854 if (dataQA) {
1855 if (dataQA->GetNLocalMaxima())
1856 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNLocalMaxima())));
1857 if (dataQA->GetMaxCharge())
1858 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMaxCharge())));
1859 if (dataQA->GetMeanCharge())
1860 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetMeanCharge())));
1861 if (dataQA->GetNoThreshold())
1862 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNoThreshold())));
1863 if (dataQA->GetNTimeBins())
1864 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNTimeBins())));
1865 if (dataQA->GetNPads())
1866 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetNPads())));
1867 if (dataQA->GetTimePosition())
1868 prep.AddComponent(new AliTPCCalPad(*(dataQA->GetTimePosition())));
1869 }
1870 prep.DumpToFile(file.Data());
1871 return kTRUE;
1872}
1873
a23ba1c3 1874Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracks(Double_t &dist, Int_t run, Int_t timeStamp, Double_t deltaT, Int_t side){
7d855b04 1875 /// Get the correction of the drift velocity using the offline laser tracks calbration
1876 ///
1877 /// run - run number
1878 /// timeStamp - tim stamp in seconds
1879 /// deltaT - integration period to calculate time0 offset
1880 /// side - 0 - A side, 1 - C side, 2 - mean from both sides
1881 /// Note in case no data form both A and C side - the value from active side used
1882
a23ba1c3 1883 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
78f17711 1884
1885 return GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
1886}
1887
1888Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracksOnline(Double_t &dist, Int_t /*run*/, Int_t timeStamp, Double_t deltaT, Int_t side){
7d855b04 1889 /// Get the correction of the drift velocity using the online laser tracks calbration
1890 ///
1891 /// run - run number
1892 /// timeStamp - tim stamp in seconds
1893 /// deltaT - integration period to calculate time0 offset
1894 /// side - 0 - A side, 1 - C side, 2 - mean from both sides
1895 /// Note in case no data form both A and C side - the value from active side used
1896
78f17711 1897 TObjArray *array =AliTPCcalibDB::Instance()->GetCEfitsDrift();
1898
1899 Double_t dv = GetVDriftTPCLaserTracksCommon(dist, timeStamp, deltaT, side, array);
1900 AliTPCParam *param =AliTPCcalibDB::Instance()->GetParameters();
1901 if (!param) return 0;
1902
1903 //the drift velocity is hard wired in the AliTPCCalibCE class, since online there is no access to OCDB
1904 dv*=param->GetDriftV()/2.61301900000000000e+06;
1905 if (dv>1e-20) dv=1/dv-1;
1906 else return 0;
1907 // T/P correction
1908 TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
1909
1910 AliTPCSensorTempArray *temp = (AliTPCSensorTempArray*)cearray->FindObject("TempMap");
2cd3a697 1911 AliDCSSensor *press = (AliDCSSensor*)cearray->FindObject("CavernAtmosPressure");
78f17711 1912
1913 Double_t corrPTA=0;
1914 Double_t corrPTC=0;
1915
1916 if (temp&&press) {
1917 AliTPCCalibVdrift corr(temp,press,0);
1918 corrPTA=corr.GetPTRelative(timeStamp,0);
1919 corrPTC=corr.GetPTRelative(timeStamp,1);
1920 }
1921
1922 if (side==0) dv -= corrPTA;
1923 if (side==1) dv -= corrPTC;
1924 if (side==2) dv -= (corrPTA+corrPTC)/2;
1925
1926 return dv;
1927}
1928
1929Double_t AliTPCcalibDButil::GetVDriftTPCLaserTracksCommon(Double_t &dist, Int_t timeStamp, Double_t deltaT,
1930 Int_t side, TObjArray * const array){
7d855b04 1931 /// common drift velocity retrieval for online and offline method
1932
a23ba1c3 1933 TGraphErrors *grlaserA=0;
1934 TGraphErrors *grlaserC=0;
1935 Double_t vlaserA=0, vlaserC=0;
1936 if (!array) return 0;
1937 grlaserA=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1938 grlaserC=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1939 Double_t deltaY;
5647625c 1940 if (grlaserA && grlaserA->GetN()>0) {
a23ba1c3 1941 AliTPCcalibDButil::GetNearest(grlaserA,timeStamp,dist,deltaY);
1942 if (TMath::Abs(dist)>deltaT) vlaserA= deltaY;
1943 else vlaserA = AliTPCcalibDButil::EvalGraphConst(grlaserA,timeStamp);
1944 }
5647625c 1945 if (grlaserC && grlaserC->GetN()>0) {
a23ba1c3 1946 AliTPCcalibDButil::GetNearest(grlaserC,timeStamp,dist,deltaY);
1947 if (TMath::Abs(dist)>deltaT) vlaserC= deltaY;
1948 else vlaserC = AliTPCcalibDButil::EvalGraphConst(grlaserC,timeStamp);
1949 }
1950 if (side==0) return vlaserA;
1951 if (side==1) return vlaserC;
1952 Double_t mdrift=(vlaserA+vlaserC)*0.5;
1953 if (!grlaserA) return vlaserC;
1954 if (!grlaserC) return vlaserA;
1955 return mdrift;
1956}
1957
1958
1959Double_t AliTPCcalibDButil::GetVDriftTPCCE(Double_t &dist,Int_t run, Int_t timeStamp, Double_t deltaT, Int_t side){
7d855b04 1960 /// Get the correction of the drift velocity using the CE laser data
1961 /// combining information from the CE, laser track calibration
1962 /// and P/T calibration
1963 ///
1964 /// run - run number
1965 /// timeStamp - tim stamp in seconds
1966 /// deltaT - integration period to calculate time0 offset
1967 /// side - 0 - A side, 1 - C side, 2 - mean from both sides
1968
a23ba1c3 1969 TObjArray *arrT =AliTPCcalibDB::Instance()->GetCErocTtime();
0d1b4cf8 1970 if (!arrT) return 0;
a23ba1c3 1971 AliTPCParam *param =AliTPCcalibDB::Instance()->GetParameters();
1972 TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
1973 AliTPCCalibVdrift * driftCalib = (AliTPCCalibVdrift *)cearray->FindObject("driftPTCE");
1974 //
1975 //
1976 Double_t corrPTA = 0, corrPTC=0;
1977 Double_t ltime0A = 0, ltime0C=0;
1978 Double_t gry=0;
1979 Double_t corrA=0, corrC=0;
1980 Double_t timeA=0, timeC=0;
5647625c 1981 const Double_t kEpsilon = 0.00001;
a23ba1c3 1982 TGraph *graphA = (TGraph*)arrT->At(72);
1983 TGraph *graphC = (TGraph*)arrT->At(73);
1984 if (!graphA && !graphC) return 0.;
1985 if (graphA &&graphA->GetN()>0) {
1986 AliTPCcalibDButil::GetNearest(graphA,timeStamp,dist,gry);
1987 timeA = AliTPCcalibDButil::EvalGraphConst(graphA,timeStamp);
1988 Int_t mtime =TMath::Nint((graphA->GetX()[0]+graphA->GetX()[graphA->GetN()-1])*0.5);
1989 ltime0A = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
5647625c 1990 if(ltime0A < kEpsilon) return 0;
a23ba1c3 1991 if (driftCalib) corrPTA = driftCalib->GetPTRelative(timeStamp,0);
1e722a63 1992 corrA = (param->GetZLength(36)/(timeA*param->GetTSample()*(1.-ltime0A)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
a23ba1c3 1993 corrA-=corrPTA;
1994 }
1995 if (graphC&&graphC->GetN()>0){
1996 AliTPCcalibDButil::GetNearest(graphC,timeStamp,dist,gry);
1997 timeC=AliTPCcalibDButil::EvalGraphConst(graphC,timeStamp);
1998 Int_t mtime=TMath::Nint((graphC->GetX()[0]+graphC->GetX()[graphC->GetN()-1])*0.5);
1999 ltime0C = GetLaserTime0(run,mtime,TMath::Nint(deltaT),0);
5647625c 2000 if(ltime0C < kEpsilon) return 0;
2001if (driftCalib) corrPTC = driftCalib->GetPTRelative(timeStamp,0);
1e722a63 2002 corrC = (param->GetZLength(54)/(timeC*param->GetTSample()*(1.-ltime0C)-param->GetL1Delay()-0*param->GetZSigma()/param->GetDriftV()))/param->GetDriftV()-1;
a23ba1c3 2003 corrC-=corrPTC;
2004 }
2005
2006 if (side ==0 ) return corrA;
2007 if (side ==1 ) return corrC;
2008 Double_t corrM= (corrA+corrC)*0.5;
2009 if (!graphA) corrM=corrC;
2010 if (!graphC) corrM=corrA;
2011 return corrM;
2012}
2013
cc65e4f5 2014Double_t AliTPCcalibDButil::GetVDriftTPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
7d855b04 2015 /// return drift velocity using the TPC-ITS matchin method
2016 /// return also distance to the closest point
2017
cc65e4f5 2018 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2019 TGraphErrors *graph=0;
2020 dist=0;
2021 if (!array) return 0;
5647625c 2022 //array->ls();
cc65e4f5 2023 graph = (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_DRIFTVD");
3760239f 2024 if (!graph) graph = (TGraphErrors*)array->FindObject("ALIGN_TOFB_TPC_DRIFTVD");
cc65e4f5 2025 if (!graph) return 0;
2026 Double_t deltaY;
2027 AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY);
2028 Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
2029 return value;
2030}
2031
2032Double_t AliTPCcalibDButil::GetTime0TPCITS(Double_t &dist, Int_t run, Int_t timeStamp){
7d855b04 2033 /// Get time dependent time 0 (trigger delay in cm) correction
2034 /// Arguments:
2035 /// timestamp - timestamp
2036 /// run - run number
2037 ///
2038 /// Notice - Extrapolation outside of calibration range - using constant function
2039
cc65e4f5 2040 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2041 TGraphErrors *graph=0;
2042 dist=0;
2043 if (!array) return 0;
3760239f 2044 graph = (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_T0");
2045 if (!graph) graph = (TGraphErrors*)array->FindObject("ALIGN_ITSB_TPC_T0");
cc65e4f5 2046 if (!graph) return 0;
2047 Double_t deltaY;
2048 AliTPCcalibDButil::GetNearest(graph,timeStamp,dist,deltaY);
2049 Double_t value = AliTPCcalibDButil::EvalGraphConst(graph,timeStamp);
2050 return value;
2051}
2052
2053
a23ba1c3 2054
2055
2056
2057Int_t AliTPCcalibDButil::MakeRunList(Int_t startRun, Int_t stopRun){
7d855b04 2058 /// VERY obscure method - we need something in framework
2059 /// Find the TPC runs with temperature OCDB entry
2060 /// cache the start and end of the run
2061
a23ba1c3 2062 AliCDBStorage* storage = AliCDBManager::Instance()->GetSpecificStorage("TPC/Calib/Temperature");
2063 if (!storage) storage = AliCDBManager::Instance()->GetDefaultStorage();
2064 if (!storage) return 0;
2065 TString path=storage->GetURI();
2066 TString runsT;
2067 {
2068 TString command;
2069 if (path.Contains("local")){ // find the list if local system
2070 path.ReplaceAll("local://","");
2071 path+="TPC/Calib/Temperature";
2072 command=Form("ls %s | sed s/_/\\ /g | awk '{print \"r\"$2}' ",path.Data());
2073 }
2074 runsT=gSystem->GetFromPipe(command);
2075 }
2076 TObjArray *arr= runsT.Tokenize("r");
2077 if (!arr) return 0;
2078 //
2079 TArrayI indexes(arr->GetEntries());
2080 TArrayI runs(arr->GetEntries());
2081 Int_t naccept=0;
2082 {for (Int_t irun=0;irun<arr->GetEntries();irun++){
2083 Int_t irunN = atoi(arr->At(irun)->GetName());
2084 if (irunN<startRun) continue;
2085 if (irunN>stopRun) continue;
2086 runs[naccept]=irunN;
2087 naccept++;
2088 }}
09d5920f 2089 delete arr;
a23ba1c3 2090 fRuns.Set(naccept);
2091 fRunsStart.Set(fRuns.fN);
2092 fRunsStop.Set(fRuns.fN);
2093 TMath::Sort(fRuns.fN, runs.fArray, indexes.fArray,kFALSE);
2094 for (Int_t irun=0; irun<fRuns.fN; irun++) fRuns[irun]=runs[indexes[irun]];
2095
2096 //
2097 AliCDBEntry * entry = 0;
2098 {for (Int_t irun=0;irun<fRuns.fN; irun++){
2099 entry = AliCDBManager::Instance()->Get("TPC/Calib/Temperature",fRuns[irun]);
2100 if (!entry) continue;
2101 AliTPCSensorTempArray * tmpRun = dynamic_cast<AliTPCSensorTempArray*>(entry->GetObject());
2102 if (!tmpRun) continue;
2103 fRunsStart[irun]=tmpRun->GetStartTime().GetSec();
2104 fRunsStop[irun]=tmpRun->GetEndTime().GetSec();
ef1807ef 2105 //AliInfo(Form("irun\t%d\tRun\t%d\t%d\t%d\n",irun,fRuns[irun],tmpRun->GetStartTime().GetSec(),tmpRun->GetEndTime().GetSec()));
a23ba1c3 2106 }}
2107 return fRuns.fN;
2108}
2109
2110
2111Int_t AliTPCcalibDButil::FindRunTPC(Int_t itime, Bool_t debug){
7d855b04 2112 /// binary search - find the run for given time stamp
2113
a23ba1c3 2114 Int_t index0 = TMath::BinarySearch(fRuns.fN, fRunsStop.fArray,itime);
2115 Int_t index1 = TMath::BinarySearch(fRuns.fN, fRunsStart.fArray,itime);
2116 Int_t cindex = -1;
2117 for (Int_t index=index0; index<=index1; index++){
2118 if (fRunsStart[index]<=itime && fRunsStop[index]>=itime) cindex=index;
2119 if (debug) {
ef1807ef 2120 AliInfo(Form("%d\t%d\t%d\n",fRuns[index], fRunsStart[index]-itime, fRunsStop[index]-itime));
a23ba1c3 2121 }
2122 }
2123 if (cindex<0) cindex =(index0+index1)/2;
2124 if (cindex<0) {
2125 return 0;
2126 }
2127 return fRuns[cindex];
2128}
2129
2130
2131
2132
2133
2134TGraph* AliTPCcalibDButil::FilterGraphMedian(TGraph * graph, Float_t sigmaCut,Double_t &medianY){
7d855b04 2135 /// filter outlyer measurement
2136 /// Only points around median +- sigmaCut filtered
2137
a23ba1c3 2138 if (!graph) return 0;
2139 Int_t kMinPoints=2;
2140 Int_t npoints0 = graph->GetN();
2141 Int_t npoints=0;
2142 Float_t rmsY=0;
a23ba1c3 2143 //
2144 //
2145 if (npoints0<kMinPoints) return 0;
a9f487a1 2146
2147 Double_t *outx=new Double_t[npoints0];
2148 Double_t *outy=new Double_t[npoints0];
a23ba1c3 2149 for (Int_t iter=0; iter<3; iter++){
2150 npoints=0;
2151 for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
2152 if (graph->GetY()[ipoint]==0) continue;
2153 if (iter>0 &&TMath::Abs(graph->GetY()[ipoint]-medianY)>sigmaCut*rmsY) continue;
2154 outx[npoints] = graph->GetX()[ipoint];
2155 outy[npoints] = graph->GetY()[ipoint];
2156 npoints++;
2157 }
2158 if (npoints<=1) break;
2159 medianY =TMath::Median(npoints,outy);
2160 rmsY =TMath::RMS(npoints,outy);
2161 }
2162 TGraph *graphOut=0;
2163 if (npoints>1) graphOut= new TGraph(npoints,outx,outy);
a9f487a1 2164 delete [] outx;
2165 delete [] outy;
a23ba1c3 2166 return graphOut;
2167}
2168
2169
2170TGraph* AliTPCcalibDButil::FilterGraphMedianAbs(TGraph * graph, Float_t cut,Double_t &medianY){
7d855b04 2171 /// filter outlyer measurement
2172 /// Only points around median +- cut filtered
2173
a23ba1c3 2174 if (!graph) return 0;
2175 Int_t kMinPoints=2;
2176 Int_t npoints0 = graph->GetN();
2177 Int_t npoints=0;
829455ad 2178// Float_t rmsY=0;
a23ba1c3 2179 //
2180 //
2181 if (npoints0<kMinPoints) return 0;
a9f487a1 2182
2183 Double_t *outx=new Double_t[npoints0];
2184 Double_t *outy=new Double_t[npoints0];
a23ba1c3 2185 for (Int_t iter=0; iter<3; iter++){
2186 npoints=0;
2187 for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
2188 if (graph->GetY()[ipoint]==0) continue;
2189 if (iter>0 &&TMath::Abs(graph->GetY()[ipoint]-medianY)>cut) continue;
2190 outx[npoints] = graph->GetX()[ipoint];
2191 outy[npoints] = graph->GetY()[ipoint];
2192 npoints++;
2193 }
2194 if (npoints<=1) break;
2195 medianY =TMath::Median(npoints,outy);
829455ad 2196// rmsY =TMath::RMS(npoints,outy);
a23ba1c3 2197 }
2198 TGraph *graphOut=0;
2199 if (npoints>1) graphOut= new TGraph(npoints,outx,outy);
a9f487a1 2200 delete [] outx;
2201 delete [] outy;
a23ba1c3 2202 return graphOut;
2203}
2204
2205
2206
8166d5d7 2207TGraphErrors* AliTPCcalibDButil::FilterGraphMedianErr(TGraphErrors * const graph, Float_t sigmaCut,Double_t &medianY){
7d855b04 2208 /// filter outlyer measurement
2209 /// Only points with normalized errors median +- sigmaCut filtered
2210
a23ba1c3 2211 Int_t kMinPoints=10;
2212 Int_t npoints0 = graph->GetN();
2213 Int_t npoints=0;
2214 Float_t medianErr=0, rmsErr=0;
a9f487a1 2215 //
2216 //
2217 if (npoints0<kMinPoints) return 0;
2218
a23ba1c3 2219 Double_t *outx=new Double_t[npoints0];
2220 Double_t *outy=new Double_t[npoints0];
2221 Double_t *erry=new Double_t[npoints0];
2222 Double_t *nerry=new Double_t[npoints0];
2223 Double_t *errx=new Double_t[npoints0];
a9f487a1 2224
a23ba1c3 2225 for (Int_t iter=0; iter<3; iter++){
2226 npoints=0;
2227 for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
2228 nerry[npoints] = graph->GetErrorY(ipoint);
2229 if (iter>0 &&TMath::Abs(nerry[npoints]-medianErr)>sigmaCut*rmsErr) continue;
2230 erry[npoints] = graph->GetErrorY(ipoint);
2231 outx[npoints] = graph->GetX()[ipoint];
2232 outy[npoints] = graph->GetY()[ipoint];
2233 errx[npoints] = graph->GetErrorY(ipoint);
2234 npoints++;
2235 }
2236 if (npoints==0) break;
2237 medianErr=TMath::Median(npoints,erry);
2238 medianY =TMath::Median(npoints,outy);
2239 rmsErr =TMath::RMS(npoints,erry);
2240 }
2241 TGraphErrors *graphOut=0;
2242 if (npoints>1) graphOut= new TGraphErrors(npoints,outx,outy,errx,erry);
2243 delete []outx;
2244 delete []outy;
a23ba1c3 2245 delete []erry;
a9f487a1 2246 delete []nerry;
2247 delete []errx;
a23ba1c3 2248 return graphOut;
2249}
2250
2251
2252void AliTPCcalibDButil::Sort(TGraph *graph){
7d855b04 2253 /// sort array - neccessay for approx
2254
a23ba1c3 2255 Int_t npoints = graph->GetN();
2256 Int_t *indexes=new Int_t[npoints];
2257 Double_t *outx=new Double_t[npoints];
2258 Double_t *outy=new Double_t[npoints];
2259 TMath::Sort(npoints, graph->GetX(),indexes,kFALSE);
2260 for (Int_t i=0;i<npoints;i++) outx[i]=graph->GetX()[indexes[i]];
2261 for (Int_t i=0;i<npoints;i++) outy[i]=graph->GetY()[indexes[i]];
2262 for (Int_t i=0;i<npoints;i++) graph->GetX()[i]=outx[i];
2263 for (Int_t i=0;i<npoints;i++) graph->GetY()[i]=outy[i];
2264
a9f487a1 2265 delete [] indexes;
2266 delete [] outx;
2267 delete [] outy;
a23ba1c3 2268}
2269void AliTPCcalibDButil::SmoothGraph(TGraph *graph, Double_t delta){
7d855b04 2270 /// smmoth graph - mean on the interval
2271
a23ba1c3 2272 Sort(graph);
2273 Int_t npoints = graph->GetN();
2274 Double_t *outy=new Double_t[npoints];
0d1b4cf8 2275
a23ba1c3 2276 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
2277 Double_t lx=graph->GetX()[ipoint];
2278 Int_t index0=TMath::BinarySearch(npoints, graph->GetX(),lx-delta);
2279 Int_t index1=TMath::BinarySearch(npoints, graph->GetX(),lx+delta);
2280 if (index0<0) index0=0;
2281 if (index1>=npoints-1) index1=npoints-1;
2282 if ((index1-index0)>1){
2283 outy[ipoint] = TMath::Mean(index1-index0, &(graph->GetY()[index0]));
2284 }else{
2285 outy[ipoint]=graph->GetY()[ipoint];
2286 }
2287 }
0d1b4cf8 2288 // TLinearFitter fitter(3,"pol2");
2289// for (Int_t ipoint=0; ipoint<npoints; ipoint++){
2290// Double_t lx=graph->GetX()[ipoint];
2291// Int_t index0=TMath::BinarySearch(npoints, graph->GetX(),lx-delta);
2292// Int_t index1=TMath::BinarySearch(npoints, graph->GetX(),lx+delta);
2293// if (index0<0) index0=0;
2294// if (index1>=npoints-1) index1=npoints-1;
2295// fitter.ClearPoints();
2296// for (Int_t jpoint=0;jpoint<index1-index0; jpoint++)
2297// if ((index1-index0)>1){
2298// outy[ipoint] = TMath::Mean(index1-index0, &(graph->GetY()[index0]));
2299// }else{
2300// outy[ipoint]=graph->GetY()[ipoint];
2301// }
2302// }
2303
2304
2305
a23ba1c3 2306 for (Int_t ipoint=0; ipoint<npoints; ipoint++){
2307 graph->GetY()[ipoint] = outy[ipoint];
2308 }
2309 delete[] outy;
2310}
2311
8166d5d7 2312Double_t AliTPCcalibDButil::EvalGraphConst(TGraph * const graph, Double_t xref){
7d855b04 2313 /// Use constant interpolation outside of range
2314
a23ba1c3 2315 if (!graph) {
ef1807ef 2316 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
a23ba1c3 2317 return 0;
2318 }
5647625c 2319
a23ba1c3 2320 if (graph->GetN()<1){
ef1807ef 2321 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph \n");
a23ba1c3 2322 return 0;
2323 }
5647625c 2324
2325
a23ba1c3 2326 if (xref<graph->GetX()[0]) return graph->GetY()[0];
2327 if (xref>graph->GetX()[graph->GetN()-1]) return graph->GetY()[graph->GetN()-1];
5647625c 2328
ef1807ef 2329 // AliInfo(Form("graph->Eval(graph->GetX()[0]) %f, graph->Eval(xref) %f \n",graph->Eval(graph->GetX()[0]), graph->Eval(xref)));
5647625c 2330
2331 if(graph->GetN()==1)
2332 return graph->Eval(graph->GetX()[0]);
2333
2334
2335 return graph->Eval(xref);
a23ba1c3 2336}
2337
108a67db 2338Double_t AliTPCcalibDButil::EvalGraphConst(AliSplineFit *graph, Double_t xref){
7d855b04 2339 /// Use constant interpolation outside of range also for spline fits
2340
108a67db 2341 if (!graph) {
ef1807ef 2342 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: 0 pointer\n");
108a67db 2343 return 0;
2344 }
2345 if (graph->GetKnots()<1){
ef1807ef 2346 AliInfoGeneral("AliTPCcalibDButil","AliTPCcalibDButil::EvalGraphConst: Empty graph");
108a67db 2347 return 0;
2348 }
2349 if (xref<graph->GetX()[0]) return graph->GetY0()[0];
2350 if (xref>graph->GetX()[graph->GetKnots()-1]) return graph->GetY0()[graph->GetKnots()-1];
2351 return graph->Eval( xref);
2352}
2353
1e722a63 2354Float_t AliTPCcalibDButil::FilterSensor(AliDCSSensor * sensor, Double_t ymin, Double_t ymax, Double_t maxdy, Double_t sigmaCut){
7d855b04 2355 /// Filter DCS sensor information
2356 /// ymin - minimal value
2357 /// ymax - max value
2358 /// maxdy - maximal deirivative
2359 /// sigmaCut - cut on values and derivative in terms of RMS distribution
2360 /// Return value - accepted fraction
2361 ///
2362 /// Algorithm:
2363 ///
2364 /// 0. Calculate median and rms of values in specified range
2365 /// 1. Filter out outliers - median+-sigmaCut*rms
2366 /// values replaced by median
2367
1e722a63 2368 AliSplineFit * fit = sensor->GetFit();
2369 if (!fit) return 0.;
2370 Int_t nknots = fit->GetKnots();
2371 if (nknots==0) {
2372 delete fit;
2373 sensor->SetFit(0);
2374 return 0;
2375 }
2376 //
2377 Double_t *yin0 = new Double_t[nknots];
2378 Double_t *yin1 = new Double_t[nknots];
2379 Int_t naccept=0;
2380
2381 for (Int_t iknot=0; iknot< nknots; iknot++){
2382 if (fit->GetY0()[iknot]>ymin && fit->GetY0()[iknot]<ymax){
2383 yin0[naccept] = fit->GetY0()[iknot];
2384 yin1[naccept] = fit->GetY1()[iknot];
2385 if (TMath::Abs(fit->GetY1()[iknot])>maxdy) yin1[naccept]=0;
2386 naccept++;
2387 }
2388 }
2389 if (naccept<1) {
2390 delete fit;
2391 sensor->SetFit(0);
a9f487a1 2392 delete [] yin0;
2393 delete [] yin1;
1e722a63 2394 return 0.;
2395 }
0d1b4cf8 2396
1e722a63 2397 Double_t medianY0=0, medianY1=0;
2398 Double_t rmsY0 =0, rmsY1=0;
2399 medianY0 = TMath::Median(naccept, yin0);
2400 medianY1 = TMath::Median(naccept, yin1);
2401 rmsY0 = TMath::RMS(naccept, yin0);
2402 rmsY1 = TMath::RMS(naccept, yin1);
2403 naccept=0;
2404 //
2405 // 1. Filter out outliers - median+-sigmaCut*rms
2406 // values replaced by median
2407 // if replaced the derivative set to 0
2408 //
2409 for (Int_t iknot=0; iknot< nknots; iknot++){
2410 Bool_t isOK=kTRUE;
2411 if (TMath::Abs(fit->GetY0()[iknot]-medianY0)>sigmaCut*rmsY0) isOK=kFALSE;
2412 if (TMath::Abs(fit->GetY1()[iknot]-medianY1)>sigmaCut*rmsY1) isOK=kFALSE;
2413 if (nknots<2) fit->GetY1()[iknot]=0;
2414 if (TMath::Abs(fit->GetY1()[iknot])>maxdy) fit->GetY1()[iknot]=0;
2415 if (!isOK){
2416 fit->GetY0()[iknot]=medianY0;
2417 fit->GetY1()[iknot]=0;
2418 }else{
2419 naccept++;
2420 }
2421 }
2422 delete [] yin0;
2423 delete [] yin1;
2424 return Float_t(naccept)/Float_t(nknots);
2425}
2426
2427Float_t AliTPCcalibDButil::FilterTemperature(AliTPCSensorTempArray *tempArray, Double_t ymin, Double_t ymax, Double_t sigmaCut){
7d855b04 2428 /// Filter temperature array
2429 /// tempArray - array of temperatures -
2430 /// ymin - minimal accepted temperature - default 15
2431 /// ymax - maximal accepted temperature - default 22
2432 /// sigmaCut - values filtered on interval median+-sigmaCut*rms - defaut 5
2433 /// return value - fraction of filtered sensors
2434
1e722a63 2435 const Double_t kMaxDy=0.1;
2436 Int_t nsensors=tempArray->NumSensors();
2437 if (nsensors==0) return 0.;
2438 Int_t naccept=0;
2439 for (Int_t isensor=0; isensor<nsensors; isensor++){
2440 AliDCSSensor *sensor = tempArray->GetSensorNum(isensor);
2441 if (!sensor) continue;
1e722a63 2442 FilterSensor(sensor,ymin,ymax,kMaxDy, sigmaCut);
2443 if (sensor->GetFit()==0){
0d1b4cf8 2444 //delete sensor;
1e722a63 2445 tempArray->RemoveSensorNum(isensor);
2446 }else{
2447 naccept++;
2448 }
2449 }
2450 return Float_t(naccept)/Float_t(nsensors);
2451}
2452
a23ba1c3 2453
8166d5d7 2454void AliTPCcalibDButil::FilterCE(Double_t deltaT, Double_t cutAbs, Double_t cutSigma, TTreeSRedirector * const pcstream){
7d855b04 2455 /// Filter CE data
2456 /// Input parameters:
2457 /// deltaT - smoothing window (in seconds)
2458 /// cutAbs - max distance of the time info to the median (in time bins)
2459 /// cutSigma - max distance (in the RMS)
2460 /// pcstream - optional debug streamer to store original and filtered info
2461 /// Hardwired parameters:
2462 /// kMinPoints =10; // minimal number of points to define the CE
2463 /// kMinSectors=12; // minimal number of sectors to define sideCE
2464 /// Algorithm:
2465 /// 0. Filter almost emty graphs (kMinPoints=10)
2466 /// 1. calculate median and RMS per side
2467 /// 2. Filter graphs - in respect with side medians
2468 /// - cutAbs and cutDelta used
2469 /// 3. Cut in respect wit the graph median - cutAbs and cutRMS used
2470 /// 4. Calculate mean for A side and C side
2471
1e722a63 2472 const Int_t kMinPoints =10; // minimal number of points to define the CE
2473 const Int_t kMinSectors=12; // minimal number of sectors to define sideCE
2474 const Int_t kMinTime =400; // minimal arrival time of CE
2475 TObjArray *arrT=AliTPCcalibDB::Instance()->GetCErocTtime();
a23ba1c3 2476 Double_t medianY=0;
1e722a63 2477 TObjArray* cearray =AliTPCcalibDB::Instance()->GetCEData();
a23ba1c3 2478 if (!cearray) return;
1e722a63 2479 Double_t tmin=-1;
2480 Double_t tmax=-1;
2481 //
2482 //
a23ba1c3 2483 AliTPCSensorTempArray *tempMapCE = (AliTPCSensorTempArray *)cearray->FindObject("TempMap");
2cd3a697 2484 AliDCSSensor * cavernPressureCE = (AliDCSSensor *) cearray->FindObject("CavernAtmosPressure");
a23ba1c3 2485 if ( tempMapCE && cavernPressureCE){
1e722a63 2486 //
c5dfa2dc 2487 // Bool_t isOK = FilterTemperature(tempMapCE)>0.1;
2488 // FilterSensor(cavernPressureCE,960,1050,10, 5.);
2489 // if (cavernPressureCE->GetFit()==0) isOK=kFALSE;
2490 Bool_t isOK=kTRUE;
1e722a63 2491 if (isOK) {
2492 // recalculate P/T correction map for time of the CE
2493 AliTPCCalibVdrift * driftCalib = new AliTPCCalibVdrift(tempMapCE,cavernPressureCE ,0);
2494 driftCalib->SetName("driftPTCE");
2495 driftCalib->SetTitle("driftPTCE");
2496 cearray->AddLast(driftCalib);
2497 }
a23ba1c3 2498 }
1e722a63 2499 //
2500 // 0. Filter almost emty graphs
2501 //
a23ba1c3 2502
1e722a63 2503 for (Int_t i=0; i<72;i++){
a23ba1c3 2504 TGraph *graph= (TGraph*)arrT->At(i);
29797f44 2505 if (!graph) continue;
2506 graph->Sort();
a23ba1c3 2507 if (graph->GetN()<kMinPoints){
2508 arrT->AddAt(0,i);
2509 delete graph; // delete empty graph
2510 continue;
2511 }
1e722a63 2512 if (tmin<0) tmin = graph->GetX()[0];
2513 if (tmax<0) tmax = graph->GetX()[graph->GetN()-1];
2514 //
2515 if (tmin>graph->GetX()[0]) tmin=graph->GetX()[0];
2516 if (tmax<graph->GetX()[graph->GetN()-1]) tmax=graph->GetX()[graph->GetN()-1];
2517 }
2518 //
2519 // 1. calculate median and RMS per side
2520 //
2521 TArrayF arrA(100000), arrC(100000);
2522 Int_t nA=0, nC=0;
2523 Double_t medianA=0, medianC=0;
2524 Double_t rmsA=0, rmsC=0;
2525 for (Int_t isec=0; isec<72;isec++){
2526 TGraph *graph= (TGraph*)arrT->At(isec);
2527 if (!graph) continue;
2528 for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){
2529 if (graph->GetY()[ipoint]<kMinTime) continue;
2530 if (nA>=arrA.fN) arrA.Set(nA*2);
2531 if (nC>=arrC.fN) arrC.Set(nC*2);
2532 if (isec%36<18) arrA[nA++]= graph->GetY()[ipoint];
2533 if (isec%36>=18) arrC[nC++]= graph->GetY()[ipoint];
2534 }
2535 }
2536 if (nA>0){
2537 medianA=TMath::Median(nA,arrA.fArray);
2538 rmsA =TMath::RMS(nA,arrA.fArray);
2539 }
2540 if (nC>0){
2541 medianC=TMath::Median(nC,arrC.fArray);
2542 rmsC =TMath::RMS(nC,arrC.fArray);
2543 }
2544 //
2545 // 2. Filter graphs - in respect with side medians
2546 //
2547 TArrayD vecX(100000), vecY(100000);
2548 for (Int_t isec=0; isec<72;isec++){
2549 TGraph *graph= (TGraph*)arrT->At(isec);
2550 if (!graph) continue;
2551 Double_t median = (isec%36<18) ? medianA: medianC;
2552 Double_t rms = (isec%36<18) ? rmsA: rmsC;
2553 Int_t naccept=0;
29797f44 2554 // for (Int_t ipoint=kMinPoints-1; ipoint<graph->GetN();ipoint++){ //not neccessary to remove first points
2555 for (Int_t ipoint=0; ipoint<graph->GetN();ipoint++){
1e722a63 2556 if (TMath::Abs(graph->GetY()[ipoint]-median)>cutAbs) continue;
2557 if (TMath::Abs(graph->GetY()[ipoint]-median)>cutSigma*rms) continue;
2558 vecX[naccept]= graph->GetX()[ipoint];
2559 vecY[naccept]= graph->GetY()[ipoint];
2560 naccept++;
2561 }
2562 if (naccept<kMinPoints){
2563 arrT->AddAt(0,isec);
2564 delete graph; // delete empty graph
2565 continue;
2566 }
2567 TGraph *graph2 = new TGraph(naccept, vecX.fArray, vecY.fArray);
2568 delete graph;
2569 arrT->AddAt(graph2,isec);
2570 }
2571 //
2572 // 3. Cut in respect wit the graph median
2573 //
2574 for (Int_t i=0; i<72;i++){
2575 TGraph *graph= (TGraph*)arrT->At(i);
2576 if (!graph) continue;
2577 //
2578 // filter in range
2579 //
2580 TGraph* graphTS0= FilterGraphMedianAbs(graph,cutAbs,medianY);
a23ba1c3 2581 if (!graphTS0) continue;
2582 if (graphTS0->GetN()<kMinPoints) {
2583 delete graphTS0;
2584 delete graph;
2585 arrT->AddAt(0,i);
2586 continue;
2587 }
1e722a63 2588 TGraph* graphTS= FilterGraphMedian(graphTS0,cutSigma,medianY);
f03e487b 2589 if (!graphTS) continue;
a23ba1c3 2590 graphTS->Sort();
2591 AliTPCcalibDButil::SmoothGraph(graphTS,deltaT);
2592 if (pcstream){
2593 Int_t run = AliTPCcalibDB::Instance()->GetRun();
2594 (*pcstream)<<"filterCE"<<
2595 "run="<<run<<
2596 "isec="<<i<<
2597 "mY="<<medianY<<
2598 "graph.="<<graph<<
2599 "graphTS0.="<<graphTS0<<
2600 "graphTS.="<<graphTS<<
2601 "\n";
2602 }
2603 delete graphTS0;
a23ba1c3 2604 arrT->AddAt(graphTS,i);
2605 delete graph;
2606 }
1e722a63 2607 //
2608 // Recalculate the mean time A side C side
2609 //
2610 TArrayF xA(200), yA(200), eA(200), xC(200),yC(200), eC(200);
2611 Int_t meanPoints=(nA+nC)/72; // mean number of points
2612 for (Int_t itime=0; itime<200; itime++){
2613 nA=0, nC=0;
2614 Double_t time=tmin+(tmax-tmin)*Float_t(itime)/200.;
2615 for (Int_t i=0; i<72;i++){
2616 TGraph *graph= (TGraph*)arrT->At(i);
2617 if (!graph) continue;
2618 if (graph->GetN()<(meanPoints/4)) continue;
2619 if ( (i%36)<18 ) arrA[nA++]=graph->Eval(time);
2620 if ( (i%36)>=18 ) arrC[nC++]=graph->Eval(time);
2621 }
2622 xA[itime]=time;
2623 xC[itime]=time;
2624 yA[itime]=(nA>0)? TMath::Mean(nA,arrA.fArray):0;
2625 yC[itime]=(nC>0)? TMath::Mean(nC,arrC.fArray):0;
2626 eA[itime]=(nA>0)? TMath::RMS(nA,arrA.fArray):0;
2627 eC[itime]=(nC>0)? TMath::RMS(nC,arrC.fArray):0;
2628 }
2629 //
2630 Double_t rmsTA = TMath::RMS(200,yA.fArray)+TMath::Mean(200,eA.fArray);
2631 Double_t rmsTC = TMath::RMS(200,yC.fArray)+TMath::Mean(200,eC.fArray);
2632 if (pcstream){
2633 Int_t run = AliTPCcalibDB::Instance()->GetRun();
2634 (*pcstream)<<"filterAC"<<
2635 "run="<<run<<
2636 "nA="<<nA<<
2637 "nC="<<nC<<
2638 "rmsTA="<<rmsTA<<
2639 "rmsTC="<<rmsTC<<
2640 "\n";
2641 }
2642 //
2643 TGraphErrors *grA = new TGraphErrors(200,xA.fArray,yA.fArray,0, eA.fArray);
2644 TGraphErrors *grC = new TGraphErrors(200,xC.fArray,yC.fArray,0, eC.fArray);
2645 TGraph* graphTSA= FilterGraphMedian(grA,cutSigma,medianY);
2646 if (graphTSA&&graphTSA->GetN()) SmoothGraph(graphTSA,deltaT);
2647 TGraph* graphTSC= FilterGraphMedian(grC,cutSigma,medianY);
2648 if (graphTSC&&graphTSC->GetN()>0) SmoothGraph(graphTSC,deltaT);
2649 delete grA;
2650 delete grC;
2651 if (nA<kMinSectors) arrT->AddAt(0,72);
2652 else arrT->AddAt(graphTSA,72);
2653 if (nC<kMinSectors) arrT->AddAt(0,73);
2654 else arrT->AddAt(graphTSC,73);
a23ba1c3 2655}
2656
2657
8166d5d7 2658void AliTPCcalibDButil::FilterTracks(Int_t run, Double_t cutSigma, TTreeSRedirector * const pcstream){
7d855b04 2659 /// Filter Drift velocity measurement using the tracks
2660 /// 0. remove outlyers - error based
2661 /// cutSigma
2662
a23ba1c3 2663 const Int_t kMinPoints=1; // minimal number of points to define value
2664 TObjArray *arrT=AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2665 Double_t medianY=0;
2666 if (!arrT) return;
2667 for (Int_t i=0; i<arrT->GetEntries();i++){
14301155 2668 TGraphErrors *graph= dynamic_cast<TGraphErrors*>(arrT->At(i));
a23ba1c3 2669 if (!graph) continue;
2670 if (graph->GetN()<kMinPoints){
2671 delete graph;
2672 arrT->AddAt(0,i);
2673 continue;
2674 }
5647625c 2675 TGraphErrors *graph2 = NULL;
2676 if(graph->GetN()<10) {
2677 graph2 = new TGraphErrors(graph->GetN(),graph->GetX(),graph->GetY(),graph->GetEX(),graph->GetEY());
2678 if (!graph2) {
2679 delete graph; arrT->AddAt(0,i); continue;
2680 }
2681 }
2682 else {
2683 graph2= FilterGraphMedianErr(graph,cutSigma,medianY);
2684 if (!graph2) {
2685 delete graph; arrT->AddAt(0,i); continue;
2686 }
a23ba1c3 2687 }
2688 if (graph2->GetN()<1) {
2689 delete graph; arrT->AddAt(0,i); continue;
2690 }
2691 graph2->SetName(graph->GetName());
2692 graph2->SetTitle(graph->GetTitle());
2693 arrT->AddAt(graph2,i);
2694 if (pcstream){
2695 (*pcstream)<<"filterTracks"<<
2696 "run="<<run<<
2697 "isec="<<i<<
2698 "mY="<<medianY<<
2699 "graph.="<<graph<<
2700 "graph2.="<<graph2<<
2701 "\n";
2702 }
2703 delete graph;
2704 }
2705}
2706
2707
a23ba1c3 2708
2709
2710
2711Double_t AliTPCcalibDButil::GetLaserTime0(Int_t run, Int_t timeStamp, Int_t deltaT, Int_t side){
7d855b04 2712 /// get laser time offset
2713 /// median around timeStamp+-deltaT
2714 /// QA - chi2 needed for later usage - to be added
2715 /// - currently cut on error
2716
a23ba1c3 2717 Int_t kMinPoints=1;
2718 Double_t kMinDelay=0.01;
2719 Double_t kMinDelayErr=0.0001;
2720
2721 TObjArray *array =AliTPCcalibDB::Instance()->GetTimeVdriftSplineRun(run);
2722 if (!array) return 0;
2723 TGraphErrors *tlaser=0;
2724 if (array){
2725 if (side==0) tlaser=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DELAY_LASER_ALL_A");
2726 if (side==1) tlaser=(TGraphErrors*)array->FindObject("GRAPH_MEAN_DELAY_LASER_ALL_C");
2727 }
2728 if (!tlaser) return 0;
2729 Int_t npoints0= tlaser->GetN();
2730 if (npoints0==0) return 0;
2731 Double_t *xlaser = new Double_t[npoints0];
2732 Double_t *ylaser = new Double_t[npoints0];
2733 Int_t npoints=0;
2734 for (Int_t i=0;i<npoints0;i++){
2735 //printf("%d\n",i);
2736 if (tlaser->GetY()[i]<=kMinDelay) continue; // filter zeros
2737 if (tlaser->GetErrorY(i)>TMath::Abs(kMinDelayErr)) continue;
2738 xlaser[npoints]=tlaser->GetX()[npoints];
2739 ylaser[npoints]=tlaser->GetY()[npoints];
2740 npoints++;
2741 }
2742 //
2743 //
2744 Int_t index0=TMath::BinarySearch(npoints, xlaser, Double_t(timeStamp-deltaT))-1;
2745 Int_t index1=TMath::BinarySearch(npoints, xlaser, Double_t(timeStamp+deltaT))+1;
2746 //if (index1-index0 <kMinPoints) { index1+=kMinPoints; index0-=kMinPoints;}
2747 if (index0<0) index0=0;
2748 if (index1>=npoints-1) index1=npoints-1;
f03e487b 2749 if (index1-index0<kMinPoints) {
2750 delete [] ylaser;
2751 delete [] xlaser;
2752 return 0;
2753 }
a23ba1c3 2754 //
2755 //Double_t median = TMath::Median(index1-index0, &(ylaser[index0]));
2756 Double_t mean = TMath::Mean(index1-index0, &(ylaser[index0]));
2757 delete [] ylaser;
2758 delete [] xlaser;
2759 return mean;
2760}
0d1b4cf8 2761
2762
2763
2764
8166d5d7 2765void AliTPCcalibDButil::FilterGoofie(AliDCSSensorArray * goofieArray, Double_t deltaT, Double_t cutSigma, Double_t minVd, Double_t maxVd, TTreeSRedirector * const pcstream){
7d855b04 2766 /// Filter Goofie data
2767 /// goofieArray - points will be filtered
2768 /// deltaT - smmothing time window
2769 /// cutSigma - outler sigma cut in rms
2770 /// minVn, maxVd- range absolute cut for variable vd/pt
2771 /// - to be tuned
2772 ///
2773 /// Ignore goofie if not enough points
2774
0d1b4cf8 2775 const Int_t kMinPoints = 3;
2776 //
2777
2778 TGraph *graphvd = goofieArray->GetSensorNum(2)->GetGraph();
2779 TGraph *graphan = goofieArray->GetSensorNum(8)->GetGraph();
2780 TGraph *graphaf = goofieArray->GetSensorNum(9)->GetGraph();
2781 TGraph *graphpt = goofieArray->GetSensorNum(15)->GetGraph();
2782 if (!graphvd) return;
2783 if (graphvd->GetN()<kMinPoints){
2784 delete graphvd;
2785 goofieArray->GetSensorNum(2)->SetGraph(0);
2786 return;
2787 }
2788 //
2789 // 1. Caluclate medians of critical variables
2790 // drift velcocity
2791 // P/T
2792 // area near peak
2793 // area far peak
2794 //
2795 Double_t medianpt=0;
1fabc823 2796 Double_t medianvd=0, sigmavd=0;
0d1b4cf8 2797 Double_t medianan=0;
2798 Double_t medianaf=0;
1fabc823 2799 Int_t entries=graphvd->GetN();
2800 Double_t yvdn[10000];
2801 Int_t nvd=0;
2802 //
2803 for (Int_t ipoint=0; ipoint<entries; ipoint++){
2804 if (graphpt->GetY()[ipoint]<=0.0000001) continue;
2805 if (graphvd->GetY()[ipoint]/graphpt->GetY()[ipoint]<minVd) continue;
2806 if (graphvd->GetY()[ipoint]/graphpt->GetY()[ipoint]>maxVd) continue;
2807 yvdn[nvd++]=graphvd->GetY()[ipoint];
2808 }
2809 if (nvd<kMinPoints){
2810 delete graphvd;
2811 goofieArray->GetSensorNum(2)->SetGraph(0);
2812 return;
2813 }
2814 //
2815 Int_t nuni = TMath::Min(TMath::Nint(nvd*0.4+2), nvd-1);
2816 if (nuni>=kMinPoints){
2817 AliMathBase::EvaluateUni(nvd, yvdn, medianvd,sigmavd,nuni);
2818 }else{
2819 medianvd = TMath::Median(nvd, yvdn);
2820 }
2821
0d1b4cf8 2822 TGraph * graphpt0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphpt,10,medianpt);
2823 TGraph * graphpt1 = AliTPCcalibDButil::FilterGraphMedian(graphpt0,2,medianpt);
2824 TGraph * graphan0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphan,10,medianan);
2825 TGraph * graphan1 = AliTPCcalibDButil::FilterGraphMedian(graphan0,2,medianan);
2826 TGraph * graphaf0 = AliTPCcalibDButil::FilterGraphMedianAbs(graphaf,10,medianaf);
2827 TGraph * graphaf1 = AliTPCcalibDButil::FilterGraphMedian(graphaf0,2,medianaf);
0d1b4cf8 2828 delete graphpt0;
2829 delete graphpt1;
2830 delete graphan0;
2831 delete graphan1;
2832 delete graphaf0;
2833 delete graphaf1;
2834 //
2835 // 2. Make outlyer graph
2836 //
1fabc823 2837 Int_t nOK=0;
0d1b4cf8 2838 TGraph graphOut(*graphvd);
2839 for (Int_t i=0; i<entries;i++){
2840 //
2841 Bool_t isOut=kFALSE;
1fabc823 2842 if (graphpt->GetY()[i]<=0.0000001) { graphOut.GetY()[i]=1; continue;}
2843 if (graphvd->GetY()[i]/graphpt->GetY()[i]<minVd || graphvd->GetY()[i]/graphpt->GetY()[i]>maxVd) { graphOut.GetY()[i]=1; continue;}
2844
2845 if (TMath::Abs((graphvd->GetY()[i]/graphpt->GetY()[i])/medianvd-1.)<0.05)
2846 isOut|=kTRUE;
0d1b4cf8 2847 if (TMath::Abs(graphpt->GetY()[i]/medianpt-1.)>0.02) isOut|=kTRUE;
1fabc823 2848 if (TMath::Abs(graphan->GetY()[i]/medianan-1.)>0.2) isOut|=kTRUE;
2849 if (TMath::Abs(graphaf->GetY()[i]/medianaf-1.)>0.2) isOut|=kTRUE;
0d1b4cf8 2850 graphOut.GetY()[i]= (isOut)?1:0;
1fabc823 2851 if (!isOut) nOK++;
0d1b4cf8 2852 }
1fabc823 2853 if (nOK<kMinPoints) {
2854 delete graphvd;
2855 goofieArray->GetSensorNum(2)->SetGraph(0);
2856 return;
2857 }
0d1b4cf8 2858 //
2859 // 3. Filter out outlyers - and smooth
2860 //
2861 TVectorF vmedianArray(goofieArray->NumSensors());
2862 TVectorF vrmsArray(goofieArray->NumSensors());
2863 Double_t xnew[10000];
2864 Double_t ynew[10000];
2865 TObjArray junk;
2866 junk.SetOwner(kTRUE);
2867 Bool_t isOK=kTRUE;
2868 //
2869 //
2870 for (Int_t isensor=0; isensor<goofieArray->NumSensors();isensor++){
2871 isOK=kTRUE;
2872 AliDCSSensor *sensor = goofieArray->GetSensorNum(isensor);
2873 TGraph *graphOld=0, *graphNew=0, * graphNew0=0,*graphNew1=0,*graphNew2=0;
2874 //
2875 if (!sensor) continue;
2876 graphOld = sensor->GetGraph();
2877 if (graphOld) {
2878 sensor->SetGraph(0);
2879 Int_t nused=0;
2880 for (Int_t i=0;i<entries;i++){
2881 if (graphOut.GetY()[i]>0.5) continue;
2882 xnew[nused]=graphOld->GetX()[i];
2883 ynew[nused]=graphOld->GetY()[i];
2884 nused++;
2885 }
2886 graphNew = new TGraph(nused,xnew,ynew);
2887 junk.AddLast(graphNew);
2888 junk.AddLast(graphOld);
2889 Double_t median=0;
2890 graphNew0 = AliTPCcalibDButil::FilterGraphMedian(graphNew,cutSigma,median);
2891 if (graphNew0!=0){
2892 junk.AddLast(graphNew0);
2893 graphNew1 = AliTPCcalibDButil::FilterGraphMedian(graphNew0,cutSigma,median);
2894 if (graphNew1!=0){
1fabc823 2895 junk.AddLast(graphNew1);
0d1b4cf8 2896 graphNew2 = AliTPCcalibDButil::FilterGraphMedian(graphNew1,cutSigma,median);
2897 if (graphNew2!=0) {
1fabc823 2898 vrmsArray[isensor] =TMath::RMS(graphNew2->GetN(),graphNew2->GetY());
0d1b4cf8 2899 AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
2900 AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
2901 AliTPCcalibDButil::SmoothGraph(graphNew2,deltaT);
ef1807ef 2902 // AliInfo(Form("%d\t%f\t%f\n",isensor, median,vrmsArray[isensor]));
0d1b4cf8 2903 vmedianArray[isensor]=median;
0d1b4cf8 2904 //
2905 }
2906 }
2907 }
2908 }
2909 if (!graphOld) { isOK=kFALSE; graphOld =&graphOut;}
2910 if (!graphNew0) { isOK=kFALSE; graphNew0=graphOld;}
2911 if (!graphNew1) { isOK=kFALSE; graphNew1=graphOld;}
2912 if (!graphNew2) { isOK=kFALSE; graphNew2=graphOld;}
2913 (*pcstream)<<"goofieA"<<
2914 Form("isOK_%d.=",isensor)<<isOK<<
2915 Form("s_%d.=",isensor)<<sensor<<
2916 Form("gr_%d.=",isensor)<<graphOld<<
2917 Form("gr0_%d.=",isensor)<<graphNew0<<
2918 Form("gr1_%d.=",isensor)<<graphNew1<<
2919 Form("gr2_%d.=",isensor)<<graphNew2;
1fabc823 2920 if (isOK) sensor->SetGraph(graphNew2);
2921 }
2922 (*pcstream)<<"goofieA"<<
2923 "vmed.="<<&vmedianArray<<
2924 "vrms.="<<&vrmsArray<<
2925 "\n";
2926 junk.Delete(); // delete temoprary graphs
0d1b4cf8 2927
2928}
2929
2930
a980538f 2931
2932
2933
8166d5d7 2934TMatrixD* AliTPCcalibDButil::MakeStatRelKalman(TObjArray * const array, Float_t minFraction, Int_t minStat, Float_t maxvd){
7d855b04 2935 /// Make a statistic matrix
2936 /// Input parameters:
2937 /// array - TObjArray of AliRelKalmanAlign
2938 /// minFraction - minimal ration of accepted tracks
2939 /// minStat - minimal statistic (number of accepted tracks)
2940 /// maxvd - maximal deviation for the 1
2941 /// Output matrix:
2942 /// columns - Mean, Median, RMS
2943 /// row - parameter type (rotation[3], translation[3], drift[3])
2944
a980538f 2945 if (!array) return 0;
2946 if (array->GetEntries()<=0) return 0;
cc65e4f5 2947 // Int_t entries = array->GetEntries();
a980538f 2948 Int_t entriesFast = array->GetEntriesFast();
2949 TVectorD state(9);
2950 TVectorD *valArray[9];
2951 for (Int_t i=0; i<9; i++){
2952 valArray[i] = new TVectorD(entriesFast);
2953 }
2954 Int_t naccept=0;
2955 for (Int_t ikalman=0; ikalman<entriesFast; ikalman++){
2956 AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(ikalman);
2957 if (!kalman) continue;
2958 if (TMath::Abs(kalman->GetTPCvdCorr()-1)>maxvd) continue;
2959 if (kalman->GetNUpdates()<minStat) continue;
938ce618 2960 if (Float_t(kalman->GetNUpdates())/Float_t(kalman->GetNTracks())<minFraction) continue;
a980538f 2961 kalman->GetState(state);
2962 for (Int_t ipar=0; ipar<9; ipar++)
2963 (*valArray[ipar])[naccept]=state[ipar];
2964 naccept++;
2965 }
5647625c 2966 //if (naccept<2) return 0;
2967 if (naccept<1) return 0;
a980538f 2968 TMatrixD *pstat=new TMatrixD(9,3);
2969 TMatrixD &stat=*pstat;
2970 for (Int_t ipar=0; ipar<9; ipar++){
2971 stat(ipar,0)=TMath::Mean(naccept, valArray[ipar]->GetMatrixArray());
2972 stat(ipar,1)=TMath::Median(naccept, valArray[ipar]->GetMatrixArray());
2973 stat(ipar,2)=TMath::RMS(naccept, valArray[ipar]->GetMatrixArray());
2974 }
177f532f 2975 for (Int_t i=0; i<9; i++){
2976 delete valArray[i];
2977 }
a980538f 2978 return pstat;
2979}
2980
2981
8166d5d7 2982TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const array, const TMatrixD & stat, Bool_t direction, Float_t sigmaCut){
7d855b04 2983 /// Smooth the array of AliRelKalmanAlign - detector alignment and drift calibration)
2984 /// Input:
2985 /// array - input array
2986 /// stat - mean parameters statistic
2987 /// direction -
2988 /// sigmaCut - maximal allowed deviation from mean in terms of RMS
2989
a980538f 2990 if (!array) return 0;
2991 if (array->GetEntries()<=0) return 0;
32100b1d 2992 if (!(&stat)) return 0;
cc65e4f5 2993 // error increase in 1 hour
2994 const Double_t kerrsTime[9]={
2995 0.00001, 0.00001, 0.00001,
2996 0.001, 0.001, 0.001,
dfb83639 2997 0.002, 0.01, 0.001};
cc65e4f5 2998 //
2999 //
a980538f 3000 Int_t entries = array->GetEntriesFast();
3001 TObjArray *sArray= new TObjArray(entries);
3002 AliRelAlignerKalman * sKalman =0;
3003 TVectorD state(9);
3004 for (Int_t i=0; i<entries; i++){
3005 Int_t index=(direction)? entries-i-1:i;
3006 AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) array->UncheckedAt(index);
3007 if (!kalman) continue;
3008 Bool_t isOK=kTRUE;
3009 kalman->GetState(state);
3010 for (Int_t ipar=0; ipar<9; ipar++){
3011 if (TMath::Abs(state[ipar]-stat(ipar,1))>sigmaCut*stat(ipar,2)) isOK=kFALSE;
3012 }
3013 if (!sKalman &&isOK) {
3014 sKalman=new AliRelAlignerKalman(*kalman);
3015 sKalman->SetRejectOutliers(kFALSE);
3016 sKalman->SetRunNumber(kalman->GetRunNumber());
3017 sKalman->SetTimeStamp(kalman->GetTimeStamp());
3018 }
3019 if (!sKalman) continue;
3020 Double_t deltaT=TMath::Abs(Int_t(kalman->GetTimeStamp())-Int_t(sKalman->GetTimeStamp()))/3600.;
cc65e4f5 3021 for (Int_t ipar=0; ipar<9; ipar++){
3022// (*(sKalman->GetStateCov()))(6,6)+=deltaT*errvd*errvd;
3023// (*(sKalman->GetStateCov()))(7,7)+=deltaT*errt0*errt0;
3024// (*(sKalman->GetStateCov()))(8,8)+=deltaT*errvy*errvy;
3025 (*(sKalman->GetStateCov()))(ipar,ipar)+=deltaT*kerrsTime[ipar]*kerrsTime[ipar];
3026 }
a980538f 3027 sKalman->SetRunNumber(kalman->GetRunNumber());
3028 if (!isOK) sKalman->SetRunNumber(0);
3029 sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
3030 if (!isOK) continue;
3031 sKalman->SetRejectOutliers(kFALSE);
3032 sKalman->SetRunNumber(kalman->GetRunNumber());
3033 sKalman->SetTimeStamp(kalman->GetTimeStamp());
3034 sKalman->Merge(kalman);
3035 sArray->AddAt(new AliRelAlignerKalman(*sKalman),index);
3036 //sKalman->Print();
3037 }
3038 return sArray;
3039}
3040
8166d5d7 3041TObjArray *AliTPCcalibDButil::SmoothRelKalman(TObjArray * const arrayP, TObjArray * const arrayM){
7d855b04 3042 /// Merge 2 RelKalman arrays
3043 /// Input:
3044 /// arrayP - rel kalman in direction plus
3045 /// arrayM - rel kalman in direction minus
3046
cc65e4f5 3047 if (!arrayP) return 0;
3048 if (arrayP->GetEntries()<=0) return 0;
3049 if (!arrayM) return 0;
3050 if (arrayM->GetEntries()<=0) return 0;
3a4b0aed 3051
cc65e4f5 3052 Int_t entries = arrayP->GetEntriesFast();
3053 TObjArray *array = new TObjArray(arrayP->GetEntriesFast());
3a4b0aed 3054
cc65e4f5 3055 for (Int_t i=0; i<entries; i++){
3056 AliRelAlignerKalman * kalmanP = (AliRelAlignerKalman *) arrayP->UncheckedAt(i);
3057 AliRelAlignerKalman * kalmanM = (AliRelAlignerKalman *) arrayM->UncheckedAt(i);
3058 if (!kalmanP) continue;
3059 if (!kalmanM) continue;
3a4b0aed 3060
3061 AliRelAlignerKalman *kalman = NULL;
3062 if(kalmanP->GetRunNumber() != 0 && kalmanM->GetRunNumber() != 0) {
3063 kalman = new AliRelAlignerKalman(*kalmanP);
3064 kalman->Merge(kalmanM);
3065 }
3066 else if (kalmanP->GetRunNumber() == 0) {
3067 kalman = new AliRelAlignerKalman(*kalmanM);
3068 }
3069 else if (kalmanM->GetRunNumber() == 0) {
3070 kalman = new AliRelAlignerKalman(*kalmanP);
3071 }
3072 else
3073 continue;
3074
cc65e4f5 3075 array->AddAt(kalman,i);
3076 }
3a4b0aed 3077
cc65e4f5 3078 return array;
3079}
c4e4498c 3080
3081//_____________________________________________________________________________________
3082TTree* AliTPCcalibDButil::ConnectGainTrees(TString baseDir)
3083{
7d855b04 3084 /// baseDir: Base directory with the raw Kr calibration trees
3085 /// and the trees from the calibQA
3086 /// it assumes to following structure below:
3087 /// KryptonCalib/<year>/calibKr/calibKr.<year>.<id>.root
3088 /// calibQAdEdx/<year>/calibQA.<year>.<perid>.tree.root
3089 /// map/treeMapping.root
3090
c4e4498c 3091
3092 // === add main tree, which will be a mapping file ================
3093 TFile *fin = TFile::Open(Form("%s/map/treeMapping.root",baseDir.Data()));
3094 gROOT->cd();
3095 TTree *tMain = (TTree*)fin->Get("calPads");
a08e21e8 3096 tMain->SetAlias("Pad0","MapPadLength.fElements==7.5"); // pad types
3097 tMain->SetAlias("Pad1","MapPadLength.fElements==10.0");
3098 tMain->SetAlias("Pad2","MapPadLength.fElements==15.0");
3099 //
3100 tMain->SetAlias("dRowNorm0","(row.fElements/32-1)"); // normalized distance to the center of the chamber in lx (-1,1)
3101 tMain->SetAlias("dRowNorm1","(row.fElements/32-1)"); //
3102 tMain->SetAlias("dRowNorm2","((row.fElements-63)/16-1)"); //
3103 tMain->SetAlias("dRowNorm","(row.fElements<63)*(row.fElements/32-1)+(row.fElements>63)*((row.fElements-63)/16-1)");
3104 tMain->SetAlias("dPhiNorm","(ly.fElements/lx.fElements)/(pi/18)"); // normalized distance to the center of the chamber in phi (-1,1)
3105 //
3106 tMain->SetAlias("fsector","(sector%36)+(0.5+9*atan2(ly.fElements,lx.fElements)/pi)"); // float sector number
3107 tMain->SetAlias("posEdge","((pi/18.)-abs(atan(ly.fElements/lx.fElements)))*lx.fElements"); //distance to the edge
c4e4498c 3108
3109 // === add the krypton calibration trees ==========================
3110 TString inputTreesKrCalib = gSystem->GetFromPipe(Form("ls %s/KryptonCalib/20*/calibKr/*.tree.root",baseDir.Data()));
3111 TObjArray *arrInputTreesKrCalib = inputTreesKrCalib.Tokenize("\n");
3112
3113 for (Int_t itree=0; itree<arrInputTreesKrCalib->GetEntriesFast(); ++itree) {
3114 TFile *fin2 = TFile::Open(arrInputTreesKrCalib->At(itree)->GetName());
3115 TTree *tin = (TTree*)fin2->Get("calPads");
3116 gROOT->cd();
3117 TString friendName=gSystem->BaseName(arrInputTreesKrCalib->At(itree)->GetName());
3118 friendName.ReplaceAll("calibKr.","");
3119 friendName.ReplaceAll(".tree.root","");
a08e21e8 3120 friendName="Kr."+friendName;
c4e4498c 3121 tMain->AddFriend(tin,friendName.Data());
3122
3123 // set aliases
3124
3125 // TODO: finish implementation of alias via lists
3126// const Int_t nbranchAlias = 2;
3127// const char* branchNames[nbranchAlias]={"spectrMean","fitMean"};
3128// const Int_t nbranchStat = 2;
3129// const char* statNames[nbranchStat] = {"Median","LTM"};
3130//
3131// for (Int_t iname=0; iname<nbranchAlias; ++iname) {
3132// TString branchName = TString::Format("%s.%s", friendName.Data(), bNames[i]);
3133//
3134// for (Int_t istat=0; istat<nbranchStat; ++istat) {
3135//
3136// }
3137// }
3138
3139 tMain->SetAlias((friendName+".spectrMean_LTMRatio").Data(),
05ff31fd 3140 TString::Format("(%s.spectrMean.fElements/(%s.spectrMean_LTM+0))",
c4e4498c 3141 friendName.Data(),friendName.Data()).Data());
3142
3143 tMain->SetAlias((friendName+".spectrMean_MedianRatio").Data(),
05ff31fd 3144 TString::Format("(%s.spectrMean.fElements/(%s.spectrMean_Median+0))",
c4e4498c 3145 friendName.Data(),friendName.Data()).Data());
a08e21e8 3146 tMain->SetAlias((friendName+".spectrMean_MeanRatio").Data(),
05ff31fd 3147 TString::Format("(%s.spectrMean.fElements/(%s.spectrMean_Mean+0))",
a08e21e8 3148 friendName.Data(),friendName.Data()).Data());
e2179c10 3149 tMain->SetAlias((friendName+".spectrMean_MeanRatio").Data(),
3150 TString::Format("(%s.spectrMean.fElements/%s.spectrMean_Mean)",
3151 friendName.Data(),friendName.Data()).Data());
c4e4498c 3152
3153 tMain->SetAlias((friendName+".fitMean_LTMRatio").Data(),
05ff31fd 3154 TString::Format("(%s.fitMean.fElements/(%s.fitMean_LTM+0))",
3155 friendName.Data(),friendName.Data()).Data());
3156 tMain->SetAlias((friendName+".fitRMS_LTMRatio").Data(),
3157 TString::Format("(%s.fitRMS.fElements/(%s.fitRMS_LTM+0))",
c4e4498c 3158 friendName.Data(),friendName.Data()).Data());
3159
3160 tMain->SetAlias((friendName+".fitMean_MedianRatio").Data(),
05ff31fd 3161 TString::Format("(%s.fitMean.fElements/(%s.fitMean_Median+0))",
3162 friendName.Data(),friendName.Data()).Data());
3163 tMain->SetAlias((friendName+".fitRMS_MedianRatio").Data(),
3164 TString::Format("(%s.fitRMS.fElements/(%s.fitRMS_Median+0))",
c4e4498c 3165 friendName.Data(),friendName.Data()).Data());
a08e21e8 3166 tMain->SetAlias((friendName+".fitMean_MeanRatio").Data(),
05ff31fd 3167 TString::Format("(%s.fitMean.fElements/(%s.fitMean_Mean+0))",
3168 friendName.Data(),friendName.Data()).Data());
3169 tMain->SetAlias((friendName+".fitRMS_MeanRatio").Data(),
3170 TString::Format("(%s.fitRMS.fElements/(%s.fitRMS_Mean+0))",
a08e21e8 3171 friendName.Data(),friendName.Data()).Data());
e2179c10 3172 tMain->SetAlias((friendName+".fitMean_MeanRatio").Data(),
3173 TString::Format("(%s.fitMean.fElements/%s.fitMean_Mean)",
3174 friendName.Data(),friendName.Data()).Data());
c4e4498c 3175
3176 }
3177
3178 // === add the calibQA trees ======================================
3179 TString inputTreesQACalib = gSystem->GetFromPipe(Form("ls %s/calibQAdEdx/20*/*.tree.root",baseDir.Data()));
3180 TObjArray *arrInputTreesQACalib = inputTreesQACalib.Tokenize("\n");
3181
3182 for (Int_t itree=0; itree<arrInputTreesQACalib->GetEntriesFast(); ++itree) {
3183 TFile *fin2 = TFile::Open(arrInputTreesQACalib->At(itree)->GetName());
3184 TTree *tin = (TTree*)fin2->Get("calPads");
3185 gROOT->cd();
3186 TString friendName=gSystem->BaseName(arrInputTreesQACalib->At(itree)->GetName());
3187 friendName.ReplaceAll("calibQA.","");
3188 friendName.ReplaceAll(".tree.root","");
a08e21e8 3189 friendName="QA."+friendName;
c4e4498c 3190 tMain->AddFriend(tin,friendName.Data());
3191
3192 // set aliases
3193 tMain->SetAlias((friendName+".MaxCharge_LTMRatio").Data(),
3194 TString::Format("(%s.MaxCharge.fElements/%s.MaxCharge_LTM)",
3195 friendName.Data(),friendName.Data()).Data());
3196
3197 tMain->SetAlias((friendName+".MaxCharge_MedianRatio").Data(),
3198 TString::Format("(%s.MaxCharge.fElements/%s.MaxCharge_Median)",
3199 friendName.Data(),friendName.Data()).Data());
a08e21e8 3200 tMain->SetAlias((friendName+".MaxCharge_MeanRatio").Data(),
3201 TString::Format("(%s.MaxCharge.fElements/%s.MaxCharge_Mean)",
3202 friendName.Data(),friendName.Data()).Data());
c4e4498c 3203
3204 tMain->SetAlias((friendName+".MeanCharge_LTMRatio").Data(),
3205 TString::Format("(%s.MeanCharge.fElements/%s.MeanCharge_LTM)",
3206 friendName.Data(),friendName.Data()).Data());
3207
3208 tMain->SetAlias((friendName+".MeanCharge_MedianRatio").Data(),
3209 TString::Format("(%s.MeanCharge.fElements/%s.MeanCharge_Median)",
3210 friendName.Data(),friendName.Data()).Data());
a08e21e8 3211 tMain->SetAlias((friendName+".MeanCharge_MeanRatio").Data(),
3212 TString::Format("(%s.MeanCharge.fElements/%s.MeanCharge_Mean)",
3213 friendName.Data(),friendName.Data()).Data());
c4e4498c 3214
3215 }
3216
3217 return tMain;
3218}
3219
06a262f6 3220
3221//_____________________________________________________________________________________
3222TTree* AliTPCcalibDButil::ConnectPulserTrees(TString baseDir, TTree *tMain)
3223{
7d855b04 3224 /// baseDir: Base directory with Pulser information
3225 /// TTrees are added to the base tree as a friend tree
3226 ///
3227 /// === add the calibPulser trees ======================================
3228
06a262f6 3229 TString inputTreesPulserCalib = gSystem->GetFromPipe(Form("ls %s/calibPulser/20*/*.tree.root",baseDir.Data()));
3230 TObjArray *arrInputTreesPulserCalib = inputTreesPulserCalib.Tokenize("\n");
3231 for (Int_t itree=0; itree<arrInputTreesPulserCalib->GetEntriesFast(); ++itree) {
3232 TFile *fin2 = TFile::Open(arrInputTreesPulserCalib->At(itree)->GetName());
3233 TTree *tin = (TTree*)fin2->Get("calPads");
3234 gROOT->cd();
3235 TString friendName=gSystem->BaseName(arrInputTreesPulserCalib->At(itree)->GetName());
3236 friendName.ReplaceAll("calibPulser.","");
3237 friendName.ReplaceAll(".tree.root","");
3238 friendName="Pulser."+friendName;
3239 tMain->AddFriend(tin,friendName.Data());
3240 // set aliases
3241
3242 tMain->SetAlias((friendName+".CEQmean_LTMRatio").Data(),
3243 TString::Format("(%s.CEQmean.fElements/%s.CEQmean_LTM)",
3244 friendName.Data(),friendName.Data()).Data());
3245 tMain->SetAlias((friendName+".CEQmean_MedianRatio").Data(),
3246 TString::Format("(%s.CEQmean.fElements/%s.CEQmean_Median)",
3247 friendName.Data(),friendName.Data()).Data());
3248 tMain->SetAlias((friendName+".CEQmean_MeanRatio").Data(),
3249 TString::Format("(%s.CEQmean.fElements/%s.CEQmean_Mean)",
3250 friendName.Data(),friendName.Data()).Data());
3251 //
3252 tMain->SetAlias((friendName+".CETmean_LTMDelta").Data(),
3253 TString::Format("(%s.CETmean.fElements-%s.CETmean_LTM)",
3254 friendName.Data(),friendName.Data()).Data());
3255 tMain->SetAlias((friendName+".CETmean_MedianDelta").Data(),
c4f17a0d 3256 TString::Format("(%s.CETmean.fElements-%s.CETmean_Median)",
06a262f6 3257 friendName.Data(),friendName.Data()).Data());
3258 tMain->SetAlias((friendName+".CETmean_MeanDelta").Data(),
3259 TString::Format("(%s.CETmean.fElements-%s.CETmean_Mean)",
3260 friendName.Data(),friendName.Data()).Data());
3261 }
c4f17a0d 3262 return tMain;
06a262f6 3263}
3264
c4f17a0d 3265
525f22d2 3266TTree* AliTPCcalibDButil::ConnectDistortionTrees(TString baseDir, TString selection, TTree *tMain){
7d855b04 3267 /// baseDir: Base directory with Distortion information
3268 /// TTrees are added to the base tree as a friend tree
3269 /// If base tree not provide - first tree from list is used as base
3270 ///
3271 /// === add the calibDistortion trees ======================================
3272 /// TString inputTreesDistortionCalib = gSystem->GetFromPipe(Form("ls %s/calibDistortion/20*/*.tree.root",baseDir.Data()));
3273 /// TString baseDir="$NOTES/reconstruction/distortionFit/"; TTree *tMain=0;
3274 /// AliTPCcalibDButil::ConnectDistortionTrees("$NOTES/reconstruction/distortionFit/", "calibTimeResHisto.root", 0);
c4f17a0d 3275
525f22d2 3276 TString inputTreesDistortionCalib = "";
3277 if (selection.Contains(".list")){
3278 inputTreesDistortionCalib=gSystem->GetFromPipe(Form("cat %s",selection.Data()));
3279 }else{
3280 inputTreesDistortionCalib=gSystem->GetFromPipe(Form("find %s -iname \"%s\"",baseDir.Data(),selection.Data()));
3281 }
c4f17a0d 3282 TObjArray *arrInputTreesDistortionCalib = inputTreesDistortionCalib.Tokenize("\n");
3283 //
b2aacbe9 3284 TString treePrefix="";
c4f17a0d 3285 for (Int_t itree=0; itree<arrInputTreesDistortionCalib->GetEntriesFast(); ++itree) {
b2aacbe9 3286 TString fstring = arrInputTreesDistortionCalib->At(itree)->GetName();
3287 if (fstring.Index("Prefix:")==0){ //get tree descriptor
3288 treePrefix=TString(&(fstring[7]));
3289 continue;
3290 }
3291 if (fstring.Index("#")==0){ // ignore comment field
3292 continue;
3293 }
c4f17a0d 3294 TFile *finput= TFile::Open(arrInputTreesDistortionCalib->At(itree)->GetName());
3295 TString strFile=arrInputTreesDistortionCalib->At(itree)->GetName();
3296 TObjArray *path=strFile.Tokenize("/");
3297 Int_t plength=path->GetEntries();
3298 if (!finput) continue;
3299 TList* list = finput->GetListOfKeys();
3300 Int_t nkeys=list->GetEntries();
3301 for (Int_t ikey=0; ikey<nkeys; ikey++){
3302 TKey * key = (TKey*)list->At(ikey);
3303 if (strstr(key->GetClassName(),"TTree")==0) continue;
3304 TTree * tree = dynamic_cast<TTree*>(finput->Get(list->At(ikey)->GetName()));
3305 if (!tree) continue;
b2aacbe9 3306 TString friendName="";
3307 if (treePrefix.Length()==0) {
3308 friendName=TString::Format("%s.%s.%s",path->At(plength-3)->GetName(),path->At(plength-2)->GetName(), tree->GetName());
3309 }else{
3310 friendName=TString::Format("%s.%s",treePrefix.Data(), tree->GetName());
3311 }
c4f17a0d 3312 ::Info("AliTPCcalibDButil::ConnectDistortionTrees","%s",friendName.Data());
37e35994 3313 if (tMain==0) {
3314 tMain=tree;
3315 tree = dynamic_cast<TTree*>(finput->Get(list->At(ikey)->GetName()));
3316 }
c4f17a0d 3317 tMain->AddFriend(tree,friendName.Data());
3318 }
3319 }
3320 // tMain->SetAlias("");
3321 return tMain;
3322}
3323
3324
3325//_____________________________________________________________________________________
085597e9 3326TTree* AliTPCcalibDButil::ConnectCalPadTrees(TString baseDir, TString pattern, TTree *tMain, Bool_t checkAliases)
c4f17a0d 3327{
7d855b04 3328 /// baseDir: Base directory with per Pad information
3329 /// TTrees are added to the base tree as a friend tree
3330 /// Example usage
3331 /// TString baseDir="/hera/alice/fsozzi/summarymaps/calib2/"; // prefix directory with calibration with slash at the end
3332 /// TString pattern="QA/*/*root";
3333 /// TTree * tree = AliTPCcalibDButil::ConnectCalPadTrees(baseDir,pattern,0); //create tree and attach calibration as friends
085597e9 3334
c4f17a0d 3335 //
3336 // === add the calibPulser trees ======================================
3337 TString inputTreesCalPad = gSystem->GetFromPipe(Form("ls %s/%s",baseDir.Data(), pattern.Data()));
3338 TObjArray *arrInputTreesCalPad = inputTreesCalPad.Tokenize("\n");
3339 //
3340 for (Int_t itree=0; itree<arrInputTreesCalPad->GetEntriesFast(); ++itree) {
3341 TFile *fin2 = TFile::Open(arrInputTreesCalPad->At(itree)->GetName());
3342 TTree *tin = (TTree*)fin2->Get("calPads");
3343 gROOT->cd();
3344 TString friendName=arrInputTreesCalPad->At(itree)->GetName();
085597e9 3345 friendName.ReplaceAll("//","/");
c4f17a0d 3346 friendName.ReplaceAll(baseDir.Data(),"");
085597e9 3347 friendName.ReplaceAll("^/","");
c4f17a0d 3348 friendName.ReplaceAll("/",".");
ad0cd2a6 3349 friendName.ReplaceAll(".tree.",".");
c4f17a0d 3350 friendName.ReplaceAll(".root","");
c4f17a0d 3351 printf("%s\n", friendName.Data());
3352 ::Info("AliTPCcalibDButil::ConnectCalPadTrees","%s",friendName.Data());
3353 if (tMain==0) tMain=tin;
3354 tMain->AddFriend(tin,friendName.Data());
085597e9 3355 TObjArray * branches=tin->GetListOfBranches();
3356 Int_t nBranches=branches->GetEntries();
3357 for (Int_t ibranch=0; ibranch<nBranches; ibranch++){
3358 TString bname=branches->At(ibranch)->GetName();
3359 if (bname.Contains(".")>0){
3360 bname.ReplaceAll(".","");
3361 // replace elements
3362 tin->SetAlias((bname).Data(), (bname+".fElements").Data());
3363 tMain->SetAlias((friendName+"."+bname).Data(), (friendName+"."+bname+".fElements").Data());
3364 //
3365 // make normalized values per chamber
3366 //
3367 if (branches->FindObject(bname+"_LTM")!=0){
3368 tMain->SetAlias((friendName+"."+bname+"_MeanRatio").Data(), (friendName+"."+bname+".fElements/"+friendName+"."+bname+"_Mean").Data());
3369 tMain->SetAlias((friendName+"."+bname+"_MedianRatio").Data(), (friendName+"."+bname+".fElements/"+friendName+"."+bname+"_Median").Data());
3370 tMain->SetAlias((friendName+"."+bname+"_LTMRatio").Data(), (friendName+"."+bname+".fElements/"+friendName+"."+bname+"_LTM").Data());
3371 tMain->SetAlias((friendName+"."+bname+"_MeanDelta").Data(), (friendName+"."+bname+".fElements-"+friendName+"."+bname+"_Mean").Data());
3372 tMain->SetAlias((friendName+"."+bname+"_MedianDelta").Data(), (friendName+"."+bname+".fElements-"+friendName+"."+bname+"_Median").Data());
3373 tMain->SetAlias((friendName+"."+bname+"_LTMDelta").Data(), (friendName+"."+bname+".fElements-"+friendName+"."+bname+"_LTM").Data());
3374 }
8bc3ddf0 3375 // if (branches->FindObject(bname+"_Med3.")!=0){
3376 tMain->SetAlias((friendName+"."+bname+"_Med3Ratio").Data(), (friendName+"."+bname+".fElements/"+friendName+"."+bname+"Med3.fElements").Data());
3377 tMain->SetAlias((friendName+"."+bname+"_Med5Ratio").Data(), (friendName+"."+bname+".fElements/"+friendName+"."+bname+"Med5.fElements").Data());
3378 tMain->SetAlias((friendName+"."+bname+"_Par6GRatio").Data(), (friendName+"."+bname+".fElements/"+friendName+"."+bname+"Par6G.fElements").Data());
3379 tMain->SetAlias((friendName+"."+bname+"_Med3Delta").Data(), (friendName+"."+bname+".fElements-"+friendName+"."+bname+"Med3.fElements").Data());
3380 tMain->SetAlias((friendName+"."+bname+"_Med5Delta").Data(), (friendName+"."+bname+".fElements-"+friendName+"."+bname+"Med5.fElements").Data());
3381 tMain->SetAlias((friendName+"."+bname+"_Par6GDelta").Data(), (friendName+"."+bname+".fElements-"+friendName+"."+bname+"Par6G.fElements").Data());
3382 // }
085597e9 3383 }
3384 }
3385 }
3386 //
3387 //
3388 //
3389 if (checkAliases){
3390 // to be implemented
c4f17a0d 3391 }
3392 return tMain;
3393}
3394
3395
3396