1 /**************************************************************************
2 * Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
4 * Author: The ALICE Off-line Project. *
5 * Contributors are mentioned in the code where appropriate. *
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 **************************************************************************/
17 ///////////////////////////////////////////////////////////////////////////////
19 // TPC tender: reapply pid on the fly //
21 ///////////////////////////////////////////////////////////////////////////////
24 #include <TObjArray.h>
25 #include <TObjString.h>
30 #include <TGraphErrors.h>
32 #include <AliDCSSensor.h>
33 #include <AliGRPObject.h>
34 #include <AliESDpid.h>
36 #include <AliESDEvent.h>
37 #include <AliExternalTrackParam.h>
38 #include <AliESDtrack.h>
39 #include <AliESDInputHandler.h>
40 #include <AliAnalysisManager.h>
41 #include <AliSplineFit.h>
43 #include <AliCDBManager.h>
44 #include <AliCDBEntry.h>
45 #include <AliCDBRunRange.h>
46 #include <AliTender.h>
47 #include <AliTPCcalibDButil.h>
50 #include "AliTPCTenderSupply.h"
52 ClassImp(AliTPCTenderSupply)
54 AliTPCTenderSupply::AliTPCTenderSupply() :
61 fGainCorrection(kTRUE),
62 fAttachmentCorrection(kFALSE),
64 fMultiCorrection(kFALSE),
65 fArrPidResponseMaster(0x0),
68 fSpecificStorages(0x0),
82 //_____________________________________________________
83 AliTPCTenderSupply::AliTPCTenderSupply(const char *name, const AliTender *tender) :
84 AliTenderSupply(name,tender),
90 fGainCorrection(kTRUE),
91 fAttachmentCorrection(kFALSE),
93 fMultiCorrection(kFALSE),
94 fArrPidResponseMaster(0x0),
97 fSpecificStorages(0x0),
111 //_____________________________________________________
112 void AliTPCTenderSupply::Init()
115 // Initialise TPC tender
118 AliLog::SetClassDebugLevel("AliTPCTenderSupply",10);
119 AliAnalysisManager *mgr=AliAnalysisManager::GetAnalysisManager();
123 fIsMC=mgr->GetMCtruthEventHandler();
125 // Check if another detector already created the esd pid object
126 // if not we create it and set it to the ESD input handler
127 fESDpid=fTender->GetESDhandler()->GetESDpid();
129 fESDpid=new AliESDpid(fIsMC);
130 fTender->GetESDhandler()->SetESDpid(fESDpid);
133 //setup specific storages
134 if (fSpecificStorages){
136 TIter nextStorage(fSpecificStorages);;
137 while ( (storage=(TNamed*)nextStorage()) ){
138 fTender->GetCDBManager()->SetSpecificStorage(storage->GetName(),storage->GetTitle());
139 AliInfo(Form("Setting specific storage: %s (%s)",storage->GetName(), storage->GetTitle()));
144 //force no gain and P correction in MC
145 fGainCorrection=kFALSE;
147 fAttachmentCorrection=kFALSE;
151 //_____________________________________________________
152 void AliTPCTenderSupply::ProcessEvent()
155 // Reapply pid information
158 AliESDEvent *event=fTender->GetEvent();
161 //load gain correction if run has changed
162 if (fTender->RunChanged()){
165 if ( fBeamType == "PBPB" ) fMultiCorrection=kTRUE;
167 if (fDebugLevel>0) AliInfo(Form("Run Changed (%d)",fTender->GetRun()));
168 SetParametrisation();
169 if (fGainCorrection) SetSplines();
173 // get gain correction factor
175 Double_t corrFactor = GetGainCorrection();
176 Double_t corrAttachSlope = 0;
177 Double_t corrGainMultiplicityPbPb=1;
178 if (fAttachmentCorrection && fGainAttachment) corrAttachSlope = fGainAttachment->Eval(event->GetTimeStamp());
179 if (fMultiCorrection&&fMultiCorrMean) corrGainMultiplicityPbPb = fMultiCorrMean->Eval(GetTPCMultiplicityBin());
182 // - correct TPC signals
183 // - recalculate PID probabilities for TPC
184 // - correct TPC signal multiplicity dependence
186 Int_t ntracks=event->GetNumberOfTracks();
187 for(Int_t itrack = 0; itrack < ntracks; itrack++){
188 AliESDtrack *track=event->GetTrack(itrack);
189 const AliExternalTrackParam *inner=track->GetInnerParam();
191 // skip tracks without TPC information
192 if (!inner) continue;
194 //calculate total gain correction factor given by
195 // o gain calibration factor
196 // o attachment correction
197 // o multiplicity correction in PbPb
198 Float_t meanDrift= 250. - 0.5*TMath::Abs(2*inner->GetZ() + (247-83)*inner->GetTgl());
199 Double_t corrGainTotal=corrFactor*(1 + corrAttachSlope*180.)/(1 + corrAttachSlope*meanDrift)/corrGainMultiplicityPbPb;
201 // apply gain correction
202 track->SetTPCsignal(track->GetTPCsignal()*corrGainTotal ,track->GetTPCsignalSigma(), track->GetTPCsignalN());
204 // recalculate pid probabilities
205 fESDpid->MakeTPCPID(track);
209 //_____________________________________________________
210 Double_t AliTPCTenderSupply::GetTPCMultiplicityBin()
213 // Get TPC multiplicity in bins of 150
216 AliESDEvent *event=fTender->GetEvent();
217 const AliESDVertex* vertexTPC = event->GetPrimaryVertexTPC();
218 Double_t tpcMulti=0.;
220 Double_t vertexContribTPC=vertexTPC->GetNContributors();
221 tpcMulti=vertexContribTPC/150.;
222 if (tpcMulti>20.) tpcMulti=20.;
227 //_____________________________________________________
228 Double_t AliTPCTenderSupply::GetMultiplicityCorrectionMean(Double_t tpcMulti)
231 // calculate correction factor for dEdx mean
233 Double_t meancorrection;
237 meancorrection=1.00054 + (0.00189566)*tpcMulti + (2.07777e-05)*tpcMulti*tpcMulti;
242 meancorrection=0.999509 + (-0.00271488)*tpcMulti + (-2.98873e-06)*tpcMulti*tpcMulti;
245 return meancorrection;
249 //_____________________________________________________
250 Double_t AliTPCTenderSupply::GetMultiplicityCorrectionSigma(Double_t tpcMulti)
253 // calculate correction factor for dEdx sigma
255 Double_t sigmacorrection;
259 sigmacorrection=0.95972 + 0.0103721*tpcMulti;
264 sigmacorrection=1.01817 + 0.0143673*tpcMulti;
266 return sigmacorrection;
270 //_____________________________________________________
271 void AliTPCTenderSupply::SetSplines()
274 // Get Gain splines from OCDB
277 AliInfo("Update Gain splines");
280 // Get GPR info for pressure correction
284 AliCDBEntry *entryGRP=fTender->GetCDBManager()->Get("GRP/GRP/Data",fTender->GetRun());
286 AliError("No new GRP entry found");
288 fGRP = (AliGRPObject*)entryGRP->GetObject();
290 if (fDebugLevel>1) AliInfo(Form("GRP entry used: %s",entryGRP->GetId().ToString().Data()));
295 //find previous entry from the UserInfo
297 // TTree *tree=((TChain*)fTender->GetInputData(0))->GetTree();
298 AliAnalysisManager*mgr = AliAnalysisManager::GetAnalysisManager();
299 AliAnalysisTaskSE *task = (AliAnalysisTaskSE*)mgr->GetTasks()->First();
301 TTree *tree=((TChain*)task->GetInputData(0))->GetTree();
303 AliError("Tree not found in ESDhandler");
307 TList *userInfo=(TList*)tree->GetUserInfo();
309 AliError("No UserInfo found in tree");
313 TList *cdbList=(TList*)userInfo->FindObject("cdbList");
315 AliError("No cdbList found in UserInfo");
316 if (AliLog::GetGlobalLogLevel()>=AliLog::kError) userInfo->Print();
320 TIter nextCDB(cdbList);
322 while ( (os=(TObjString*)nextCDB()) ){
323 if (!(os->GetString().Contains("TPC/Calib/TimeGain"))) continue;
324 AliCDBId *id=AliCDBId::MakeFromString(os->GetString());
326 AliCDBEntry *entry=fTender->GetCDBManager()->Get(*id);
328 AliError("No previous gain calibration entry found");
332 if (fDebugLevel>1) AliInfo(Form("Used old Gain entry: %s",entry->GetId().ToString().Data()));
334 TObjArray *arr=(TObjArray *)entry->GetObject();
336 AliError("Gain Splines array not found in calibration entry");
340 AliSplineFit *fit=(AliSplineFit*)arr->At(0);
342 AliError("Spline fit not found in array");
352 //new gain correction
355 // This is in principle sill needed for the 2009 data and the 2010 b+c pass1 data
356 // however not supported any longer.
357 // For the LHC10c pass2 there is an exception and we still load the splines, but a defined version
358 // In case the attachment correction should be check again, this part of the code needs to be changed
359 // in order to load the gain entry again
360 Bool_t special10cPass2=fLHCperiod=="LHC10C" && fRecoPass==2;
362 AliCDBEntry *entryNew=0x0;
363 if (special10cPass2) {
364 entryNew=fTender->GetCDBManager()->Get("TPC/Calib/TimeGain",fTender->GetRun(),8);
367 AliError("No new gain calibration entry found");
370 if (fDebugLevel>1) AliInfo(Form("Used new Gain entry: %s",entryNew->GetId().ToString().Data()));
372 if (entryNew->GetId().GetLastRun()==AliCDBRunRange::Infinity()){
373 if (fDebugLevel>0) AliInfo("Use P correction");
377 TObjArray *arrSplines=(TObjArray *)entryNew->GetObject();
379 AliError("Gain Splines array not found in new calibration entry");
383 fGainNew = (AliSplineFit*)arrSplines->At(0);
384 fGainAttachment = (TGraphErrors*)arrSplines->FindObject("TGRAPHERRORS_MEAN_ATTACHMENT_BEAM_ALL");
386 if (!fGainNew) AliError("No recent spline fit object found");
389 //_____________________________________________________
390 Double_t AliTPCTenderSupply::GetGainCorrection()
393 // Calculate gain correction factor
395 AliESDEvent *event=fTender->GetEvent();
396 UInt_t time=event->GetTimeStamp();
403 //first correction for the eval const problem
404 // needs to be removed when the fix is in AliROOT and
405 // the production was done with EvalGraphConst
406 // This should be the case from V4-20-Rev11 on
408 if ( fLHCperiod.Contains("LHC09") ||
409 ((fLHCperiod=="LHC10B" || fLHCperiod=="LHC10C" || fLHCperiod=="LHC10D") && fRecoPass==2) ||
410 (fLHCperiod=="LHC10E" && fRecoPass==1) ||
411 (fLHCperiod=="LHC10H" && fRecoPass==1)
413 Double_t valDefault = fGainOld->Eval(time);
414 Double_t valConst = AliTPCcalibDButil::EvalGraphConst(fGainOld, time);
415 gain = valDefault/valConst;
419 gain *= AliTPCcalibDButil::EvalGraphConst(fGainOld,time)/AliTPCcalibDButil::EvalGraphConst(fGainNew,time);
423 //If there is only the default calibration, at least apply correction for pressure
426 Double_t pressure=fGRP->GetCavernAtmosPressure()->GetValue(time);
427 // gain=fGainOld->Eval(time)/(7.03814-0.00459798*pressure)/49.53*fMip;
428 // gain=fGainOld->Eval(time)/(7.03814-0.00459798*pressure)/51.51*fMip;
429 gain=AliTPCcalibDButil::EvalGraphConst(fGainOld,time)/(7.03814-0.00459798*pressure)/51.51*fMip;
436 //_____________________________________________________
437 void AliTPCTenderSupply::SetBeamType()
443 fBeamType=fTender->GetEvent()->GetBeamType();
444 if (fBeamType.IsNull()||fBeamType.Contains("No Beam")) fBeamType="p-p";
446 fBeamType.ReplaceAll("-","");
449 //_____________________________________________________
450 void AliTPCTenderSupply::SetRecoInfo()
453 // Set reconstruction information
461 //Get the current file to check the reconstruction pass (UGLY, but not stored in ESD... )
462 AliESDInputHandler *esdIH = dynamic_cast<AliESDInputHandler*> (fTender->GetESDhandler());
464 TTree *tree= (TTree*)esdIH->GetTree();
465 TFile *file= (TFile*)tree->GetCurrentFile();
467 AliError("Current file not found, cannot set reconstruction information");
471 TString fileName(file->GetName());
473 Int_t run=fTender->GetRun();
476 TPRegexp reg(".*(LHC11[a-z]+[0-9]+[a-z]*)/.*");
477 //find the period by run number (UGLY, but not stored in ESD... )
478 if (run>=114737&&run<=117223) { fLHCperiod="LHC10B"; fMCperiod="LHC10D1"; }
479 else if (run>=118503&&run<=121040) { fLHCperiod="LHC10C"; fMCperiod="LHC10D1"; }
480 else if (run>=122195&&run<=126437) { fLHCperiod="LHC10D"; fMCperiod="LHC10F6A"; }
481 else if (run>=127719&&run<=130850) { fLHCperiod="LHC10E"; fMCperiod="LHC10F6A"; }
482 else if (run>=133004&&run<=135029) { fLHCperiod="LHC10F"; fMCperiod="LHC10F6A"; }
483 else if (run>=135654&&run<=136377) { fLHCperiod="LHC10G"; fMCperiod="LHC10F6A"; }
484 else if (run>=136851&&run<=139517) {
487 if (reg.MatchB(fileName)) fMCperiod="LHC11A10";
489 else if ( (run>=144871 && run <=146459 ) || ( run >=146686 && run<= 146860) ) {
490 // low energy: 146686 - 146860
491 fLHCperiod="LHC11A"; fMCperiod="LHC10F6A";
493 else if ( run>=148541 ){
494 fLHCperiod="LHC11B"; fMCperiod="LHC10F6A";
497 //exception new pp MC productions from 2011
498 if (fBeamType=="PP" && reg.MatchB(fileName)) fMCperiod="LHC11B2";
500 //find pass from file name (UGLY, but not stored in ESD... )
501 if (fileName.Contains("/pass1")) {
503 } else if (fileName.Contains("/pass2")) {
505 } else if (fileName.Contains("/pass3")) {
511 //_____________________________________________________
512 void AliTPCTenderSupply::SetParametrisation()
515 // Change PbPb multiplicity gain correction factor
518 if (fLHCperiod.IsNull()) {
519 AliError("No period set, not changing parametrisation");
523 //Get CDB Entry with pid response parametrisations
524 AliCDBEntry *pidCDB=fTender->GetCDBManager()->Get("TPC/Calib/PidResponse",fTender->GetRun());
525 if (!fArrPidResponseMaster && pidCDB){
526 fArrPidResponseMaster=dynamic_cast<TObjArray*>(pidCDB->GetObject());
527 AliInfo(Form("Using pid response objects: %s",pidCDB->GetId().ToString().Data()));
530 if (!fArrPidResponseMaster){
531 AliError("No valid PidResponse master found in OCDB");
535 TString datatype="DATA";
536 TString period=fLHCperiod;
537 //in case of mc fRecoPass is per default 1
544 // Set PbPb correction
545 fMultiCorrMean=(TF1*)fArrPidResponseMaster->FindObject(Form("TF1_%s_ALL_%s_PASS%d_%s_MEAN",datatype.Data(),period.Data(),fRecoPass,fBeamType.Data()));
547 if (fMultiCorrMean) AliInfo(Form("Setting multiplicity correction function: %s",fMultiCorrMean->GetName()));
551 //____________________________________________________________
552 void AliTPCTenderSupply::AddSpecificStorage(const char* cdbPath, const char* storage)
555 // Add a specific storage to be set up in Init
557 if (!fSpecificStorages) fSpecificStorages=new TObjArray;
558 fSpecificStorages->Add(new TNamed(cdbPath, storage));