]> git.uio.no Git - u/mrichter/AliRoot.git/blob - TPC/AliTPCPreprocessorOffline.cxx
Adding the preprocessor for calibration
[u/mrichter/AliRoot.git] / TPC / AliTPCPreprocessorOffline.cxx
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