da268e11 |
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 | |
18 | /* |
19 | .x ~/rootlogon.C |
20 | gSystem->Load("libANALYSIS"); |
21 | gSystem->Load("libTPCcalib"); |
22 | .L $ALICE_ROOT/TPC/AliTPCPreprocessorOffline.cxx+ |
23 | |
24 | AliTPCPreprocessorOffline proces; |
25 | proces.CalibTimeGain( |
26 | |
27 | */ |
28 | |
29 | #if !defined(__CINT__) || defined(__MAKECINT__) |
30 | #include "TMap.h" |
31 | #include "TGraphErrors.h" |
32 | #include "AliExternalTrackParam.h" |
33 | #include "TFile.h" |
34 | #include "TGraph.h" |
35 | #include "TMultiGraph.h" |
36 | #include "TCanvas.h" |
37 | #include "THnSparse.h" |
38 | #include "TLegend.h" |
39 | #include "TPad.h" |
40 | #include "TH2D.h" |
41 | #include "AliTPCROC.h" |
42 | #include "AliTPCCalROC.h" |
43 | |
44 | #include "AliESDfriend.h" |
45 | |
46 | |
47 | #include "AliTPCcalibTime.h" |
48 | #include "AliSplineFit.h" |
49 | #include "AliCDBMetaData.h" |
50 | #include "AliCDBId.h" |
51 | #include "AliCDBManager.h" |
52 | #include "AliCDBStorage.h" |
53 | #include "AliTPCcalibBase.h" |
54 | #include "AliTPCcalibDB.h" |
55 | #include "AliTPCcalibDButil.h" |
56 | #include "AliRelAlignerKalman.h" |
57 | #include "AliTPCParamSR.h" |
58 | #include "AliTPCcalibTimeGain.h" |
59 | #include "AliSplineFit.h" |
60 | #include "AliTPCPreprocessorOffline.h" |
61 | #endif |
62 | |
63 | |
64 | ClassImp(AliTPCPreprocessorOffline) |
65 | |
66 | AliTPCPreprocessorOffline::AliTPCPreprocessorOffline(): |
67 | TNamed("PreprocessorOffline","PreprocessorOffline"), |
68 | kMinEntries(500), // minimal number of entries for fit |
69 | startRun(0), // start Run - used to make fast selection in THnSparse |
70 | endRun(0), // end Run - used to make fast selection in THnSparse |
71 | startTime(0), // startTime - used to make fast selection in THnSparse |
72 | endTime(0), // endTime - used to make fast selection in THnSparse |
73 | ocdbStorage(""), // path to the OCDB storage |
74 | fVdriftArray(new TObjArray), |
75 | fTimeDrift(0), |
76 | fGraphMIP(0), // graph time dependence of MIP |
77 | fGraphCosmic(0), // graph time dependence at Plateu |
78 | fFitMIP(0), // fit of dependence - MIP |
79 | fFitCosmic(0), // fit of dependence - Plateu |
80 | fGainArray(new TObjArray), // array to be stored in the OCDB |
81 | fGainMIP(0), // calibration component for MIP |
82 | fGainCosmic(0) // calibration component for cosmic |
83 | { |
84 | // |
85 | } |
86 | |
87 | AliTPCPreprocessorOffline::~AliTPCPreprocessorOffline() { |
88 | // |
89 | // Destructor |
90 | // |
91 | } |
92 | |
93 | |
94 | |
95 | |
96 | void AliTPCPreprocessorOffline::GetRunRange(AliTPCcalibTime* fTimeDrift){ |
97 | // |
98 | // find the fist and last run |
99 | // |
100 | TObjArray *hisArray =fTimeDrift->GetHistoDrift(); |
101 | {for (Int_t i=0; i<hisArray->GetEntriesFast(); i++){ |
102 | THnSparse* addHist=(THnSparse*)hisArray->UncheckedAt(i); |
103 | if (addHist->GetEntries()<kMinEntries) continue; |
104 | if (!addHist) continue; |
105 | TH1D* histo =addHist->Projection(3); |
106 | TH1D* histoTime=addHist->Projection(0); |
107 | printf("%s\t%f\t%d\t%d\n",histo->GetName(), histo->GetEntries(),histo->FindFirstBinAbove(0),histo->FindLastBinAbove(0)); |
108 | |
109 | if (startRun<=0){ |
110 | startRun=histo->FindFirstBinAbove(0); |
111 | endRun =histo->FindLastBinAbove(0); |
112 | }else{ |
113 | startRun=TMath::Min(histo->FindFirstBinAbove(0),startRun); |
114 | endRun =TMath::Max(histo->FindLastBinAbove(0),endRun); |
115 | } |
116 | if (startTime==0){ |
117 | startTime=histoTime->FindFirstBinAbove(0); |
118 | endTime =histoTime->FindLastBinAbove(0); |
119 | }else{ |
120 | startTime=TMath::Min(histoTime->FindFirstBinAbove(0),startTime); |
121 | endTime =TMath::Max(histoTime->FindLastBinAbove(0),endTime); |
122 | } |
123 | delete histo; |
124 | delete histoTime; |
125 | }} |
126 | if (startRun<0) startRun=0; |
127 | if (endRun<0) endRun=100000000; |
128 | printf("Run range :\t%d-%d\n", startRun, endRun); |
129 | printf("Time range :\t%d-%d\n", startTime, endTime); |
130 | |
131 | } |
132 | |
133 | |
134 | |
135 | void AliTPCPreprocessorOffline::CalibTimeVdrift(Char_t* file, Int_t ustartRun, Int_t uendRun, TString pocdbStorage){ |
136 | // |
137 | // |
138 | // |
139 | const Int_t kMinEntries=500; // minimal number of entries |
140 | if (pocdbStorage.Length()>0) ocdbStorage=pocdbStorage; |
141 | else |
142 | ocdbStorage="local://"+gSystem->GetFromPipe("pwd")+"/OCDB"; |
143 | // |
144 | // 1. Initialization and run range setting |
145 | TFile fcalib(file); |
146 | fTimeDrift=(AliTPCcalibTime*)fcalib.Get("calibTime"); |
147 | startRun=ustartRun; |
148 | endRun=ustartRun; |
149 | TObjArray *hisArray =fTimeDrift->GetHistoDrift(); |
150 | GetRunRange(fTimeDrift); |
151 | for (Int_t i=0; i<hisArray->GetEntriesFast(); i++){ |
152 | THnSparse* addHist=(THnSparse*)hisArray->At(i); |
153 | if (!addHist) continue; |
154 | if (startTime<endTime) addHist->GetAxis(0)->SetRange(startTime-1,endTime+1); |
155 | if (startRun<endRun) addHist->GetAxis(3)->SetRange(startRun-1,endRun+1); |
156 | } |
157 | // |
158 | // |
159 | // 2. extraction of the information |
160 | // |
161 | fVdriftArray = new TObjArray(); |
162 | AddAlignmentGraphs(fVdriftArray,fTimeDrift); |
163 | AddHistoGraphs(fVdriftArray,fTimeDrift,kMinEntries); |
164 | AddLaserGraphs(fVdriftArray,fTimeDrift); |
165 | // |
166 | // 3. Append QA plots |
167 | // |
168 | MakeDefaultPlots(fVdriftArray,fVdriftArray); |
169 | // |
170 | // |
171 | // 4. update of OCDB |
172 | // |
173 | // |
174 | |
175 | UpdateOCDBDrift(ustartRun,uendRun,ocdbStorage); |
176 | } |
177 | |
178 | void AliTPCPreprocessorOffline::UpdateOCDBDrift( Int_t ustartRun, Int_t uendRun, const char* storagePath ){ |
179 | // |
180 | // Update OCDB |
181 | // |
182 | AliCDBMetaData *metaData= new AliCDBMetaData(); |
183 | metaData->SetObjectClassName("TObjArray"); |
184 | metaData->SetResponsible("Marian Ivanov"); |
185 | metaData->SetBeamPeriod(1); |
186 | metaData->SetAliRootVersion("05-25-01"); //root version |
187 | metaData->SetComment("Calibration of the time dependence of the drift velocity"); |
188 | AliCDBId* id1=NULL; |
189 | id1=new AliCDBId("TPC/Calib/TimeDrift", ustartRun, uendRun); |
190 | AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(storagePath); |
191 | gStorage->Put(fVdriftArray, (*id1), metaData); |
192 | } |
193 | |
194 | |
195 | |
196 | void AliTPCPreprocessorOffline::UpdateDriftParam(AliTPCParam *param, TObjArray *arr, Int_t startRun){ |
197 | // |
198 | // update the OCDB entry for the nominal time0 |
199 | // |
200 | // |
201 | // AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters(); |
202 | AliTPCParam *paramNew = (AliTPCParam *)param->Clone(); |
203 | TGraphErrors *grT = (TGraphErrors *)arr->FindObject("ALIGN_ITSM_TPC_T0"); |
204 | Double_t deltaTcm = TMath::Median(grT->GetN(),grT->GetY()); |
205 | Double_t deltaT = deltaTcm/param->GetDriftV(); |
206 | paramNew->SetL1Delay(param->GetL1Delay()-deltaT); |
207 | paramNew->Update(); |
208 | |
209 | AliCDBMetaData *metaData= new AliCDBMetaData(); |
210 | metaData->SetObjectClassName("TObjArray"); |
211 | metaData->SetResponsible("Marian Ivanov"); |
212 | metaData->SetBeamPeriod(1); |
213 | metaData->SetAliRootVersion("05-25-02"); //root version |
214 | metaData->SetComment("Updated calibration of nominal time 0"); |
215 | AliCDBId* id1=NULL; |
216 | id1=new AliCDBId("TPC/Calib/Parameters", startRun, AliCDBRunRange::Infinity()); |
217 | AliCDBStorage* gStorage = AliCDBManager::Instance()->GetStorage(ocdbStorage); |
218 | gStorage->Put(param, (*id1), metaData); |
219 | |
220 | } |
221 | |
222 | |
223 | void AliTPCPreprocessorOffline::PrintArray(TObjArray *array){ |
224 | // |
225 | // |
226 | // |
227 | Int_t entries = array->GetEntries(); |
228 | for (Int_t i=0; i<entries; i++){ |
229 | if (!array->At(i)) continue; |
230 | printf("%d\t %s\n", i, array->At(i)->GetName()); |
231 | } |
232 | } |
233 | |
234 | |
235 | |
236 | TGraphErrors* AliTPCPreprocessorOffline::FilterGraphDrift(TGraphErrors * graph, Float_t errSigmaCut, Float_t medianCutAbs){ |
237 | // 2 filters: |
238 | // 1. filter graph - error cut errSigmaCut |
239 | // 2. filter graph - medianCutAbs around median |
240 | // |
241 | // errSigmaCut - cut on error |
242 | // medianCutAbs - cut on value around median |
243 | Double_t dummy=0; // |
244 | // |
245 | // 1. filter graph - error cut errSigmaCut |
246 | // |
247 | TGraphErrors *graphF; |
248 | graphF = AliTPCcalibDButil::FilterGraphMedianErr(graph,errSigmaCut,dummy); |
249 | delete graph; |
250 | if (!graphF) return 0; |
251 | graph = AliTPCcalibDButil::FilterGraphMedianErr(graphF,errSigmaCut,dummy); |
252 | delete graphF; |
253 | if (!graph) return 0; |
254 | // |
255 | // filter graph - kMedianCutAbs around median |
256 | // |
257 | graphF=FilterGraphMedianAbs(graph, medianCutAbs,dummy); |
258 | delete graph; |
259 | if (!graphF) return 0; |
260 | graph=FilterGraphMedianAbs(graphF, medianCutAbs,dummy); |
261 | delete graphF; |
262 | if (!graph) return 0; |
263 | return graph; |
264 | } |
265 | |
266 | |
267 | |
268 | TGraphErrors* AliTPCPreprocessorOffline::FilterGraphMedianAbs(TGraphErrors * graph, Float_t cut,Double_t &medianY){ |
269 | // |
270 | // filter outlyer measurement |
271 | // Only points around median +- cut filtered |
272 | // |
273 | if (!graph) return 0; |
274 | Int_t kMinPoints=2; |
275 | Int_t npoints0 = graph->GetN(); |
276 | Int_t npoints=0; |
277 | Float_t rmsY=0; |
278 | Double_t *outx=new Double_t[npoints0]; |
279 | Double_t *outy=new Double_t[npoints0]; |
280 | Double_t *errx=new Double_t[npoints0]; |
281 | Double_t *erry=new Double_t[npoints0]; |
282 | // |
283 | // |
284 | if (npoints0<kMinPoints) return 0; |
285 | for (Int_t iter=0; iter<3; iter++){ |
286 | npoints=0; |
287 | for (Int_t ipoint=0; ipoint<npoints0; ipoint++){ |
288 | if (graph->GetY()[ipoint]==0) continue; |
289 | if (iter>0 &&TMath::Abs(graph->GetY()[ipoint]-medianY)>cut) continue; |
290 | outx[npoints] = graph->GetX()[ipoint]; |
291 | outy[npoints] = graph->GetY()[ipoint]; |
292 | errx[npoints] = graph->GetErrorX(ipoint); |
293 | erry[npoints] = graph->GetErrorY(ipoint); |
294 | npoints++; |
295 | } |
296 | if (npoints<=1) break; |
297 | medianY =TMath::Median(npoints,outy); |
298 | rmsY =TMath::RMS(npoints,outy); |
299 | } |
300 | TGraphErrors *graphOut=0; |
301 | if (npoints>1) graphOut= new TGraphErrors(npoints,outx,outy,errx,erry); |
302 | return graphOut; |
303 | } |
304 | |
305 | |
306 | void AliTPCPreprocessorOffline::AddHistoGraphs( TObjArray * vdriftArray, AliTPCcalibTime *timeDrift, Int_t minEntries){ |
307 | // |
308 | // Add graphs corresponding to the alignment |
309 | // |
310 | const Double_t kErrSigmaCut=5; // error sigma cut - for filtering |
311 | const Double_t kMedianCutAbs=0.03; // error sigma cut - for filtering |
312 | // |
313 | TObjArray * array=timeDrift->GetHistoDrift(); |
314 | if (array){ |
315 | THnSparse* hist=NULL; |
316 | // 2.a) cosmics with different triggers |
317 | for (Int_t i=0; i<array->GetEntriesFast();i++){ |
318 | hist=(THnSparseF*)array->UncheckedAt(i); |
319 | if(!hist) continue; |
320 | if (hist->GetEntries()<minEntries) continue; |
321 | //hist->Print(); |
322 | TString name=hist->GetName(); |
323 | Int_t dim[4]={0,1,2,3}; |
324 | THnSparse* newHist=hist->Projection(4,dim); |
325 | newHist->SetName(name); |
326 | TGraphErrors* graph=AliTPCcalibBase::FitSlices(newHist,2,0,400,100,0.05,0.95, kTRUE); |
327 | printf("name=%s graph=%i, N=%i\n", name.Data(), graph==0, graph->GetN()); |
328 | Int_t pos=name.Index("_"); |
329 | name=name(pos,name.Capacity()-pos); |
330 | TString graphName=graph->ClassName(); |
331 | graphName+=name; |
332 | graphName.ToUpper(); |
333 | // |
334 | graph = FilterGraphDrift(graph, kErrSigmaCut, kMedianCutAbs); |
335 | if (!graph) { |
336 | printf("Graph =%s filtered out\n", name.Data()); |
337 | continue; |
338 | } |
339 | // |
340 | graph->SetMarkerStyle(i%8+20); |
341 | graph->SetMarkerColor(i%7); |
342 | graph->GetXaxis()->SetTitle("Time"); |
343 | graph->GetYaxis()->SetTitle("v_{dcor}"); |
344 | graph->SetName(graphName); |
345 | graph->SetTitle(graphName); |
346 | printf("Graph %d\t=\t%s\n", i, graphName.Data()); |
347 | vdriftArray->Add(graph); |
348 | } |
349 | } |
350 | } |
351 | |
352 | |
353 | |
354 | |
355 | void AliTPCPreprocessorOffline::AddAlignmentGraphs( TObjArray * vdriftArray, AliTPCcalibTime *timeDrift){ |
356 | // |
357 | // Add graphs corresponding to alignment to the object array |
358 | // |
359 | TObjArray *arrayITS=0; |
360 | TObjArray *arrayTOF=0; |
361 | TObjArray *arrayTRD=0; |
362 | TMatrixD *mstatITS=0; |
363 | TMatrixD *mstatTOF=0; |
364 | TMatrixD *mstatTRD=0; |
365 | // |
366 | arrayITS=timeDrift->GetAlignITSTPC(); |
367 | arrayTRD=timeDrift->GetAlignTRDTPC(); |
368 | arrayTOF=timeDrift->GetAlignTOFTPC(); |
369 | |
370 | if (arrayITS->GetEntries()>0) mstatITS= AliTPCcalibDButil::MakeStatRelKalman(arrayITS,0.9,50,0.025); |
371 | if (arrayTOF->GetEntries()>0) mstatTOF= AliTPCcalibDButil::MakeStatRelKalman(arrayTOF,0.9,1000,0.025); |
372 | if (arrayTRD->GetEntries()>0) mstatTRD= AliTPCcalibDButil::MakeStatRelKalman(arrayTRD,0.9,50,0.025); |
373 | // |
374 | TObjArray * arrayITSP= AliTPCcalibDButil::SmoothRelKalman(arrayITS,*mstatITS, 0, 5.); |
375 | TObjArray * arrayITSM= AliTPCcalibDButil::SmoothRelKalman(arrayITS,*mstatITS, 1, 5.); |
376 | TObjArray * arrayITSB= AliTPCcalibDButil::SmoothRelKalman(arrayITSP,arrayITSM); |
377 | TObjArray * arrayTOFP= AliTPCcalibDButil::SmoothRelKalman(arrayTOF,*mstatTOF, 0, 5.); |
378 | TObjArray * arrayTOFM= AliTPCcalibDButil::SmoothRelKalman(arrayTOF,*mstatTOF, 1, 5.); |
379 | TObjArray * arrayTOFB= AliTPCcalibDButil::SmoothRelKalman(arrayTOFP,arrayTOFM); |
380 | |
381 | TObjArray * arrayTRDP= 0x0; |
382 | TObjArray * arrayTRDM= 0x0; |
383 | TObjArray * arrayTRDB= 0x0; |
384 | arrayTRDP= AliTPCcalibDButil::SmoothRelKalman(arrayTRD,*mstatTRD, 0, 5.); |
385 | arrayTRDM= AliTPCcalibDButil::SmoothRelKalman(arrayTRD,*mstatTRD, 1, 5.); |
386 | arrayTRDB= AliTPCcalibDButil::SmoothRelKalman(arrayTRDP,arrayTRDM); |
387 | // |
388 | // |
389 | Int_t entries=TMath::Max(arrayITS->GetEntriesFast(),arrayTOF->GetEntriesFast()); |
390 | TObjArray *arrays[12]={arrayITS, arrayITSP, arrayITSM, arrayITSB, |
391 | arrayTRD, arrayTRDP, arrayTRDM, arrayTRDB, |
392 | arrayTOF, arrayTOFP, arrayTOFM, arrayTOFB}; |
393 | TString grnames[12]={"ALIGN_ITS", "ALIGN_ITSP", "ALIGN_ITSM", "ALIGN_ITSB", |
394 | "ALIGN_TRD", "ALIGN_TRDP", "ALIGN_TRDM","ALIGN_TRDB", |
395 | "ALIGN_TOF", "ALIGN_TOFP", "ALIGN_TOFM","ALIGN_TOFB"}; |
396 | TString grpar[9]={"DELTAPSI", "DELTATHETA", "DELTAPHI", |
397 | "DELTAX", "DELTAY", "DELTAZ", |
398 | "DRIFTVD", "T0", "VDGY"}; |
399 | |
400 | |
401 | TVectorD vX(entries); |
402 | TVectorD vY(entries); |
403 | TVectorD vEx(entries); |
404 | TVectorD vEy(entries); |
405 | TObjArray *arr=0; |
406 | for (Int_t iarray=0; iarray<12; iarray++){ |
407 | arr = arrays[iarray]; |
408 | if (arr==0) continue; |
409 | for (Int_t ipar=0; ipar<9; ipar++){ |
410 | Int_t counter=0; |
411 | for (Int_t itime=0; itime<arr->GetEntriesFast(); itime++){ |
412 | AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) arr->UncheckedAt(itime); |
413 | if (!kalman) continue; |
414 | vX[counter]=kalman->GetTimeStamp(); |
415 | vY[counter]=(*(kalman->GetState()))[ipar]; |
416 | if (ipar==6) vY[counter]=1./(*(kalman->GetState()))[ipar]-1; |
417 | vEx[counter]=0; |
418 | vEy[counter]=TMath::Sqrt((*(kalman->GetStateCov()))(ipar,ipar)); |
419 | counter++; |
420 | } |
421 | |
422 | TGraphErrors * graph=new TGraphErrors(counter, vX.GetMatrixArray(), |
423 | vY.GetMatrixArray(), |
424 | vEx.GetMatrixArray(), |
425 | vEy.GetMatrixArray()); |
426 | TString grName=grnames[iarray]; |
427 | grName+="_TPC_"; |
428 | grName+=grpar[ipar]; |
429 | graph->SetName(grName.Data()); |
430 | vdriftArray->AddLast(graph); |
431 | } |
432 | } |
433 | } |
434 | |
435 | |
436 | |
437 | |
438 | void AliTPCPreprocessorOffline::AddLaserGraphs( TObjArray * vdriftArray, AliTPCcalibTime *timeDrift){ |
439 | // |
440 | // add graphs for laser |
441 | // |
442 | const Double_t delayL0L1 = 0.071; //this is hack for 1/2 weeks |
443 | THnSparse *hisN=0; |
444 | TGraphErrors *grLaser[6]={0,0,0,0,0,0}; |
445 | hisN = timeDrift->GetHistVdriftLaserA(0); |
446 | if (timeDrift->GetHistVdriftLaserA(0)){ |
447 | grLaser[0]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserA(0),0,2,5,delayL0L1); |
448 | grLaser[0]->SetName("GRAPH_MEAN_DELAY_LASER_ALL_A"); |
449 | vdriftArray->AddLast(grLaser[0]); |
450 | } |
451 | if (timeDrift->GetHistVdriftLaserA(1)){ |
452 | grLaser[1]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserA(1),0,2,5); |
453 | grLaser[1]->SetName("GRAPH_MEAN_DRIFT_LASER_ALL_A"); |
454 | vdriftArray->AddLast(grLaser[1]); |
455 | } |
456 | if (timeDrift->GetHistVdriftLaserA(2)){ |
457 | grLaser[2]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserA(2),0,2,5); |
458 | grLaser[2]->SetName("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A"); |
459 | vdriftArray->AddLast(grLaser[2]); |
460 | } |
461 | if (timeDrift->GetHistVdriftLaserC(0)){ |
462 | grLaser[3]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserC(0),0,2,5,delayL0L1); |
463 | grLaser[3]->SetName("GRAPH_MEAN_DELAY_LASER_ALL_C"); |
464 | vdriftArray->AddLast(grLaser[3]); |
465 | } |
466 | if (timeDrift->GetHistVdriftLaserC(1)){ |
467 | grLaser[4]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserC(1),0,2,5); |
468 | grLaser[4]->SetName("GRAPH_MEAN_DRIFT_LASER_ALL_C"); |
469 | vdriftArray->AddLast(grLaser[4]); |
470 | } |
471 | if (timeDrift->GetHistVdriftLaserC(2)){ |
472 | grLaser[5]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserC(2),0,2,5); |
473 | grLaser[5]->SetName("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C"); |
474 | vdriftArray->AddLast(grLaser[5]); |
475 | } |
476 | for (Int_t i=0; i<6;i++){ |
477 | if (grLaser[i]) { |
478 | SetDefaultGraphDrift(grLaser[i], 1,(i+20)); |
479 | grLaser[i]->GetYaxis()->SetTitle("Laser Correction"); |
480 | } |
481 | } |
482 | } |
483 | |
484 | |
485 | TGraphErrors * AliTPCPreprocessorOffline::MakeGraphFilter0(THnSparse *hisN, Int_t itime, Int_t ival, Int_t minEntries, Double_t offset){ |
486 | // |
487 | // Make graph with mean values and rms |
488 | // |
489 | hisN->GetAxis(itime)->SetRange(0,100000000); |
490 | hisN->GetAxis(ival)->SetRange(0,100000000); |
491 | TH1 * hisT = hisN->Projection(itime); |
492 | TH1 * hisV = hisN->Projection(ival); |
493 | // |
494 | Int_t firstBinA = hisT->FindFirstBinAbove(2); |
495 | Int_t lastBinA = hisT->FindLastBinAbove(2); |
496 | Int_t firstBinV = hisV->FindFirstBinAbove(0); |
497 | Int_t lastBinV = hisV->FindLastBinAbove(0); |
498 | hisN->GetAxis(itime)->SetRange(firstBinA,lastBinA); |
499 | hisN->GetAxis(ival)->SetRange(firstBinV,lastBinV); |
500 | Int_t entries=0; |
501 | for (Int_t ibin=firstBinA; ibin<lastBinA; ibin++){ |
502 | Double_t cont = hisT->GetBinContent(ibin); |
503 | if (cont<minEntries) continue; |
504 | entries++; |
505 | } |
506 | TVectorD vecTime(entries); |
507 | TVectorD vecMean0(entries); |
508 | TVectorD vecRMS0(entries); |
509 | TVectorD vecMean1(entries); |
510 | TVectorD vecRMS1(entries); |
511 | entries=0; |
512 | {for (Int_t ibin=firstBinA; ibin<lastBinA; ibin++){ |
513 | Double_t cont = hisT->GetBinContent(ibin); |
514 | if (cont<minEntries) continue; |
515 | hisN->GetAxis(itime)->SetRange(ibin-1,ibin+1); |
516 | Double_t time = hisT->GetBinCenter(ibin); |
517 | TH1 * his = hisN->Projection(ival); |
518 | Double_t nentries0= his->GetBinContent(his->FindBin(0)); |
519 | if (cont-nentries0<minEntries) continue; |
520 | // |
521 | his->SetBinContent(his->FindBin(0),0); |
522 | vecTime[entries]=time; |
523 | vecMean0[entries]=his->GetMean()+offset; |
524 | vecMean1[entries]=his->GetMeanError(); |
525 | vecRMS0[entries] =his->GetRMS(); |
526 | vecRMS1[entries] =his->GetRMSError(); |
527 | delete his; |
528 | entries++; |
529 | }} |
530 | delete hisT; |
531 | delete hisV; |
532 | TGraphErrors * graph = new TGraphErrors(entries,vecTime.GetMatrixArray(), vecMean0.GetMatrixArray(), 0, vecMean1.GetMatrixArray()); |
533 | return graph; |
534 | } |
535 | |
536 | |
537 | |
538 | |
539 | |
540 | |
541 | |
542 | |
543 | void AliTPCPreprocessorOffline::SetDefaultGraphDrift(TGraph *graph, Int_t color, Int_t style){ |
544 | // |
545 | // |
546 | // |
547 | graph->GetXaxis()->SetTimeDisplay(kTRUE); |
548 | graph->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}"); |
549 | graph->SetMaximum( 0.025); |
550 | graph->SetMinimum(-0.025); |
551 | graph->GetXaxis()->SetTitle("Time"); |
552 | graph->GetYaxis()->SetTitle("v_{dcorr}"); |
553 | // |
554 | graph->GetYaxis()->SetLabelSize(0.03); |
555 | graph->GetXaxis()->SetLabelSize(0.03); |
556 | // |
557 | graph->GetXaxis()->SetNdivisions(10,5,0); |
558 | graph->GetYaxis()->SetNdivisions(10,5,0); |
559 | // |
560 | graph->GetXaxis()->SetLabelOffset(0.02); |
561 | graph->GetYaxis()->SetLabelOffset(0.005); |
562 | // |
563 | graph->GetXaxis()->SetTitleOffset(1.3); |
564 | graph->GetYaxis()->SetTitleOffset(1.2); |
565 | // |
566 | graph->SetMarkerColor(color); |
567 | graph->SetLineColor(color); |
568 | graph->SetMarkerStyle(style); |
569 | } |
570 | |
571 | void AliTPCPreprocessorOffline::SetPadStyle(TPad *pad, Float_t mx0, Float_t mx1, Float_t my0, Float_t my1){ |
572 | // |
573 | // |
574 | pad->SetTicks(1,1); |
575 | pad->SetMargin(mx0,mx1,my0,my1); |
576 | } |
577 | |
578 | |
579 | void AliTPCPreprocessorOffline::MakeDefaultPlots(TObjArray * arr, TObjArray *picArray){ |
580 | // |
581 | // |
582 | // |
583 | // margins |
584 | Float_t mx0=0.12, mx1=0.1, my0=0.15, my1=0.1; |
585 | // |
586 | TGraphErrors* laserA =(TGraphErrors*)arr->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A"); |
587 | TGraphErrors* laserC =(TGraphErrors*)arr->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C"); |
588 | TGraphErrors* cosmic =(TGraphErrors*)arr->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL"); |
589 | TGraphErrors* cross =(TGraphErrors*)arr->FindObject("TGRAPHERRORS_VDRIFT_CROSS_ALL"); |
590 | TGraphErrors* itstpcP =(TGraphErrors*)arr->FindObject("ALIGN_ITSP_TPC_DRIFTVD"); |
591 | TGraphErrors* itstpcM =(TGraphErrors*)arr->FindObject("ALIGN_ITSM_TPC_DRIFTVD"); |
592 | TGraphErrors* itstpcB =(TGraphErrors*)arr->FindObject("ALIGN_ITSB_TPC_DRIFTVD"); |
593 | // |
594 | if (laserA) SetDefaultGraphDrift(laserA,2,25); |
595 | if (laserC) SetDefaultGraphDrift(laserC,4,26); |
596 | if (cosmic) SetDefaultGraphDrift(cosmic,3,27); |
597 | if (cross) SetDefaultGraphDrift(cross,4,28); |
598 | if (itstpcP) SetDefaultGraphDrift(itstpcP,2,29); |
599 | if (itstpcM) SetDefaultGraphDrift(itstpcM,4,30); |
600 | if (itstpcB) SetDefaultGraphDrift(itstpcB,1,31); |
601 | // |
602 | // |
603 | TPad *pad=0; |
604 | // |
605 | // Laser-Laser |
606 | // |
607 | if (laserA&&laserC){ |
608 | pad = new TCanvas("TPCLaserVDrift","TPCLaserVDrift"); |
609 | laserA->Draw("alp"); |
610 | SetPadStyle(pad,mx0,mx1,my0,my1); |
611 | laserA->Draw("apl"); |
612 | laserC->Draw("p"); |
613 | TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction"); |
614 | legend->AddEntry(laserA,"Laser A side"); |
615 | legend->AddEntry(laserC,"Laser C side"); |
616 | legend->Draw(); |
617 | picArray->AddLast(pad); |
618 | } |
619 | |
620 | if (itstpcP&&itstpcM){ |
621 | pad = new TCanvas("ITSTPC","ITSTPC"); |
622 | itstpcP->Draw("alp"); |
623 | SetPadStyle(pad,mx0,mx1,my0,my1); |
624 | itstpcP->Draw("alp"); |
625 | gPad->Clear(); |
626 | itstpcM->Draw("apl"); |
627 | itstpcP->Draw("p"); |
628 | itstpcB->Draw("p"); |
629 | TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction"); |
630 | legend->AddEntry(itstpcP,"ITS-TPC smooth plus"); |
631 | legend->AddEntry(itstpcM,"ITS-TPC smooth minus"); |
632 | legend->AddEntry(itstpcB,"ITS-TPC smooth "); |
633 | legend->Draw(); |
634 | picArray->AddLast(pad); |
635 | } |
636 | |
637 | if (itstpcB&&laserA){ |
638 | pad = new TCanvas("ITSTPC_LASER","ITSTPC_LASER"); |
639 | SetPadStyle(pad,mx0,mx1,my0,my1); |
640 | laserA->Draw("alp"); |
641 | itstpcP->Draw("p"); |
642 | itstpcM->Draw("p"); |
643 | itstpcB->Draw("p"); |
644 | TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction"); |
645 | legend->AddEntry(laserA,"TPC laser"); |
646 | legend->AddEntry(itstpcP,"ITS-TPC smooth plus"); |
647 | legend->AddEntry(itstpcM,"ITS-TPC smooth minus"); |
648 | legend->AddEntry(itstpcB,"ITS-TPC smooth "); |
649 | legend->Draw(); |
650 | picArray->AddLast(pad); |
651 | } |
652 | |
653 | if (itstpcP&&cross){ |
654 | pad = new TCanvas("ITSTPC_CROSS","ITSTPC_CROSS"); |
655 | SetPadStyle(pad,mx0,mx1,my0,my1); |
656 | itstpcP->Draw("alp"); |
657 | pad->Clear(); |
658 | cross->Draw("ap"); |
659 | itstpcP->Draw("p"); |
660 | // |
661 | TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction"); |
662 | |
663 | legend->AddEntry(cross,"TPC cross tracks"); |
664 | legend->AddEntry(itstpcB,"ITS-TPC smooth"); |
665 | legend->Draw(); |
666 | picArray->AddLast(pad); |
667 | } |
668 | if (itstpcP&&cosmic){ |
669 | pad = new TCanvas("ITSTPC_COSMIC","ITSTPC_COSMIC"); |
670 | SetPadStyle(pad,mx0,mx1,my0,my1); |
671 | itstpcP->Draw("alp"); |
672 | pad->Clear(); |
673 | cosmic->Draw("ap"); |
674 | itstpcP->Draw("p"); |
675 | // |
676 | TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction"); |
677 | |
678 | legend->AddEntry(cosmic,"TPC cross tracks0 up-down"); |
679 | legend->AddEntry(itstpcB,"ITS-TPC smooth"); |
680 | legend->Draw(); |
681 | picArray->AddLast(pad); |
682 | } |
683 | } |
684 | |
685 | |
686 | |
687 | |
688 | void AliTPCPreprocessorOffline::CalibTimeGain(Char_t* fileName, Int_t startRunNumber, Int_t endRunNumber, TString ocdbStorage){ |
689 | // |
690 | // Update OCDB gain |
691 | // |
692 | ReadGainGlobal(fileName); |
693 | AnalyzeGain(startRunNumber,endRunNumber, 1000,1.43); |
694 | MakeQAPlot(1.43); |
695 | if (ocdbStorage.Length()==0) ocdbStorage+="local://"+gSystem->GetFromPipe("pwd")+"/OCDB"; |
696 | UpdateOCDBGain( startRunNumber, endRunNumber, ocdbStorage.Data()); |
697 | } |
698 | |
699 | |
700 | |
701 | |
702 | void AliTPCPreprocessorOffline::ReadGainGlobal(Char_t* fileName){ |
703 | // |
704 | // read calibration entries from file |
705 | // |
706 | TFile fcalib(fileName); |
707 | TObjArray * array = (TObjArray*)fcalib.Get("TPCCalib"); |
708 | if (array){ |
709 | fGainMIP = ( AliTPCcalibTimeGain *)array->FindObject("calibTimeGain"); |
710 | fGainCosmic = ( AliTPCcalibTimeGain *)array->FindObject("calibTimeGainCosmic"); |
711 | }else{ |
712 | fGainMIP = ( AliTPCcalibTimeGain *)fcalib.Get("calibTimeGain"); |
713 | fGainCosmic = ( AliTPCcalibTimeGain *)fcalib.Get("calibTimeGainCosmic"); |
714 | } |
715 | TH1 * hisT=0; |
716 | Int_t firstBinA =0, lastBinA=0; |
717 | |
718 | if (fGainCosmic){ |
719 | hisT= fGainCosmic->GetHistGainTime()->Projection(1); |
720 | firstBinA = hisT->FindFirstBinAbove(2); |
721 | lastBinA = hisT->FindLastBinAbove(2); |
722 | fGainCosmic->GetHistGainTime()->GetAxis(1)->SetRange(firstBinA,lastBinA); |
723 | delete hisT; |
724 | } |
725 | |
726 | if (fGainMIP){ |
727 | hisT= fGainMIP->GetHistGainTime()->Projection(1); |
728 | firstBinA = hisT->FindFirstBinAbove(2); |
729 | lastBinA = hisT->FindLastBinAbove(2); |
730 | fGainMIP->GetHistGainTime()->GetAxis(1)->SetRange(firstBinA,lastBinA); |
731 | delete hisT; |
732 | } |
733 | |
734 | } |
735 | |
736 | |
737 | |
738 | Bool_t AliTPCPreprocessorOffline::AnalyzeGain(Int_t startRunNumber, Int_t endRunNumber, Int_t minEntriesGaussFit, Float_t FPtoMIPratio){ |
739 | // |
740 | // |
741 | // |
742 | fGainMIP->GetHistGainTime()->GetAxis(5)->SetRangeUser(startRunNumber, endRunNumber); |
743 | // 1.) try to create MIP spline |
744 | fGainMIP->GetHistGainTime()->GetAxis(2)->SetRangeUser(1.51,2.49); // only beam data |
745 | fGainMIP->GetHistGainTime()->GetAxis(4)->SetRangeUser(0.39,0.51); // only MIP pions |
746 | // |
747 | fGraphMIP = AliTPCcalibBase::FitSlices(fGainMIP->GetHistGainTime(),0,1,minEntriesGaussFit,10,0.1,0.7); |
748 | if (fGraphMIP->GetN()==0) fGraphMIP = 0x0; |
749 | if (fGraphMIP) fFitMIP = AliTPCcalibTimeGain::MakeSplineFit(fGraphMIP); |
750 | if (fGraphMIP) fGraphMIP->SetName("TGRAPHERRORS_MEAN_GAIN_BEAM_ALL");// set proper names according to naming convention |
751 | fGainArray->AddAt(fFitMIP,0); |
752 | |
753 | |
754 | // 2.) try to create Cosmic spline |
755 | fGainCosmic->GetHistGainTime()->GetAxis(2)->SetRangeUser(0.51,1.49); // only cosmics |
756 | fGainCosmic->GetHistGainTime()->GetAxis(4)->SetRangeUser(20,100); // only Fermi-Plateau muons |
757 | // |
758 | fGraphCosmic = AliTPCcalibBase::FitSlices(fGainCosmic->GetHistGainTime(),0,1,minEntriesGaussFit,10); |
759 | if (fGraphCosmic->GetN()==0) fGraphCosmic = 0x0; |
760 | // |
761 | if (fGraphCosmic) { |
762 | for(Int_t i=0; i < fGraphCosmic->GetN(); i++) { |
763 | fGraphCosmic->GetY()[i] /= FPtoMIPratio; |
764 | fGraphCosmic->GetEY()[i] /= FPtoMIPratio; |
765 | } |
766 | } |
767 | // |
768 | if (fGraphCosmic) fFitCosmic = AliTPCcalibTimeGain::MakeSplineFit(fGraphCosmic); |
769 | if (fGraphCosmic) fGraphCosmic->SetName("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL"); // set proper names according to naming convention |
770 | fGainArray->AddAt(fFitCosmic,1); |
771 | // with naming convention and backward compatibility |
772 | fGainArray->AddAt(fGraphMIP,2); |
773 | fGainArray->AddAt(fGraphCosmic,3); |
774 | cout << "fGraphCosmic: " << fGraphCosmic << " fGraphMIP " << fGraphMIP << endl; |
775 | return kTRUE; |
776 | |
777 | } |
778 | |
779 | |
780 | |
781 | void AliTPCPreprocessorOffline::UpdateOCDBGain(Int_t startRunNumber, Int_t endRunNumber, const Char_t *storagePath){ |
782 | // |
783 | // Update OCDB entry |
784 | // |
785 | AliCDBMetaData *metaData= new AliCDBMetaData(); |
786 | metaData->SetObjectClassName("TObjArray"); |
787 | metaData->SetResponsible("Alexander Kalweit"); |
788 | metaData->SetBeamPeriod(1); |
789 | metaData->SetAliRootVersion("05-24-00"); //root version |
790 | metaData->SetComment("Calibration of the time dependence of the gain due to pressure and temperature changes."); |
791 | AliCDBId id1("TPC/Calib/TimeGain", startRunNumber, endRunNumber); |
792 | AliCDBStorage * gStorage = AliCDBManager::Instance()->GetStorage(storagePath); |
793 | gStorage->Put(fGainArray, id1, metaData); |
794 | } |
795 | |
796 | void AliTPCPreprocessorOffline::MakeQAPlot(Float_t FPtoMIPratio) { |
797 | // |
798 | // Make QA plot to visualize results |
799 | // |
800 | // |
801 | // |
802 | if (fGraphCosmic) { |
803 | TCanvas * canvasCosmic = new TCanvas("gain Cosmic", "time dependent gain QA histogram cosmic"); |
804 | canvasCosmic->cd(); |
805 | TH2D * gainHistoCosmic = fGainCosmic->GetHistGainTime()->Projection(0,1); |
806 | gainHistoCosmic->SetDirectory(0); |
807 | gainHistoCosmic->SetName("GainHistoCosmic"); |
808 | gainHistoCosmic->GetXaxis()->SetTimeDisplay(kTRUE); |
809 | gainHistoCosmic->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}"); |
810 | gainHistoCosmic->Draw("colz"); |
811 | fGraphCosmic->SetMarkerStyle(25); |
812 | fGraphCosmic->Draw("lp"); |
813 | fGraphCosmic->SetMarkerStyle(25); |
814 | TGraph * grfFitCosmic = fFitCosmic->MakeGraph(fGraphCosmic->GetX()[0],fGraphCosmic->GetX()[fGraphCosmic->GetN()-1],50000,0); |
815 | if (grfFitCosmic) { |
816 | for(Int_t i=0; i < grfFitCosmic->GetN(); i++) { |
817 | grfFitCosmic->GetY()[i] *= FPtoMIPratio; |
818 | } |
819 | for(Int_t i=0; i < fGraphCosmic->GetN(); i++) { |
820 | fGraphCosmic->GetY()[i] *= FPtoMIPratio; |
821 | } |
822 | } |
823 | fGraphCosmic->Draw("lp"); |
824 | grfFitCosmic->SetLineColor(2); |
825 | grfFitCosmic->Draw("lu"); |
826 | fGainArray->AddLast(gainHistoCosmic); |
827 | fGainArray->AddLast(canvasCosmic->Clone()); |
828 | delete canvasCosmic; |
829 | } |
830 | if (fFitMIP) { |
831 | TCanvas * canvasMIP = new TCanvas("gain MIP", "time dependent gain QA histogram MIP"); |
832 | canvasMIP->cd(); |
833 | TH2D * gainHistoMIP = fGainMIP->GetHistGainTime()->Projection(0,1); |
834 | gainHistoMIP->SetName("GainHistoCosmic"); |
835 | gainHistoMIP->SetDirectory(0); |
836 | gainHistoMIP->GetXaxis()->SetTimeDisplay(kTRUE); |
837 | gainHistoMIP->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}"); |
838 | gainHistoMIP->Draw("colz"); |
839 | fGraphMIP->SetMarkerStyle(25); |
840 | fGraphMIP->Draw("lp"); |
841 | TGraph * grfFitMIP = fFitMIP->MakeGraph(fGraphMIP->GetX()[0],fGraphMIP->GetX()[fGraphMIP->GetN()-1],50000,0); |
842 | grfFitMIP->SetLineColor(2); |
843 | grfFitMIP->Draw("lu"); |
844 | fGainArray->AddLast(gainHistoMIP); |
845 | fGainArray->AddLast(canvasMIP->Clone()); |
846 | delete canvasMIP; |
847 | } |
848 | } |
849 | |
850 | |
851 | |