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 :
18 : /*
19 : Responsible: marian.ivanov@cern.ch
20 : Code to analyze the TPC calibration and to produce OCDB entries
21 :
22 :
23 : .x ~/rootlogon.C
24 : gSystem->Load("libANALYSIS");
25 : gSystem->Load("libTPCcalib");
26 :
27 : AliTPCPreprocessorOffline proces;
28 : TString ocdbPath="local:////"
29 : ocdbPath+=gSystem->GetFromPipe("pwd");
30 :
31 : proces.CalibTimeGain("CalibObjects.root",run0,run1,ocdbPath);
32 : proces.CalibTimeVdrift("CalibObjects.root",run0,run1,ocdbPath);
33 : // take the raw calibration data from the file CalibObjects.root
34 : // and make a OCDB entry with run validity run0-run1
35 : // results are stored at the ocdbPath - local or alien ...
36 : // default storage ""- data stored at current working directory
37 :
38 : e.g.
39 : gSystem->Load("libANALYSIS");
40 : gSystem->Load("libTPCcalib");
41 : AliTPCPreprocessorOffline proces;
42 : proces.CalibTimeGain("TPCMultObjects.root",114000,140040,0);
43 : TFile oo("OCDB/TPC/Calib/TimeGain/Run114000_121040_v0_s0.root")
44 : TObjArray * arr = AliCDBEntry->GetObject()
45 : arr->At(4)->Draw("alp")
46 :
47 : */
48 : #include "Riostream.h"
49 : #include <fstream>
50 : #include "TMap.h"
51 : #include "TGraphErrors.h"
52 : #include "AliExternalTrackParam.h"
53 : #include "TROOT.h"
54 : #include "TFile.h"
55 : #include "TDirectory.h"
56 : #include "TGraph.h"
57 : #include "TMultiGraph.h"
58 : #include "TCanvas.h"
59 : #include "THnSparse.h"
60 : #include "TLegend.h"
61 : #include "TPad.h"
62 : #include "TH2D.h"
63 : #include "TH3D.h"
64 : #include "AliTPCROC.h"
65 : #include "AliTPCCalROC.h"
66 : //#include "AliESDfriend.h"
67 : #include "AliTPCcalibTime.h"
68 : #include "AliSplineFit.h"
69 : #include "AliCDBMetaData.h"
70 : #include "AliCDBId.h"
71 : #include "AliCDBManager.h"
72 : #include "AliCDBStorage.h"
73 : #include "AliTPCcalibBase.h"
74 : #include "AliTPCcalibDB.h"
75 : #include "AliTPCcalibDButil.h"
76 : #include "AliRelAlignerKalman.h"
77 : #include "AliTPCParamSR.h"
78 : #include "AliTPCcalibTimeGain.h"
79 : #include "AliTPCcalibGainMult.h"
80 : #include "AliTPCcalibAlign.h"
81 : #include "AliSplineFit.h"
82 : #include "AliTPCComposedCorrection.h"
83 : #include "AliTPCExBTwist.h"
84 : #include "AliTPCCalibGlobalMisalignment.h"
85 : #include "TStatToolkit.h"
86 : #include "TChain.h"
87 : #include "TCut.h"
88 : #include "AliTrackerBase.h"
89 : #include "AliTracker.h"
90 : #include "AliTPCPreprocessorOffline.h"
91 : #include "AliTPCCorrectionFit.h"
92 : #include "AliCDBEntry.h"
93 :
94 : #include "AliTPCClusterParam.h"
95 : #include "AliTPCRecoParam.h"
96 :
97 : using std::endl;
98 : using std::cout;
99 :
100 6 : ClassImp(AliTPCPreprocessorOffline)
101 : //_____________________________________________________________________________
102 : AliTPCPreprocessorOffline::AliTPCPreprocessorOffline():
103 0 : TNamed("TPCPreprocessorOffline","TPCPreprocessorOffline"),
104 0 : fNormaliseQA(kTRUE),
105 0 : fGainCalibrationType(kFullGainCalib), // gain calibration type
106 0 : fMinEntries(500), // minimal number of entries for fit
107 0 : fStartRun(0), // start Run - used to make fast selection in THnSparse
108 0 : fEndRun(0), // end Run - used to make fast selection in THnSparse
109 0 : fStartTime(0), // fStartTime - used to make fast selection in THnSparse
110 0 : fEndTime(0), // fEndTime - used to make fast selection in THnSparse
111 0 : fOCDBstorage(0), // OCDB storage
112 0 : fVdriftArray(new TObjArray),
113 0 : fTimeDrift(0),
114 0 : fGraphMIP(0), // graph time dependence of MIP
115 0 : fGraphCosmic(0), // graph time dependence at Plateu
116 0 : fGraphAttachmentMIP(0),
117 0 : fFitMIP(0), // fit of dependence - MIP
118 0 : fFitCosmic(0), // fit of dependence - Plateu
119 0 : fGainArray(new TObjArray), // array to be stored in the OCDB
120 0 : fGainArrayCombined(0x0),
121 0 : fArrQAhist(0x0),
122 0 : fGainMIP(0), // calibration component for MIP
123 0 : fGainCosmic(0), // calibration component for cosmic
124 0 : fGainMult(0),
125 0 : fAlignTree(0), // alignment tree
126 0 : fSwitchOnValidation(kFALSE), // flag to switch on validation of OCDB parameters
127 0 : fMinGain(1.5),
128 0 : fMaxGain(4.5),
129 0 : fMaxVdriftCorr(0.03),
130 0 : fNtracksVdrift(0),
131 0 : fMinTracksVdrift(0),
132 0 : fNeventsVdrift(0),
133 0 : fMinEventsVdrift(0),
134 0 : fCalibrationStatus(0),
135 0 : fDriftCDBentry(NULL)
136 0 : {
137 : //
138 : // default constructor
139 : //
140 0 : }
141 :
142 : //_____________________________________________________________________________
143 0 : AliTPCPreprocessorOffline::~AliTPCPreprocessorOffline() {
144 : //
145 : // Destructor
146 : //
147 0 : delete fDriftCDBentry;
148 0 : }
149 :
150 : //_____________________________________________________________________________
151 : void AliTPCPreprocessorOffline::GetRunRange(AliTPCcalibTime * const timeDrift){
152 : //
153 : // find the fist and last run
154 : //
155 0 : TObjArray *hisArray =timeDrift->GetHistoDrift();
156 0 : {for (Int_t i=0; i<hisArray->GetEntriesFast(); i++){
157 0 : THnSparse* addHist=(THnSparse*)hisArray->UncheckedAt(i);
158 0 : if (!addHist) continue;
159 0 : if (addHist->GetEntries()<fMinEntries) continue;
160 0 : TH1D* histo =addHist->Projection(3);
161 0 : TH1D* histoTime=addHist->Projection(0);
162 0 : AliInfo(Form("%s\t%f\t%d\t%d",histo->GetName(), histo->GetEntries(),histo->FindFirstBinAbove(0),histo->FindLastBinAbove(0)));
163 :
164 0 : if (fStartRun<=0){
165 0 : fStartRun=histo->FindFirstBinAbove(0);
166 0 : fEndRun =histo->FindLastBinAbove(0);
167 0 : }else{
168 0 : fStartRun=TMath::Min(histo->FindFirstBinAbove(0),fStartRun);
169 0 : fEndRun =TMath::Max(histo->FindLastBinAbove(0),fEndRun);
170 : }
171 0 : if (fStartTime==0){
172 0 : fStartTime=histoTime->FindFirstBinAbove(0);
173 0 : fEndTime =histoTime->FindLastBinAbove(0);
174 0 : }else{
175 0 : fStartTime=TMath::Min(histoTime->FindFirstBinAbove(0),fStartTime);
176 0 : fEndTime =TMath::Max(histoTime->FindLastBinAbove(0),fEndTime);
177 : }
178 0 : delete histo;
179 0 : delete histoTime;
180 0 : }}
181 0 : if (fStartRun<0) fStartRun=0;
182 0 : if (fEndRun<0) fEndRun=100000000;
183 0 : AliInfo(Form("Run range :\t%d-%d", fStartRun, fEndRun));
184 0 : AliInfo(Form("Time range :\t%d-%d", fStartTime, fEndTime));
185 :
186 0 : }
187 :
188 : //_____________________________________________________________________________
189 : Int_t AliTPCPreprocessorOffline::CalibTimeVdrift(AliTPCcalibTime* timeDrift, Int_t ustartRun, Int_t uendRun)
190 : {
191 : // make calibration of the drift velocity
192 : // Input parameters:
193 : // timeDrift - the calibration object
194 : // ustartRun, uendRun - run validity period
195 : // return 0 on success, 1 on failure
196 :
197 0 : fTimeDrift=timeDrift;
198 0 : fStartRun=ustartRun;
199 0 : fEndRun=ustartRun;
200 0 : GetRunRange(fTimeDrift);
201 :
202 : //extract statistics
203 0 : fNtracksVdrift = TMath::Nint(fTimeDrift->GetResHistoTPCITS(0)->GetEntries());
204 : //if we have 0 ITS TPC matches it means we have no ITS tracks and we try to use TPC-TOF matching for calibration
205 0 : if (fNtracksVdrift==0) fNtracksVdrift=TMath::Nint(fTimeDrift->GetResHistoTPCTOF(0)->GetEntries());
206 0 : fNeventsVdrift = TMath::Nint(fTimeDrift->GetTPCVertexHisto(0)->GetEntries());
207 :
208 0 : TObjArray *hisArray =fTimeDrift->GetHistoDrift();
209 0 : for (Int_t i=0; i<hisArray->GetEntriesFast(); i++){
210 0 : THnSparse* addHist=(THnSparse*)hisArray->At(i);
211 0 : if (!addHist) continue;
212 0 : if (fStartTime<fEndTime) addHist->GetAxis(0)->SetRange(fStartTime-1,fEndTime+1);
213 0 : if (fStartRun<fEndRun) addHist->GetAxis(3)->SetRange(fStartRun-1,fEndRun+1);
214 0 : }
215 : //
216 : //
217 : // 2. extraction of the information
218 : //
219 0 : if (fVdriftArray)
220 : {
221 0 : fVdriftArray->Delete();
222 0 : delete fVdriftArray;
223 : }
224 0 : fVdriftArray = new TObjArray();
225 0 : AddAlignmentGraphs(fVdriftArray,fTimeDrift);
226 0 : AddHistoGraphs(fVdriftArray,fTimeDrift,fMinEntries);
227 0 : AddLaserGraphs(fVdriftArray,fTimeDrift);
228 :
229 : //
230 : // 3. Append QA plots
231 : //
232 0 : MakeDefaultPlots(fVdriftArray,fVdriftArray);
233 :
234 : //
235 : // 4. validate OCDB entries
236 : //
237 0 : if(fSwitchOnValidation==kTRUE && ValidateTimeDrift()==kFALSE) {
238 0 : AliWarning("TPC time drift OCDB parameters out of range!");
239 0 : return 1;
240 : }
241 : //
242 : //4.b make alignment
243 : //
244 0 : MakeFitTime();
245 0 : TFile * ftime= TFile::Open("fitITSVertex.root");
246 0 : if (ftime){
247 0 : TObject * alignmentTime=ftime->Get("FitCorrectionTime");
248 0 : if (alignmentTime) fVdriftArray->AddLast(alignmentTime);
249 0 : }
250 : //
251 : // 5.) Add the RecoParam and ClusterParam - for compatibility checks -different sets of parameters can invalidate calibration
252 : //
253 0 : AliTPCClusterParam *clParam = AliTPCcalibDB::Instance()->GetClusterParam();
254 0 : TObjArray *recoParams = new TObjArray(4) ;
255 0 : for (Int_t i=0;i<4;i++) recoParams->AddAt(AliTPCcalibDB::Instance()->GetRecoParam(i),i);
256 0 : fVdriftArray->AddLast(clParam);
257 0 : fVdriftArray->AddLast(recoParams);
258 : return 0;
259 0 : }
260 :
261 : //_____________________________________________________________________________
262 : void AliTPCPreprocessorOffline::CalibTimeVdrift(const Char_t* file, Int_t ustartRun, Int_t uendRun, AliCDBStorage* pocdbStorage){
263 : //
264 : // make calibration of the drift velocity
265 : // Input parameters:
266 : // file - the location of input file
267 : // ustartRun, uendRun - run validity period
268 : // pocdbStorage - path to hte OCDB storage
269 : // - if empty - local storage 'pwd' uesed
270 0 : if (pocdbStorage) fOCDBstorage=pocdbStorage;
271 : else {
272 0 : TString localStorage = "local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
273 0 : fOCDBstorage=AliCDBManager::Instance()->GetStorage(localStorage.Data());
274 0 : }
275 :
276 : //
277 : // 1. Extract the calibration object form file, may have a number of layouts
278 0 : TFile fcalib(file);
279 0 : TObject* obj = dynamic_cast<TObject*>(fcalib.Get("TPCCalib"));
280 0 : TObjArray* array = dynamic_cast<TObjArray*>(obj);
281 0 : TDirectory* dir = dynamic_cast<TDirectory*>(obj);
282 : AliTPCcalibTime* timeDrift = NULL;
283 0 : if (dir) {
284 0 : timeDrift = dynamic_cast<AliTPCcalibTime*>(dir->Get("calibTime"));
285 0 : }
286 0 : else if (array){
287 0 : timeDrift = (AliTPCcalibTime *)array->FindObject("calibTime");
288 0 : } else {
289 0 : timeDrift = (AliTPCcalibTime*)fcalib.Get("calibTime");
290 : }
291 0 : if(!timeDrift) return;
292 :
293 : //calculate the calibration
294 0 : if (CalibTimeVdrift(timeDrift,ustartRun,uendRun)!=0) return;
295 :
296 : //
297 : //
298 : // 6. update of OCDB
299 : //
300 : //
301 0 : UpdateOCDBDrift(ustartRun,uendRun,fOCDBstorage);
302 0 : }
303 :
304 : //_____________________________________________________________________________
305 : AliCDBEntry* AliTPCPreprocessorOffline::CreateDriftCDBentryObject(Int_t ustartRun, Int_t uendRun)
306 : {
307 : //create the CDB entry (and cache internally)
308 :
309 : //reset if we dont have anything
310 0 : if (!fVdriftArray)
311 : {
312 0 : delete fDriftCDBentry; fDriftCDBentry=NULL;
313 0 : return NULL;
314 : }
315 :
316 : //will be owned by the cdb entry once attached
317 0 : AliCDBMetaData* metaData = new AliCDBMetaData;
318 0 : metaData->SetObjectClassName("TObjArray");
319 0 : metaData->SetResponsible("Marian Ivanov");
320 0 : metaData->SetBeamPeriod(1);
321 0 : metaData->SetAliRootVersion("05-25-01"); //root version
322 0 : metaData->SetComment("Calibration of the time dependence of the drift velocity");
323 :
324 0 : AliCDBId id1("TPC/Calib/TimeDrift", ustartRun, uendRun);
325 :
326 : //now the entry owns the metadata, but NOT the data
327 0 : delete fDriftCDBentry;
328 0 : fDriftCDBentry=new AliCDBEntry(fVdriftArray,id1,metaData,kFALSE);
329 :
330 : return fDriftCDBentry;
331 0 : }
332 :
333 : //_____________________________________________________________________________
334 : void AliTPCPreprocessorOffline::UpdateOCDBDrift( Int_t ustartRun, Int_t uendRun, AliCDBStorage* storage ){
335 : //
336 : // Update OCDB
337 : //
338 : Bool_t status=kFALSE;
339 0 : if (CreateDriftCDBentryObject(ustartRun,uendRun))
340 : {
341 0 : status=storage->Put(fDriftCDBentry);
342 0 : }
343 0 : if (status==kFALSE) fCalibrationStatus|=kCalibFailedExport ;
344 0 : }
345 :
346 : void AliTPCPreprocessorOffline::TakeOwnershipDriftCDBEntry(){
347 0 : fVdriftArray = NULL;
348 0 : fDriftCDBentry = NULL;
349 0 : }
350 :
351 : //_____________________________________________________________________________
352 : Bool_t AliTPCPreprocessorOffline::ValidateTimeGain()
353 : {
354 : //
355 : // Validate time gain corrections
356 : //
357 0 : AliInfo("ValidateTimeGain..." );
358 0 : Float_t minGain = fMinGain;
359 0 : Float_t maxGain = fMaxGain;
360 :
361 0 : TGraphErrors *gr = (TGraphErrors*)fGainArray->FindObject("TGRAPHERRORS_MEAN_GAIN_BEAM_ALL");
362 :
363 : // ===| treat the case if the combined calibration should be used |==========
364 0 : if (fGainCalibrationType==kCombinedGainCalib) {
365 0 : gr = (TGraphErrors*)fGainArrayCombined->FindObject("TGRAPHERRORS_MEAN_GAIN_BEAM_ALL");
366 0 : }
367 :
368 0 : if (!gr) {
369 0 : gr = (TGraphErrors*)fGainArray->FindObject("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL");
370 0 : if (fGainCalibrationType==kCombinedGainCalib) {
371 0 : gr = (TGraphErrors*)fGainArrayCombined->FindObject("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL");
372 0 : }
373 0 : if (!gr)
374 : {
375 0 : fCalibrationStatus |= kCalibFailedTimeGain;
376 0 : return kFALSE;
377 : }
378 0 : AliInfo("Assuming given run is a cosmic run. Using gain calibration from Fermi-plateau muons.");
379 0 : }
380 0 : if(gr->GetN()<1)
381 : {
382 0 : fCalibrationStatus |= kCalibFailedTimeGain;
383 0 : return kFALSE;
384 : }
385 :
386 : // check whether gain in the range
387 0 : for(Int_t iPoint=0; iPoint<gr->GetN(); iPoint++)
388 : {
389 0 : if(gr->GetY()[iPoint] < minGain || gr->GetY()[iPoint] > maxGain)
390 : {
391 0 : fCalibrationStatus |= kCalibFailedTimeGain;
392 0 : AliError(TString::Format("Gain point outside of range %f != (%f,%f)",gr->GetY()[iPoint], minGain, maxGain ).Data());
393 0 : return kFALSE;
394 : }
395 : }
396 :
397 0 : AliInfo("Validation successful");
398 0 : return kTRUE;
399 0 : }
400 :
401 : //_____________________________________________________________________________
402 : AliTPCPreprocessorOffline::EGainCalibType AliTPCPreprocessorOffline::GetGainCalibrationTypeFromString(const TString& type)
403 : {
404 : //
405 : // return the gain calibration type analysing the string 'type'
406 : // if an error occurs, return kNGainCalibTypes
407 : //
408 0 : if (type.IsNull()) {
409 0 : ::Warning("AliTPCPreprocessorOffline::GetGainCalibrationTypeFromString","Empty gain calibration type string");
410 0 : return kNGainCalibTypes;
411 : }
412 :
413 0 : if (!type.IsDigit()) {
414 0 : ::Warning("AliTPCPreprocessorOffline::GetGainCalibrationTypeFromString","Gain calibration string '%s' is not a digit", type.Data());
415 0 : return kNGainCalibTypes;
416 : }
417 :
418 0 : const Int_t gainType = type.Atoi();
419 0 : if (gainType<0 || gainType>=Int_t(kNGainCalibTypes)) {
420 0 : ::Warning("AliTPCPreprocessorOffline::GetGainCalibrationTypeFromString","Gain calibration string '%s' is not a valid gain calibration type (0-%d)", type.Data(), kNGainCalibTypes-1);
421 0 : return kNGainCalibTypes;
422 : }
423 :
424 0 : return EGainCalibType(gainType);
425 0 : }
426 :
427 : //_____________________________________________________________________________
428 : Bool_t AliTPCPreprocessorOffline::SetGainCalibrationType(const TString& type)
429 : {
430 : //
431 : // set the gain calibration type analysing the string 'type'
432 : //
433 0 : EGainCalibType gainType=GetGainCalibrationTypeFromString(type);
434 0 : if (type==kNGainCalibTypes) return kFALSE;
435 :
436 0 : fGainCalibrationType=gainType;
437 :
438 0 : return kTRUE;
439 0 : }
440 :
441 : //_____________________________________________________________________________
442 : Bool_t AliTPCPreprocessorOffline::ProduceCombinedGainCalibration()
443 : {
444 : //
445 : // This function will produce the combined calibratin of the objects presently stored in the OCDB
446 : // and the calibration extracted in this calibration
447 : //
448 :
449 : // ===| write some info |=====================================================
450 0 : AliCDBManager *cdbMan = AliCDBManager::Instance();
451 0 : TString calibTimeGainStorage=cdbMan->GetDefaultStorage()->GetURI();
452 0 : const AliCDBEntry *e=cdbMan->Get("TPC/Calib/TimeGain");
453 0 : const TString timeGainID=e->GetId().ToString();
454 0 : if (cdbMan->GetSpecificStorage("TPC/Calib/TimeGain")) {
455 0 : calibTimeGainStorage=cdbMan->GetSpecificStorage("TPC/Calib/TimeGain")->GetURI();
456 : }
457 0 : AliInfoF("Using TimeGain '%s','%s' for combined gain calibration", calibTimeGainStorage.Data(), timeGainID.Data());
458 :
459 : // ===| get latest gain calibration from OCDB |===============================
460 0 : TObjArray *gainOCDB = AliTPCcalibDB::Instance()->GetTimeGainSplines();
461 0 : if (!gainOCDB) {
462 0 : AliError("Could not retrieve gain calibration from OCDB. Cannot perform combined calibration.");
463 0 : return kFALSE;
464 : }
465 :
466 0 : const Int_t nOCDB=gainOCDB->GetEntriesFast();
467 0 : const Int_t nThis=fGainArray->GetEntriesFast();
468 :
469 : // // ===| check consistency of entries |=======================================
470 : // TString type("this");
471 : // if ( nOCDB != nThis ) {
472 : // AliError(TString::Format("Entries in present OCDB calibration and this pass differ: %d != %d", nOCDB, nThis));
473 : // TObjArray *a1=gainOCDB->GetEntriesFast();
474 : // TObjArray *a2=fGainArray->GetEntriesFast();
475 : // if (nThis>nOCDB) {
476 : // a2=gainOCDB->GetEntriesFast();
477 : // a1=fGainArray->GetEntriesFast();
478 : // type="OCDB";
479 : // }
480 : //
481 : // for (Int_t icalib=0; icalib<a1->GetEntriesFast(); ++icalib) {
482 : // const TObject *o=a1->At(icalib);
483 : // if (!o) continue;
484 : // if (!a2->FindObject(o->GetName())) {
485 : // AliError(TString::Format("Could not find '%s' in %s calibration", o->GetName(), type.Data()));
486 : // }
487 : // }
488 : // return kFALSE;
489 : // }
490 :
491 : // ===| create combined gain array if needed and reset |=====================
492 0 : if (!fGainArrayCombined) fGainArrayCombined=new TObjArray(nThis);
493 : //fGainArrayCombined->SetOwner(); // either not owner, or all steering objects must be cloned
494 0 : fGainArrayCombined->Clear();
495 :
496 : // ===| explicitly treat entries |===========================================
497 0 : TGraphErrors *grOCDB = 0x0;
498 0 : TGraphErrors *grThis = 0x0;
499 : TGraphErrors *grCombined = 0x0;
500 : AliSplineFit *splineFit = 0x0;
501 :
502 : Bool_t error=kFALSE;
503 :
504 : // ---| gain vs time |--------------------------------------------------------
505 0 : GetGraphs("TGRAPHERRORS_MEAN_GAIN_BEAM_ALL", grOCDB, grThis);
506 0 : AliInfo(Form("Graphs: %p, %p: %s, %s", grOCDB, grThis, grOCDB?grOCDB->GetName():"", grThis?grThis->GetName():""));
507 0 : if (!grOCDB || !grThis) {
508 0 : AliError("Gain vs. time for beam cannot be processed");
509 0 : if (fGainMIP) {
510 : error=kTRUE;
511 0 : }
512 : } else {
513 0 : grCombined = CombineGraphs(grOCDB, grThis, 1 );
514 0 : AliInfo(Form("Combined: %p: %s", grCombined, grCombined?grCombined->GetName():""));
515 0 : if (grCombined) {
516 0 : splineFit = AliTPCcalibTimeGain::MakeSplineFit(grCombined);
517 0 : fGainArrayCombined->AddAt(splineFit ,0);
518 0 : fGainArrayCombined->AddAt(grCombined,2);
519 : } else {
520 0 : AliError("Gain vs. time for beam cannot be processed");
521 : error=kTRUE;
522 : }
523 : }
524 :
525 0 : GetGraphs("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL", grOCDB, grThis);
526 0 : AliInfo(Form("Graphs: %p, %p: %s, %s", grOCDB, grThis, grOCDB?grOCDB->GetName():"", grThis?grThis->GetName():""));
527 0 : if (!grOCDB || !grThis) {
528 0 : AliError("Gain vs. time from cosmics cannot be processed");
529 0 : if (fGainCosmic) {
530 : error=kTRUE;
531 0 : }
532 : } else {
533 0 : grCombined = CombineGraphs(grOCDB, grThis, 1);
534 0 : AliInfo(Form("Combined: %p: %s", grCombined, grCombined?grCombined->GetName():""));
535 0 : if (grCombined) {
536 0 : splineFit = AliTPCcalibTimeGain::MakeSplineFit(grCombined);
537 0 : fGainArrayCombined->AddAt(splineFit ,1);
538 0 : fGainArrayCombined->AddAt(grCombined,3);
539 : } else {
540 0 : AliError("Gain vs. time from cosmics cannot be processed");
541 : error=kTRUE;
542 : }
543 :
544 : }
545 :
546 : // ===| steering objects |====================================================
547 0 : TObjArray steeringObjectNames;
548 0 : steeringObjectNames.Add(new TNamed("GainSlopesHV","1"));
549 0 : steeringObjectNames.Add(new TNamed("GainSlopesPT","1"));
550 0 : steeringObjectNames.Add(new TNamed("AliTPCClusterParam","1"));
551 0 : steeringObjectNames.Add(new TNamed("TObjArray","1"));
552 :
553 0 : for (Int_t isteer=0; isteer<steeringObjectNames.GetEntriesFast(); ++isteer) {
554 0 : TObject *objName = steeringObjectNames.At(isteer);
555 0 : TObject *steerObj = fGainArray->FindObject(objName->GetName());
556 0 : if (!steerObj) {
557 0 : AliErrorF("%s cannot be processed", objName->GetName());
558 : // ---| check if missing object should produce an error |---
559 0 : if (TString(objName->GetTitle()).Atoi()) {
560 : error=kTRUE;
561 0 : }
562 0 : continue;
563 : }
564 0 : fGainArrayCombined->AddLast(steerObj);
565 0 : }
566 :
567 : // ===| attachement is not applied, simply copy |=============================
568 0 : fGainArrayCombined->AddLast(fGainArray->FindObject("TGRAPHERRORS_MEAN_ATTACHMENT_BEAM_ALL"));
569 :
570 : // ===| multiplicative corrections |==========================================
571 0 : TObjArray graphsToCombine;
572 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL","1"));
573 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL","1"));
574 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL","0"));
575 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL","0"));
576 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEAN_CHAMBERGAIN_SHORT_BEAM_ALL","1"));
577 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEAN_CHAMBERGAIN_MEDIUM_BEAM_ALL","1"));
578 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_MEAN_CHAMBERGAIN_LONG_BEAM_ALL","1"));
579 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QMAX_DIPANGLE_SHORT_BEAM_ALL","1"));
580 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QTOT_DIPANGLE_SHORT_BEAM_ALL","1"));
581 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QMAX_DIPANGLE_MEDIUM_BEAM_ALL","1"));
582 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QTOT_DIPANGLE_MEDIUM_BEAM_ALL","1"));
583 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QMAX_DIPANGLE_LONG_BEAM_ALL","1"));
584 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QTOT_DIPANGLE_LONG_BEAM_ALL","1"));
585 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QMAX_DIPANGLE_ABSOLUTE_BEAM_ALL","1"));
586 0 : graphsToCombine.Add(new TNamed("TGRAPHERRORS_QTOT_DIPANGLE_ABSOLUTE_BEAM_ALL","1"));
587 :
588 0 : for (Int_t igraph=0; igraph<graphsToCombine.GetEntriesFast(); ++igraph) {
589 0 : TObject *graphObj=graphsToCombine.At(igraph);
590 0 : GetGraphs(graphObj->GetName(), grOCDB, grThis);
591 :
592 : // --- check graphs
593 0 : if (!grOCDB || !grThis) {
594 0 : AliError(TString::Format("%s cannot be processed missing object(s) OCDB: %d, This: %d", graphObj->GetName(), grOCDB!=0x0, grThis!=0x0));
595 0 : if (TString(graphObj->GetTitle()).Atoi()) {
596 : error=kTRUE;
597 0 : }
598 0 : continue;
599 : }
600 :
601 : // --- combine graphs
602 0 : grCombined = CombineGraphs(grOCDB, grThis);
603 0 : fGainArrayCombined->AddLast(grCombined);
604 :
605 : // --- normalize pad region gain
606 0 : if ( TString(graphObj->GetName()).Contains("PADREGIONGAIN") ) {
607 : // first normalize to the weighted mean using the number of
608 : // rows in the different pad regions
609 0 : NormaliseYToWeightedMeandEdx(grCombined);
610 : // now correct for the effect the truncated mean in the dE/dx
611 : // calculation would have
612 0 : NormaliseYToTruncateddEdx(grCombined);
613 : }
614 :
615 : // --- for dip angle graphs normalize and do fit
616 0 : if ( TString(graphObj->GetName()).Contains("DIPANGLE") ) {
617 0 : NormaliseYToMean(grCombined);
618 0 : TF1 * fun= new TF1("","1++abs(x)++abs(x*x)");
619 0 : grCombined->Fit(fun,"w","rob=0.9",-0.8,0.8);
620 0 : TString funName(graphObj->GetName());
621 0 : funName.ReplaceAll("TGRAPHERRORS","TF1");
622 0 : fun->SetNameTitle(funName,funName);
623 0 : fGainArrayCombined->AddLast(fun);
624 0 : }
625 0 : }
626 :
627 0 : return !error;
628 0 : }
629 :
630 : //_____________________________________________________________________________
631 : void AliTPCPreprocessorOffline::GetGraphs(const char* name, TGraphErrors* &grOCDB, TGraphErrors* &grThis)
632 : {
633 : //
634 : // get graphs from OCDB gain array and local gain array
635 : //
636 :
637 0 : grOCDB=0x0;
638 0 : grThis=0x0;
639 :
640 0 : TObjArray *gainOCDB = AliTPCcalibDB::Instance()->GetTimeGainSplines();
641 0 : if (!gainOCDB) return;
642 :
643 0 : grOCDB = dynamic_cast<TGraphErrors*>(gainOCDB ->FindObject(name));
644 0 : grThis = dynamic_cast<TGraphErrors*>(fGainArray->FindObject(name));
645 :
646 0 : if (!grOCDB) {
647 0 : AliError(TString::Format("Could not find graph '%s' in OCDB",name));
648 0 : }
649 :
650 0 : if (!grThis) {
651 0 : AliError(TString::Format("Could not find graph '%s' in present calibration",name));
652 0 : }
653 0 : }
654 :
655 : //_____________________________________________________________________________
656 : TGraphErrors* AliTPCPreprocessorOffline::CombineGraphs(TGraphErrors *grOCDB, TGraphErrors *grThis, const Int_t type/*=0*/, const Bool_t multiply/*=kTRUE*/)
657 : {
658 : //
659 : // Combine two graphs.
660 : // type
661 : // 0: Combine point by point, only do interpolation using Eval
662 : // 1: Combine using EvalConst
663 : // 2: Combine using Eval
664 : //
665 : // If mult is true, multiply the data points, otherwise add
666 : //
667 :
668 0 : Double_t x1,y1,x2,y2,x1Err,y1Err,y2Err,yNew,yNewErr;
669 0 : x1=y1=x2=y2=x1Err=y1Err=y2Err=yNew=yNewErr=0;
670 :
671 0 : const Int_t nOCDB=grOCDB->GetN();
672 0 : const Int_t nThis=grThis->GetN();
673 :
674 : // ===| output graph |========================================================
675 : // copy from gThis to retain the attributes
676 0 : TGraphErrors *grCombined=new TGraphErrors(*grThis);
677 0 : grCombined->Set(0);
678 :
679 : // ===| sort graphs for better comparison |===================================
680 0 : grOCDB->Sort();
681 0 : grThis->Sort();
682 :
683 0 : const Double_t xMinOCDB = grOCDB->GetX()[0];
684 0 : const Double_t xMaxOCDB = grOCDB->GetX()[nOCDB-1];
685 0 : const Double_t xMinThis = grThis->GetX()[0];
686 0 : const Double_t xMaxThis = grThis->GetX()[nThis-1];
687 :
688 : // ===========================================================================
689 : // ===| treat combination types |=============================================
690 : //
691 : const Double_t kVerySmall=1e-10;
692 : Int_t ninterpol=0;
693 :
694 0 : const Bool_t interpol = (type==1) || (type==2);
695 0 : const Bool_t evalConst = type!=2;
696 :
697 : Bool_t fallback=kFALSE;
698 :
699 0 : if (type==0) {
700 0 : if ( (xMinOCDB+kVerySmall < xMinThis) || (xMaxOCDB-kVerySmall > xMaxThis) ) {
701 0 : AliErrorF("Point by point combination of %s requested, but ranges are not compatible: [%.2f, %.2f] != [%.2f,%.2f]", grThis->GetName(), xMinOCDB, xMaxOCDB, xMinThis, xMaxThis);
702 0 : return 0x0;
703 : }
704 : }
705 :
706 0 : for (Int_t ipoint=0; ipoint<nThis; ++ipoint) {
707 0 : x2=y2=0;
708 0 : grThis->GetPoint(ipoint, x1, y1);
709 0 : x1Err=grThis->GetErrorX(ipoint);
710 0 : y1Err=grThis->GetErrorY(ipoint);
711 :
712 0 : if (type==0 && !fallback) {
713 0 : if (ipoint<nOCDB) {
714 0 : grOCDB->GetPoint(ipoint, x2, y2);
715 0 : y2Err=grOCDB->GetErrorY(ipoint);
716 0 : fallback=!TMath::AreEqualAbs(x1, x2, kVerySmall);
717 0 : }
718 : else {
719 : fallback=kTRUE;
720 : }
721 : }
722 :
723 0 : if (interpol || fallback) {
724 0 : GetPointWithError(grOCDB, x1, y2, y2Err, evalConst);
725 0 : ++ninterpol;
726 0 : }
727 :
728 0 : if (multiply) {
729 0 : yNew = y1*y2;
730 : yNewErr=0.;
731 0 : if (!TMath::AreEqualAbs(yNew, 0., kVerySmall)) {
732 0 : yNewErr = TMath::Sqrt( (y1Err*y1Err)/(y1*y1) + (y2Err*y2Err)/(y2*y2) ) * yNew;
733 0 : } else {
734 0 : AliErrorF("Cannot combined points from graph %s This y = %.4g +- %.4g, OCDB y = %.4g +- %.4g", grCombined->GetName(), y1, y1Err, y2, y2Err);
735 : }
736 : }
737 : else {
738 0 : yNew = y1+y2;
739 0 : yNewErr = TMath::Sqrt( (y1Err*y1Err) + (y2Err*y2Err) );
740 : }
741 :
742 0 : const Int_t point=grCombined->GetN();
743 0 : grCombined->SetPoint (point, x1 , yNew );
744 0 : grCombined->SetPointError(point, x1Err, yNewErr);
745 : }
746 :
747 0 : if ( (type==0) && ninterpol ) AliWarningF("%d number of points were interpolated for %s, although point-by-point combination was requested",ninterpol, grCombined->GetName());
748 :
749 0 : return grCombined;
750 0 : }
751 :
752 : //_____________________________________________________________________________
753 : Bool_t AliTPCPreprocessorOffline::GetPointWithError(const TGraphErrors *gr, const Double_t xPos, Double_t &y, Double_t &ey, Bool_t evalConst/*=kTRUE*/)
754 : {
755 : //
756 : // The function assumes the points to be sorted in x
757 : //
758 : // Evaluate the graph at xPos, do linear interpolation between neighbouring points
759 : // if 'evalConst' is true, the first/last point will be returned in case xPos is outside the graph range
760 : //
761 : // Errors in y are also calculated by linear interpolation between neighbouring points
762 : // Errors in x are not treated
763 : //
764 : // Return value indicates if xPos was inside the range
765 :
766 : // ===| reset input values |==================================================
767 0 : y=ey=0.;
768 :
769 : // ===| treat case of 0 point |===============================================
770 0 : if (!gr || gr->GetN()==0) return kFALSE;
771 :
772 : // ===| init variables |======================================================
773 0 : Double_t x1,x2,y1,y2, ey1,ey2;
774 0 : x1=x2=y1=y2=ey1=ey2=0.;
775 :
776 0 : const Int_t npoints=gr->GetN();
777 0 : const Double_t xmin=gr->GetX()[0];
778 0 : const Double_t xmax=gr->GetX()[npoints-1];
779 :
780 0 : const Bool_t belowBound = xPos<xmin;
781 0 : const Bool_t aboveBound = xPos>xmax;
782 0 : const Bool_t returnValue = !(belowBound || aboveBound);
783 :
784 : // ===| treat case of 1 point |===============================================
785 0 : if (npoints==1) {
786 0 : y = gr->GetY()[0];
787 0 : ey = gr->GetErrorY(0);
788 0 : return returnValue;
789 : }
790 :
791 : // ===| treat eval const case |===============================================
792 0 : if (evalConst) {
793 0 : if (belowBound) {
794 0 : y = gr->GetY()[0];
795 0 : ey = gr->GetErrorY(0);
796 0 : return returnValue;
797 : }
798 :
799 0 : if (aboveBound) {
800 0 : y = gr->GetY()[npoints-1];
801 0 : ey = gr->GetErrorY(npoints-1);
802 0 : return returnValue;
803 : }
804 : }
805 :
806 : // ===| 2 and more points |===================================================
807 0 : Int_t point = TMath::BinarySearch(npoints, gr->GetX(), xPos);
808 0 : Printf("n, i: %d, %d", npoints, point);
809 0 : if (point==-1) point=0;
810 0 : if (point==npoints-1) --point;
811 :
812 0 : gr->GetPoint(point, x1, y1);
813 0 : ey1 = gr->GetErrorY(point);
814 :
815 0 : gr->GetPoint(point+1, x2, y2);
816 0 : ey2 = gr->GetErrorY(point+1);
817 :
818 0 : Printf("%d, (%.2f, %.2f), (%.2f, %.2f)", point, x1, y1, x2, y2);
819 :
820 0 : if ( !(x2>x1) ) {
821 0 : AliTPCPreprocessorOffline p;
822 0 : p.Error("GetPointWithError","Graph not sorted, or error in extracting points");
823 : return kFALSE;
824 0 : }
825 :
826 0 : y = y1 + (y2-y1) /(x2-x1) * (xPos-x1);
827 0 : ey=ey1 + (ey2-ey1)/(x2-x1) * (xPos-x1);
828 :
829 : // ===| linear error increase outside bounds |================================
830 0 : if (belowBound) {
831 0 : ey=ey1 + (ey1)/(x2-x1) * TMath::Abs(xPos-x1);
832 0 : }
833 0 : else if (aboveBound) {
834 0 : ey=ey2 + (ey1)/(x2-x1) * TMath::Abs(xPos-x2);
835 0 : }
836 :
837 0 : return returnValue;
838 0 : }
839 :
840 : //_____________________________________________________________________________
841 : Bool_t AliTPCPreprocessorOffline::ValidateTimeDrift()
842 : {
843 : //
844 : // Validate time drift velocity corrections
845 : //
846 0 : AliInfo("ValidateTimeDrift..." );
847 :
848 0 : Float_t maxVDriftCorr = fMaxVdriftCorr;
849 :
850 0 : TGraphErrors* gr = (TGraphErrors*)fVdriftArray->FindObject("ALIGN_ITSB_TPC_DRIFTVD");
851 0 : AliInfo(Form("ALIGN_ITSB_TPC_DRIFTVD graph = %p",gr));
852 0 : if (!gr)
853 : {
854 0 : gr = (TGraphErrors*)fVdriftArray->FindObject("ALIGN_TOFB_TPC_DRIFTVD");
855 0 : AliInfo(Form("ALIGN_TOFB_TPC_DRIFTVD graph = %p",gr));
856 0 : }
857 :
858 0 : if(!gr)
859 : {
860 0 : fCalibrationStatus|=kCalibFailedTimeDrift;
861 0 : return kFALSE;
862 : }
863 :
864 : // for now we validate even with low statistics
865 : ////check if we have enough statistics
866 : //if (fNtracksVdrift<fMinTracksVdrift)
867 : //{
868 : // fCalibrationStatus|=kCalibFailedTimeDrift;
869 : // return kFALSE;
870 : //}
871 :
872 0 : if(gr->GetN()<1) {
873 0 : AliInfo(Form("ALIGN_ITSB_TPC_DRIFTVD number of points = %d",gr->GetN()));
874 : {
875 0 : fCalibrationStatus|=kCalibFailedTimeDrift;
876 0 : return kFALSE;
877 : }
878 : }
879 :
880 : // check whether drift velocity corrections in the range
881 0 : for(Int_t iPoint = 0; iPoint<gr->GetN(); iPoint++)
882 : {
883 : //AliInfo(Form("Y value from the graph: %f",TMath::Abs(gr->GetY()[iPoint])));
884 0 : if(TMath::Abs(gr->GetY()[iPoint]) > maxVDriftCorr)
885 : {
886 0 : fCalibrationStatus|=kCalibFailedTimeDrift;
887 0 : return kFALSE;
888 : }
889 : }
890 :
891 0 : return kTRUE;
892 0 : }
893 :
894 : //_____________________________________________________________________________
895 : void AliTPCPreprocessorOffline::UpdateDriftParam(AliTPCParam *param, TObjArray *const arr, Int_t lstartRun){
896 : //
897 : // update the OCDB entry for the nominal time0
898 : //
899 : //
900 : // AliTPCParam * param = AliTPCcalibDB::Instance()->GetParameters();
901 0 : AliTPCParam *paramNew = (AliTPCParam *)param->Clone();
902 0 : TGraphErrors *grT = (TGraphErrors *)arr->FindObject("ALIGN_ITSM_TPC_T0");
903 0 : Double_t deltaTcm = TMath::Median(grT->GetN(),grT->GetY());
904 0 : Double_t deltaT = deltaTcm/param->GetDriftV();
905 0 : paramNew->SetL1Delay(param->GetL1Delay()-deltaT);
906 0 : paramNew->Update();
907 :
908 0 : AliCDBMetaData *metaData= new AliCDBMetaData();
909 0 : metaData->SetObjectClassName("TObjArray");
910 0 : metaData->SetResponsible("Marian Ivanov");
911 0 : metaData->SetBeamPeriod(1);
912 0 : metaData->SetAliRootVersion("05-25-02"); //root version
913 0 : metaData->SetComment("Updated calibration of nominal time 0");
914 : AliCDBId* id1=NULL;
915 0 : id1=new AliCDBId("TPC/Calib/Parameters", lstartRun, AliCDBRunRange::Infinity());
916 0 : Bool_t status = fOCDBstorage->Put(param, (*id1), metaData);
917 0 : if (status==kFALSE) fCalibrationStatus|=kCalibFailedExport ;
918 0 : }
919 :
920 : //_____________________________________________________________________________
921 : void AliTPCPreprocessorOffline::PrintArray(TObjArray *array){
922 : //
923 : // Print the names of the entries in array
924 : //
925 0 : Int_t entries = array->GetEntries();
926 0 : for (Int_t i=0; i<entries; i++){
927 0 : if (!array->At(i)) continue;
928 0 : Printf("%d\t %s", i, array->At(i)->GetName());
929 0 : }
930 0 : }
931 :
932 : //_____________________________________________________________________________
933 : TGraphErrors* AliTPCPreprocessorOffline::FilterGraphDrift(TGraphErrors * graph, Float_t errSigmaCut, Float_t medianCutAbs){
934 : // 2 filters:
935 : // 1. filter graph - error cut errSigmaCut
936 : // 2. filter graph - medianCutAbs around median
937 : //
938 : // errSigmaCut - cut on error
939 : // medianCutAbs - cut on value around median
940 0 : Double_t dummy=0; //
941 : //
942 : // 1. filter graph - error cut errSigmaCut
943 : //
944 : TGraphErrors *graphF;
945 0 : graphF = AliTPCcalibDButil::FilterGraphMedianErr(graph,errSigmaCut,dummy);
946 0 : delete graph;
947 0 : if (!graphF) return 0;
948 0 : graph = AliTPCcalibDButil::FilterGraphMedianErr(graphF,errSigmaCut,dummy);
949 0 : delete graphF;
950 0 : if (!graph) return 0;
951 : //
952 : // filter graph - kMedianCutAbs around median
953 : //
954 0 : graphF=FilterGraphMedianAbs(graph, medianCutAbs,dummy);
955 0 : delete graph;
956 0 : if (!graphF) return 0;
957 0 : graph=FilterGraphMedianAbs(graphF, medianCutAbs,dummy);
958 0 : delete graphF;
959 0 : if (!graph) return 0;
960 0 : return graph;
961 0 : }
962 :
963 : //_____________________________________________________________________________
964 : TGraphErrors* AliTPCPreprocessorOffline::FilterGraphMedianAbs(TGraphErrors * graph, Float_t cut,Double_t &medianY){
965 : //
966 : // filter outlyer measurement
967 : // Only points around median +- cut filtered
968 : //
969 0 : if (!graph) return 0;
970 : Int_t kMinPoints=2;
971 0 : Int_t npoints0 = graph->GetN();
972 : Int_t npoints=0;
973 : Float_t rmsY=0;
974 0 : Double_t *outx=new Double_t[npoints0];
975 0 : Double_t *outy=new Double_t[npoints0];
976 0 : Double_t *errx=new Double_t[npoints0];
977 0 : Double_t *erry=new Double_t[npoints0];
978 : //
979 : //
980 0 : if (npoints0<kMinPoints) {
981 0 : delete []outx;
982 0 : delete []outy;
983 0 : delete []errx;
984 0 : delete []erry;
985 0 : return 0;
986 : }
987 0 : for (Int_t iter=0; iter<3; iter++){
988 : npoints=0;
989 0 : for (Int_t ipoint=0; ipoint<npoints0; ipoint++){
990 0 : if (graph->GetY()[ipoint]==0) continue;
991 0 : if (iter>0 &&TMath::Abs(graph->GetY()[ipoint]-medianY)>cut) continue;
992 0 : outx[npoints] = graph->GetX()[ipoint];
993 0 : outy[npoints] = graph->GetY()[ipoint];
994 0 : errx[npoints] = graph->GetErrorX(ipoint);
995 0 : erry[npoints] = graph->GetErrorY(ipoint);
996 0 : npoints++;
997 0 : }
998 0 : if (npoints<=1) break;
999 0 : medianY =TMath::Median(npoints,outy);
1000 0 : rmsY =TMath::RMS(npoints,outy);
1001 : }
1002 : TGraphErrors *graphOut=0;
1003 0 : if (npoints>1) graphOut= new TGraphErrors(npoints,outx,outy,errx,erry);
1004 0 : delete []outx;
1005 0 : delete []outy;
1006 0 : delete []errx;
1007 0 : delete []erry;
1008 : return graphOut;
1009 0 : }
1010 :
1011 : //_____________________________________________________________________________
1012 : void AliTPCPreprocessorOffline::AddHistoGraphs( TObjArray * vdriftArray, AliTPCcalibTime * const timeDrift, Int_t minEntries){
1013 : //
1014 : // Add graphs corresponding to the alignment
1015 : //
1016 : const Double_t kErrSigmaCut=5; // error sigma cut - for filtering
1017 : const Double_t kMedianCutAbs=0.03; // error sigma cut - for filtering
1018 : //
1019 0 : TObjArray * array=timeDrift->GetHistoDrift();
1020 0 : if (array){
1021 : THnSparse* hist=NULL;
1022 : // 2.a) cosmics with different triggers
1023 0 : for (Int_t i=0; i<array->GetEntriesFast();i++){
1024 0 : hist=(THnSparseF*)array->UncheckedAt(i);
1025 0 : if(!hist) continue;
1026 0 : if (hist->GetEntries()<minEntries) continue;
1027 : //hist->Print();
1028 0 : TString name=hist->GetName();
1029 0 : Int_t dim[4]={0,1,2,3};
1030 0 : THnSparse* newHist=hist->Projection(4,dim);
1031 0 : newHist->SetName(name);
1032 0 : TGraphErrors* graph=AliTPCcalibBase::FitSlices(newHist,2,0,400,100,0.05,0.95, kTRUE);
1033 0 : delete newHist;
1034 0 : if (!graph) {
1035 0 : AliInfo(Form("Graph =%s filtered out", name.Data()));
1036 0 : continue;
1037 : }
1038 0 : AliInfo(Form("name=%s graph=%i, N=%i", name.Data(), graph==0, graph->GetN()));
1039 0 : Int_t pos=name.Index("_");
1040 0 : name=name(pos,name.Capacity()-pos);
1041 0 : TString graphName=graph->ClassName();
1042 0 : graphName+=name;
1043 0 : graphName.ToUpper();
1044 : //
1045 0 : graph = FilterGraphDrift(graph, kErrSigmaCut, kMedianCutAbs);
1046 : //
1047 0 : if (graph){
1048 0 : graph->SetMarkerStyle(i%8+20);
1049 0 : graph->SetMarkerColor(i%7);
1050 0 : graph->GetXaxis()->SetTitle("Time");
1051 0 : graph->GetYaxis()->SetTitle("v_{dcor}");
1052 0 : graph->SetName(graphName);
1053 0 : graph->SetTitle(graphName);
1054 0 : AliInfo(Form("Graph %d\t=\t%s", i, graphName.Data()));
1055 0 : vdriftArray->Add(graph);
1056 : }
1057 0 : }
1058 0 : }
1059 0 : }
1060 :
1061 : //_____________________________________________________________________________
1062 : void AliTPCPreprocessorOffline::AddAlignmentGraphs( TObjArray * vdriftArray, AliTPCcalibTime *const timeDrift){
1063 : //
1064 : // Add graphs corresponding to alignment to the object array
1065 : //
1066 : TObjArray *arrayITS=0;
1067 : TObjArray *arrayTOF=0;
1068 : TObjArray *arrayTRD=0;
1069 : TMatrixD *mstatITS=0;
1070 : TMatrixD *mstatTOF=0;
1071 : TMatrixD *mstatTRD=0;
1072 : //
1073 0 : arrayITS=timeDrift->GetAlignITSTPC();
1074 0 : arrayTRD=timeDrift->GetAlignTRDTPC();
1075 0 : arrayTOF=timeDrift->GetAlignTOFTPC();
1076 :
1077 0 : if (arrayITS->GetEntries()>0) mstatITS= AliTPCcalibDButil::MakeStatRelKalman(arrayITS,0.7,50,fMaxVdriftCorr);
1078 0 : if (arrayTOF->GetEntries()>0) mstatTOF= AliTPCcalibDButil::MakeStatRelKalman(arrayTOF,0.7,1000,fMaxVdriftCorr);
1079 0 : if (arrayTRD->GetEntries()>0) mstatTRD= AliTPCcalibDButil::MakeStatRelKalman(arrayTRD,0.7,50,fMaxVdriftCorr);
1080 : //
1081 0 : TObjArray * arrayITSP= AliTPCcalibDButil::SmoothRelKalman(arrayITS,mstatITS, 0, 5.);
1082 0 : TObjArray * arrayITSM= AliTPCcalibDButil::SmoothRelKalman(arrayITS,mstatITS, 1, 5.);
1083 0 : TObjArray * arrayITSB= AliTPCcalibDButil::SmoothRelKalman(arrayITSP,arrayITSM);
1084 0 : TObjArray * arrayTOFP= AliTPCcalibDButil::SmoothRelKalman(arrayTOF,mstatTOF, 0, 5.);
1085 0 : TObjArray * arrayTOFM= AliTPCcalibDButil::SmoothRelKalman(arrayTOF,mstatTOF, 1, 5.);
1086 0 : TObjArray * arrayTOFB= AliTPCcalibDButil::SmoothRelKalman(arrayTOFP,arrayTOFM);
1087 :
1088 : TObjArray * arrayTRDP= 0x0;
1089 : TObjArray * arrayTRDM= 0x0;
1090 : TObjArray * arrayTRDB= 0x0;
1091 0 : arrayTRDP= AliTPCcalibDButil::SmoothRelKalman(arrayTRD,mstatTRD, 0, 5.);
1092 0 : arrayTRDM= AliTPCcalibDButil::SmoothRelKalman(arrayTRD,mstatTRD, 1, 5.);
1093 0 : arrayTRDB= AliTPCcalibDButil::SmoothRelKalman(arrayTRDP,arrayTRDM);
1094 : //
1095 : //
1096 0 : Int_t entries=TMath::Max(arrayITS->GetEntriesFast(),arrayTOF->GetEntriesFast());
1097 0 : TObjArray *arrays[12]={arrayITS, arrayITSP, arrayITSM, arrayITSB,
1098 : arrayTRD, arrayTRDP, arrayTRDM, arrayTRDB,
1099 : arrayTOF, arrayTOFP, arrayTOFM, arrayTOFB};
1100 0 : TString grnames[12]={"ALIGN_ITS", "ALIGN_ITSP", "ALIGN_ITSM", "ALIGN_ITSB",
1101 0 : "ALIGN_TRD", "ALIGN_TRDP", "ALIGN_TRDM","ALIGN_TRDB",
1102 0 : "ALIGN_TOF", "ALIGN_TOFP", "ALIGN_TOFM","ALIGN_TOFB"};
1103 0 : TString grpar[9]={"DELTAPSI", "DELTATHETA", "DELTAPHI",
1104 0 : "DELTAX", "DELTAY", "DELTAZ",
1105 0 : "DRIFTVD", "T0", "VDGY"};
1106 :
1107 :
1108 0 : TVectorD vX(entries);
1109 0 : TVectorD vY(entries);
1110 0 : TVectorD vEx(entries);
1111 0 : TVectorD vEy(entries);
1112 : TObjArray *arr=0;
1113 0 : for (Int_t iarray=0; iarray<12; iarray++){
1114 0 : arr = arrays[iarray];
1115 0 : if (arr==0) continue;
1116 0 : for (Int_t ipar=0; ipar<9; ipar++){
1117 : Int_t counter=0;
1118 0 : for (Int_t itime=0; itime<arr->GetEntriesFast(); itime++){
1119 0 : AliRelAlignerKalman * kalman = (AliRelAlignerKalman *) arr->UncheckedAt(itime);
1120 0 : if (!kalman) continue;
1121 0 : vX[counter]=kalman->GetTimeStamp();
1122 0 : vY[counter]=(*(kalman->GetState()))[ipar];
1123 0 : if (ipar==6) vY[counter]=1./(*(kalman->GetState()))[ipar]-1;
1124 0 : vEx[counter]=0;
1125 0 : vEy[counter]=TMath::Sqrt((*(kalman->GetStateCov()))(ipar,ipar));
1126 0 : counter++;
1127 0 : }
1128 :
1129 0 : TGraphErrors * graph=new TGraphErrors(counter, vX.GetMatrixArray(),
1130 0 : vY.GetMatrixArray(),
1131 0 : vEx.GetMatrixArray(),
1132 0 : vEy.GetMatrixArray());
1133 0 : TString grName=grnames[iarray];
1134 0 : grName+="_TPC_";
1135 0 : grName+=grpar[ipar];
1136 0 : graph->SetName(grName.Data());
1137 0 : vdriftArray->AddLast(graph);
1138 0 : }
1139 0 : delete arrays[iarray];
1140 : }
1141 0 : }
1142 :
1143 : //_____________________________________________________________________________
1144 : void AliTPCPreprocessorOffline::AddLaserGraphs( TObjArray * vdriftArray, AliTPCcalibTime *timeDrift){
1145 : //
1146 : // add graphs for laser
1147 : //
1148 : const Double_t delayL0L1 = 0.071; //this is hack for 1/2 weeks
1149 : //THnSparse *hisN=0;
1150 0 : TGraphErrors *grLaser[6]={0,0,0,0,0,0};
1151 : //hisN = timeDrift->GetHistVdriftLaserA(0);
1152 0 : if (timeDrift->GetHistVdriftLaserA(0)){
1153 0 : grLaser[0]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserA(0),0,2,5,delayL0L1);
1154 0 : grLaser[0]->SetName("GRAPH_MEAN_DELAY_LASER_ALL_A");
1155 0 : vdriftArray->AddLast(grLaser[0]);
1156 0 : }
1157 0 : if (timeDrift->GetHistVdriftLaserA(1)){
1158 0 : grLaser[1]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserA(1),0,2,5);
1159 0 : grLaser[1]->SetName("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1160 0 : vdriftArray->AddLast(grLaser[1]);
1161 0 : }
1162 0 : if (timeDrift->GetHistVdriftLaserA(2)){
1163 0 : grLaser[2]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserA(2),0,2,5);
1164 0 : grLaser[2]->SetName("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_A");
1165 0 : vdriftArray->AddLast(grLaser[2]);
1166 0 : }
1167 0 : if (timeDrift->GetHistVdriftLaserC(0)){
1168 0 : grLaser[3]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserC(0),0,2,5,delayL0L1);
1169 0 : grLaser[3]->SetName("GRAPH_MEAN_DELAY_LASER_ALL_C");
1170 0 : vdriftArray->AddLast(grLaser[3]);
1171 0 : }
1172 0 : if (timeDrift->GetHistVdriftLaserC(1)){
1173 0 : grLaser[4]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserC(1),0,2,5);
1174 0 : grLaser[4]->SetName("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1175 0 : vdriftArray->AddLast(grLaser[4]);
1176 0 : }
1177 0 : if (timeDrift->GetHistVdriftLaserC(2)){
1178 0 : grLaser[5]=MakeGraphFilter0(timeDrift->GetHistVdriftLaserC(2),0,2,5);
1179 0 : grLaser[5]->SetName("GRAPH_MEAN_GLOBALYGRADIENT_LASER_ALL_C");
1180 0 : vdriftArray->AddLast(grLaser[5]);
1181 0 : }
1182 0 : for (Int_t i=0; i<6;i++){
1183 0 : if (grLaser[i]) {
1184 0 : SetDefaultGraphDrift(grLaser[i], 1,(i+20));
1185 0 : grLaser[i]->GetYaxis()->SetTitle("Laser Correction");
1186 0 : }
1187 : }
1188 0 : }
1189 :
1190 : //_____________________________________________________________________________
1191 : TGraphErrors * AliTPCPreprocessorOffline::MakeGraphFilter0(THnSparse *hisN, Int_t itime, Int_t ival, Int_t minEntries, Double_t offset){
1192 : //
1193 : // Make graph with mean values and rms
1194 : //
1195 0 : hisN->GetAxis(itime)->SetRange(0,100000000);
1196 0 : hisN->GetAxis(ival)->SetRange(0,100000000);
1197 0 : TH1 * hisT = hisN->Projection(itime);
1198 0 : TH1 * hisV = hisN->Projection(ival);
1199 : //
1200 0 : Int_t firstBinA = hisT->FindFirstBinAbove(2);
1201 0 : Int_t lastBinA = hisT->FindLastBinAbove(2);
1202 0 : Int_t firstBinV = hisV->FindFirstBinAbove(0);
1203 0 : Int_t lastBinV = hisV->FindLastBinAbove(0);
1204 0 : hisN->GetAxis(itime)->SetRange(firstBinA,lastBinA);
1205 0 : hisN->GetAxis(ival)->SetRange(firstBinV,lastBinV);
1206 : Int_t entries=0;
1207 0 : for (Int_t ibin=firstBinA; ibin<=lastBinA; ibin++){
1208 0 : Double_t cont = hisT->GetBinContent(ibin);
1209 0 : if (cont<minEntries) continue;
1210 0 : entries++;
1211 0 : }
1212 0 : TVectorD vecTime(entries);
1213 0 : TVectorD vecMean0(entries);
1214 0 : TVectorD vecRMS0(entries);
1215 0 : TVectorD vecMean1(entries);
1216 0 : TVectorD vecRMS1(entries);
1217 : entries=0;
1218 0 : for (Int_t ibin=firstBinA; ibin<=lastBinA; ibin++){
1219 0 : Double_t cont = hisT->GetBinContent(ibin);
1220 0 : if (cont<minEntries) continue;
1221 : //hisN->GetAxis(itime)->SetRange(ibin-1,ibin+1);
1222 0 : Int_t minBin = ibin-1;
1223 0 : Int_t maxBin = ibin+1;
1224 0 : if(minBin <= 0) minBin = 1;
1225 0 : if(maxBin >= hisN->GetAxis(itime)->GetNbins()) maxBin = hisN->GetAxis(itime)->GetNbins()-1;
1226 0 : hisN->GetAxis(itime)->SetRange(minBin,maxBin);
1227 :
1228 0 : Double_t time = hisT->GetBinCenter(ibin);
1229 0 : TH1 * his = hisN->Projection(ival);
1230 0 : Double_t nentries0= his->GetBinContent(his->FindBin(0));
1231 0 : if (cont-nentries0<minEntries) continue;
1232 : //
1233 0 : his->SetBinContent(his->FindBin(0),0);
1234 0 : vecTime[entries]=time;
1235 0 : vecMean0[entries]=his->GetMean()+offset;
1236 0 : vecMean1[entries]=his->GetMeanError();
1237 0 : vecRMS0[entries] =his->GetRMS();
1238 0 : vecRMS1[entries] =his->GetRMSError();
1239 0 : delete his;
1240 0 : entries++;
1241 0 : }
1242 0 : delete hisT;
1243 0 : delete hisV;
1244 0 : TGraphErrors * graph = new TGraphErrors(entries,vecTime.GetMatrixArray(), vecMean0.GetMatrixArray(), 0, vecMean1.GetMatrixArray());
1245 :
1246 : return graph;
1247 0 : }
1248 :
1249 : //_____________________________________________________________________________
1250 : void AliTPCPreprocessorOffline::SetDefaultGraphDrift(TGraph *graph, Int_t color, Int_t style){
1251 : //
1252 : // Set default style for QA views
1253 : //
1254 0 : graph->GetXaxis()->SetTimeDisplay(kTRUE);
1255 0 : graph->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}");
1256 0 : graph->SetMaximum( 0.025);
1257 0 : graph->SetMinimum(-0.025);
1258 0 : graph->GetXaxis()->SetTitle("Time");
1259 0 : graph->GetYaxis()->SetTitle("v_{dcorr}");
1260 : //
1261 0 : graph->GetYaxis()->SetLabelSize(0.03);
1262 0 : graph->GetXaxis()->SetLabelSize(0.03);
1263 : //
1264 0 : graph->GetXaxis()->SetNdivisions(10,5,0);
1265 0 : graph->GetYaxis()->SetNdivisions(10,5,0);
1266 : //
1267 0 : graph->GetXaxis()->SetLabelOffset(0.02);
1268 0 : graph->GetYaxis()->SetLabelOffset(0.005);
1269 : //
1270 0 : graph->GetXaxis()->SetTitleOffset(1.3);
1271 0 : graph->GetYaxis()->SetTitleOffset(1.2);
1272 : //
1273 0 : graph->SetMarkerColor(color);
1274 0 : graph->SetLineColor(color);
1275 0 : graph->SetMarkerStyle(style);
1276 0 : }
1277 :
1278 : //_____________________________________________________________________________
1279 : void AliTPCPreprocessorOffline::SetPadStyle(TPad *pad, Float_t mx0, Float_t mx1, Float_t my0, Float_t my1){
1280 : //
1281 : // Set default pad style for QA
1282 : //
1283 0 : pad->SetTicks(1,1);
1284 0 : pad->SetMargin(mx0,mx1,my0,my1);
1285 0 : }
1286 :
1287 : //_____________________________________________________________________________
1288 : void AliTPCPreprocessorOffline::MakeDefaultPlots(TObjArray * const arr, TObjArray * /*picArray*/){
1289 : //
1290 : // 0. make a default QA plots
1291 : // 1. Store them in the array
1292 : //
1293 : //
1294 : Float_t mx0=0.12, mx1=0.1, my0=0.15, my1=0.1;
1295 : //
1296 0 : TGraphErrors* laserA =(TGraphErrors*)arr->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_A");
1297 0 : TGraphErrors* laserC =(TGraphErrors*)arr->FindObject("GRAPH_MEAN_DRIFT_LASER_ALL_C");
1298 0 : TGraphErrors* cosmic =(TGraphErrors*)arr->FindObject("TGRAPHERRORS_MEAN_VDRIFT_COSMICS_ALL");
1299 0 : TGraphErrors* cross =(TGraphErrors*)arr->FindObject("TGRAPHERRORS_VDRIFT_CROSS_ALL");
1300 0 : TGraphErrors* itstpcP =(TGraphErrors*)arr->FindObject("ALIGN_ITSP_TPC_DRIFTVD");
1301 0 : TGraphErrors* itstpcM =(TGraphErrors*)arr->FindObject("ALIGN_ITSM_TPC_DRIFTVD");
1302 0 : TGraphErrors* itstpcB =(TGraphErrors*)arr->FindObject("ALIGN_ITSB_TPC_DRIFTVD");
1303 : //
1304 0 : if (laserA) SetDefaultGraphDrift(laserA,2,25);
1305 0 : if (laserC) SetDefaultGraphDrift(laserC,4,26);
1306 0 : if (cosmic) SetDefaultGraphDrift(cosmic,3,27);
1307 0 : if (cross) SetDefaultGraphDrift(cross,4,28);
1308 0 : if (itstpcP) SetDefaultGraphDrift(itstpcP,2,29);
1309 0 : if (itstpcM) SetDefaultGraphDrift(itstpcM,4,30);
1310 0 : if (itstpcB) SetDefaultGraphDrift(itstpcB,1,31);
1311 : //
1312 : //
1313 : TPad *pad=0;
1314 : //
1315 : // Laser-Laser
1316 : //
1317 0 : if (laserA&&laserC){
1318 0 : pad = new TCanvas("TPCLaserVDrift","TPCLaserVDrift");
1319 0 : laserA->Draw("alp");
1320 0 : SetPadStyle(pad,mx0,mx1,my0,my1);
1321 0 : laserA->Draw("apl");
1322 0 : laserC->Draw("p");
1323 0 : TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction");
1324 0 : legend->AddEntry(laserA,"Laser A side");
1325 0 : legend->AddEntry(laserC,"Laser C side");
1326 0 : legend->Draw();
1327 : //picArray->AddLast(pad);
1328 0 : }
1329 :
1330 0 : if (itstpcP&&itstpcM&&itstpcB){
1331 0 : pad = new TCanvas("ITSTPC","ITSTPC");
1332 0 : itstpcP->Draw("alp");
1333 0 : SetPadStyle(pad,mx0,mx1,my0,my1);
1334 0 : itstpcP->Draw("alp");
1335 0 : gPad->Clear();
1336 0 : itstpcM->Draw("apl");
1337 0 : itstpcP->Draw("p");
1338 0 : itstpcB->Draw("p");
1339 0 : TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction");
1340 0 : legend->AddEntry(itstpcP,"ITS-TPC smooth plus");
1341 0 : legend->AddEntry(itstpcM,"ITS-TPC smooth minus");
1342 0 : legend->AddEntry(itstpcB,"ITS-TPC smooth ");
1343 0 : legend->Draw();
1344 : //picArray->AddLast(pad);
1345 0 : }
1346 :
1347 0 : if (itstpcB&&laserA&&itstpcP&&itstpcM){
1348 0 : pad = new TCanvas("ITSTPC_LASER","ITSTPC_LASER");
1349 0 : SetPadStyle(pad,mx0,mx1,my0,my1);
1350 0 : laserA->Draw("alp");
1351 0 : itstpcP->Draw("p");
1352 0 : itstpcM->Draw("p");
1353 0 : itstpcB->Draw("p");
1354 0 : TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction");
1355 0 : legend->AddEntry(laserA,"TPC laser");
1356 0 : legend->AddEntry(itstpcP,"ITS-TPC smooth plus");
1357 0 : legend->AddEntry(itstpcM,"ITS-TPC smooth minus");
1358 0 : legend->AddEntry(itstpcB,"ITS-TPC smooth ");
1359 0 : legend->Draw();
1360 : //picArray->AddLast(pad);
1361 0 : }
1362 :
1363 0 : if (itstpcP&&cross){
1364 0 : pad = new TCanvas("ITSTPC_CROSS","ITSTPC_CROSS");
1365 0 : SetPadStyle(pad,mx0,mx1,my0,my1);
1366 0 : itstpcP->Draw("alp");
1367 0 : pad->Clear();
1368 0 : cross->Draw("ap");
1369 0 : itstpcP->Draw("p");
1370 : //
1371 0 : TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction");
1372 :
1373 0 : legend->AddEntry(cross,"TPC cross tracks");
1374 0 : legend->AddEntry(itstpcB,"ITS-TPC smooth");
1375 0 : legend->Draw();
1376 : //picArray->AddLast(pad);
1377 0 : }
1378 0 : if (itstpcP&&cosmic){
1379 0 : pad = new TCanvas("ITSTPC_COSMIC","ITSTPC_COSMIC");
1380 0 : SetPadStyle(pad,mx0,mx1,my0,my1);
1381 0 : itstpcP->Draw("alp");
1382 0 : pad->Clear();
1383 0 : cosmic->Draw("ap");
1384 0 : itstpcP->Draw("p");
1385 : //
1386 0 : TLegend *legend = new TLegend(mx0+0.01,1-my1-0.2, 0.5, 1-my1-0.01, "Drift velocity correction");
1387 :
1388 0 : legend->AddEntry(cosmic,"TPC cross tracks0 up-down");
1389 0 : legend->AddEntry(itstpcB,"ITS-TPC smooth");
1390 0 : legend->Draw();
1391 : //picArray->AddLast(pad);
1392 0 : }
1393 0 : }
1394 :
1395 : //_____________________________________________________________________________
1396 : void AliTPCPreprocessorOffline::CalibTimeGain(const Char_t* fileName, Int_t startRunNumber, Int_t endRunNumber, AliCDBStorage* fullStorage, AliCDBStorage* residualStorage){
1397 : //
1398 : // Update OCDB gain
1399 : // fullStorage is where the full calibration object should go
1400 : // residualStorage is where the residual calibration for QA purposes should go
1401 : //
1402 0 : if (fullStorage==0) {
1403 0 : const TString localStorage = "local://"+gSystem->GetFromPipe("pwd")+"/OCDB";
1404 0 : fullStorage = AliCDBManager::Instance()->GetStorage(localStorage.Data());
1405 0 : }
1406 0 : if ( (fGainCalibrationType==kResidualGainQA || fGainCalibrationType==kCombinedGainCalib) && residualStorage==0x0) {
1407 0 : const TString localStorage = "local://"+gSystem->GetFromPipe("pwd")+"/residualOCDB";
1408 0 : residualStorage = AliCDBManager::Instance()->GetStorage(localStorage.Data());
1409 0 : }
1410 :
1411 : // dump info
1412 0 : AliInfoF("Analyse gain from file %s", fileName);
1413 :
1414 : //
1415 : // 1. Read gain values
1416 : //
1417 0 : ReadGainGlobal(fileName);
1418 :
1419 : //
1420 : // 2. Extract calibration values
1421 : //
1422 0 : AnalyzeGain(startRunNumber,endRunNumber, 1000,1.43);
1423 0 : AnalyzeAttachment(startRunNumber,endRunNumber);
1424 0 : AnalyzePadRegionGain();
1425 0 : AnalyzeGainMultiplicity();
1426 0 : AnalyzeGainChamberByChamber();
1427 : //
1428 0 : AnalyzeGainDipAngle(0); // short pads
1429 0 : AnalyzeGainDipAngle(1); // medium pads
1430 0 : AnalyzeGainDipAngle(2); // long pads
1431 0 : AnalyzeGainDipAngle(3); // absolute calibration on full track
1432 :
1433 : //
1434 : // 2.a produce combined calibration if requested
1435 : //
1436 :
1437 : Bool_t combinedGainSuccessful=kTRUE;
1438 0 : if (fGainCalibrationType==kCombinedGainCalib) {
1439 0 : combinedGainSuccessful=ProduceCombinedGainCalibration();
1440 0 : AliInfoF("Result of combined gain calibration: %d", combinedGainSuccessful);
1441 0 : }
1442 :
1443 : //
1444 : // 3. Make control plots
1445 : //
1446 0 : MakeQAPlot(1.43);
1447 :
1448 : //
1449 : // 4. validate OCDB entries
1450 : //
1451 0 : if(fSwitchOnValidation==kTRUE &&
1452 0 : (fGainCalibrationType==kFullGainCalib || fGainCalibrationType==kCombinedGainCalib) &&
1453 0 : (!combinedGainSuccessful || !ValidateTimeGain()) ) {
1454 0 : AliWarning("TPC time gain OCDB parameters out of range!");
1455 0 : return;
1456 : }
1457 :
1458 : //
1459 : // 5. Update OCDB
1460 : //
1461 0 : if (fGainCalibrationType != kNoGainCalib ) {
1462 0 : UpdateOCDBGain( startRunNumber, endRunNumber, fullStorage, residualStorage);
1463 0 : }
1464 0 : }
1465 :
1466 : //_____________________________________________________________________________
1467 : void AliTPCPreprocessorOffline::ReadGainGlobal(const Char_t* fileName){
1468 : //
1469 : // read calibration entries from file
1470 : //
1471 0 : TFile fcalib(fileName);
1472 0 : TObject* obj = dynamic_cast<TObject*>(fcalib.Get("TPCCalib"));
1473 0 : TObjArray * array = dynamic_cast<TObjArray*>(obj);
1474 0 : TDirectory * dir = dynamic_cast<TDirectory*>(obj);
1475 0 : if (dir) {
1476 0 : fGainMIP = dynamic_cast<AliTPCcalibTimeGain *>(dir->Get("calibTimeGain"));
1477 0 : fGainCosmic = dynamic_cast<AliTPCcalibTimeGain *>(dir->Get("calibTimeGainCosmic"));
1478 0 : fGainMult = dynamic_cast<AliTPCcalibGainMult *>(dir->Get("calibGainMult"));
1479 0 : }
1480 0 : else if (array){
1481 0 : fGainMIP = ( AliTPCcalibTimeGain *)array->FindObject("calibTimeGain");
1482 0 : fGainCosmic = ( AliTPCcalibTimeGain *)array->FindObject("calibTimeGainCosmic");
1483 0 : fGainMult = ( AliTPCcalibGainMult *)array->FindObject("calibGainMult");
1484 0 : }else{
1485 0 : fGainMIP = ( AliTPCcalibTimeGain *)fcalib.Get("calibTimeGain");
1486 0 : fGainCosmic = ( AliTPCcalibTimeGain *)fcalib.Get("calibTimeGainCosmic");
1487 0 : fGainMult = ( AliTPCcalibGainMult *)fcalib.Get("calibGainMult");
1488 : }
1489 0 : if (!fGainMult){
1490 0 : TFile calibMultFile("TPCMultObjects.root");
1491 0 : fGainMult = ( AliTPCcalibGainMult *)calibMultFile.Get("calibGainMult");
1492 0 : }
1493 : TH1 * hisT=0;
1494 : Int_t firstBinA =0, lastBinA=0;
1495 :
1496 0 : if (fGainCosmic){
1497 0 : hisT= fGainCosmic->GetHistGainTime()->Projection(1);
1498 0 : firstBinA = hisT->FindFirstBinAbove(2);
1499 0 : lastBinA = hisT->FindLastBinAbove(2);
1500 0 : fGainCosmic->GetHistGainTime()->GetAxis(1)->SetRange(firstBinA,lastBinA);
1501 0 : delete hisT;
1502 : }
1503 :
1504 0 : if (fGainMIP){
1505 0 : hisT= fGainMIP->GetHistGainTime()->Projection(1);
1506 0 : firstBinA = hisT->FindFirstBinAbove(2);
1507 0 : lastBinA = hisT->FindLastBinAbove(2);
1508 0 : fGainMIP->GetHistGainTime()->GetAxis(1)->SetRange(firstBinA,lastBinA);
1509 0 : delete hisT;
1510 : }
1511 :
1512 0 : }
1513 :
1514 : //_____________________________________________________________________________
1515 : Bool_t AliTPCPreprocessorOffline::AnalyzeGain(Int_t startRunNumber, Int_t endRunNumber, Int_t minEntriesGaussFit, Float_t FPtoMIPratio){
1516 : //
1517 : // Analyze gain - produce the calibration graphs
1518 : // Uses the MIP pions integrated over all chambers, eta and multiplicity
1519 : // This provides the absolute normalization to channel 50 in the end
1520 : //
1521 : // TODO: o What happens in case the MIPs are not flat in eta, and/or multiplicity?
1522 : // In CPass0 it will not be flat.
1523 : // Can we fill the histograms flat in multiplicity?
1524 : // o Does the phi distribution play a role (inactive sector parts)?
1525 : // o In principle one could normalise over eta, by first projecting in slices
1526 : // of eta, normalize each slice and then sum
1527 : //
1528 :
1529 : // 1.) try to create MIP spline
1530 0 : if (fGainMIP)
1531 : {
1532 0 : fGainMIP->GetHistGainTime()->GetAxis(5)->SetRangeUser(startRunNumber, endRunNumber);
1533 0 : fGainMIP->GetHistGainTime()->GetAxis(2)->SetRangeUser(1.51,2.49); // only beam data
1534 0 : fGainMIP->GetHistGainTime()->GetAxis(4)->SetRangeUser(0.39,0.51); // only MIP pions
1535 :
1536 : // ---| QA histogram |---
1537 0 : if (fArrQAhist) {
1538 0 : TH2D *hQA = fGainMIP->GetHistGainTime()->Projection(0,1);
1539 0 : hQA->SetName("TGRAPHERRORS_MEAN_GAIN_BEAM_ALL_QA");
1540 0 : hQA->SetTitle("MIP calibration collisions; time;d#it{E}/d#it{x} (arb. unit)");
1541 0 : hQA->GetXaxis()->SetRangeUser(hQA->FindFirstBinAbove(1), hQA->FindLastBinAbove(1));
1542 0 : fArrQAhist->Add(hQA);
1543 0 : }
1544 :
1545 : //
1546 0 : fGraphMIP = AliTPCcalibBase::FitSlices(fGainMIP->GetHistGainTime(),0,1,minEntriesGaussFit,10,0.1,0.7);
1547 0 : if (fGraphMIP->GetN()==0) fGraphMIP = 0x0;
1548 0 : if (fGraphMIP) fFitMIP = AliTPCcalibTimeGain::MakeSplineFit(fGraphMIP);
1549 0 : if (fGraphMIP) fGraphMIP->SetName("TGRAPHERRORS_MEAN_GAIN_BEAM_ALL");// set proper names according to naming convention
1550 0 : fGainArray->AddAt(fFitMIP,0);
1551 0 : }
1552 :
1553 : // 2.) try to create Cosmic spline
1554 0 : if (fGainCosmic)
1555 : {
1556 0 : fGainCosmic->GetHistGainTime()->GetAxis(2)->SetRangeUser(0.51,1.49); // only cosmics
1557 0 : fGainCosmic->GetHistGainTime()->GetAxis(4)->SetRangeUser(20,100); // only Fermi-Plateau muons
1558 :
1559 : // ---| QA histogram |---
1560 0 : if (fArrQAhist) {
1561 0 : TH2D *hQA = fGainMIP->GetHistGainTime()->Projection(0,1);
1562 0 : hQA->SetName("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL_QA");
1563 0 : hQA->SetTitle("MIP calibration cosmics; time;d#it{E}/d#it{x} (arb. unit)");
1564 0 : hQA->GetXaxis()->SetRangeUser(hQA->FindFirstBinAbove(1), hQA->FindLastBinAbove(1));
1565 0 : fArrQAhist->Add(hQA);
1566 0 : }
1567 :
1568 : //
1569 0 : fGraphCosmic = AliTPCcalibBase::FitSlices(fGainCosmic->GetHistGainTime(),0,1,minEntriesGaussFit,10);
1570 0 : if (fGraphCosmic->GetN()==0) fGraphCosmic = 0x0;
1571 : //
1572 0 : if (fGraphCosmic) {
1573 0 : for(Int_t i=0; i < fGraphCosmic->GetN(); i++) {
1574 0 : fGraphCosmic->GetY()[i] /= FPtoMIPratio;
1575 0 : fGraphCosmic->GetEY()[i] /= FPtoMIPratio;
1576 : }
1577 0 : }
1578 : //
1579 0 : if (fGraphCosmic) fFitCosmic = AliTPCcalibTimeGain::MakeSplineFit(fGraphCosmic);
1580 0 : if (fGraphCosmic) fGraphCosmic->SetName("TGRAPHERRORS_MEAN_GAIN_COSMIC_ALL"); // set proper names according to naming convention
1581 0 : fGainArray->AddAt(fFitCosmic,1);
1582 0 : }
1583 : // with naming convention and backward compatibility
1584 0 : fGainArray->AddAt(fGraphMIP,2);
1585 0 : fGainArray->AddAt(fGraphCosmic,3);
1586 : //
1587 : // 3.) Add HV and PT correction parameterization which was used
1588 : //
1589 0 : AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
1590 0 : if (param->GetGainSlopesHV()) fGainArray->AddLast(param->GetGainSlopesHV());
1591 0 : if (param->GetGainSlopesPT()) fGainArray->AddLast(param->GetGainSlopesPT());
1592 : //
1593 : // 4.) Add the RecoParam and ClusterParam - for compatibility checks -deffrent sets of paramters can invalidate calibration
1594 : //
1595 0 : AliTPCClusterParam *clParam = AliTPCcalibDB::Instance()->GetClusterParam();
1596 0 : TObjArray *recoParams = new TObjArray(4) ;
1597 0 : for (Int_t i=0;i<4;i++) recoParams->AddAt(AliTPCcalibDB::Instance()->GetRecoParam(i),i);
1598 0 : fGainArray->AddLast(clParam);
1599 0 : fGainArray->AddLast(recoParams);
1600 : //
1601 0 : cout << "fGraphCosmic: " << fGraphCosmic << " fGraphMIP " << fGraphMIP << endl;
1602 0 : return kTRUE;
1603 :
1604 0 : }
1605 :
1606 : //_____________________________________________________________________________
1607 : Bool_t AliTPCPreprocessorOffline::AnalyzeAttachment(Int_t startRunNumber, Int_t endRunNumber, Int_t minEntriesFit) {
1608 : //
1609 : // determine slope as a function of mean driftlength
1610 : //
1611 0 : if(!fGainMIP) return kFALSE;
1612 :
1613 0 : fGainMIP->GetHistGainTime()->GetAxis(5)->SetRangeUser(startRunNumber, endRunNumber);
1614 : //
1615 0 : fGainMIP->GetHistGainTime()->GetAxis(2)->SetRangeUser(1.51,2.49); // only beam data
1616 0 : fGainMIP->GetHistGainTime()->GetAxis(4)->SetRangeUser(0.39,0.51); // only MIP pions
1617 : //
1618 0 : fGainMIP->GetHistGainTime()->GetAxis(3)->SetRangeUser(125,250);// only full tracking region (driftlength)
1619 0 : fGainMIP->GetHistGainTime()->GetAxis(0)->SetRangeUser(1.5,3.5);// only full tracking region (driftlength)
1620 : //
1621 0 : TH3D * hist = fGainMIP->GetHistGainTime()->Projection(1, 0, 3);
1622 : //
1623 0 : Double_t *xvec = new Double_t[hist->GetNbinsX()];
1624 0 : Double_t *yvec = new Double_t[hist->GetNbinsX()];
1625 0 : Double_t *xerr = new Double_t[hist->GetNbinsX()];
1626 0 : Double_t *yerr = new Double_t[hist->GetNbinsX()];
1627 : Int_t counter = 0;
1628 : //
1629 0 : for(Int_t i=1; i < hist->GetNbinsX(); i++) {
1630 : Int_t nsum=0;
1631 : Int_t imin = i;
1632 : Int_t imax = i;
1633 0 : for (Int_t idelta=0; idelta<5; idelta++){
1634 : //
1635 0 : imin = TMath::Max(i-idelta,1);
1636 0 : imax = TMath::Min(i+idelta,hist->GetNbinsX());
1637 0 : nsum = TMath::Nint(hist->Integral(imin,imax,1,hist->GetNbinsY()-1,1,hist->GetNbinsZ()-1));
1638 : //if (nsum==0) break;
1639 0 : if (nsum>minEntriesFit) break;
1640 : }
1641 0 : if (nsum<minEntriesFit) continue;
1642 : //
1643 0 : fGainMIP->GetHistGainTime()->GetAxis(1)->SetRangeUser(hist->GetXaxis()->GetBinCenter(imin-1),hist->GetXaxis()->GetBinCenter(imax+1)); // define time range
1644 0 : TH2D * histZdep = fGainMIP->GetHistGainTime()->Projection(0,3);
1645 0 : TObjArray arr;
1646 0 : histZdep->FitSlicesY(0,0,-1,0,"QNR",&arr);
1647 0 : TH1D * driftDep = (TH1D*)arr.At(1);
1648 0 : delete histZdep;
1649 : //TGraphErrors * driftDep = AliTPCcalibBase::FitSlices(fGainMIP->GetHistGainTime(),0,3,100,1,0.,1);
1650 : /*if (driftDep->GetN() < 4) {
1651 : delete driftDep;
1652 : continue;
1653 : }*/
1654 : //
1655 : //TObjArray arr;
1656 : //
1657 0 : TF1 pol1("polynom1","pol1",125,240);
1658 : //driftDep->Fit(&pol1,"QNRROB=0.8");
1659 0 : driftDep->Fit(&pol1,"QNR");
1660 0 : xvec[counter] = 0.5*(hist->GetXaxis()->GetBinCenter(imin-1)+hist->GetXaxis()->GetBinCenter(imax+1));
1661 0 : yvec[counter] = pol1.GetParameter(1)/pol1.GetParameter(0);
1662 0 : xerr[counter] = hist->GetXaxis()->GetBinCenter(imax+1)-hist->GetXaxis()->GetBinCenter(imin-1);
1663 0 : yerr[counter] = pol1.GetParError(1)/pol1.GetParameter(0);
1664 0 : counter++;
1665 : //
1666 : //delete driftDep;
1667 0 : }
1668 : //
1669 0 : fGraphAttachmentMIP = new TGraphErrors(counter, xvec, yvec, xerr, yerr);
1670 0 : if (fGraphAttachmentMIP) fGraphAttachmentMIP->SetName("TGRAPHERRORS_MEAN_ATTACHMENT_BEAM_ALL");// set proper names according to naming convention
1671 0 : fGainArray->AddLast(fGraphAttachmentMIP);
1672 : //
1673 0 : delete [] xvec;
1674 0 : delete [] yvec;
1675 0 : delete [] xerr;
1676 0 : delete [] yerr;
1677 0 : delete hist;
1678 : //
1679 0 : if (counter < 1) return kFALSE;
1680 0 : return kTRUE;
1681 :
1682 0 : }
1683 :
1684 : //_____________________________________________________________________________
1685 : Bool_t AliTPCPreprocessorOffline::AnalyzePadRegionGain(){
1686 : //
1687 : // Analyze gain for different pad regions - produce the calibration graphs 0,1,2
1688 : // Uses the MIP pions integrated over all chambers, eta and multiplicity
1689 : // TODO: o What happens in case the MIPs are not equally distributed over
1690 : // eta and multiplicity? In CPass0 neither will be flat.
1691 : // Can we fill the histograms flat in eta (and multiplicity)?
1692 : // o In principle one could normalise over eta, by first projecting in slices
1693 : // of eta, normalize each slice and then sum
1694 : //
1695 0 : if (!fGainMult) return kFALSE;
1696 :
1697 0 : THnSparseF *histPadEqual=fGainMult->GetHistPadEqual();
1698 : // histPadEqual->GetAxis(4)->SetRangeUser(.35,.65);
1699 : // TH2D * histQmaxTmp = (TH2D*) histPadEqual->Projection(0,2);
1700 : // TH2D * histQtotTmp = (TH2D*) histPadEqual->Projection(1,2);
1701 : // histQmaxTmp->SetDirectory(0);
1702 : // histQtotTmp->SetDirectory(0);
1703 : // histPadEqual->GetAxis(4)->SetRangeUser(-.65,-.35);
1704 : // TH2D * histQmax = (TH2D*) histPadEqual->Projection(0,2);
1705 : // TH2D * histQtot = (TH2D*) histPadEqual->Projection(1,2);
1706 : // histQmax->Add(histQmaxTmp);
1707 : // histQtot->Add(histQtotTmp);
1708 : // delete histQmaxTmp;
1709 : // delete histQtotTmp;
1710 0 : TH2 * histQmax = AliTPCcalibBase::NormalizedProjection(histPadEqual,0,2,4);
1711 0 : TH2 * histQtot = AliTPCcalibBase::NormalizedProjection(histPadEqual,1,2,4);
1712 :
1713 : // === old part
1714 : // TObjArray arr;
1715 : // histQmax->FitSlicesY(0,0,-1,0,"QNR",&arr);
1716 : // Double_t xMax[3] = {0,1,2};
1717 : // Double_t yMax[3] = {((TH1D*)arr.At(1))->GetBinContent(1),
1718 : // ((TH1D*)arr.At(1))->GetBinContent(2),
1719 : // ((TH1D*)arr.At(1))->GetBinContent(3)};
1720 : // Double_t yMaxErr[3] = {((TH1D*)arr.At(1))->GetBinError(1),
1721 : // ((TH1D*)arr.At(1))->GetBinError(2),
1722 : // ((TH1D*)arr.At(1))->GetBinError(3)};
1723 : // //
1724 : // histQtot->FitSlicesY(0,0,-1,0,"QNR",&arr);
1725 : // Double_t xTot[3] = {0,1,2};
1726 : // Double_t yTot[3] = {((TH1D*)arr.At(1))->GetBinContent(1),
1727 : // ((TH1D*)arr.At(1))->GetBinContent(2),
1728 : // ((TH1D*)arr.At(1))->GetBinContent(3)};
1729 : // Double_t yTotErr[3] = {((TH1D*)arr.At(1))->GetBinError(1),
1730 : // ((TH1D*)arr.At(1))->GetBinError(2),
1731 : // ((TH1D*)arr.At(1))->GetBinError(3)};
1732 : // Double_t truncationFactor=AliTPCcalibGainMult::GetTruncatedMeanPosition(yTot[0],yTot[1],yTot[2],1000);
1733 : // for (Int_t i=0;i<3; i++){
1734 : // yMax[i]*=truncationFactor;
1735 : // yTot[i]*=truncationFactor;
1736 : // }
1737 : //
1738 : // TGraphErrors * fitPadRegionQmax = new TGraphErrors(3, xMax, yMax, 0, yMaxErr);
1739 : // TGraphErrors * fitPadRegionQtot = new TGraphErrors(3, xTot, yTot, 0, yTotErr);
1740 : // ^^^ End old part
1741 :
1742 : // histQmax->GetXaxis()->SetRange(1,3);
1743 : // histQtot->GetXaxis()->SetRange(1,3);
1744 0 : TGraphErrors *fitPadRegionQmax = AliTPCcalibBase::FitSlices(histQmax,200,1,.15,.85);
1745 0 : TGraphErrors *fitPadRegionQtot = AliTPCcalibBase::FitSlices(histQtot,200,1,.15,.85);
1746 0 : histQmax->GetXaxis()->SetRange(0,-1);
1747 0 : histQtot->GetXaxis()->SetRange(0,-1);
1748 0 : fitPadRegionQmax->RemovePoint(3);
1749 0 : fitPadRegionQtot->RemovePoint(3);
1750 :
1751 0 : Double_t *yMax =fitPadRegionQmax->GetY();
1752 0 : Double_t *yTot =fitPadRegionQtot->GetY();
1753 0 : Double_t *eyMax=fitPadRegionQmax->GetEY();
1754 0 : Double_t *eyTot=fitPadRegionQtot->GetEY();
1755 0 : Double_t truncationFactorMax=AliTPCcalibGainMult::GetTruncatedMeanPosition(yMax[0],yMax[1],yMax[2],1000);
1756 0 : Double_t truncationFactorTot=AliTPCcalibGainMult::GetTruncatedMeanPosition(yTot[0],yTot[1],yTot[2],1000);
1757 :
1758 0 : if (truncationFactorMax>0) {
1759 0 : for (Int_t i=0;i<3; i++){
1760 0 : yMax[i] /=truncationFactorMax;
1761 0 : eyMax[i]/=truncationFactorMax;
1762 : }
1763 0 : }
1764 : else {
1765 0 : AliError("truncationFactorMax<=0, could not normalize");
1766 : }
1767 :
1768 0 : if (truncationFactorTot>0) {
1769 0 : for (Int_t i=0;i<3; i++){
1770 0 : yTot[i] /=truncationFactorTot;
1771 0 : eyTot[i]/=truncationFactorTot;
1772 : }
1773 0 : }
1774 : else {
1775 0 : AliError("truncationFactorTot<=0, could not normalize");
1776 : }
1777 :
1778 : //
1779 0 : fitPadRegionQtot->SetName("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL");// set proper names according to naming convention
1780 0 : fitPadRegionQmax->SetName("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL");// set proper names according to naming convention
1781 : //
1782 0 : fGainArray->AddLast(fitPadRegionQtot);
1783 0 : fGainArray->AddLast(fitPadRegionQmax);
1784 :
1785 : // ---| QA histograms |---
1786 0 : if (fArrQAhist) {
1787 : // --- Qmax ---
1788 0 : histQmax->SetName("TGRAPHERRORS_MEANQMAX_PADREGIONGAIN_BEAM_ALL_QA");
1789 0 : histQmax->SetTitle("Pad region calibration Q_{max}; pad region;d#it{E}/d#it{x}_{Qmax} (arb. unit)");
1790 0 : fArrQAhist->Add(histQmax);
1791 :
1792 : // --- Qtot ---
1793 0 : histQtot->SetName("TGRAPHERRORS_MEANQTOT_PADREGIONGAIN_BEAM_ALL_QA");
1794 0 : histQtot->SetTitle("Pad region calibration Q_{tot}; pad region;d#it{E}/d#it{x}_{Qtot} (arb. unit)");
1795 0 : fArrQAhist->Add(histQtot);
1796 :
1797 0 : } else {
1798 0 : delete histQmax;
1799 0 : delete histQtot;
1800 : }
1801 :
1802 : return kTRUE;
1803 0 : }
1804 :
1805 : //_____________________________________________________________________________
1806 : Bool_t AliTPCPreprocessorOffline::AnalyzeGainDipAngle(Int_t padRegion) {
1807 : //
1808 : // Analyze gain as a function of multiplicity and produce calibration graphs
1809 : // padRegion -- 0: short, 1: medium, 2: long, 3: absolute calibration of full track
1810 : // Uses the MIP pions integrated over all chambers and multiplicity
1811 : // Noramlisation is done to the mean of the slices fit (i.e. tan(lambda)=0.5)
1812 : //
1813 : // TODO: What happens in case the MIPs are not equally distributed over
1814 : // multiplicity? In CPass0 it will not be flat.
1815 : // Can we fill the histograms flat in multiplicity?
1816 : //
1817 0 : Int_t kMarkers[10]={25,24,20,21,22};
1818 0 : Int_t kColors[10]={1,2,4,3,6};
1819 0 : if (!fGainMult) return kFALSE;
1820 0 : if (!(fGainMult->GetHistTopology())) return kFALSE;
1821 : const Double_t kMinStat=100;
1822 : //
1823 : // "dEdxRatioMax","dEdxRatioTot","padType","mult","driftlength"
1824 0 : TObjArray arrMax;
1825 0 : TObjArray arrTot;
1826 : //
1827 : TH2D * histQmax = 0x0;
1828 : TH2D * histQtot = 0x0;
1829 0 : fGainMult->GetHistPadEqual()->GetAxis(4)->SetRangeUser(-0.85,0.85);
1830 0 : fGainMult->GetHistTopology()->GetAxis(2)->SetRangeUser(-0.85,0.85);
1831 0 : if (padRegion < 3) {
1832 0 : fGainMult->GetHistPadEqual()->GetAxis(2)->SetRangeUser(padRegion,padRegion); // short,medium,long
1833 0 : histQmax = (TH2D*) fGainMult->GetHistPadEqual()->Projection(0,4);
1834 0 : histQtot = (TH2D*) fGainMult->GetHistPadEqual()->Projection(1,4);
1835 0 : } else {
1836 0 : fGainMult->GetHistTopology()->GetAxis(1)->SetRangeUser(1,1); //Qmax
1837 0 : histQmax = (TH2D*) fGainMult->GetHistTopology()->Projection(0,2);
1838 0 : histQmax->SetName("fGainMult_GetHistPadEqual_11");
1839 0 : fGainMult->GetHistTopology()->GetAxis(1)->SetRangeUser(0,0); //Qtot
1840 0 : histQtot = (TH2D*) fGainMult->GetHistTopology()->Projection(0,2);
1841 0 : histQtot->SetName("fGainMult_GetHistPadEqual_00");
1842 : }
1843 : //
1844 :
1845 0 : if (histQmax->GetEntries()<=kMinStat || histQtot->GetEntries()<=kMinStat) {
1846 0 : AliError(Form("hisQtot.GetEntries()=%f",histQtot->GetEntries()));
1847 0 : AliError(Form("hisQmax.GetEntries()=%f",histQmax->GetEntries()));
1848 0 : return kFALSE;
1849 : }
1850 :
1851 : // TGraphErrors * graphMax = TStatToolkit::MakeStat1D( histQmax,0,0.8,4,kMarkers[padRegion],kColors[padRegion]);
1852 : // TGraphErrors * graphTot = TStatToolkit::MakeStat1D( histQtot,0,0.8,4,kMarkers[padRegion],kColors[padRegion]);
1853 0 : TGraphErrors * graphMax = TStatToolkit::MakeStat1D( histQmax,0,0.9,6,kMarkers[padRegion],kColors[padRegion]);
1854 0 : TGraphErrors * graphTot = TStatToolkit::MakeStat1D( histQtot,0,0.9,6,kMarkers[padRegion],kColors[padRegion]);
1855 :
1856 : //
1857 0 : const char* names[4]={"SHORT","MEDIUM","LONG","ABSOLUTE"};
1858 : //
1859 0 : const Double_t meanMax = TMath::Mean(graphMax->GetN(), graphMax->GetY());
1860 0 : const Double_t meanTot = TMath::Mean(graphTot->GetN(), graphTot->GetY());
1861 :
1862 : // ---| QA histograms |---
1863 0 : if (fArrQAhist) {
1864 : // --- Qmax ---
1865 0 : histQmax->SetName(Form("TGRAPHERRORS_QMAX_DIPANGLE_%s_BEAM_ALL_QA",names[padRegion]));
1866 0 : histQmax->SetTitle(Form("tan(#lambda) calibration Q_{max} %s; tan(#lambda);d#it{E}/d#it{x}_{Qmax} (arb. unit)",names[padRegion]));
1867 0 : fArrQAhist->Add(histQmax);
1868 :
1869 : // --- Qtot ---
1870 0 : histQtot->SetName(Form("TGRAPHERRORS_QTOT_DIPANGLE_%s_BEAM_ALL_QA",names[padRegion]));
1871 0 : histQtot->SetTitle(Form("tan(#lambda) calibration Q_{tot} %s; tan(#lambda);d#it{E}/d#it{x}_{Qtot} (arb. unit)",names[padRegion]));
1872 0 : fArrQAhist->Add(histQtot);
1873 :
1874 : // ---| scale to mean multiplicity |---
1875 0 : if(fNormaliseQA && meanMax>0) {
1876 0 : TAxis *a=histQmax->GetYaxis();
1877 0 : a->SetLimits(a->GetXmin()/meanMax, a->GetXmax()/meanMax);
1878 0 : }
1879 0 : if(fNormaliseQA && meanTot>0) {
1880 0 : TAxis *a=histQtot->GetYaxis();
1881 0 : a->SetLimits(a->GetXmin()/meanTot, a->GetXmax()/meanTot);
1882 0 : }
1883 :
1884 : } else {
1885 0 : delete histQmax;
1886 0 : delete histQtot;
1887 : }
1888 :
1889 : //
1890 0 : if (meanMax<=0 || meanTot<=0){
1891 0 : AliError(Form("meanMax=%f",meanMax));
1892 0 : AliError(Form("meanTot=%f",meanTot));
1893 0 : return kFALSE;
1894 : }
1895 : //
1896 0 : for (Int_t ipoint=0; ipoint<graphMax->GetN(); ipoint++) {
1897 0 : graphMax->GetY()[ipoint]/=meanMax;
1898 0 : graphMax->GetEY()[ipoint]/=meanMax;
1899 : }
1900 0 : for (Int_t ipoint=0; ipoint<graphTot->GetN(); ipoint++) {
1901 0 : graphTot->GetY()[ipoint]/=meanTot;
1902 0 : graphTot->GetEY()[ipoint]/=meanTot;
1903 : }
1904 : //
1905 0 : graphMax->SetNameTitle(Form("TGRAPHERRORS_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
1906 0 : Form("TGRAPHERRORS_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
1907 0 : graphTot->SetNameTitle(Form("TGRAPHERRORS_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
1908 0 : Form("TGRAPHERRORS_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
1909 : //
1910 0 : fGainArray->AddLast(graphMax);
1911 0 : fGainArray->AddLast(graphTot);
1912 : //
1913 : // Normalization to 1 (mean of the graph.fY --> 1)
1914 : //
1915 0 : TF1 * funMax= new TF1("","1++abs(x)++abs(x*x)");
1916 0 : TF1 * funTot= new TF1("","1++abs(x)++abs(x*x)");
1917 0 : graphMax->Fit(funMax,"w","rob=0.9",-0.8,0.8);
1918 0 : graphTot->Fit(funTot,"w","rob=0.9",-0.8,0.8);
1919 0 : funMax->SetNameTitle(Form("TF1_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
1920 0 : Form("TF1_QMAX_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
1921 0 : funTot->SetNameTitle(Form("TF1_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]),
1922 0 : Form("TF1_QTOT_DIPANGLE_%s_BEAM_ALL",names[padRegion]));
1923 :
1924 : //
1925 0 : fGainArray->AddLast(funMax);
1926 0 : fGainArray->AddLast(funTot);
1927 : //
1928 : return kTRUE;
1929 0 : }
1930 :
1931 : //_____________________________________________________________________________
1932 : Bool_t AliTPCPreprocessorOffline::AnalyzeGainMultiplicity() {
1933 : //
1934 : // Analyze gain as a function of multiplicity and produce calibration graphs
1935 : // Uses the MIP pions integrated over all chambers and eta
1936 : // Noramlisation is done to the mean of the slices fit (i.e. sector average)
1937 : //
1938 : // TODO: o What happens in case the MIPs are not flat in eta?
1939 : // In CPass0 it will not be flat.
1940 : // Can we fill the histograms flat in multiplicity?
1941 : // o Is it better to use the median in case one chamber fit fails?
1942 : // o The gain mult does not have tan(lambda) as dim
1943 : //
1944 0 : if (!fGainMult) return kFALSE;
1945 0 : fGainMult->GetHistGainMult()->GetAxis(3)->SetRangeUser(3,3);
1946 0 : TH2D * histMultMax = fGainMult->GetHistGainMult()->Projection(0,4);
1947 0 : TH2D * histMultTot = fGainMult->GetHistGainMult()->Projection(1,4);
1948 0 : histMultMax->RebinX(4);
1949 0 : histMultTot->RebinX(4);
1950 : //
1951 0 : TObjArray arrMax;
1952 0 : TObjArray arrTot;
1953 0 : TF1 fitGaus("fitGaus","gaus(0)",histMultMax->GetYaxis()->GetXmin(),histMultMax->GetYaxis()->GetXmax());
1954 0 : fitGaus.SetParameters(histMultMax->GetEntries()/10., histMultMax->GetMean(2), TMath::Sqrt(TMath::Abs(histMultMax->GetMean(2))));
1955 0 : histMultMax->FitSlicesY(&fitGaus,0,-1,1,"QNRB",&arrMax);
1956 0 : fitGaus.SetParameters(histMultTot->GetEntries()/10., histMultTot->GetMean(2), TMath::Sqrt(TMath::Abs(histMultTot->GetMean(2))));
1957 0 : histMultTot->FitSlicesY(&fitGaus,0,-1,1,"QNRB",&arrTot);
1958 : //
1959 0 : TH1D * meanMax = (TH1D*)arrMax.At(1);
1960 0 : TH1D * meanTot = (TH1D*)arrTot.At(1);
1961 0 : Float_t meanMult = histMultMax->GetMean();
1962 0 : const Double_t qMaxCont=meanMax->GetBinContent(meanMax->FindBin(meanMult));
1963 0 : const Double_t qTotCont=meanTot->GetBinContent(meanTot->FindBin(meanMult));
1964 :
1965 : // ---| QA histograms |---
1966 0 : if (fArrQAhist) {
1967 : // --- Qmax ---
1968 0 : histMultMax->SetName("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL_QA");
1969 0 : histMultMax->SetTitle("Multiplicity correction Q_{max};#ESD tracks;d#it{E}/d#it{x}_{Qmax} (arb. unit)");
1970 0 : fArrQAhist->Add(histMultMax);
1971 :
1972 : // --- Qtot ---
1973 0 : histMultTot->SetName("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL_QA");
1974 0 : histMultTot->SetTitle("Multiplicity correction Q_{tot};#ESD tracks;d#it{E}/d#it{x}_{Qtot} (arb. unit)");
1975 0 : fArrQAhist->Add(histMultTot);
1976 :
1977 : // ---| scale to mean multiplicity |---
1978 0 : if(fNormaliseQA && qMaxCont>0) {
1979 0 : TAxis *a=histMultMax->GetYaxis();
1980 0 : a->SetLimits(a->GetXmin()/qMaxCont, a->GetXmax()/qMaxCont);
1981 0 : }
1982 0 : if(fNormaliseQA && qTotCont>0) {
1983 0 : TAxis *a=histMultTot->GetYaxis();
1984 0 : a->SetLimits(a->GetXmin()/qTotCont, a->GetXmax()/qTotCont);
1985 0 : }
1986 :
1987 : } else {
1988 0 : delete histMultMax;
1989 0 : delete histMultTot;
1990 : }
1991 :
1992 : // ---| scale to mean multiplicity |---
1993 0 : if(qMaxCont) {
1994 0 : meanMax->Scale(1./qMaxCont);
1995 : }
1996 : else {
1997 0 : return kFALSE;
1998 : }
1999 0 : if(qTotCont) {
2000 0 : meanTot->Scale(1./qTotCont);
2001 : }
2002 : else {
2003 0 : return kFALSE;
2004 : }
2005 0 : Float_t xMultMax[50];
2006 0 : Float_t yMultMax[50];
2007 0 : Float_t yMultErrMax[50];
2008 0 : Float_t xMultTot[50];
2009 0 : Float_t yMultTot[50];
2010 0 : Float_t yMultErrTot[50];
2011 : //
2012 : Int_t nCountMax = 0;
2013 0 : for(Int_t iBin = 1; iBin < meanMax->GetXaxis()->GetNbins(); iBin++) {
2014 0 : Float_t yValMax = meanMax->GetBinContent(iBin);
2015 0 : if (yValMax < 0.7) continue;
2016 0 : if (yValMax > 1.3) continue;
2017 0 : if (meanMax->GetBinError(iBin)/yValMax > 0.01) continue;
2018 0 : xMultMax[nCountMax] = meanMax->GetXaxis()->GetBinCenter(iBin);
2019 0 : yMultMax[nCountMax] = yValMax;
2020 0 : yMultErrMax[nCountMax] = meanMax->GetBinError(iBin);
2021 0 : nCountMax++;
2022 0 : }
2023 : //
2024 0 : if (nCountMax < 10) return kFALSE;
2025 0 : TGraphErrors * fitMultMax = new TGraphErrors(nCountMax, xMultMax, yMultMax, 0, yMultErrMax);
2026 0 : fitMultMax->SetName("TGRAPHERRORS_MEANQMAX_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2027 : //
2028 : Int_t nCountTot = 0;
2029 0 : for(Int_t iBin = 1; iBin < meanTot->GetXaxis()->GetNbins(); iBin++) {
2030 0 : Float_t yValTot = meanTot->GetBinContent(iBin);
2031 0 : if (yValTot < 0.7) continue;
2032 0 : if (yValTot > 1.3) continue;
2033 0 : if (meanTot->GetBinError(iBin)/yValTot > 0.1) continue;
2034 0 : xMultTot[nCountTot] = meanTot->GetXaxis()->GetBinCenter(iBin);
2035 0 : yMultTot[nCountTot] = yValTot;
2036 0 : yMultErrTot[nCountTot] = meanTot->GetBinError(iBin);
2037 0 : nCountTot++;
2038 0 : }
2039 : //
2040 0 : if (nCountTot < 10) return kFALSE;
2041 0 : TGraphErrors * fitMultTot = new TGraphErrors(nCountTot, xMultTot, yMultTot, 0, yMultErrTot);
2042 0 : fitMultTot->SetName("TGRAPHERRORS_MEANQTOT_MULTIPLICITYDEPENDENCE_BEAM_ALL");
2043 : //
2044 0 : fGainArray->AddLast(fitMultMax);
2045 0 : fGainArray->AddLast(fitMultTot);
2046 : //
2047 : return kTRUE;
2048 :
2049 0 : }
2050 :
2051 : //_____________________________________________________________________________
2052 : Bool_t AliTPCPreprocessorOffline::AnalyzeGainChamberByChamber(){
2053 : //
2054 : // get chamber by chamber gain
2055 : //
2056 0 : if (!fGainMult) return kFALSE;
2057 0 : TGraphErrors *grShort = fGainMult->GetGainPerChamberRobust(0, kFALSE, fArrQAhist, fNormaliseQA);
2058 0 : TGraphErrors *grMedium = fGainMult->GetGainPerChamberRobust(1, kFALSE, fArrQAhist, fNormaliseQA);
2059 0 : TGraphErrors *grLong = fGainMult->GetGainPerChamberRobust(2, kFALSE, fArrQAhist, fNormaliseQA);
2060 0 : if (grShort==0x0 || grMedium==0x0 || grLong==0x0) {
2061 0 : delete grShort;
2062 0 : delete grMedium;
2063 0 : delete grLong;
2064 0 : return kFALSE;
2065 : }
2066 :
2067 0 : fGainArray->AddLast(grShort);
2068 0 : fGainArray->AddLast(grMedium);
2069 0 : fGainArray->AddLast(grLong);
2070 :
2071 0 : return kTRUE;
2072 0 : }
2073 :
2074 : //_____________________________________________________________________________
2075 : void AliTPCPreprocessorOffline::UpdateOCDBGain(Int_t startRunNumber, Int_t endRunNumber, AliCDBStorage *fullStorage, AliCDBStorage* residualStorage/*=0x0*/)
2076 : {
2077 : //
2078 : // Update OCDB entry
2079 : //
2080 0 : AliCDBMetaData *metaData= new AliCDBMetaData();
2081 0 : metaData->SetObjectClassName("TObjArray");
2082 0 : metaData->SetResponsible("Jens Wiechula");
2083 0 : metaData->SetBeamPeriod(1);
2084 0 : metaData->SetAliRootVersion("05-24-00"); //root version
2085 0 : metaData->SetComment("Calibration of the time dependence of the gain due to pressure and temperature changes.");
2086 0 : AliCDBId id1("TPC/Calib/TimeGain", startRunNumber, endRunNumber);
2087 0 : if (fGainCalibrationType==kFullGainCalib) {
2088 0 : AliInfoF("Writing gain calibration object to the full storage: %s", fullStorage->GetURI().Data());
2089 0 : fullStorage->Put(fGainArray, id1, metaData);
2090 : }
2091 0 : else if (fGainCalibrationType==kResidualGainQA) {
2092 0 : AliInfoF("Writing gain calibration object to the residual storage: %s", residualStorage->GetURI().Data());
2093 0 : residualStorage->Put(fGainArray, id1, metaData);
2094 : }
2095 0 : else if (fGainCalibrationType==kCombinedGainCalib) {
2096 0 : if (residualStorage){
2097 0 : AliInfoF("Writing residual gain calibration object to the residual storage: %s", residualStorage->GetURI().Data());
2098 0 : residualStorage->Put(fGainArray, id1, metaData);
2099 : }
2100 : else {
2101 0 : AliError("No residual storage set, but calibration type is combined + residual QA");
2102 : }
2103 :
2104 : // write the combined calibration after the residual calibration to make sure this is the
2105 : // latest object in case fullStorage and residualStorage are identical
2106 0 : AliInfoF("Writing combined gain calibration object to the full storage: %s", fullStorage->GetURI().Data());
2107 0 : fullStorage->Put(fGainArrayCombined, id1, metaData);
2108 : }
2109 : else {
2110 0 : AliFatalF("Unsupported gain calibration type: %d", Int_t(fGainCalibrationType));
2111 : }
2112 0 : }
2113 :
2114 : //_____________________________________________________________________________
2115 : void AliTPCPreprocessorOffline::MakeQAPlot(Float_t FPtoMIPratio) {
2116 : //
2117 : // Make QA plot to visualize results
2118 : //
2119 : //
2120 : //
2121 0 : if (fGraphCosmic) {
2122 0 : TCanvas * canvasCosmic = new TCanvas("gain Cosmic", "time dependent gain QA histogram cosmic");
2123 0 : canvasCosmic->cd();
2124 0 : TH2D * gainHistoCosmic = fGainCosmic->GetHistGainTime()->Projection(0,1);
2125 0 : gainHistoCosmic->SetDirectory(0);
2126 0 : gainHistoCosmic->SetName("GainHistoCosmic");
2127 0 : gainHistoCosmic->GetXaxis()->SetTimeDisplay(kTRUE);
2128 0 : gainHistoCosmic->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}");
2129 0 : gainHistoCosmic->Draw("colz");
2130 0 : fGraphCosmic->SetMarkerStyle(25);
2131 0 : fGraphCosmic->Draw("lp");
2132 0 : fGraphCosmic->SetMarkerStyle(25);
2133 0 : TGraph * grfFitCosmic = fFitCosmic->MakeGraph(fGraphCosmic->GetX()[0],fGraphCosmic->GetX()[fGraphCosmic->GetN()-1],50000,0);
2134 0 : if (grfFitCosmic) {
2135 0 : for(Int_t i=0; i < grfFitCosmic->GetN(); i++) {
2136 0 : grfFitCosmic->GetY()[i] *= FPtoMIPratio;
2137 : }
2138 0 : for(Int_t i=0; i < fGraphCosmic->GetN(); i++) {
2139 0 : fGraphCosmic->GetY()[i] *= FPtoMIPratio;
2140 : }
2141 0 : }
2142 0 : fGraphCosmic->Draw("lp");
2143 0 : if (grfFitCosmic) {
2144 0 : grfFitCosmic->SetLineColor(2);
2145 0 : grfFitCosmic->Draw("lu");
2146 0 : }
2147 0 : fGainArray->AddLast(gainHistoCosmic);
2148 : //fGainArray->AddLast(canvasCosmic->Clone());
2149 0 : delete canvasCosmic;
2150 0 : }
2151 0 : if (fFitMIP) {
2152 0 : TCanvas * canvasMIP = new TCanvas("gain MIP", "time dependent gain QA histogram MIP");
2153 0 : canvasMIP->cd();
2154 0 : TH2D * gainHistoMIP = fGainMIP->GetHistGainTime()->Projection(0,1);
2155 0 : gainHistoMIP->SetName("GainHistoCosmic");
2156 0 : gainHistoMIP->SetDirectory(0);
2157 0 : gainHistoMIP->GetXaxis()->SetTimeDisplay(kTRUE);
2158 0 : gainHistoMIP->GetXaxis()->SetTimeFormat("#splitline{%d/%m}{%H:%M}");
2159 0 : gainHistoMIP->Draw("colz");
2160 0 : fGraphMIP->SetMarkerStyle(25);
2161 0 : fGraphMIP->Draw("lp");
2162 0 : TGraph * grfFitMIP = fFitMIP->MakeGraph(fGraphMIP->GetX()[0],fGraphMIP->GetX()[fGraphMIP->GetN()-1],50000,0);
2163 0 : grfFitMIP->SetLineColor(2);
2164 0 : grfFitMIP->Draw("lu");
2165 0 : fGainArray->AddLast(gainHistoMIP);
2166 : //fGainArray->AddLast(canvasMIP->Clone());
2167 0 : delete canvasMIP;
2168 0 : delete grfFitMIP;
2169 0 : }
2170 0 : }
2171 :
2172 : //_____________________________________________________________________________
2173 : void AliTPCPreprocessorOffline::MakeFitTime(){
2174 : //
2175 : // make aligment fit - store results in the file
2176 : //
2177 : const Int_t kMinEntries=1000;
2178 0 : MakeChainTime();
2179 0 : MakePrimitivesTime();
2180 0 : if (!fAlignTree) return;
2181 0 : if (fAlignTree->GetEntries()<kMinEntries) return;
2182 0 : fAlignTree->SetAlias("ptype","type");
2183 0 : fAlignTree->SetAlias("hasITS","(1+0)");
2184 0 : fAlignTree->SetAlias("dITS","1-2*(refX<40)");
2185 0 : fAlignTree->SetAlias("isITS","refX>10");
2186 0 : fAlignTree->SetAlias("isVertex","refX<10");
2187 : //
2188 : Int_t npointsMax=30000000;
2189 0 : Double_t chi2=0;
2190 0 : Int_t npoints=0;
2191 0 : TVectorD param;
2192 0 : TMatrixD covar;
2193 :
2194 0 : TString fstringFast="";
2195 0 : fstringFast+="FExBTwistX++";
2196 0 : fstringFast+="FExBTwistY++";
2197 0 : fstringFast+="FAlignRot0D++";
2198 0 : fstringFast+="FAlignTrans0D++";
2199 0 : fstringFast+="FAlignTrans1D++";
2200 : //
2201 0 : fstringFast+="hasITS*FAlignTrans0++";
2202 0 : fstringFast+="hasITS*FAlignTrans1++";
2203 0 : fstringFast+="hasITS*FAlignRot0++";
2204 0 : fstringFast+="hasITS*FAlignRot1++";
2205 0 : fstringFast+="hasITS*FAlignRot2++";
2206 : //
2207 0 : fstringFast+="dITS*FAlignTrans0++";
2208 0 : fstringFast+="dITS*FAlignTrans1++";
2209 0 : fstringFast+="dITS*FAlignRot0++";
2210 0 : fstringFast+="dITS*FAlignRot1++";
2211 0 : fstringFast+="dITS*FAlignRot2++";
2212 :
2213 0 : TCut cutFit="entries>10&&abs(mean)>0.00001&&rms>0";
2214 0 : fAlignTree->SetAlias("err","rms");
2215 :
2216 0 : TString *strDeltaITS = TStatToolkit::FitPlaneConstrain(fAlignTree,"mean:err", fstringFast.Data(),cutFit, chi2,npoints,param,covar,-1,0, npointsMax, 1);
2217 0 : TObjArray* tokArr = strDeltaITS->Tokenize("++");
2218 0 : static bool verboseOutput = !(getenv("HLT_ONLINE_MODE") && strcmp(getenv("HLT_ONLINE_MODE"), "on") == 0);
2219 0 : if (verboseOutput) tokArr->Print();
2220 0 : delete tokArr;
2221 0 : fAlignTree->SetAlias("fitYFast",strDeltaITS->Data());
2222 0 : delete strDeltaITS;
2223 :
2224 : //
2225 0 : TVectorD paramC= param;
2226 0 : TMatrixD covarC= covar;
2227 0 : TStatToolkit::Constrain1D(fstringFast,"Trans0D",paramC,covarC,0, 0.1);
2228 0 : TStatToolkit::Constrain1D(fstringFast,"Trans1D",paramC,covarC,0, 0.1);
2229 0 : TStatToolkit::Constrain1D(fstringFast,"TwistX",paramC,covarC,0, 0.1);
2230 0 : TStatToolkit::Constrain1D(fstringFast,"TwistY",paramC,covarC,0, 0.1);
2231 0 : TString strFitConst=TStatToolkit::MakeFitString(fstringFast, paramC,covar);
2232 0 : fAlignTree->SetAlias("fitYFastC",strFitConst.Data());
2233 0 : CreateAlignTime(fstringFast,paramC);
2234 :
2235 0 : }
2236 :
2237 : //_____________________________________________________________________________
2238 : void AliTPCPreprocessorOffline::MakeChainTime(){
2239 : //
2240 : //
2241 : //
2242 0 : TFile f("CalibObjects.root");
2243 :
2244 : // const char *cdtype[7]={"ITS","TRD","Vertex","TOF","TPC","TPC0","TPC1"};
2245 : //const char *cptype[5]={"dy","dz","dsnp","dtheta","d1pt"};
2246 0 : const char * hname[5]={"dy","dz","dsnp","dtheta","d1pt"};
2247 : Int_t run=0;
2248 : AliTPCcalibTime *calibTime = 0;
2249 0 : TObject* obj = dynamic_cast<TObject*>(f.Get("TPCCalib"));
2250 0 : TObjArray * array = dynamic_cast<TObjArray*>(obj);
2251 0 : TDirectory * dir = dynamic_cast<TDirectory*>(obj);
2252 0 : if (dir) {
2253 0 : calibTime = dynamic_cast<AliTPCcalibTime*>(dir->Get("calibTime"));
2254 0 : }
2255 0 : else if (array){
2256 0 : calibTime = (AliTPCcalibTime *)array->FindObject("calibTime");
2257 0 : } else {
2258 0 : calibTime = (AliTPCcalibTime*)f.Get("calibTime");
2259 : }
2260 0 : if (!calibTime) return;
2261 0 : AliTPCCorrectionFit::CreateAlignMaps(AliTracker::GetBz(), run);
2262 0 : TTreeSRedirector *pcstream = new TTreeSRedirector("meanITSVertex.root");
2263 : //
2264 : Int_t ihis=0;
2265 0 : THnSparse *his = calibTime->GetResHistoTPCITS(ihis);
2266 0 : if (his){
2267 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2268 0 : his->GetAxis(2)->SetRange(0,1000000);
2269 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2270 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("ITS%s",hname[ihis]),run,85.,ihis,3);
2271 : }
2272 : ihis=1;
2273 0 : his = calibTime->GetResHistoTPCITS(ihis);
2274 0 : if (his){
2275 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2276 0 : his->GetAxis(2)->SetRange(0,1000000);
2277 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2278 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("ITS%s",hname[ihis]),run,85.,ihis,3);
2279 : }
2280 : ihis=2;
2281 0 : his = calibTime->GetResHistoTPCITS(ihis);
2282 0 : if (his){
2283 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2284 0 : his->GetAxis(2)->SetRange(0,1000000);
2285 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2286 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("ITS%s",hname[ihis]),run,85.,ihis,3);
2287 : }
2288 : ihis=0;
2289 0 : his = calibTime->GetResHistoTPCvertex(ihis);
2290 0 : if (his){
2291 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2292 0 : his->GetAxis(2)->SetRange(0,1000000);
2293 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2294 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("Vertex%s",hname[ihis]),run,0.,ihis,3);
2295 : }
2296 : ihis=2;
2297 0 : his = calibTime->GetResHistoTPCvertex(ihis);
2298 0 : if (his){
2299 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2300 0 : his->GetAxis(2)->SetRange(0,1000000);
2301 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2302 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("Vertex%s",hname[ihis]),run,0.,ihis,3);
2303 :
2304 : }
2305 : ihis=1;
2306 0 : his = calibTime->GetResHistoTPCvertex(ihis);
2307 0 : if (his){
2308 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2309 0 : his->GetAxis(2)->SetRange(0,1000000);
2310 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2311 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("Vertex%s",hname[ihis]),run,0.,ihis,3);
2312 :
2313 : }
2314 : ihis=0;
2315 0 : his = calibTime->GetResHistoTPCTOF(ihis);
2316 0 : if (his){
2317 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2318 0 : his->GetAxis(2)->SetRange(0,1000000);
2319 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2320 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("TOF%s",hname[ihis]),run,0.,ihis,3);
2321 :
2322 : }
2323 : ihis=0;
2324 0 : his = calibTime->GetResHistoTPCTRD(ihis);
2325 0 : if (his){
2326 0 : his->GetAxis(1)->SetRangeUser(-1.1,1.1);
2327 0 : his->GetAxis(2)->SetRange(0,1000000);
2328 0 : his->GetAxis(3)->SetRangeUser(-0.35,0.35);
2329 0 : AliTPCCorrection::MakeDistortionMap(his,pcstream, Form("TRD%s",hname[ihis]),run,0.,ihis,3);
2330 :
2331 : }
2332 0 : if (dir || (!dir && !array)) { // the object is taken from a directory or a file
2333 0 : delete calibTime;
2334 : }
2335 0 : delete pcstream;
2336 0 : }
2337 :
2338 : //_____________________________________________________________________________
2339 : Double_t AliTPCPreprocessorOffline::EvalAt(Double_t phi, Double_t refX, Double_t theta, Int_t corr, Int_t ptype){
2340 : //
2341 : //
2342 : //
2343 0 : Double_t sector = 9*phi/TMath::Pi();
2344 0 : if (sector<0) sector+=18;
2345 0 : Double_t y85=AliTPCCorrection::GetCorrSector(sector,85,theta,1,corr);
2346 0 : Double_t y245=AliTPCCorrection::GetCorrSector(sector,245,theta,1,corr);
2347 0 : if (ptype==0) return y85+(y245-y85)*(refX-85.)/(245.-85.);
2348 0 : if (ptype==2) return (y245-y85)/(245.-85.);
2349 0 : return 0;
2350 0 : }
2351 :
2352 : //_____________________________________________________________________________
2353 : Double_t AliTPCPreprocessorOffline::EvalAtPar(Double_t phi0, Double_t snp, Double_t refX, Double_t theta, Int_t corr, Int_t ptype, Int_t nsteps){
2354 : //
2355 : // Fit the distortion along the line with the parabolic model
2356 : // Parameters:
2357 : // phi0 - phi at the entrance of the TPC
2358 : // snp - local inclination angle at the entrance of the TPC
2359 : // refX - ref X where the distortion is evanluated
2360 : // theta
2361 : //
2362 0 : static TLinearFitter fitter(3,"pol2");
2363 0 : fitter.ClearPoints();
2364 0 : if (nsteps<3) nsteps=3;
2365 0 : Double_t deltaX=(245-85)/(nsteps);
2366 0 : for (Int_t istep=0; istep<(nsteps+1); istep++){
2367 : //
2368 0 : Double_t localX =85.+deltaX*istep;
2369 0 : Double_t localPhi=phi0+deltaX*snp*istep;
2370 0 : Double_t sector = 9*localPhi/TMath::Pi();
2371 0 : if (sector<0) sector+=18;
2372 0 : Double_t y=AliTPCCorrection::GetCorrSector(sector,localX,theta,1,corr);
2373 0 : Double_t dlocalX=AliTPCCorrection::GetCorrSector(sector,localX,theta,0,corr);
2374 0 : Double_t x[1]={localX-dlocalX};
2375 0 : fitter.AddPoint(x,y);
2376 0 : }
2377 0 : fitter.Eval();
2378 : Double_t par[3];
2379 0 : par[0]=fitter.GetParameter(0);
2380 0 : par[1]=fitter.GetParameter(1);
2381 0 : par[2]=fitter.GetParameter(2);
2382 :
2383 0 : if (ptype==0) return par[0]+par[1]*refX+par[2]*refX*refX;
2384 0 : if (ptype==2) return par[1]+2*par[2]*refX;
2385 0 : if (ptype==4) return par[2];
2386 0 : return 0;
2387 0 : }
2388 :
2389 : //_____________________________________________________________________________
2390 : void AliTPCPreprocessorOffline::MakePrimitivesTime(){
2391 : //
2392 : // Create primitive transformation to fit
2393 : //
2394 0 : fAlignTree=new TChain("fit","fit");
2395 0 : fAlignTree->AddFile("meanITSVertex.root",10000000,"ITSdy");
2396 0 : fAlignTree->AddFile("meanITSVertex.root",10000000,"ITSdsnp");
2397 0 : fAlignTree->AddFile("meanITSVertex.root",10000000,"Vertexdy");
2398 0 : fAlignTree->AddFile("meanITSVertex.root",10000000,"Vertexdsnp");
2399 : //
2400 0 : AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
2401 0 : Double_t bzField=AliTrackerBase::GetBz();
2402 0 : Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
2403 : Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
2404 0 : Double_t wtP = -10.0 * (bzField) * vdrift / ezField ;
2405 0 : AliTPCExBTwist *fitExBTwistX= new AliTPCExBTwist;
2406 0 : AliTPCExBTwist *fitExBTwistY= new AliTPCExBTwist;
2407 0 : AliTPCCalibGlobalMisalignment *trans0 =new AliTPCCalibGlobalMisalignment;
2408 0 : AliTPCCalibGlobalMisalignment *trans1 =new AliTPCCalibGlobalMisalignment;
2409 0 : AliTPCCalibGlobalMisalignment *trans0D =new AliTPCCalibGlobalMisalignment;
2410 0 : AliTPCCalibGlobalMisalignment *trans1D =new AliTPCCalibGlobalMisalignment;
2411 0 : AliTPCCalibGlobalMisalignment *rot0 =new AliTPCCalibGlobalMisalignment;
2412 0 : AliTPCCalibGlobalMisalignment *rot1 =new AliTPCCalibGlobalMisalignment;
2413 0 : AliTPCCalibGlobalMisalignment *rot2 =new AliTPCCalibGlobalMisalignment;
2414 0 : AliTPCCalibGlobalMisalignment *rot3 =new AliTPCCalibGlobalMisalignment;
2415 : //
2416 : //
2417 0 : fitExBTwistX->SetXTwist(0.001);
2418 0 : fitExBTwistX->SetOmegaTauT1T2(wtP,1,1);
2419 : //
2420 0 : fitExBTwistY->SetYTwist(0.001);
2421 0 : fitExBTwistY->SetOmegaTauT1T2(wtP,1,1);
2422 : //
2423 0 : TGeoHMatrix *matrixRot = new TGeoHMatrix;
2424 0 : TGeoHMatrix *matrixX = new TGeoHMatrix;
2425 0 : TGeoHMatrix *matrixY = new TGeoHMatrix;
2426 0 : matrixX->SetDx(0.1);
2427 0 : matrixY->SetDy(0.1);
2428 0 : Double_t rotAngles0[9]={0};
2429 0 : Double_t rotAngles1[9]={0};
2430 0 : Double_t rotAngles2[9]={0};
2431 : //
2432 0 : Double_t rotAngles3[9]={0};
2433 :
2434 0 : rotAngles0[0]=1; rotAngles0[4]=1; rotAngles0[8]=1;
2435 0 : rotAngles1[0]=1; rotAngles1[4]=1; rotAngles1[8]=1;
2436 0 : rotAngles2[0]=1; rotAngles2[4]=1; rotAngles2[8]=1;
2437 0 : rotAngles3[0]=1; rotAngles3[4]=1; rotAngles3[8]=1;
2438 :
2439 0 : rotAngles0[1]=-0.001;rotAngles0[3]=0.001;
2440 0 : rotAngles1[5]=-0.001;rotAngles1[7]=0.001;
2441 0 : rotAngles2[2]=0.001;rotAngles2[6]=-0.001;
2442 0 : rotAngles3[1]=0.001;rotAngles3[3]=-0.001;
2443 0 : matrixRot->SetRotation(rotAngles0);
2444 0 : rot0->SetAlignGlobal(matrixRot);
2445 0 : matrixRot->SetRotation(rotAngles1);
2446 0 : rot1->SetAlignGlobal(matrixRot);
2447 0 : matrixRot->SetRotation(rotAngles2);
2448 0 : rot2->SetAlignGlobal(matrixRot);
2449 0 : matrixRot->SetRotation(rotAngles3);
2450 0 : rot3->SetAlignGlobalDelta(matrixRot);
2451 : //
2452 0 : trans0->SetAlignGlobal(matrixX);
2453 0 : trans1->SetAlignGlobal(matrixY);
2454 0 : trans0D->SetAlignGlobalDelta(matrixX);
2455 0 : trans1D->SetAlignGlobalDelta(matrixY);
2456 0 : fitExBTwistX->Init();
2457 0 : fitExBTwistY->Init();
2458 : //
2459 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(fitExBTwistX->Clone()),100);
2460 0 : fitExBTwistY->AddVisualCorrection((AliTPCExBTwist*)(fitExBTwistY->Clone()),101);
2461 : //
2462 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(rot0->Clone()),102);
2463 0 : fitExBTwistY->AddVisualCorrection((AliTPCExBTwist*)(rot1->Clone()),103);
2464 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(rot2->Clone()),104);
2465 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(rot3->Clone()),105);
2466 :
2467 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(trans0->Clone()),106);
2468 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(trans1->Clone()),107);
2469 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(trans0D->Clone()),108);
2470 0 : fitExBTwistX->AddVisualCorrection((AliTPCExBTwist*)(trans1D->Clone()),109);
2471 : //
2472 0 : fAlignTree->SetAlias("FExBTwistX", "AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,100,ptype)+0");
2473 0 : fAlignTree->SetAlias("FExBTwistY","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,101,ptype)+0");
2474 0 : fAlignTree->SetAlias("FAlignRot0","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,102,ptype)+0");
2475 0 : fAlignTree->SetAlias("FAlignRot0D","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,105,ptype)+0");
2476 0 : fAlignTree->SetAlias("FAlignRot1","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,103,ptype)+0");
2477 0 : fAlignTree->SetAlias("FAlignRot2","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,104,ptype)+0");
2478 0 : fAlignTree->SetAlias("FAlignTrans0","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,106,ptype)+0");
2479 0 : fAlignTree->SetAlias("FAlignTrans1","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,107,ptype)+0");
2480 0 : fAlignTree->SetAlias("FAlignTrans0D","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,108,ptype)+0");
2481 0 : fAlignTree->SetAlias("FAlignTrans1D","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,109,ptype)+0");
2482 : //
2483 : // test fast function
2484 : //
2485 : // fAlignTree->Draw("FExBTwistX:ExBTwistX","isITS&&ptype==0&&abs(snp)<0.05","");
2486 : // fAlignTree->Draw("FExBTwistY:ExBTwistY","isITS&&ptype==0&&abs(snp)<0.05","");
2487 : // fAlignTree->Draw("FAlignRot0:alignRot0","isITS&&ptype==0&&abs(snp)<0.05","");
2488 : // fAlignTree->Draw("FAlignRot1:alignRot1","isITS&&ptype==0&&abs(snp)<0.05","");
2489 : // fAlignTree->Draw("FAlignRot2:alignRot2","isITS&&ptype==0&&abs(snp)<0.05","");
2490 : // //
2491 : // fAlignTree->Draw("FAlignTrans0:alignTrans0","isITS&&ptype==0&&abs(snp)<0.05","");
2492 : // fAlignTree->Draw("FAlignTrans1:alignTrans1","isITS&&ptype==0&&abs(snp)<0.05","");
2493 :
2494 0 : }
2495 :
2496 : //_____________________________________________________________________________
2497 : void AliTPCPreprocessorOffline::CreateAlignTime(TString fstring, TVectorD paramC){
2498 : //
2499 : //
2500 : //
2501 : //
2502 0 : TGeoHMatrix *matrixDelta = new TGeoHMatrix;
2503 0 : TGeoHMatrix *matrixGlobal = new TGeoHMatrix;
2504 0 : Double_t rAngles[9];
2505 : Int_t index=0;
2506 : //
2507 0 : index=TStatToolkit::GetFitIndex(fstring,"FAlignTrans0D");
2508 0 : if (index>=0) matrixDelta->SetDx(paramC[index+1]*0.1);
2509 0 : index=TStatToolkit::GetFitIndex(fstring,"FAlignTrans1D");
2510 0 : if (index>=0) matrixDelta->SetDy(paramC[index+1]*0.1);
2511 0 : rAngles[0]=1; rAngles[4]=1; rAngles[8]=1;
2512 0 : index=TStatToolkit::GetFitIndex(fstring,"FAlignRot0D");
2513 0 : rAngles[1]=-paramC[index+1]*0.001; rAngles[3]=paramC[index+1]*0.001;
2514 0 : rAngles[5]=0; rAngles[7] =0;
2515 0 : rAngles[2]=0; rAngles[6] =0;
2516 0 : matrixDelta->SetRotation(rAngles);
2517 : //
2518 : //
2519 : //
2520 0 : index=TStatToolkit::GetFitIndex(fstring,"hasITS*FAlignTrans0");
2521 0 : if (index>=0) matrixGlobal->SetDx(paramC[index+1]*0.1);
2522 0 : index=TStatToolkit::GetFitIndex(fstring,"hasITS*FAlignTrans1");
2523 0 : if (index>=0) matrixGlobal->SetDy(paramC[index+1]*0.1);
2524 0 : rAngles[0]=1; rAngles[4]=1; rAngles[8]=1;
2525 0 : index=TStatToolkit::GetFitIndex(fstring,"hasITS*FAlignRot0");
2526 0 : rAngles[1]=-paramC[index+1]*0.001; rAngles[3]=paramC[index+1]*0.001;
2527 0 : index=TStatToolkit::GetFitIndex(fstring,"hasITS*FAlignRot1");
2528 0 : rAngles[5]=-paramC[index+1]*0.001; rAngles[7]=paramC[index+1]*0.001;
2529 0 : index=TStatToolkit::GetFitIndex(fstring,"hasITS*FAlignRot2");
2530 0 : rAngles[2]=paramC[index+1]*0.001; rAngles[6] =-paramC[index+1]*0.001;
2531 0 : matrixGlobal->SetRotation(rAngles);
2532 : //
2533 : AliTPCCalibGlobalMisalignment *fitAlignTime =0;
2534 0 : fitAlignTime =new AliTPCCalibGlobalMisalignment;
2535 0 : fitAlignTime->SetName("FitAlignTime");
2536 0 : fitAlignTime->SetTitle("FitAlignTime");
2537 0 : fitAlignTime->SetAlignGlobalDelta(matrixDelta);
2538 0 : fitAlignTime->SetAlignGlobal(matrixGlobal);
2539 : //
2540 0 : AliTPCExBTwist * fitExBTwist= new AliTPCExBTwist;
2541 0 : Int_t indexX=TStatToolkit::GetFitIndex(fstring,"ExBTwistX");
2542 0 : Int_t indexY=TStatToolkit::GetFitIndex(fstring,"ExBTwistY");
2543 0 : fitExBTwist->SetXTwist(0.001*paramC[indexX+1]); // 1 mrad twist in x
2544 0 : fitExBTwist->SetYTwist(0.001*paramC[indexY+1]); // 1 mrad twist in x
2545 0 : fitExBTwist->SetName("FitExBTwistTime");
2546 0 : fitExBTwist->SetTitle("FitExBTwistTime");
2547 0 : AliTPCParam *param= AliTPCcalibDB::Instance()->GetParameters();
2548 0 : Double_t bzField=AliTrackerBase::GetBz();
2549 0 : Double_t vdrift = param->GetDriftV()/1000000.; // [cm/us] // From dataBase: to be updated: per second (ideally)
2550 :
2551 : Double_t ezField = 400; // [V/cm] // to be updated: never (hopefully)
2552 0 : Double_t wt = -10.0 * (bzField) * vdrift / ezField ;
2553 : //
2554 0 : fitExBTwist->SetOmegaTauT1T2(wt,1,1);
2555 0 : fitExBTwist->Init();
2556 :
2557 0 : AliTPCComposedCorrection *corrTime = new AliTPCComposedCorrection;
2558 0 : TObjArray *arr = new TObjArray;
2559 0 : corrTime->SetCorrections(arr);
2560 :
2561 0 : corrTime->GetCorrections()->Add(fitExBTwist);
2562 0 : corrTime->GetCorrections()->Add(fitAlignTime);
2563 0 : corrTime->SetName("FitCorrectionTime");
2564 0 : corrTime->SetTitle("FitCorrectionTime");
2565 :
2566 0 : fitExBTwist->AddVisualCorrection((AliTPCExBTwist*)(fitExBTwist->Clone()),1001);
2567 0 : fitAlignTime->AddVisualCorrection((AliTPCExBTwist*)(fitAlignTime->Clone()),1002);
2568 0 : fitAlignTime->AddVisualCorrection((AliTPCExBTwist*)(corrTime->Clone()),1003);
2569 :
2570 :
2571 0 : fAlignTree->SetAlias("ExBTwistTime","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,1001,ptype)+0");
2572 0 : fAlignTree->SetAlias("AlignTime","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,1002,ptype)+0");
2573 0 : fAlignTree->SetAlias("FitCorrectionTime","AliTPCPreprocessorOffline::EvalAt(phi,refX,theta,1003,ptype)+0");
2574 :
2575 :
2576 0 : TFile *f = new TFile("fitITSVertex.root","update");
2577 0 : corrTime->Write("FitCorrectionTime");
2578 0 : f->Close();
2579 0 : }
2580 :
2581 : //_____________________________________________________________________________
2582 : Int_t AliTPCPreprocessorOffline::GetStatus()
2583 : {
2584 : //get the calibration status
2585 : // 0 means OK
2586 : // positive numbers invalidate for unknown reasons.
2587 : // negative numbers invalidate with a known reason (e.g. low statistics).
2588 : // the returned integer has one bit set for every component that failed.
2589 :
2590 0 : Bool_t enoughStatistics = (fNtracksVdrift>fMinTracksVdrift && fNeventsVdrift>fMinEventsVdrift);
2591 :
2592 0 : if (!enoughStatistics)
2593 : {
2594 0 : fCalibrationStatus=-TMath::Abs(fCalibrationStatus);
2595 0 : }
2596 :
2597 0 : return fCalibrationStatus;
2598 : }
2599 :
2600 : //_____________________________________________________________________________
2601 : void AliTPCPreprocessorOffline::FillQA(Bool_t qa, Bool_t norm/*=kTRUE*/)
2602 : {
2603 : // setup QA histogram array
2604 0 : if (qa && !fArrQAhist) {
2605 0 : fArrQAhist = new TObjArray;
2606 0 : fArrQAhist->SetOwner();
2607 0 : } else {
2608 0 : delete fArrQAhist;
2609 0 : fArrQAhist = 0x0;
2610 : }
2611 :
2612 0 : fNormaliseQA=norm;
2613 0 : }
2614 :
2615 : //_____________________________________________________________________________
2616 : void AliTPCPreprocessorOffline::MakeQAPlotsGain(TString outputDirectory/*=""*/, TString fileTypes/*="png"*/)
2617 : {
2618 : // Draw QA histograms, one per file
2619 : // if outputDirectory is non empty, the QA canvases will be written to the output directory
2620 : // fileTypes can contain output formats, comma separated. Default is one png per canvas.
2621 : // also recognized jpg, gif, root.
2622 : // in case of root, all canvases are written to one root file
2623 0 : if (!fArrQAhist) return;
2624 :
2625 0 : TDirectory *dir=gDirectory;
2626 : TFile *f=0x0;
2627 0 : if (fileTypes.Contains("root")) {
2628 0 : f=new TFile(TString::Format("%s/GainQA.root", outputDirectory.Data()),"recreate");
2629 0 : }
2630 :
2631 : const Int_t ntypes=5;
2632 0 : const TString ftypes[ntypes]={"png","jpg","gif","pdf","eps"};
2633 :
2634 0 : for (Int_t ihist=0; ihist<fArrQAhist->GetEntriesFast(); ++ihist) {
2635 0 : dir->cd();
2636 0 : TH2 *h = static_cast<TH2*>(fArrQAhist->UncheckedAt(ihist));
2637 0 : if (!h) continue;
2638 0 : TString histName = h->GetName();
2639 0 : TString canvName=histName;
2640 0 : canvName.Prepend("c_");
2641 0 : TCanvas *c = static_cast<TCanvas*>(gROOT->GetListOfCanvases()->FindObject(canvName));
2642 0 : if (!c) {
2643 0 : c=new TCanvas(canvName, canvName, 700,500);
2644 0 : }
2645 0 : c->Clear();
2646 0 : c->SetLogz();
2647 :
2648 0 : h->Draw("colz");
2649 :
2650 : // ---| check for derived histogram and draw it on top |---
2651 0 : histName.ReplaceAll("_QA","");
2652 0 : TObject *o = fGainArray->FindObject(histName);
2653 0 : if (o) {
2654 0 : o->Draw("same");
2655 : }
2656 :
2657 : // ---| save output |---
2658 0 : if (!outputDirectory.IsNull()) {
2659 : // --- loop over file types ---
2660 0 : for (Int_t itype=0; itype<ntypes; ++itype) {
2661 0 : if (fileTypes.Contains(ftypes[itype])) {
2662 0 : c->SaveAs(TString::Format("%s/%s.%s", outputDirectory.Data(), c->GetName(), ftypes[itype].Data()));
2663 0 : }
2664 : }
2665 :
2666 : // --- save to file if requested ---
2667 0 : if (f) {
2668 0 : f->cd();
2669 0 : c->Write();
2670 0 : dir->cd();
2671 : }
2672 : }
2673 0 : }
2674 :
2675 0 : delete f;
2676 0 : }
2677 :
2678 :
2679 : void AliTPCPreprocessorOffline::ScaleY(TGraphErrors *graph, Double_t normval)
2680 : {
2681 0 : for (Int_t ipoint=0; ipoint<graph->GetN(); ipoint++) {
2682 0 : graph->GetY()[ipoint]*=normval;
2683 0 : graph->GetEY()[ipoint]*=normval;
2684 : }
2685 0 : }
2686 :
2687 : Bool_t AliTPCPreprocessorOffline::NormaliseYToMean(TGraphErrors *graph)
2688 : {
2689 0 : const Double_t mean = TMath::Mean(graph->GetN(), graph->GetY());
2690 :
2691 0 : if (mean<=0){
2692 0 : AliError(Form("mean=%f",mean));
2693 0 : return kFALSE;
2694 : }
2695 :
2696 0 : ScaleY(graph, 1./mean);
2697 0 : }
2698 :
2699 : Bool_t AliTPCPreprocessorOffline::NormaliseYToWeightedMeandEdx(TGraphErrors *graph)
2700 : {
2701 0 : const Double_t *y=graph->GetY();
2702 0 : Double_t scaleFactor=(63.*y[0] + 64.*y[1] + 32*y[2])/159.;
2703 :
2704 0 : if (scaleFactor<=0){
2705 0 : AliError(Form("scaleFactor=%f",scaleFactor));
2706 0 : return kFALSE;
2707 : }
2708 :
2709 0 : ScaleY(graph, 1./scaleFactor);
2710 0 : }
2711 :
2712 : Bool_t AliTPCPreprocessorOffline::NormaliseYToTruncateddEdx(TGraphErrors *graph)
2713 : {
2714 0 : const Double_t *y=graph->GetY();
2715 0 : Double_t truncationFactor=AliTPCcalibGainMult::GetTruncatedMeanPosition(y[0],y[1],y[2],1000);
2716 :
2717 0 : if (truncationFactor<=0){
2718 0 : AliError(Form("truncationFactor=%f",truncationFactor));
2719 0 : return kFALSE;
2720 : }
2721 :
2722 0 : ScaleY(graph, 1./truncationFactor);
2723 0 : }
2724 :
2725 : /*
2726 : Short sequence to acces the calbration entry:
2727 : TFile *f = TFile::Open("CalibObjects.root");
2728 : AliTPCcalibGainMult * fGainMult = (AliTPCcalibGainMult *)f->Get("TPCCalib/calibGainMult");
2729 :
2730 :
2731 : */
|