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