5 //#include "AliESDtrackCuts.h"
6 //#include "AliAnalysisCuts.h"
7 //#include "AliFlowTrackSimple.h" // added as hint for hidden library dependency to libPWGflowBase
8 //#include "AliFlowCandidateTrack.h" // added as hint for hidden library dependency to libPWGflowTasks
9 //#include "AliCFContainer.h" // added as hint for hidden library dependency to libCORRFW
10 //#include "AliAODRecoDecayHF2Prong.h" // added as hint for hidden library dependency to libPWGHFvertexingHF
12 #include "AliAnalysisTaskDxHFECorrelation.h"
13 #include "AliDxHFECorrelation.h"
14 #incldue "AliReducedParticle.h"
15 #include "AliHFCorrelator.h"
16 #include "AliHFAssociatedTrackCuts.h"
17 #include "AliAnalysisManager.h"
18 #include "AliAnalysisDataContainer.h"
19 #include "AliHFEcuts.h"
23 #include "TDirectory.h"
25 #include "AliRDHFCutsD0toKpi.h"
26 #include "AliHFEextraCuts.h"
30 const char* poolInfoName="PoolInfo";
31 AliAnalysisCuts* createDefaultPoolConfig();
32 AliAnalysisCuts* createPbPbPoolConfig();
34 /// @file AddTaskDxHFECorrelation.C
35 /// @author Matthias.Richter@ift.uib.no
37 /// @brief Add the D0-HFE correlation task to the manager
39 int AddTaskDxHFECorrelation(TString configuration="", TString analysisName="PWGHFcorrelationDxHF")
41 //First check to see if user wants to see help
42 if (configuration.BeginsWith("help") ||
43 configuration.BeginsWith("--help") ||
44 configuration.BeginsWith("-h") ||
45 configuration.BeginsWith("options") ) {
46 cout <<"\n\n============================================" << endl;
47 cout << "Keywords for AddTaskDxHFECorrelation.C:\n"
48 << "file= - Filename to store output in\n"
49 << "name= - Name of analysis, will correspond to directory inside the file \n"
50 << "cutname= - Filename where information on event pool for event-mixing is stored (if use external file)\n"
51 << "runD0MassReference - If you also want to include D2H task for D0selection (for comparison purposes)\n"
53 << "usekine - To run on kinematical level \n"
54 << "event-mixing/mixing - Whether to also run event-mixing (NB! Use AddTaskDxHFECorrelationME.C for eventmixing)\n"
55 << "trigger=D/D0/electron - Which particle to trigger on \n"
56 << "\nD0 settings: \n"
57 << "fillD0scheme=both/D0/D0bar - Which fillsheme to use for D0\n"
58 << "\nelectron settings: \n"
59 << "useinvmasscut - If you want to use invariant mass cut (default is 100MeV/c)\n"
60 << "invmasscut= - If you want to specify a different invariant mass cut \n"
61 << "extraname= - extraname for directory and list if you run several tasks at once\n"
62 << "tpcclusters= - How many TPC clusters to use on single track cuts for electrons (default=120)\n"
63 << "itsclusters= - How many itsclusters to be used in single track cuts for electrons (default=4) \n"
64 << "itsreq= - (kFirst,kAny,kNone) Which ITSpixel requirement you want to impose\n"
65 << "elmcreco= - (aftertrackcuts/aftertofpid/afterfullpid) Where you want to stop in track selection to look for electrons for mc \n\n";
72 Bool_t bEventMixing=kFALSE;
73 Bool_t bRunD0MassReference=kFALSE;
74 TString poolConfigFile="";
75 // TODO: revise the logic for task options in order to forward every option
76 // by default and filter out the options meant for the macro, that allows
77 // to introduce new task options without the need to specifically forward them
79 Int_t NrTPCclusters=120; // quick fix for problem sending hfe track cut object to addtask
80 Int_t NrITSclusters=4;
81 Int_t ITSreq=AliHFEextraCuts::kFirst;
82 Int_t triggerParticle=AliDxHFECorrelation::kD;
83 Bool_t bUseMCReco=kFALSE;
84 Bool_t bUseKine=kFALSE;
87 cout << endl << "===============================================" << endl;
88 cout << "Setting up Correlation task: " << configuration << endl;
90 // look for configuration arguments if nothing specified
91 // in the function call
92 if (configuration.IsNull() && gDirectory) {
93 const char* confObjectName="run_single_task_configuration";
94 TObject* confObject=gDirectory->FindObject(confObjectName);
96 configuration=confObject->GetTitle();
99 {// deprecated, but keep for formatting
100 {// deprecated, but keep for formatting
101 TObjArray* tokens=configuration.Tokenize(" ");
105 while ((token=next())) {
106 TString argument=token->GetName();
107 if (argument.BeginsWith("file=")) {
108 argument.ReplaceAll("file=", "");
111 else if (argument.BeginsWith("name=")) {
112 argument.ReplaceAll("name=", "");
113 analysisName=argument;
115 if (argument.BeginsWith("cutname=")) {
116 argument.ReplaceAll("cutname=", "");
117 poolConfigFile=argument;
119 if (argument.BeginsWith("mc")) {
123 if(argument.BeginsWith("tpcclusters=")){
124 argument.ReplaceAll("tpcclusters=", "");
125 NrTPCclusters=argument.Atoi();
126 ::Info("AddTaskDxHFEParticleSelection",Form("Setting nr TPC clusters to %d",NrTPCclusters));
128 if (argument.BeginsWith("usekine") ||argument.BeginsWith("kine")) {
130 taskOptions+=" usekine";
132 if (argument.BeginsWith("event-mixing") ||
133 argument.BeginsWith("mixing")/*deprecated, to be removed later*/) {
135 taskOptions+=" event-mixing";
137 if (argument.BeginsWith("PbPb") ||
138 argument.BeginsWith("system=1") ||
139 argument.BeginsWith("Pb-Pb")) {
141 taskOptions+=" system=Pb-Pb";
143 if (argument.BeginsWith("fillD0scheme=")){
144 taskOptions+=" "+argument;
146 if(argument.BeginsWith("elmcreco")){
148 taskOptions+=" "+argument;
150 if (argument.BeginsWith("trigger=")) {
151 taskOptions+=" "+argument;
152 argument.ReplaceAll("trigger=","");
153 if (argument.CompareTo("D0")==0) triggerParticle=AliDxHFECorrelation::kD;
154 else if (argument.CompareTo("D")==0) triggerParticle=AliDxHFECorrelation::kD;
155 else if (argument.CompareTo("electron")==0) triggerParticle=AliDxHFECorrelation::kElectron;
157 if (argument.CompareTo("runD0MassReference")==0){
158 bRunD0MassReference=kTRUE;
160 if(argument.BeginsWith("useinvmasscut"))
161 taskOptions+=" "+argument;
162 if(argument.BeginsWith("twoselectedinvmasscut"))
163 taskOptions+=" "+argument;
164 if(argument.BeginsWith("invmasscut="))
165 taskOptions+=" "+argument;
166 if(argument.BeginsWith("impactparamcut"))
167 taskOptions+=" "+argument;
168 if(argument.BeginsWith("etacut"))
169 taskOptions+=" "+argument;
170 if(argument.BeginsWith("storelastcutstep"))
171 taskOptions+=" "+argument;
172 if(argument.BeginsWith("extraname=")){
173 argument.ReplaceAll("extraname=", "");
176 if(argument.BeginsWith("itsclusters=")){
177 argument.ReplaceAll("itsclusters=", "");
178 NrITSclusters=argument.Atoi();
180 if(argument.BeginsWith("itsreq=")){
181 argument.ReplaceAll("itsreq=", "");
182 if(argument.CompareTo("kFirst")==0) ITSreq=AliHFEextraCuts::kFirst;
183 else if(argument.CompareTo("kAny")==0) ITSreq=AliHFEextraCuts::kAny;
184 else if(argument.CompareTo("kNone")==0) ITSreq=AliHFEextraCuts::kNone;
193 AliAnalysisManager *pManager = AliAnalysisManager::GetAnalysisManager();
195 ::Error("AddTaskDxHFECorrelation", "No analysis manager to connect to.");
199 if(bUseMCReco && bUseKine) {
200 ::Fatal("AddTaskDxHFECorrelation","CAN'T SET BOTH usekine AND elmcreco AT THE SAME TIME");
205 // check for existence of PID task and add if not available
206 const char* pidTaskName="PIDResponseTask";
207 const char* pidTaskMacro="$ALICE_ROOT/ANALYSIS/macros/AddTaskPIDResponse.C";
208 AliAnalysisTask* pidTask=pManager->GetTask(pidTaskName);
210 gROOT->LoadMacro(pidTaskMacro);
212 pidFunction.Form("AddTaskPIDResponse(%d, %d)", bUseMC, kTRUE);
213 gROOT->ProcessLine(pidFunction);
214 if (pManager->GetTask(pidTaskName)==NULL) {
215 ::Error("AddTaskDxHFECorrelation", Form("failed to add PID task '%s' from macro '%s'",
216 pidTaskName, pidTaskMacro));
220 // TODO: would like to check if the PID task was set up
221 // with consistent parameters, however there are no getters at the moment
222 ::Info("AddTaskDxHFECorrelation", Form("PID task '%s' already existing", pidTaskName));
225 // optionally add D0Mass task for reference analysis
226 if (bRunD0MassReference && !bEventMixing) {
228 TString path("AddTaskD0Mass.C");
229 if (gSystem->AccessPathName(path)!=0) {
230 // first try local macro, than AliRoot default path
231 path="$ALICE_ROOT/PWGHF/vertexingHF/macros/AddTaskD0Mass.C";
233 if (gSystem->AccessPathName(path)==0) {
234 cout << "Setting up D0Mass reference task " << path << endl;
236 cout << "Can not find D0Mass reference task " << path << endl;
238 gROOT->LoadMacro(path);
240 const char* taskName=AliAnalysisTaskSED0Mass::Class()->GetName();
241 if (pManager->GetTask(taskName)) {
242 ::Warning("AddTaskDxHFECorrelation", Form("task '%s' already existing, skipping ...",
246 //flag, readMC,filldistr,cutonDistr, system, flagD0D0bar,minC,maxC,finDirname,finname, finObjname,flagAOD049,FillMassPt, FillImptPar
247 AliAnalysisTaskSED0Mass *d0massTask = AddTaskD0Mass(0,bUseMC,kTRUE,kTRUE, 0, 0, 0, 0, "", "","D0toKpiCuts", kFALSE, false, false);
251 if(triggerParticle==AliDxHFECorrelation::kElectron)
252 analysisName="HFExD";
253 if (ofilename.IsNull()) ofilename=AliAnalysisManager::GetCommonFileName();
254 ofilename+=":"+analysisName;
256 ///______________________________________________________________________
259 AliRDHFCutsD0toKpi* RDHFD0toKpi=new AliRDHFCutsD0toKpi();
260 // TODO: we might want to move this to separate functions if more data
261 // sets are going to be handled
263 RDHFD0toKpi->SetStandardCutsPP2010();
265 // TODO: think about p-Pb
266 RDHFD0toKpi->SetStandardCutsPbPb2011();
268 // For centrality 0-10%, add centrality flattening
269 //NB! NEED FOR THE MOMENT THE FILE!
270 TFile *fFlat=TFile::Open("CentrDistrBins005.root","READ");
271 TCanvas *c=fFlat->Get("cintegral");
272 TH1F *hfl=(TH1F*)c->FindObject("hint");
273 RDHFD0toKpi->SetHistoForCentralityFlattening(hfl,0.,10.,0.,0);
274 // RDHFD0toKpi->SetUseCentrality(AliRDHFCuts::kCentV0M);
276 RDHFD0toKpi->SetMinCentrality(0.);// 40.*1.01
277 RDHFD0toKpi->SetMaxCentrality(10.);// 80.*1.01
280 ///______________________________________________________________________
283 if (system==0) hfeCutsName="HFE Standard Cuts";
284 else hfeCutsName="HFE Cuts PbPb";
285 AliHFEcuts *hfecuts = new AliHFEcuts("hfeCutsTPCTOF", hfeCutsName);
286 hfecuts->CreateStandardCuts();
288 hfecuts->SetTPCmodes(AliHFEextraCuts::kFound,AliHFEextraCuts::kFoundOverFindable);
289 hfecuts->SetMinNClustersTPC(NrTPCclusters); //Default = 80
290 hfecuts->SetMinNClustersTPCPID(80); //Default = 80
291 hfecuts->SetMinRatioTPCclusters(0.6); //Default = 0.6
294 hfecuts->SetCutITSpixel(ITSreq); //Cut on SPD
295 //hfecuts->SetCutITSdrift(AliHFEextraCuts::kAny); //Cut on SDD
296 //hfecuts->SetCheckITSLayerStatus(kFALSE);
297 hfecuts->SetMinNClustersITS(NrITSclusters); //Default = 4
300 hfecuts->SetTOFPIDStep(kTRUE);
303 hfecuts->SetPtRange(0.30, 10.5);
304 hfecuts->SetMaxImpactParam(1.,2.);
305 hfecuts->SetVertexRange(10.);
310 AliHFEpid *fPIDOnlyTOF = new AliHFEpid("hfePidTOF");
311 if(!fPIDOnlyTOF->GetNumberOfPIDdetectors()) {
312 fPIDOnlyTOF->AddDetector("TOF",0);
314 fPIDOnlyTOF->ConfigureTOF(3); // number of sigma TOF
315 fPIDOnlyTOF->InitializePID();
317 // PID object for TPC and TOF combined
318 AliHFEpid *fPID = new AliHFEpid("hfePid");
319 if(!fPID->GetNumberOfPIDdetectors()) {
320 fPID->AddDetector("TOF",0);
321 fPID->AddDetector("TPC",1);
323 //Add settings for asymmetric cut on nSigma TPC
324 const int paramSize=4;
325 Double_t params[paramSize];
326 memset(params, 0, sizeof(Double_t)*paramSize);
328 fPID->ConfigureTPCdefaultCut(NULL, params, 3.);
329 fPID->InitializePID();
332 AliHFEpid *fPIDOnlyTPC = new AliHFEpid("hfePidTPC");
333 if(!fPIDOnlyTPC->GetNumberOfPIDdetectors()) {
334 fPIDOnlyTPC->AddDetector("TPC",0);
336 fPIDOnlyTPC->ConfigureTPCdefaultCut(NULL, params, 3.);
337 fPIDOnlyTPC->InitializePID();
339 //Create TList of HFE pid and track cuts
340 TList *listHFE = new TList;
341 listHFE->SetName("cut objects HFE");
342 listHFE->Add(hfecuts);
344 listHFE->Add(fPIDOnlyTOF);
347 ///______________________________________________________________________
349 // TODO: Don't think we need the MC part of AliHFCorrelator, needs to be checked
350 AliAnalysisCuts* poolConfiguration=NULL;
351 if (poolConfigFile.IsNull()) {
352 // load the default configuration from below if no file is specified
353 if (system==0) poolConfiguration=createDefaultPoolConfig();
354 else poolConfiguration=createPbPbPoolConfig();
356 // load configuration from file, and abort if something goes wrong
357 TFile* filePoolConfiguration=TFile::Open(poolConfigFile.Data());
358 if(!filePoolConfiguration){
359 ::Error("AddTaskDxHFECorrelation", Form("Pool configuration object file %s not found, exiting", poolConfigFile.Data()));
362 TObject* pObj=filePoolConfiguration->Get(poolInfoName);
364 ::Error("AddTaskDxHFECorrelation", Form("No Pool configuration object with name '%s' found in file %s, exiting", poolInfoName, poolConfigFile.Data()));
367 poolConfiguration = dynamic_cast<AliHFAssociatedTrackCuts*>(pObj);
368 if (!poolConfiguration) {
369 ::Error("AddTaskDxHFECorrelation", Form("Pool configuration object '%s' has inconsistent class type %s, exiting", poolInfoName, pObj->ClassName()));
374 if(!poolConfiguration){
375 ::Fatal("AddTaskDxHFECorrelation", Form("Pool configuration not found"));
378 poolConfiguration->Print();
380 //Taken out, causes problem when adding more than one task
381 /*const char* taskName=AliAnalysisTaskDxHFECorrelation::Class()->GetName();
382 if (pManager->GetTask(taskName)) {
383 ::Warning("AddTaskDxHFECorrelation", Form("task '%s' already existing, skipping ...",
388 AliAnalysisTaskDxHFECorrelation *pTask=new AliAnalysisTaskDxHFECorrelation(taskOptions);
390 ::Error("AddTaskDxHFECorrelation", "failed to create task.");
393 //TODO: Could also consider putting RDHFD0toKpi in a list (ParticleSelectionD0 allows it)
394 pTask->SetCutsD0(RDHFD0toKpi);
395 pTask->SetCutsHFE(listHFE);
396 pTask->SetCuts(poolConfiguration);
398 pManager->AddTask(pTask);
400 // The AnalysisManager handles the output file name in the following way:
401 // The output file names are set by the function SetOutputFiles
402 // If the file name given to the container begins with one of the initialized
403 // file names, the data is stored in the corresponding file in a folder with
404 // the full name specified to the container
405 // E.g. output file has been set to "myanalysis", the container is created with
406 // file name "myanalysis_A", data ends up in file "myanalysis" in folder
408 // IMPORTANT: choosing a file name with a different stem at this point will
409 // probably lead to an empty file.
412 TString cutnameD0="cutsD0Corr";
413 TString cutnameEl="cutsElCorr";
414 TString cutnamePool="PoolInfo";
415 if(triggerParticle==AliDxHFECorrelation::kElectron){
416 cutnameD0+="Eltrigg";
417 cutnameEl+="Eltrigg";
418 cutnamePool+="Eltrigg";
419 listName="HFExDlist";
421 else listName="DxHFElist";
424 cutnameD0+=extraname;
425 cutnameEl+=extraname;
426 cutnamePool+=extraname;
437 if(bEventMixing) ::Info("AddTaskDxHFECorrelation", Form("\ninitializing analysis '%s'%s, output file '%s', Event Mixing Analysis\n", analysisName.Data(), bUseMC?" (using MC)":"", ofilename.Data()));
438 if(!bEventMixing) ::Info("AddTaskDxHFECorrelation", Form("\ninitializing analysis '%s'%s, output file '%s', Single Event Analysis\n", analysisName.Data(), bUseMC?" (using MC)":"", ofilename.Data()));
441 AliAnalysisDataContainer *pContainer=pManager->CreateContainer(listName, TList::Class(), AliAnalysisManager::kOutputContainer, ofilename.Data());
442 AliAnalysisDataContainer *pContainer2=pManager->CreateContainer(cutnameD0,AliRDHFCutsD0toKpi::Class(),AliAnalysisManager::kOutputContainer, ofilename.Data()); //cuts D0
443 AliAnalysisDataContainer *pContainer3=pManager->CreateContainer(cutnameEl,TList::Class(),AliAnalysisManager::kOutputContainer, ofilename.Data()); //cuts El
444 AliAnalysisDataContainer *pContainer4=pManager->CreateContainer(cutnamePool,AliHFAssociatedTrackCuts::Class(),AliAnalysisManager::kOutputContainer, ofilename.Data()); // contains event pool info
446 pManager->ConnectInput(pTask,0,pManager->GetCommonInputContainer());
447 pManager->ConnectOutput(pTask,1,pContainer);
448 pManager->ConnectOutput(pTask,2,pContainer2);
449 pManager->ConnectOutput(pTask,3,pContainer3);
450 pManager->ConnectOutput(pTask,4,pContainer4);
455 // old signature kept for backward compatibility
456 int AddTaskDxHFECorrelation(Bool_t bUseMC, TString analysisName)
458 TString arguments(bUseMC?"mc":"");
459 if (!analysisName.IsNull()) {
460 arguments+=Form(" name=%s", analysisName.Data())
462 AddTaskDxHFECorrelation(arguments)
465 // Note: AliHFAssociatedTrackCuts keeps an instance of the external
466 // pointer, the arrays thus need to be global
467 // TODO: try a proper implementation of AliHFAssociatedTrackCuts later
468 const Int_t nofMBins=5;
469 const Double_t MBins[nofMBins+1]={0,20,40,60,80,500};
470 const Double_t * MultiplicityBins = MBins;
471 const Int_t nofZBins=5;
472 const Double_t ZBins[nofZBins+1]={-10,-5,-2.5,2.5,5,10};
473 const Double_t *ZVrtxBins = ZBins;
475 AliAnalysisCuts* createDefaultPoolConfig()
477 AliHFAssociatedTrackCuts* HFCorrelationCuts=new AliHFAssociatedTrackCuts();
478 HFCorrelationCuts->SetName("PoolInfo");
479 HFCorrelationCuts->SetTitle("Info on Pool for EventMixing");
481 // NEED to check this
482 HFCorrelationCuts->SetMaxNEventsInPool(200);
483 HFCorrelationCuts->SetMinNTracksInPool(100);
484 HFCorrelationCuts->SetMinEventsToMix(8);
485 HFCorrelationCuts->SetNofPoolBins(nofZBins,nofMBins); // Note: the arrays have dimension x+1
486 HFCorrelationCuts->SetPoolBins(ZVrtxBins,MultiplicityBins);
488 TString description = "Info on Pool for EventMixing";
489 HFCorrelationCuts->AddDescription(description);
491 return HFCorrelationCuts;
494 AliAnalysisCuts* createPbPbPoolConfig()
496 AliHFAssociatedTrackCuts* HFCorrelationCuts=new AliHFAssociatedTrackCuts();
497 HFCorrelationCuts->SetName("PoolInfo");
498 HFCorrelationCuts->SetTitle("Info on Pool for EventMixing");
500 // NEED to check this
501 HFCorrelationCuts->SetMaxNEventsInPool(250);
502 HFCorrelationCuts->SetMinNTracksInPool(80);
503 HFCorrelationCuts->SetMinEventsToMix(5);
504 HFCorrelationCuts->SetNofPoolBins(nofZBins,nofMBins); // Note: the arrays have dimension x+1
505 HFCorrelationCuts->SetPoolBins(ZVrtxBins,MultiplicityBins);
507 TString description = "Info on Pool for EventMixing";
508 HFCorrelationCuts->AddDescription(description);
510 return HFCorrelationCuts;