]>
Commit | Line | Data |
---|---|---|
d731501a | 1 | // $Id$ |
2 | ||
3 | //************************************************************************** | |
4 | //* This file is property of and copyright by the ALICE Project * | |
5 | //* ALICE Experiment at CERN, All rights reserved. * | |
6 | //* * | |
7 | //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> * | |
8 | //* Hege Erdal <hege.erdal@gmail.com> * | |
9 | //* * | |
10 | //* Permission to use, copy, modify and distribute this software and its * | |
11 | //* documentation strictly for non-commercial purposes is hereby granted * | |
12 | //* without fee, provided that the above copyright notice appears in all * | |
13 | //* copies and that both the copyright notice and this permission notice * | |
14 | //* appear in the supporting documentation. The authors make no claims * | |
15 | //* about the suitability of this software for any purpose. It is * | |
16 | //* provided "as is" without express or implied warranty. * | |
17 | //************************************************************************** | |
18 | ||
19 | /// @file AliDxHFEParticleSelectionMCD0.cxx | |
20 | /// @author Hege Erdal, Matthias Richter | |
21 | /// @date 2012-07-19 | |
22 | /// @brief MC D0 selection for D0-HFE correlation | |
23 | /// | |
24 | ||
25 | #include "AliDxHFEParticleSelectionMCD0.h" | |
26 | #include "AliAODRecoDecayHF2Prong.h" | |
27 | #include "AliAODTrack.h" | |
28 | #include "AliAODMCParticle.h" | |
b4779749 | 29 | #include "AliRDHFCuts.h" |
d731501a | 30 | #include "AliVParticle.h" |
dfe96b90 | 31 | #include "AliReducedParticle.h" |
b4779749 | 32 | #include "THnSparse.h" |
dfe96b90 | 33 | #include "TH1F.h" |
d731501a | 34 | #include <iostream> |
35 | #include <cerrno> | |
36 | #include <memory> | |
37 | ||
38 | using namespace std; | |
39 | ||
40 | /// ROOT macro for the implementation of ROOT specific class methods | |
41 | ClassImp(AliDxHFEParticleSelectionMCD0) | |
42 | ||
d731501a | 43 | AliDxHFEParticleSelectionMCD0::AliDxHFEParticleSelectionMCD0(const char* opt) |
44 | : AliDxHFEParticleSelectionD0(opt) | |
45 | , fMCTools() | |
dfe96b90 | 46 | , fPDGnotMCD0(NULL) |
d731501a | 47 | , fResultMC(0) |
48 | , fOriginMother(0) | |
b4779749 | 49 | , fUseKine(kFALSE) |
50 | , fD0PropertiesKine(NULL) | |
d731501a | 51 | { |
52 | // constructor | |
53 | // | |
54 | // | |
55 | // | |
b4779749 | 56 | // TODO: Could implement ParseArgument if need more arguments for MC |
57 | TString strOption(opt); | |
58 | AliInfo(strOption.Data()); | |
59 | if (strOption.Contains("usekine")) fUseKine=kTRUE; | |
d731501a | 60 | |
61 | // TODO: argument scan, pass only relevant arguments to tools | |
62 | fMCTools.~AliDxHFEToolsMC(); | |
63 | TString toolopt("pdg=421 mc-last"); | |
b4779749 | 64 | if(fUseKine) toolopt+=" usekine"; |
d731501a | 65 | new (&fMCTools) AliDxHFEToolsMC(toolopt); |
66 | } | |
67 | ||
68 | AliDxHFEParticleSelectionMCD0::~AliDxHFEParticleSelectionMCD0() | |
69 | { | |
70 | // destructor | |
b4779749 | 71 | if (fD0PropertiesKine) { |
72 | delete fD0PropertiesKine; | |
73 | fD0PropertiesKine=NULL; | |
74 | } | |
75 | if(fPDGnotMCD0){ | |
76 | delete fPDGnotMCD0; | |
77 | fPDGnotMCD0=NULL; | |
78 | } | |
79 | } | |
80 | ||
81 | int AliDxHFEParticleSelectionMCD0::InitControlObjects() | |
82 | { | |
83 | /// init the control objects, can be overloaded by childs which should | |
84 | /// call AliDxHFEParticleSelection::InitControlObjects() explicitly | |
85 | AliInfo("Setting up control objects"); | |
86 | ||
87 | if(fUseKine) { | |
88 | fD0PropertiesKine=DefineTHnSparse(); | |
89 | AddControlObject(fD0PropertiesKine); | |
90 | return AliDxHFEParticleSelection::InitControlObjects(); | |
91 | } | |
92 | else{ | |
93 | return AliDxHFEParticleSelectionD0::InitControlObjects(); | |
94 | } | |
d731501a | 95 | } |
dcf83226 | 96 | |
97 | THnSparse* AliDxHFEParticleSelectionMCD0::DefineTHnSparse() | |
d731501a | 98 | { |
99 | // | |
100 | // Defines the THnSparse. | |
d731501a | 101 | |
dcf83226 | 102 | // here is the only place to change the dimension |
dfe96b90 | 103 | const int thnSize2 = 6; |
dcf83226 | 104 | InitTHnSparseArray(thnSize2); |
d731501a | 105 | const double Pi=TMath::Pi(); |
106 | TString name; | |
107 | name.Form("%s info", GetName()); | |
108 | ||
dfe96b90 | 109 | // 0 1 2 3 4 5 |
110 | // Pt Phi Ptbin D0InvMass Eta mother | |
111 | int thnBins [thnSize2] = {1000, 200, 15, 200, 500, 10 }; | |
112 | double thnMin [thnSize2] = { 0, 0, 0, 1.5648, -1., -1.5 }; | |
113 | double thnMax [thnSize2] = { 100, 2*Pi, 14, 2.1648, 1., 8.5 }; | |
dcf83226 | 114 | const char* thnNames[thnSize2] = { |
115 | "Pt", | |
116 | "Phi", | |
117 | "Ptbin", | |
118 | "D0InvMass", | |
119 | "Eta", | |
dfe96b90 | 120 | "Mother of D0" // Bin -1 = not MC truth D0, rest OK |
dcf83226 | 121 | }; |
122 | ||
dfe96b90 | 123 | // Add Histo displaying pdg of D0 candidates not passing MatchToMC() |
b4779749 | 124 | // TODO: Add it to the TList of D0 main class |
dfe96b90 | 125 | fPDGnotMCD0= new TH1F("fPDGnotMCD0","PDG of track not MC truth D0",1002,-2.5,999.5); |
126 | AddControlObject(fPDGnotMCD0); | |
127 | ||
dcf83226 | 128 | return CreateControlTHnSparse(name,thnSize2,thnBins,thnMin,thnMax,thnNames); |
d731501a | 129 | } |
130 | ||
b4779749 | 131 | int AliDxHFEParticleSelectionMCD0::HistogramParticleProperties(AliVParticle* p, int selectionCode) |
132 | { | |
133 | ||
134 | // When looping on kinematical level, need a different HistogramParticleProperties than on reconstructed tracks | |
135 | if(fUseKine){ | |
136 | /// histogram particle properties | |
137 | if (!p) return -EINVAL; | |
138 | ||
139 | // fill the common histograms | |
140 | AliDxHFEParticleSelection::HistogramParticleProperties(p, selectionCode); | |
141 | ||
142 | // no daughters to fill if 0 (= no candidate) | |
143 | if (selectionCode==0){ | |
144 | return 0; | |
145 | } | |
146 | AliAODMCParticle* partMC=dynamic_cast<AliAODMCParticle*>(p); | |
147 | ||
148 | if(!partMC) { | |
149 | return 0; | |
150 | } | |
151 | ||
152 | SetInvMass(partMC->GetCalcMass()); | |
153 | AliRDHFCuts *cuts=GetHFCuts(); | |
154 | int ptbin=cuts->PtBin(partMC->Pt()); | |
155 | SetPtBin(ptbin); | |
156 | ||
157 | // Fills only for D0 or both.. | |
158 | if ((selectionCode==1 || selectionCode==3) && GetFillOnlyD0D0bar()<2) { | |
159 | if(fD0PropertiesKine && ParticleProperties()) { | |
160 | memset(ParticleProperties(), 0, GetDimTHnSparse()*sizeof(ParticleProperties()[0])); | |
161 | FillParticleProperties(p, ParticleProperties(), GetDimTHnSparse()); | |
162 | fD0PropertiesKine->Fill(ParticleProperties()); | |
163 | } | |
164 | } | |
165 | ||
166 | // Fills for D0bar or both | |
167 | if ((selectionCode==1 || selectionCode==2) && (GetFillOnlyD0D0bar()==0 || GetFillOnlyD0D0bar()==2)) { | |
168 | if(fD0PropertiesKine && ParticleProperties()) { | |
169 | memset(ParticleProperties(), 0, GetDimTHnSparse()*sizeof(ParticleProperties()[0])); | |
170 | FillParticleProperties(p, ParticleProperties(), GetDimTHnSparse()); | |
171 | fD0PropertiesKine->Fill(ParticleProperties()); | |
172 | } | |
173 | ||
174 | } | |
175 | return 0; | |
176 | } | |
177 | else { | |
178 | return AliDxHFEParticleSelectionD0::HistogramParticleProperties(p,selectionCode); | |
179 | } | |
180 | } | |
181 | ||
dcf83226 | 182 | int AliDxHFEParticleSelectionMCD0::FillParticleProperties(AliVParticle* p, Double_t* data, int dimension) const |
d731501a | 183 | { |
184 | // fill the data array from the particle data | |
185 | if (!data) return -EINVAL; | |
186 | AliAODTrack *track=(AliAODTrack*)p; | |
187 | if (!track) return -ENODATA; | |
188 | int i=0; | |
dcf83226 | 189 | if (dimension!=GetDimTHnSparse()) { |
d731501a | 190 | // TODO: think about filling only the available data and throwing a warning |
191 | return -ENOSPC; | |
192 | } | |
193 | data[i++]=track->Pt(); | |
194 | data[i++]=track->Phi(); | |
195 | data[i++]=AliDxHFEParticleSelectionMCD0::GetPtBin(); | |
196 | data[i++]=AliDxHFEParticleSelectionMCD0::GetInvMass(); | |
197 | data[i++]=track->Eta(); | |
d731501a | 198 | data[i++]=fOriginMother; // at the moment not included background. Should expand |
199 | ||
200 | return i; | |
201 | } | |
202 | ||
203 | int AliDxHFEParticleSelectionMCD0::IsSelected(AliVParticle* p, const AliVEvent* pEvent) | |
204 | { | |
205 | /// overloaded from AliDxHFEParticleSelection: check particle | |
206 | /// H: Have changed function. Now doing particle selection first, then run MC over | |
207 | /// selected tracks. Could configure it to be configurable, but not sure if it | |
208 | /// is needed. | |
209 | /// result from normal track selection is returned, result from MC is stored in | |
210 | /// THnSparse. | |
211 | ||
212 | int iResult=0; | |
213 | fOriginMother=-1; | |
b4779749 | 214 | if(fUseKine){ |
215 | // Will here loop on all tracks in the stack, and checks whether they are D0s (through CheckMCParticle()) | |
216 | if (!fMCTools.IsInitialized() && (iResult=fMCTools.InitMCParticles(pEvent))<0) { | |
217 | return 0; // no meaningful filtering on mc possible | |
218 | } | |
d731501a | 219 | |
b4779749 | 220 | Int_t result = fMCTools.CheckMCParticle(p); |
221 | if(result==1) return 0; | |
222 | fMCTools.FindMotherPDG(p); | |
223 | fOriginMother=fMCTools.GetOriginMother(); | |
224 | //TODO: Should also return whether D0 or D0bar... at the moment only care of absolute value of D0 | |
225 | return 1; | |
226 | } | |
227 | else{ | |
d731501a | 228 | // step 1: |
229 | // MC selection | |
230 | if (fMCTools.MCFirst() && (iResult=CheckMC(p, pEvent))==0) { | |
231 | // histograming? | |
232 | return iResult; | |
233 | } | |
234 | ||
235 | // step 2 or 1, depending on sequence: | |
236 | // normal particle selection | |
237 | iResult=AliDxHFEParticleSelectionD0::IsSelected(p, pEvent); | |
238 | if (fMCTools.MCFirst() || iResult==0) return iResult; | |
239 | ||
240 | // step 2, only executed if MC check is last | |
241 | // MC selection - > Should maybe also distinguish between D0 and D0bar | |
dcf83226 | 242 | // result stored to be filled into THnSparse |
243 | // TODO: strictly speaken the particles should be rejected | |
244 | // if not mc selected, however skip this for the moment, because of | |
245 | // the logic outside | |
246 | fResultMC=CheckMC(p, pEvent); | |
dfe96b90 | 247 | |
d731501a | 248 | return iResult; |
b4779749 | 249 | } |
250 | ||
251 | return 0; | |
d731501a | 252 | } |
253 | ||
254 | int AliDxHFEParticleSelectionMCD0::CheckMC(AliVParticle* p, const AliVEvent* pEvent) | |
255 | { | |
256 | /// check if MC criteria are fulfilled | |
257 | // Check both D0 and D0bar (for now only D0) | |
258 | ||
259 | if (!p || !pEvent){ | |
260 | return -EINVAL; | |
261 | } | |
262 | int iResult=0; | |
263 | ||
264 | if (!fMCTools.IsInitialized() && (iResult=fMCTools.InitMCParticles(pEvent))<0) { | |
265 | // TODO: message? but has to be filtered in order to avoid message flood | |
266 | return 0; // no meaningful filtering on mc possible | |
267 | } | |
268 | ||
269 | AliAODRecoDecayHF2Prong *particle = dynamic_cast<AliAODRecoDecayHF2Prong*>(p); | |
270 | ||
271 | if(!particle) return 0; | |
272 | ||
273 | Int_t pdgDgD0toKpi[2]={AliDxHFEToolsMC::kPDGkaon,AliDxHFEToolsMC::kPDGpion}; | |
274 | ||
275 | TClonesArray* fMCArray = dynamic_cast<TClonesArray*>(fMCTools.GetMCArray()); | |
276 | if(!fMCArray) {cout << "no array" << endl; return -1;} | |
277 | ||
278 | // find associated MC particle for D0->Kpi | |
279 | Int_t MClabel=-9999; | |
280 | ||
281 | //return MC particle label if the array corresponds to a D0, -1 if not (cf. AliAODRecoDecay.cxx). Checks both D0s and daughters | |
282 | MClabel=particle->MatchToMC(AliDxHFEToolsMC::kPDGD0,fMCArray,2,pdgDgD0toKpi); | |
283 | ||
2229ac91 | 284 | //TODO: Need a different strategy!!! |
285 | // ALSO: look at AliAnalysisTaskSED0Mass for tips | |
d731501a | 286 | if(MClabel<0){ |
dfe96b90 | 287 | // Checking PDG of particle if not MC truth D0 |
288 | // TODO: done the right way?? | |
289 | Int_t MCl = p->GetLabel(); | |
290 | if(MCl<0) { | |
291 | fPDGnotMCD0->Fill(-2); | |
292 | return 0; | |
293 | } | |
294 | int pdgPart=-1; | |
295 | AliAODMCParticle* aodmcp=0; | |
296 | aodmcp=dynamic_cast<AliAODMCParticle*>(fMCArray->At(MCl)); | |
297 | if (aodmcp) | |
298 | pdgPart=TMath::Abs(aodmcp->GetPdgCode()); | |
299 | if (pdgPart<0){ | |
300 | fPDGnotMCD0->Fill(-1); | |
301 | return 0; | |
302 | } | |
303 | else{ | |
304 | fPDGnotMCD0->Fill(pdgPart); | |
305 | } | |
d731501a | 306 | fOriginMother=-1; |
307 | return 0; | |
308 | } | |
309 | ||
310 | fMCTools.SetMClabel(MClabel); | |
311 | fMCTools.FindMotherPDG(p,AliDxHFEToolsMC::kGetOriginMother); | |
312 | fOriginMother=fMCTools.GetOriginMother(); | |
313 | ||
314 | return 1; | |
315 | } | |
316 | ||
317 | void AliDxHFEParticleSelectionMCD0::Clear(const char* option) | |
318 | { | |
319 | /// clear internal memory | |
320 | fMCTools.Clear(option); | |
321 | } | |
dfe96b90 | 322 | |
323 | AliVParticle *AliDxHFEParticleSelectionMCD0::CreateParticle(AliVParticle* track) | |
324 | { | |
325 | // | |
326 | //Created object which contain variables needed for correlation. | |
327 | // | |
328 | ||
329 | AliReducedParticle *part = new AliReducedParticle(track->Eta(), track->Phi(), track->Pt(),AliDxHFEParticleSelectionMCD0::GetInvMass(),AliDxHFEParticleSelectionMCD0::GetPtBin(), fOriginMother); | |
330 | ||
331 | return part; | |
332 | ||
333 | } |