3 //**************************************************************************
4 //* This file is property of and copyright by the ALICE Project *
5 //* ALICE Experiment at CERN, All rights reserved. *
7 //* Primary Authors: Matthias Richter <Matthias.Richter@ift.uib.no> *
8 //* Sedat Altinpinar <Sedat.Altinpinar@cern.ch> *
9 //* Hege Erdal <hege.erdal@gmail.com> *
11 //* Permission to use, copy, modify and distribute this software and its *
12 //* documentation strictly for non-commercial purposes is hereby granted *
13 //* without fee, provided that the above copyright notice appears in all *
14 //* copies and that both the copyright notice and this permission notice *
15 //* appear in the supporting documentation. The authors make no claims *
16 //* about the suitability of this software for any purpose. It is *
17 //* provided "as is" without express or implied warranty. *
18 //**************************************************************************
20 /// @file AliDxHFEParticleSelectionD0.cxx
21 /// @author Sedat Altinpinar, Hege Erdal, Matthias Richter
23 /// @brief D0 selection for D0-HFE correlation
26 #include "AliDxHFEParticleSelectionD0.h"
27 #include "AliVParticle.h"
28 //#include "AliAnalysisCuts.h" // required dependency libANALYSISalice.so
29 //#include "AliFlowTrackSimple.h" // required dependency libPWGflowBase.so
30 //#include "AliFlowCandidateTrack.h" // required dependency libPWGflowTasks.so
31 //#include "AliCFContainer.h" // required dependency libCORRFW.so
32 #include "AliAODRecoDecayHF2Prong.h" // libPWGHFvertexingHF
33 #include "AliRDHFCutsD0toKpi.h"
34 #include "TObjArray.h"
35 #include "THnSparse.h"
36 #include "AliReducedParticle.h"
45 /// ROOT macro for the implementation of ROOT specific class methods
46 ClassImp(AliDxHFEParticleSelectionD0)
48 AliDxHFEParticleSelectionD0::AliDxHFEParticleSelectionD0(const char* opt)
49 : AliDxHFEParticleSelection("D0", opt)
67 AliDxHFEParticleSelectionD0::~AliDxHFEParticleSelectionD0()
87 // Note: external object deleted elsewhere
91 const char* AliDxHFEParticleSelectionD0::fgkDgTrackControlBinNames[]={
99 const char* AliDxHFEParticleSelectionD0::fgkCutBinNames[]={
102 "IsInFiducialAcceptance",
112 int AliDxHFEParticleSelectionD0::InitControlObjects()
114 /// init the control objects, can be overloaded by childs which should
115 /// call AliDxHFEParticleSelection::InitControlObjects() explicitly
117 fD0Properties=DefineTHnSparse();
118 AddControlObject(fD0Properties);
120 //Adding control objects for the daughters
121 InitControlObjectsDaughters("pi information",0);
122 InitControlObjectsDaughters("K information",1);
123 AliInfo(Form("D0 filling scheme: %d\n",fFillOnlyD0D0bar));
125 fHistoList=new TList;
126 fHistoList->SetName("D0 Histograms");
127 fHistoList->SetOwner();
129 // Histogram storing which cuts have been applied to the tracks
130 fHistoList->Add(CreateControlHistogram("fWhichCutD0","effective cut for a rejected particle", kNCutLabels, fgkCutBinNames));
132 AddControlObject(fHistoList);
134 return AliDxHFEParticleSelection::InitControlObjects();
137 THnSparse* AliDxHFEParticleSelectionD0::DefineTHnSparse()
140 // Defines the THnSparse.
142 // here is the only place to change the dimension
143 const int thnSize2 = 5;
144 InitTHnSparseArray(thnSize2);
146 const double Pi=TMath::Pi();
148 name.Form("%s info", GetName());
151 // Pt Phi Ptbin D0InvMass Eta
152 int thnBins [thnSize2] = {1000, 200, 15, 200, 500 };
153 double thnMin [thnSize2] = { 0, 0, 0, 1.5648, -1. };
154 double thnMax [thnSize2] = { 100, 2*Pi, 14, 2.1648, 1. };
155 const char* thnNames[thnSize2] = {"Pt", "Phi","Ptbin","D0InvMass","Eta"};
157 return CreateControlTHnSparse(name,thnSize2,thnBins,thnMin,thnMax,thnNames);
160 int AliDxHFEParticleSelectionD0::FillParticleProperties(AliVParticle* p, Double_t* data, int dimension) const
162 // fill the data array from the particle data
163 if (!data) return -EINVAL;
164 AliAODRecoDecayHF2Prong* track=dynamic_cast<AliAODRecoDecayHF2Prong*>(p);
165 if (!track) return -ENODATA;
167 if (dimension!=GetDimTHnSparse()) {
168 // TODO: think about filling only the available data and throwing a warning
171 data[i++]=track->Pt();
172 data[i++]=track->Phi();
174 data[i++]=fD0InvMass;
175 data[i++]=track->Eta();
180 int AliDxHFEParticleSelectionD0::InitControlObjectsDaughters(TString name, int daughter)
182 // Setting up Control objects for the daughters.
183 // Move to ParticleSelection??
184 AliInfo("Setting up daughter THnSparse");
186 const int thnSize2 = 5;
187 const double Pi=TMath::Pi();
189 // Pt Phi Ptbin D0InvMass Eta
190 int thnBins[thnSize2] = { 1000, 200, 21, 200, 500};
191 double thnMin [thnSize2] = { 0, 0, 0, 1.5648, -1.};
192 double thnMax [thnSize2] = { 100, 2*Pi, 20, 2.1648, 1.};
194 std::auto_ptr<THnSparseF> DaughterProperties(new THnSparseF(name, name, thnSize2, thnBins, thnMin, thnMax));
196 if (DaughterProperties.get()==NULL) {
200 for(int iLabel=0; iLabel< 5;iLabel++)
201 DaughterProperties->GetAxis(iLabel)->SetTitle(fgkDgTrackControlBinNames[iLabel]);
204 fD0Daughter0=DaughterProperties.release();
205 AddControlObject(fD0Daughter0);
209 fD0Daughter1=DaughterProperties.release();
210 AddControlObject(fD0Daughter1);
215 int AliDxHFEParticleSelectionD0::HistogramParticleProperties(AliVParticle* p, int selectionCode)
218 /// histogram particle properties
219 if (!p) return -EINVAL;
221 // fill the common histograms
222 AliDxHFEParticleSelection::HistogramParticleProperties(p, selectionCode);
224 // no daughters to fill if 0 (= no candidate)
225 if (selectionCode==0) return 0;
227 AliAODRecoDecayHF2Prong* part=dynamic_cast<AliAODRecoDecayHF2Prong*>(p);
230 // Convention: 1. daughter is postive track, 2. = negative
231 AliAODTrack *prongpos=(AliAODTrack*)part->GetDaughter(0);
232 AliAODTrack *prongneg=(AliAODTrack*)part->GetDaughter(1);
234 if(!prongpos || !prongneg) {
238 fD0InvMass= part->InvMassD0();
239 fPtBin=fCuts->PtBin(part->Pt());
241 // TODO: avoid repeated allocation of the arrays
242 Double_t KProperties[]={prongneg->Pt(),prongneg->Phi(),(Double_t)fPtBin, fD0InvMass,prongneg->Eta()};
243 Double_t piProperties[]={prongpos->Pt(),prongpos->Phi(),(Double_t)fPtBin,fD0InvMass,prongpos->Eta()};
246 // Fills only for D0 or both..
247 if ((selectionCode==1 || selectionCode==3) && fFillOnlyD0D0bar<2) {
249 if(fD0Properties && ParticleProperties()) {
250 memset(ParticleProperties(), 0, GetDimTHnSparse()*sizeof(ParticleProperties()[0]));
251 FillParticleProperties(p, ParticleProperties(), GetDimTHnSparse());
252 fD0Properties->Fill(ParticleProperties());
254 if(fD0Daughter0) fD0Daughter0->Fill(piProperties);
255 if(fD0Daughter1) fD0Daughter1->Fill(KProperties);
257 // Checks for D0bar (or hypothesis both)
258 if ((selectionCode==2 || selectionCode==3) && (fFillOnlyD0D0bar==0 || fFillOnlyD0D0bar==2)) {
259 // Set the fD0InvMass to InvMassD0bar instead..
260 fD0InvMass= part->InvMassD0bar();
261 if(fD0Properties && ParticleProperties()) {
262 memset(ParticleProperties(), 0, GetDimTHnSparse()*sizeof(ParticleProperties()[0]));
263 FillParticleProperties(p, ParticleProperties(), GetDimTHnSparse());
264 fD0Properties->Fill(ParticleProperties());
266 if(fD0Daughter0) fD0Daughter0->Fill(piProperties);
267 if(fD0Daughter1) fD0Daughter1->Fill(KProperties);
268 //reset value to InvMassD0 for when CreateParticle() is called
269 fD0InvMass= part->InvMassD0();
275 TObjArray* AliDxHFEParticleSelectionD0::Select(TObjArray* pTracks, const AliVEvent *pEvent)
277 /// create selection, array contains only pointers but does not own the objects
278 /// object array needs to be deleted by caller
279 if (!pTracks) return NULL;
280 TObjArray* selectedTracks=new TObjArray;
281 if (!selectedTracks) return NULL;
282 selectedTracks->SetOwner(kFALSE);
283 TIter itrack(pTracks);
285 while ((pObj=itrack())!=NULL) {
286 AliVParticle* track=dynamic_cast<AliVParticle*>(pObj);
287 if (!track) continue;
288 int selectionCode=IsSelected(track,pEvent);
289 HistogramParticleProperties(track, selectionCode);
291 // Add track if it is either defined as D0(selectionCode==1) or both
292 // D0bar and a D0 (selectionCode==3)
293 if ((selectionCode==1 || selectionCode==3) && fFillOnlyD0D0bar<2)
294 selectedTracks->Add(CreateParticle(track));
296 // Add track if it is either defined as D0bar(selectionCode==2) or both
297 // D0bar and a D0 (selectionCode==3)
298 if ((selectionCode==2 || selectionCode==3) && (fFillOnlyD0D0bar==0 || fFillOnlyD0D0bar==2)){
299 AliAODRecoDecayHF2Prong* prong=dynamic_cast<AliAODRecoDecayHF2Prong*>(track);
300 fD0InvMass=prong?prong->InvMassD0bar():0.;
301 selectedTracks->Add(CreateParticle(track));
305 HistogramEventProperties(AliDxHFEParticleSelection::kHistoNrTracksPrEvent,selectedTracks->GetEntries());
306 return selectedTracks;
309 int AliDxHFEParticleSelectionD0::IsSelected(AliVParticle* p, const AliVEvent* pEvent)
311 /// TODO: implement specific selection of D0 candidates
312 /// Could also return values based on where where selection "failed
313 /// Selected. Return 0 (none), 1(D0), 2(D0bar) or 3 (both)
317 AliAODRecoDecayHF2Prong *d0 = dynamic_cast<AliAODRecoDecayHF2Prong*>(p);
319 if(d0->GetSelectionMap()) if(!d0->HasSelectionBit(AliRDHFCuts::kD0toKpiCuts)){
320 AliDebug(1,"Skip D0 from Dstar");
321 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kDstar);
323 return 0; //skip the D0 from Dstar
326 // TODO: the cuts instance should be const but the function definition of
327 // AliRDHFCuts::IsSelected does not allow this
328 AliRDHFCuts* cuts=const_cast<AliRDHFCuts*>(fCuts);
332 else if(cuts->IsInFiducialAcceptance(d0->Pt(),d0->Y(421)) ) {
334 // TODO: the aod pointer should also be const but the function definition of
335 // AliRDHFCuts::IsSelected does not allow this
336 AliAODEvent* aod=NULL;
337 if (pEvent) aod=dynamic_cast<AliAODEvent*>(const_cast<AliVEvent*>(pEvent));
339 //TODO: Should add fSystem for PbPb if(fSys==0){
340 if(cuts->IsSelected(d0,AliRDHFCuts::kTracks,aod)) ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kCandSelTrack);
342 Int_t ptbin=cuts->PtBin(d0->Pt());
344 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kNegPtbin);
345 AliDebug(1,"Pt out of bounds");
349 // Selected. Return 0 (none), 1 (D0), 2 (D0bar) or 3 (both)
350 selectionCode=cuts->IsSelected(d0,AliRDHFCuts::kAll,aod);
352 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kSelected0);
355 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kSelectedD0);
358 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kSelectedD0bar);
361 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kSelectedboth);
363 AliDebug(1,Form("Candidate is %d \n", selectionCode));
365 // check daughters before calling as there is unchecked code in
366 // AliAODRecoDecayHF::HasBadDaughters called
368 if (!((o=d0->GetDaughter(0))!=NULL && dynamic_cast<AliAODTrack*>(o)!=NULL &&
369 (o=d0->GetDaughter(1))!=NULL && dynamic_cast<AliAODTrack*>(o)!=NULL)) {
370 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kNoDaugthers);
371 AliDebug(1,"at least one daughter not found!");
376 ((TH1D*)fHistoList->FindObject("fWhichCutD0"))->Fill(kIsInFinducialAcceptance);
379 return selectionCode;
382 void AliDxHFEParticleSelectionD0::SetCuts(TObject* cuts, int level)
386 fCuts=dynamic_cast<AliRDHFCuts*>(cuts);
387 if (!fCuts && cuts) {
388 AliError(Form("cuts object is not of required type AliRDHFCuts but %s", cuts->ClassName()));
392 if (level==kCutList){
393 TList* CutList=dynamic_cast<TList*>(cuts);
394 if (!CutList && cuts) {
395 AliError(Form("cuts object is not of required type TList but %s", cuts->ClassName()));
401 while((obj = next())){
404 fCuts=dynamic_cast<AliRDHFCuts*>(obj);
406 AliError(Form("Cut object is not of required type AliRDHFCuts but %s", obj->ClassName()));
415 int AliDxHFEParticleSelectionD0::ParseArguments(const char* arguments)
417 // parse arguments and set internal flags
418 TString strArguments(arguments);
419 auto_ptr<TObjArray> tokens(strArguments.Tokenize(" "));
420 if (!tokens.get()) return 0;
422 AliInfo(strArguments);
423 TIter next(tokens.get());
425 while ((token=next())) {
426 TString argument=token->GetName();
427 if (argument.BeginsWith("fillD0scheme=")){
428 argument.ReplaceAll("fillD0scheme=", "");
429 if (argument.CompareTo("both")==0){ fFillOnlyD0D0bar=0;}
430 else if (argument.CompareTo("D0")==0){ fFillOnlyD0D0bar=1;}
431 else if (argument.CompareTo("D0bar")==0){ fFillOnlyD0D0bar=2;}
433 AliWarning(Form("can not set D0 filling scheme, unknown parameter '%s'", argument.Data()));
438 // forwarding of single argument works, unless key-option pairs separated
439 // by blanks are introduced
440 AliDxHFEParticleSelection::ParseArguments(argument);
446 AliVParticle *AliDxHFEParticleSelectionD0::CreateParticle(AliVParticle* track)
449 // Creates object containing only the variables needed for correlation
452 AliReducedParticle *part = new AliReducedParticle(track->Eta(), track->Phi(), track->Pt(),fD0InvMass,fPtBin);