--- /dev/null
+#! /bin/bash
+
+make
--- /dev/null
+{
+ gSystem->Load("libDielectron.so");
+ // Set the include paths
+ gROOT->ProcessLine(".include Dielectron");
+
+ // Set our location, so that other packages can find us
+ gSystem->Setenv("Dielectron_INCLUDE", "Dielectron");
+
+}
--- /dev/null
+#ifdef __CINT__
+/* Copyright(c) 1998-1999, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+#pragma link off all globals;
+#pragma link off all classes;
+#pragma link off all functions;
+
+#pragma link C++ class AliDielectron+;
+#pragma link C++ class AliDielectronPair+;
+#pragma link C++ class AliDielectronHistos+;
+#pragma link C++ class AliDielectronCF+;
+#pragma link C++ class AliDielectronMC+;
+#pragma link C++ class AliDielectronVarManager+;
+#pragma link C++ class AliAnalysisTaskDielectronSE+;
+#pragma link C++ class AliAnalysisTaskDielectronFilter+;
+#pragma link C++ class AliAnalysisTaskDielectronEfficiency+;
+#pragma link C++ class AliAnalysisTaskMultiDielectron+;
+#pragma link C++ class AliDielectronVarCuts+;
+#pragma link C++ class AliDielectronPairLegCuts+;
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+//#####################################################
+//# #
+//# Simple efficiency study for dielectrons #
+//# Author: Jens Wiechula Jens.Wiechula@cern.ch #
+//# #
+//#####################################################
+
+#include <TParticle.h>
+#include <TParticlePDG.h>
+#include <TDatabasePDG.h>
+#include <TROOT.h>
+#include "TChain.h"
+#include <TCanvas.h>
+// #include "TTree.h"
+#include <TH1.h>
+#include <TH2F.h>
+#include <THashList.h>
+
+#include "AliAnalysisManager.h"
+
+#include "AliESDInputHandler.h"
+#include "AliMCEventHandler.h"
+#include "AliMCEvent.h"
+#include "AliVEvent.h"
+#include "AliESDEvent.h"
+#include "AliESDtrack.h"
+#include "AliStack.h"
+#include "AliKFParticle.h"
+#include "AliESDtrackCuts.h"
+#include "AliKineTrackCuts.h"
+#include "AliLog.h"
+
+#include "AliDielectronHistos.h"
+#include "AliAnalysisTaskDielectronEfficiency.h"
+
+ClassImp(AliAnalysisTaskDielectronEfficiency)
+
+
+//=================================================================================
+AliAnalysisTaskDielectronEfficiency::AliAnalysisTaskDielectronEfficiency() :
+ AliAnalysisTask(),
+ fInputEvent(0),
+ fHist(0),
+ fESDtrackCuts(0),
+ fKineCutsLegs(0),
+ fKineCutsMother(0),
+ fIdMCMother(443),
+ fIdMCDaughterP(-11),
+ fIdMCDaughterN(11),
+ fPDG(TDatabasePDG::Instance())
+{
+}
+
+//=================================================================================
+AliAnalysisTaskDielectronEfficiency::AliAnalysisTaskDielectronEfficiency(const char *name) :
+ AliAnalysisTask(name,name),
+ fInputEvent(0),
+ fHist(0),
+ fESDtrackCuts(new AliESDtrackCuts),
+ fKineCutsLegs(new AliKineTrackCuts),
+ fKineCutsMother(new AliKineTrackCuts),
+ fIdMCMother(443),
+ fIdMCDaughterP(-11),
+ fIdMCDaughterN(11),
+ fPDG(TDatabasePDG::Instance())
+{
+ //
+ // named constructor. This is the one that should be used by the user, oterwise the
+ // essential objects are not created!
+ //
+ DefineInput(0,TChain::Class());
+ DefineOutput(0, THashList::Class());
+}
+
+//=================================================================================
+AliAnalysisTaskDielectronEfficiency::~AliAnalysisTaskDielectronEfficiency()
+{
+ //
+ // dtor
+ //
+ if (fESDtrackCuts) delete fESDtrackCuts;
+ if (fKineCutsLegs) delete fKineCutsLegs;
+ if (fKineCutsMother) delete fKineCutsMother;
+}
+//=================================================================================
+void AliAnalysisTaskDielectronEfficiency::CreateOutputObjects() {
+ //
+ // Create histograms
+ // Called once
+ //
+
+ //-------------------
+ // MC truth produced
+ fHist=new AliDielectronHistos;
+ fHist->AddClass("MC;MCcut;DataSameMother;Event;DataCuts;DataTRDCuts");
+
+ fHist->UserHistogram("MC", "JpsiMCPt" ,"MC Jpsi;Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("MC", "mass" ,"MC Jpsi; Inv.Mass [GeV]" ,100,0,4);
+ fHist->UserHistogram("MC", "e+Pt" ,"MC e+ from JPsi;Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("MC", "e-Pt" ,"MC e- from JPsi;Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("MC", "dndyPt" ,"MC Jpsi procution; Rapidity;Pt",100,-4,4,100,0,10);
+ fHist->UserHistogram("MC","dndy" ,"MC dNdy Jpsi;Rapidity;Entries/event" ,100,-4,4);
+ fHist->GetHistogram("MC","dndy")->Sumw2();
+
+ //-------------------
+ //MC truth after cuts
+ fHist->UserHistogram("MCcut", "JpsiMCPt" ,"MC Jpsi;Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("MCcut", "mass" ,"MC Jpsi; Inv.Mass [GeV]" ,100,0,4);
+ fHist->UserHistogram("MCcut", "e+Pt" ,"MC e+ from JPsi;Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("MCcut", "e-Pt" ,"MC e- from JPsi;Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("MCcut", "dndyPt" ,"MC Jpsi procution; Rapidity;Pt",100,-4,4,100,0,10);
+ fHist->UserHistogram("MCcut","dndy" ,"MC dNdy Jpsi;Rapidity;Entries/event" ,100,-4,4);
+ fHist->GetHistogram("MCcut","dndy")->Sumw2();
+
+ //-----------------
+ //reconstructed data with cuts on MC truth
+ fHist->UserHistogram("DataSameMother","JpsiMCPt","Rec Jpsi; MC Pt [GeV]", 100,0,10);
+ fHist->UserHistogram("DataSameMother","dndyPtMC" ,"Rec Jpsi procution; Rapidity;Pt",100,-4,4,100,0,10);
+ fHist->UserHistogram("DataSameMother", "e+Pt" ,"Rec e+ from JPsi;MC Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataSameMother", "e-Pt" ,"Rec e- from JPsi;MC Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataSameMother","dndy" ,"Rec Jpsi;Rapidity;Entries/event" ,100,-4,4);
+ fHist->GetHistogram("DataSameMother","dndy")->Sumw2();
+
+ fHist->UserHistogram("DataSameMother","mass" ,"Rec Jpsi (KF); Inv.Mass [GeV]" ,100,0,4);
+ fHist->UserHistogram("DataSameMother","JpsiPt" ,"Rec Jpsi (KF); Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataSameMother","Chi2" ,"Rec Jpsi (KF); #Chi^{2}" ,100,0,50);
+ fHist->UserHistogram("DataSameMother","dndyPt" ,"Rec Jpsi procution (KF); Rapidity;Pt",100,-4,4,100,0,10);
+ //------------------
+ // reconstructed data after ESD track cuts and cuts on MC truth
+ //------------------
+ fHist->UserHistogram("DataCuts","JpsiMCPt","Rec Jpsi; MC Pt [GeV]", 100,0,10);
+ fHist->UserHistogram("DataCuts","dndyPtMC" ,"Rec Jpsi procution; Rapidity;Pt",100,-4,4,100,0,10);
+ fHist->UserHistogram("DataCuts", "e+Pt" ,"Rec e+ from JPsi;MC Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataCuts", "e-Pt" ,"Rec e- from JPsi;MC Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataCuts","dndy" ,"Rec Jpsi;Rapidity;Entries/event" ,100,-4,4);
+ fHist->GetHistogram("DataCuts","dndy")->Sumw2();
+
+ fHist->UserHistogram("DataCuts","mass" ,"Rec Jpsi (KF); Inv.Mass [GeV]" ,100,0,4);
+ fHist->UserHistogram("DataCuts","JpsiPt" ,"Rec Jpsi (KF); Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataCuts","Chi2" ,"Rec Jpsi (KF); #Chi^{2}" ,100,0,50);
+ fHist->UserHistogram("DataCuts","dndyPt" ,"Rec Jpsi procution (KF); Rapidity;Pt",100,-4,4,100,0,10);
+ //------------------
+ // after ESD track cuts + TRD cuts + MC cuts
+ //------------------
+ fHist->UserHistogram("DataTRDCuts","JpsiMCPt","Rec Jpsi; MC Pt [GeV]", 100,0,10);
+ fHist->UserHistogram("DataTRDCuts","dndyPtMC" ,"Rec Jpsi procution; Rapidity;Pt",100,-4,4,100,0,10);
+ fHist->UserHistogram("DataTRDCuts", "e+Pt" ,"Rec e+ from JPsi;MC Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataTRDCuts", "e-Pt" ,"Rec e- from JPsi;MC Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataTRDCuts","dndy" ,"Rec Jpsi;Rapidity;Entries/event" ,100,-4,4);
+ fHist->GetHistogram("DataTRDCuts","dndy")->Sumw2();
+
+ fHist->UserHistogram("DataTRDCuts","mass" ,"Rec Jpsi (KF); Inv.Mass [GeV]" ,100,0,4);
+ fHist->UserHistogram("DataTRDCuts","JpsiPt" ,"Rec Jpsi (KF); Pt [GeV]" ,100,0,10);
+ fHist->UserHistogram("DataTRDCuts","Chi2" ,"Rec Jpsi (KF); #Chi^{2}" ,100,0,50);
+ fHist->UserHistogram("DataTRDCuts","dndyPt" ,"Rec Jpsi procution (KF); Rapidity;Pt",100,-4,4,100,0,10);
+
+ //-----------------
+ //Event information
+ //-----------------
+ fHist->UserHistogram("Event","NEvents","Number of events",1,0,1);
+
+}
+
+// //____________________________________________________________
+void AliAnalysisTaskDielectronEfficiency::ConnectInputData(Option_t *) {
+ //
+ // connect the input data
+ //
+ fInputEvent=0;
+ TTree* tree=dynamic_cast<TTree*>(GetInputData(0));
+ if (!tree) {
+ printf("ERROR: Could not read chain from input slot 0\n");
+ } else {
+ AliInputEventHandler *eventH = dynamic_cast<AliInputEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler());
+ if (!eventH) {
+ AliError("Could not get ESDInputHandler");
+ } else {
+ fInputEvent = eventH->GetEvent();
+ AliInfo("*** CONNECTED NEW EVENT ****");
+ }
+ }
+}
+
+//=================================================================================
+void AliAnalysisTaskDielectronEfficiency::Exec(Option_t *) {
+ //
+ // Main loop. Called for every event
+ // Process the event in FillPlots and post the data afterwards
+ //
+ if (!fInputEvent) {
+ Printf("ERROR: Could not get input event\n");
+ return;
+ }
+
+ FillPlots(fInputEvent);
+
+ PostData(0, const_cast<THashList*>(fHist->GetHistogramList()));
+}
+
+
+//====================================================================================
+void AliAnalysisTaskDielectronEfficiency::FillPlots(AliVEvent *event)
+{
+ //
+ // Fill histograms
+ //
+ AliESDEvent *esd=dynamic_cast<AliESDEvent*>(event);
+
+ Int_t ntrack=esd->GetNumberOfTracks();
+
+ // Fetch Stack
+ AliMCEventHandler *mcH = (AliMCEventHandler*) ((AliAnalysisManager::GetAnalysisManager())->GetMCtruthEventHandler());
+ if(!mcH) {
+ AliError("No MC handler found\n")
+ return;
+ }
+
+ AliMCEvent *mcev=mcH->MCEvent();
+ if (!mcev){
+ AliError("No MC event found\n")
+ return;
+ }
+ AliStack* pStack = mcev->Stack();
+
+ if (!pStack) return;
+
+ //fill event info
+ fHist->Fill("Event","NEvents",0);
+
+ //fill MC histograms
+ FillMCInfo(pStack);
+
+ //
+ Float_t massMother=0;
+ if (fIdMCMother>-1) fPDG->GetParticle(fIdMCMother)->Mass();
+
+ TLorentzVector v;
+ //loop over all tracks
+ for (Int_t itrack=0; itrack<ntrack; ++itrack){
+ //negative particles only in this loop
+ AliESDtrack *trackN=esd->GetTrack(itrack);
+ if (trackN->Charge()!=-1) continue;
+
+ //MC truth
+ Int_t labelN=TMath::Abs(trackN->GetLabel());
+ if (labelN<0) continue;
+ TParticle *pN=pStack->Particle(labelN);
+ Int_t pdgN=pN->GetPdgCode();
+
+ //MC mother
+ Int_t idMotherN=pN->GetFirstMother();
+ TParticle *motherN=0;
+ Int_t pdgMotherN=-1;
+ if (fIdMCMother>-1&&idMotherN>-1){
+ motherN=pStack->Particle(idMotherN);
+ pdgMotherN=motherN->GetPdgCode();
+ }
+
+ for (Int_t itrack2=0; itrack2<ntrack; ++itrack2){
+ //positive particles only in this loop
+ AliESDtrack *trackP=esd->GetTrack(itrack2);
+ if (trackP->Charge()!=1) continue;
+
+ //MC truth
+ Int_t labelP=TMath::Abs(trackP->GetLabel());
+ if (labelP<0) continue;
+ TParticle *pP=pStack->Particle(labelP);
+ // Int_t pdgP=pP->GetPdgCode();
+
+ //MC mother
+ Int_t idMotherP=pP->GetFirstMother();
+ TParticle *motherP=0;
+ // Int_t pdgMotherP=0;
+ if (idMotherP>-1){
+ motherP=pStack->Particle(idMotherP);
+ // pdgMotherP=motherP->GetPdgCode();
+ }
+ //===============
+ //Fill histograms
+ //===============
+ Bool_t motherOK=kFALSE;
+ if (fIdMCMother==-1) motherOK=kTRUE;
+ else if (pdgMotherN==fIdMCMother) motherOK=kTRUE;
+
+ if (pdgN==fIdMCDaughterN && motherOK){ //electron and mother is fIdMCMother
+ AliKFParticle electron(*trackN,11);
+ AliKFParticle positron(*trackP,-11);
+ AliKFParticle jpsi(electron);
+ jpsi+=positron;
+
+ Bool_t sameMother=kFALSE;
+ Bool_t motherCutOK=kFALSE;
+
+ if (fIdMCMother==-1) {
+ //accept as same mother if we don't requite
+ sameMother=kTRUE;
+ motherCutOK=kTRUE;
+ }
+ else
+ {
+ if (idMotherN==idMotherP) sameMother=kTRUE;
+ if (fKineCutsMother->IsSelected(motherN)) motherCutOK=kTRUE;
+ }
+
+ if ( sameMother && // same mother
+ motherCutOK && //cuts mother MC truth
+ fKineCutsLegs->IsSelected(pN) && fKineCutsLegs->IsSelected(pP)){ //cuts legs MC truth
+
+ //MC only data
+ if (motherN){
+ fHist->Fill("DataSameMother","JpsiMCPt",motherN->Pt());
+ fHist->Fill("DataSameMother","e+Pt",pP->Pt());
+ fHist->Fill("DataSameMother","e-Pt",pN->Pt());
+ v.SetPxPyPzE(motherN->Px(),motherN->Py(),motherN->Pz(),motherN->Energy());
+ fHist->Fill("DataSameMother","dndy",v.Rapidity());
+ fHist->Fill("DataSameMother","dndyPtMC",v.Rapidity(),motherN->Pt());
+ }
+
+ //reconstructed data
+ v.SetPtEtaPhiM(jpsi.GetPt(),jpsi.GetEta(),jpsi.GetPhi(),massMother);
+// printf("Jpsi: %f,%f,%f,%f\n",jpsi.GetPt(),jpsi.GetEta(),jpsi.GetPhi(),massMother);
+ fHist->Fill("DataSameMother","JpsiPt",jpsi.GetPt());
+ fHist->Fill("DataSameMother","Chi2",jpsi.GetChi2()/jpsi.GetNDF());
+ fHist->Fill("DataSameMother","mass",jpsi.GetMass());
+ fHist->Fill("DataSameMother","dndyPt",v.Rapidity(),jpsi.GetPt());
+
+ //histograms after ESD cuts
+ if (fESDtrackCuts->IsSelected(trackN)&&fESDtrackCuts->IsSelected(trackP)){
+ //MC only
+ if (motherN) {
+ fHist->Fill("DataCuts","JpsiMCPt",motherN->Pt());
+ fHist->Fill("DataCuts","e+Pt",pP->Pt());
+ fHist->Fill("DataCuts","e-Pt",pN->Pt());
+ v.SetPxPyPzE(motherN->Px(),motherN->Py(),motherN->Pz(),motherN->Energy());
+ fHist->Fill("DataCuts","dndy",v.Rapidity());
+ fHist->Fill("DataCuts","dndyPtMC",motherN->Eta(),motherN->Pt());
+ }
+
+ //reconstructed data
+ v.SetPtEtaPhiM(jpsi.GetPt(),jpsi.GetEta(),jpsi.GetPhi(),massMother);
+ fHist->Fill("DataCuts","JpsiPt",jpsi.GetPt());
+ fHist->Fill("DataCuts","Chi2",jpsi.GetChi2()/jpsi.GetNDF());
+ fHist->Fill("DataCuts","mass",jpsi.GetMass());
+ fHist->Fill("DataCuts","dndyPt",v.Rapidity(),jpsi.GetPt());
+
+ //Additional TRD cuts
+ if ( (trackN->GetStatus()&AliESDtrack::kTRDrefit!=0) &&trackN->GetTRDntrackletsPID()>4 ){
+ if ( (trackP->GetStatus()&AliESDtrack::kTRDrefit!=0) &&trackP->GetTRDntrackletsPID()>4 ){
+ if (motherN){
+ fHist->Fill("DataTRDCuts","JpsiMCPt",motherN->Pt());
+ fHist->Fill("DataTRDCuts","e+Pt",pP->Pt());
+ fHist->Fill("DataTRDCuts","e-Pt",pN->Pt());
+ v.SetPxPyPzE(motherN->Px(),motherN->Py(),motherN->Pz(),motherN->Energy());
+ fHist->Fill("DataTRDCuts","dndy",v.Rapidity());
+ fHist->Fill("DataTRDCuts","dndyPtMC",v.Rapidity(),motherN->Pt());
+ }
+
+ //reconstructed data
+ v.SetPtEtaPhiM(jpsi.GetPt(),jpsi.GetEta(),jpsi.GetPhi(),massMother);
+ fHist->Fill("DataTRDCuts","JpsiPt",jpsi.GetPt());
+ fHist->Fill("DataTRDCuts","Chi2",jpsi.GetChi2()/jpsi.GetNDF());
+ fHist->Fill("DataTRDCuts","mass",jpsi.GetMass());
+ fHist->Fill("DataTRDCuts","dndyPt",v.Rapidity(),jpsi.GetPt());
+ }
+ }
+ }
+ }
+ }
+ }
+ }
+}
+
+//____________________________________________________________
+// Int_t AliAnalysisTaskDielectronEfficiency::Merge(TList *list)
+// {
+// //
+// // Merge function
+// //
+// if (!list) return 0;
+// if (list->IsEmpty()) return 1;
+//
+// TIter next(list);
+// while ( (TObject *o=next()) ){
+// AliAnalysisTaskDielectronEfficiency *task=dynamic_cast<AliAnalysisTaskDielectronEfficiency*>o;
+// if (!o) continue;
+// fNev+=task->fNev;
+// }
+// }
+
+
+void AliAnalysisTaskDielectronEfficiency::FillMCInfo(AliStack *pStack)
+{
+ //
+ // fill pure MC histograms
+ //
+
+ TLorentzVector v;
+ //Fill MC info
+ for (Int_t ipart=0; ipart<pStack->GetNprimary(); ++ipart){
+ TParticle *part=pStack->Particle(pStack->GetPrimary(ipart));
+// printf("Particle %d\n",part->GetPdgCode());
+ if (part->GetPdgCode()!=fIdMCMother || part->GetNDaughters()!=2) continue;
+ TParticle *d1=pStack->Particle(part->GetFirstDaughter());
+ TParticle *d2=pStack->Particle(part->GetLastDaughter());
+ TParticle *dP=0;
+ TParticle *dN=0;
+ if (fPDG->GetParticle(d1->GetPdgCode())->Charge()>0){
+ dP=d1;
+ dN=d2;
+ }else{
+ dP=d2;
+ dN=d1;
+ }
+ if ( dP->GetPdgCode()!=fIdMCDaughterP || dN->GetPdgCode()!=fIdMCDaughterN ) continue;
+ v.SetPxPyPzE(part->Px(),part->Py(),part->Pz(),part->Energy());
+ fHist->Fill("MC","JpsiMCPt",part->Pt());
+ fHist->Fill("MC","dndy",v.Rapidity());
+ fHist->Fill("MC","dndyPt",v.Rapidity(),part->Pt());
+ fHist->Fill("MC","e-Pt",dN->Pt());
+ fHist->Fill("MC","e+Pt",dP->Pt());
+ //e+ e- inv mass
+ TLorentzVector vE;
+ vE.SetPxPyPzE(dN->Px(),dN->Py(),dN->Pz(),dN->Energy());
+ TLorentzVector vP;
+ vP.SetPxPyPzE(dP->Px(),dP->Py(),dP->Pz(),dP->Energy());
+ fHist->Fill("MC","mass",(vE+vP).M());
+
+
+ //cuts
+ if (!fKineCutsMother->IsSelected(part)) continue;
+ if (!fKineCutsLegs->IsSelected(d1) || !fKineCutsLegs->IsSelected(d2) ) continue;
+
+ v.SetPxPyPzE(part->Px(),part->Py(),part->Pz(),part->Energy());
+ fHist->Fill("MCcut","JpsiMCPt",part->Pt());
+ fHist->Fill("MCcut","dndy",v.Rapidity());
+ fHist->Fill("MCcut","dndyPt",v.Rapidity(),part->Pt());
+ fHist->Fill("MCcut","e-Pt",dN->Pt());
+ fHist->Fill("MCcut","e+Pt",dP->Pt());
+ }
+}
+void AliAnalysisTaskDielectronEfficiency::SetupDefaultCuts(Int_t type)
+{
+ //
+ // setup standard ESD track cuts
+ //
+
+ if (type==0){
+ //ESD cuts
+ fESDtrackCuts->SetMaxDCAToVertexZ(3.0);
+ fESDtrackCuts->SetMaxDCAToVertexXY(3.0);
+ fESDtrackCuts->SetRequireTPCRefit(kTRUE);
+ fESDtrackCuts->SetRequireITSRefit(kTRUE);
+ fESDtrackCuts->SetAcceptKinkDaughters(kFALSE);
+ fESDtrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+
+ fESDtrackCuts->SetMinNClustersTPC(50);
+ fESDtrackCuts->SetMaxChi2PerClusterTPC(4);
+
+ //MC cuts
+ fKineCutsLegs->SetEtaRange(-0.9,0.9);
+ fKineCutsMother->SetRapRange(-0.9,0.9);
+ } else if (type==1) {
+// fESDtrackCuts->SetMaxCovDiagonalElements(2, 2, .5, .5, 2);
+ fESDtrackCuts->SetMaxDCAToVertexZ(3.0);
+ fESDtrackCuts->SetMaxDCAToVertexXY(3.0);
+ fESDtrackCuts->SetRequireTPCRefit(kTRUE);
+ fESDtrackCuts->SetRequireITSRefit(kTRUE);
+ fESDtrackCuts->SetAcceptKinkDaughters(kFALSE);
+ fESDtrackCuts->SetClusterRequirementITS(AliESDtrackCuts::kSPD,AliESDtrackCuts::kAny);
+
+ fESDtrackCuts->SetMinNClustersTPC(50);
+ fESDtrackCuts->SetMaxChi2PerClusterTPC(4);
+
+ //MC cuts
+// fKineCutsLegs->SetEtaRange(-0.9,0.9);
+// fKineCutsMother->SetRapRange(-0.9,0.9);
+
+ }
+}
+
+//===================================================================================
+void AliAnalysisTaskDielectronEfficiency::Terminate(Option_t *) {
+ //
+ // Called once at the end of the query
+ //
+
+
+ AliDielectronHistos *hist=new AliDielectronHistos;
+ hist->SetHistogramList(*(THashList*)GetOutputData(0));
+
+ if (hist->GetHistogram("Event","NEvents")){
+ //get number of events
+ Double_t nev=hist->GetHistogram("Event","NEvents")->GetBinContent(1);
+ //
+ //normalise dndy histograms
+ //
+ hist->GetHistogram("DataSameMother","dndy")->Scale(1./nev);
+ hist->GetHistogram("MC","dndy")->Scale(1./nev);
+ hist->GetHistogram("DataCuts","dndy")->Scale(1./nev);
+ hist->GetHistogram("DataTRDCuts","dndy")->Scale(1./nev);
+
+ //
+ // create the efficiency histograms
+ //
+ // hEffTracking/2D only tracking effects, no esd cuts
+ // hEffESDCuts tracking plus ESD cuts
+ // hEffTRDCuts tracking plus ESD plus TRD cuts
+ //
+ TH1F *hEffTracking=(TH1F*)hist->GetHistogram("DataSameMother","JpsiMCPt")->Clone("Efficiency");
+ hEffTracking->Divide(hist->GetHistogram("MCcut","JpsiMCPt"));
+ hEffTracking->SetTitle("Efficiencies");
+ hist->UserHistogram("DataSameMother",hEffTracking);
+
+ TH1F *hEffESDCuts=(TH1F*)hist->GetHistogram("DataCuts","JpsiMCPt")->Clone("Efficiency");
+ hEffESDCuts->Divide(hist->GetHistogram("MCcut","JpsiMCPt"));
+ hEffTracking->SetTitle("Efficiencies");
+ hist->UserHistogram("DataCuts",hEffESDCuts);
+
+ TH1F *hEffTRDCuts=(TH1F*)hist->GetHistogram("DataTRDCuts","JpsiMCPt")->Clone("Efficiency");
+ hEffTRDCuts->Divide(hist->GetHistogram("MCcut","JpsiMCPt"));
+ hEffTRDCuts->SetTitle("Efficiencies");
+ hist->UserHistogram("DataTRDCuts",hEffTRDCuts);
+
+ hist->DrawSame("Efficiency");
+
+ //2D efficiencies
+ TH2F *hEffTracking2D=(TH2F*)hist->GetHistogram("DataSameMother","dndyPtMC")->Clone("2DEfficiency");
+ hEffTracking2D->Divide(hist->GetHistogram("MCcut","dndyPt"));
+ hEffTracking2D->SetTitle("2D Efficiency - tracking");
+ hist->UserHistogram("DataSameMother",hEffTracking2D);
+
+ TH2F *hEffESDCuts2D=(TH2F*)hist->GetHistogram("DataCuts","dndyPtMC")->Clone("2DEfficiency");
+ hEffESDCuts2D->Divide(hist->GetHistogram("MCcut","dndyPt"));
+ hEffESDCuts2D->SetTitle("2D Efficiency - quality cuts");
+ hist->UserHistogram("DataCuts",hEffESDCuts2D);
+
+ TH2F *hEffTRDCuts2D=(TH2F*)hist->GetHistogram("DataTRDCuts","dndyPtMC")->Clone("2DEfficiency");
+ hEffTRDCuts2D->Divide(hist->GetHistogram("MCcut","dndyPt"));
+ hEffTRDCuts2D->SetTitle("2D Efficiency - quality+TRD cuts");
+ hist->UserHistogram("DataTRDCuts",hEffTRDCuts2D);
+
+//
+ // Draw all histograms of all histogram classes
+ // Use the Draw functionality of AliDielectronHistos
+ //
+ hist->Draw();
+
+ //
+ // Draw all histograms with the same name of all classes into one canvas
+ // Use the Draw functionality of AliDielectronHistos
+ //
+ hist->DrawSame("JpsiMCPt");
+ }
+
+ PostData(0, const_cast<THashList*>(hist->GetHistogramList()));
+}
+
--- /dev/null
+#ifndef ALIANALYSISTASKDIELECTRONEFFICIENCY_H
+#define ALIANALYSISTASKDIELECTRONEFFICIENCY_H
+//#####################################################
+//# #
+//# Analysis Task for Event Mixing for dielectron #
+//# #
+//# J.Wiechula (Jens.Wiechula@cern.ch) #
+//# #
+//#####################################################
+
+#include <AliAnalysisTask.h>
+
+class TDatabasePDG;
+
+class AliESDtrackCuts;
+class AliKineTrackCuts;
+class AliDielectronHistos;
+class AliVEvent;
+class AliStack;
+
+class AliAnalysisTaskDielectronEfficiency : public AliAnalysisTask {
+
+public:
+ AliAnalysisTaskDielectronEfficiency();
+ AliAnalysisTaskDielectronEfficiency(const char *name);
+ virtual ~AliAnalysisTaskDielectronEfficiency();
+
+ void SetupDefaultCuts(Int_t type=0);
+
+ virtual void ConnectInputData(Option_t *);
+ virtual void CreateOutputObjects();
+ virtual void Exec(Option_t *option);
+ virtual void Terminate(Option_t *);
+
+// virtual Int_t Merge(TCollection *list);
+ //getters
+ AliESDtrackCuts *GetESDTrackCuts() const {return fESDtrackCuts;}
+ AliKineTrackCuts *GetKineCutsLeg() const {return fKineCutsLegs;}
+ AliKineTrackCuts *GetKineCutsMother() const {return fKineCutsMother;}
+ //
+ Int_t GetIdMother() const {return fIdMCMother;}
+
+ //setters
+ void SetIdMother(Int_t id) {fIdMCMother=id;}
+ void SetIdDaughters(Int_t idPositive, Int_t idNegative) {fIdMCDaughterP=idPositive; fIdMCDaughterN=idNegative;}
+
+private:
+
+ AliVEvent *fInputEvent; //! Input event
+ AliDielectronHistos *fHist; //! Histogram container
+ //cut objects
+ AliESDtrackCuts *fESDtrackCuts; // ESD track cuts
+ AliKineTrackCuts *fKineCutsLegs; // MC cuts on Legs
+ AliKineTrackCuts *fKineCutsMother; // MC cuts on Mother (Id see below)
+
+ Int_t fIdMCMother; // MC Id of mother particle of interest (eg. Jpsi=443)
+ Int_t fIdMCDaughterP; // MC Id of legs without sign
+ Int_t fIdMCDaughterN; // MC Id of legs without sign
+ //
+ TDatabasePDG *fPDG; //! PDG database
+
+ void FillPlots(AliVEvent *event);
+ void FillMCInfo(AliStack *pStack);
+
+ AliAnalysisTaskDielectronEfficiency(const AliAnalysisTaskDielectronEfficiency &c);
+ AliAnalysisTaskDielectronEfficiency& operator= (const AliAnalysisTaskDielectronEfficiency &c);
+
+ ClassDef(AliAnalysisTaskDielectronEfficiency, 1);
+};
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// Basic Analysis Task //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TChain.h>
+
+#include <AliLog.h>
+#include <AliAODHandler.h>
+#include <AliAnalysisManager.h>
+#include <AliVEvent.h>
+
+#include "AliDielectron.h"
+#include "AliDielectronHistos.h"
+#include "AliAnalysisTaskDielectronFilter.h"
+
+ClassImp(AliAnalysisTaskDielectronFilter)
+
+//_________________________________________________________________________________
+AliAnalysisTaskDielectronFilter::AliAnalysisTaskDielectronFilter() :
+ AliAnalysisTaskSE(),
+ fDielectron(0)
+{
+ //
+ // Constructor
+ //
+}
+
+//_________________________________________________________________________________
+AliAnalysisTaskDielectronFilter::AliAnalysisTaskDielectronFilter(const char *name) :
+ AliAnalysisTaskSE(name),
+ fDielectron(0)
+{
+ //
+ // Constructor
+ //
+ DefineInput(0,TChain::Class());
+ DefineOutput(1, THashList::Class());
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskDielectronFilter::Init()
+{
+ // Initialization
+ if (fDebug > 1) AliInfo("Init() \n");
+
+// require AOD handler
+ AliAODHandler *aodH = (AliAODHandler*)((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
+ if (!aodH) Fatal("Init", "No AOD handler. Halting.");
+
+//require dielectron framework
+ if (!fDielectron) {
+ Error("Init","Dielectron framework class required. Please create and instance with proper cuts and set it via 'SetDielectron' before executing this task!!!");
+ return;
+ }
+
+ aodH->AddFilteredAOD("AliAOD.Dielectron.root", "DielectronEvents");
+// AddAODBranch("AliDielectronCandidates",fDielectron->GetPairArraysPointer(),"deltaAOD.Dielectron.root");
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskDielectronFilter::UserExec(Option_t *)
+{
+ //
+ // Main loop. Called for every event
+ //
+
+ if (!fDielectron) return;
+
+ //bz for AliKF
+ Double_t bz = InputEvent()->GetMagneticField();
+ AliKFParticle::SetField( bz );
+
+ fDielectron->Process(InputEvent());
+ fDielectron->FillHistograms();
+
+ if(fDielectron->HasCandidates()){
+ AliAODExtension *extDielectron = dynamic_cast<AliAODHandler*>
+ ((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler())->GetFilteredAOD("AliAOD.Dielectron.root");
+ extDielectron->SelectEvent();
+ //see if dielectron candidate branch exists, if not create is
+ TTree *t=extDielectron->GetTree();
+ if (!t->GetBranch("dielectrons")){
+ t->Bronch("dielectrons","TObjArray",fDielectron->GetPairArraysPointer());
+ }
+ }
+
+ PostData(1, const_cast<THashList*>(fDielectron->GetHistogramList()));
+}
+
--- /dev/null
+#ifndef ALIANALYSISTASKDIELECTRONFILTER_H
+#define ALIANALYSISTASKDIELECTRONFILTER_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#####################################################
+//# #
+//# Dielectron even filter task #
+//# #
+//# #
+//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#####################################################
+/*
+Filter Event based on cuts provided in the AliDielectron class.
+
+Write an AOD file containing events with Dielectron candidates.
+Add a sattelite AOD with the array of candidates.
+*/
+
+
+
+#include "AliAnalysisTaskSE.h"
+
+class AliDielectron;
+
+class AliAnalysisTaskDielectronFilter : public AliAnalysisTaskSE {
+
+public:
+ AliAnalysisTaskDielectronFilter();
+ AliAnalysisTaskDielectronFilter(const char *name);
+ virtual ~AliAnalysisTaskDielectronFilter(){}
+
+ virtual void UserExec(Option_t *option);
+ virtual void Init();
+ virtual void LocalInit() {Init();}
+
+ void SetDielectron(AliDielectron * const die) { fDielectron = die; }
+
+private:
+
+ AliDielectron *fDielectron; // J/psi framework object
+
+ AliAnalysisTaskDielectronFilter(const AliAnalysisTaskDielectronFilter &c);
+ AliAnalysisTaskDielectronFilter& operator= (const AliAnalysisTaskDielectronFilter &c);
+
+ ClassDef(AliAnalysisTaskDielectronFilter, 1);
+};
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// Basic Analysis Task //
+// for Dielectron Analysis //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TChain.h>
+
+#include <AliCFContainer.h>
+#include <AliVEvent.h>
+
+#include "AliDielectron.h"
+#include "AliDielectronHistos.h"
+#include "AliDielectronCF.h"
+#include "AliAnalysisTaskDielectronSE.h"
+
+ClassImp(AliAnalysisTaskDielectronSE)
+
+//_________________________________________________________________________________
+AliAnalysisTaskDielectronSE::AliAnalysisTaskDielectronSE() :
+ AliAnalysisTaskSE(),
+ fDielectron(0)
+{
+ //
+ // Constructor
+ //
+}
+
+//_________________________________________________________________________________
+AliAnalysisTaskDielectronSE::AliAnalysisTaskDielectronSE(const char *name) :
+ AliAnalysisTaskSE(name),
+ fDielectron(0)
+{
+ //
+ // Constructor
+ //
+ DefineInput(0,TChain::Class());
+ DefineOutput(1, THashList::Class());
+ DefineOutput(2, AliCFContainer::Class());
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskDielectronSE::UserCreateOutputObjects()
+{
+ //
+ // Initialise the framework objects
+ //
+ if (!fDielectron){
+ AliError("No Dielectron framework object set !!!");
+ return;
+ }
+ fDielectron->Init();
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskDielectronSE::UserExec(Option_t *)
+{
+ //
+ // Main loop. Called for every event
+ //
+
+ if (!fDielectron) return;
+
+ //bz for AliKF
+ Double_t bz = InputEvent()->GetMagneticField();
+ AliKFParticle::SetField( bz );
+
+ fDielectron->Process(InputEvent());
+ fDielectron->FillHistograms();
+
+ if (fDielectron->GetHistogramList()){
+ PostData(1, const_cast<THashList*>(fDielectron->GetHistogramList()));
+ }
+ if (fDielectron->GetCFManagerPair()){
+ PostData(2, const_cast<AliCFContainer*>(fDielectron->GetCFManagerPair()->GetContainer()));
+ }
+}
+
--- /dev/null
+#ifndef ALIANALYSISTASKDIELECTRONSE_H
+#define ALIANALYSISTASKDIELECTRONSE_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#####################################################
+//# #
+//# Basic Analysis task for Dielectron #
+//# single event analysis #
+//# #
+//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#####################################################
+
+#include "AliAnalysisTaskSE.h"
+
+class AliDielectron;
+
+class AliAnalysisTaskDielectronSE : public AliAnalysisTaskSE {
+
+public:
+ AliAnalysisTaskDielectronSE();
+ AliAnalysisTaskDielectronSE(const char *name);
+ virtual ~AliAnalysisTaskDielectronSE(){;}
+
+ virtual void UserExec(Option_t *option);
+ virtual void UserCreateOutputObjects();
+
+ void SetDielectron(AliDielectron * const die) { fDielectron = die; }
+
+private:
+
+ AliDielectron *fDielectron; // Dielectron framework object
+
+ AliAnalysisTaskDielectronSE(const AliAnalysisTaskDielectronSE &c);
+ AliAnalysisTaskDielectronSE& operator= (const AliAnalysisTaskDielectronSE &c);
+
+ ClassDef(AliAnalysisTaskDielectronSE, 1);
+};
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// Basic Analysis Task //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TChain.h>
+
+#include <AliCFContainer.h>
+#include <AliVEvent.h>
+
+#include "AliDielectron.h"
+#include "AliDielectronHistos.h"
+#include "AliDielectronCF.h"
+#include "AliAnalysisTaskMultiDielectron.h"
+
+ClassImp(AliAnalysisTaskMultiDielectron)
+
+//_________________________________________________________________________________
+AliAnalysisTaskMultiDielectron::AliAnalysisTaskMultiDielectron() :
+ AliAnalysisTaskSE(),
+ fListDielectron(),
+ fListHistos(),
+ fListCF()
+{
+ //
+ // Constructor
+ //
+}
+
+//_________________________________________________________________________________
+AliAnalysisTaskMultiDielectron::AliAnalysisTaskMultiDielectron(const char *name) :
+ AliAnalysisTaskSE(name),
+ fListDielectron(),
+ fListHistos(),
+ fListCF()
+{
+ //
+ // Constructor
+ //
+ DefineInput(0,TChain::Class());
+ DefineOutput(1, TList::Class());
+ DefineOutput(2, TList::Class());
+ fListHistos.SetName("Dielectron_Histos_Multi");
+ fListCF.SetName("Dielectron_CF_Multi");
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskMultiDielectron::UserCreateOutputObjects()
+{
+ //
+ // Add all histogram manager histogram lists to the output TList
+ //
+
+ if (!fListHistos.IsEmpty()) return; //already initialised
+
+ TIter nextDie(&fListDielectron);
+ AliDielectron *die=0;
+ while ( (die=static_cast<AliDielectron*>(nextDie())) ){
+ die->Init();
+ if (die->GetHistogramList()) fListHistos.Add(const_cast<THashList*>(die->GetHistogramList()));
+ if (die->GetCFManagerPair()) fListCF.Add(const_cast<AliCFContainer*>(die->GetCFManagerPair()->GetContainer()));
+ }
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskMultiDielectron::UserExec(Option_t *)
+{
+ //
+ // Main loop. Called for every event
+ //
+
+ if (fListHistos.IsEmpty()) return;
+
+ //bz for AliKF
+ Double_t bz = InputEvent()->GetMagneticField();
+ AliKFParticle::SetField( bz );
+
+ //Process event in all AliDielectron instances
+ TIter nextDie(&fListDielectron);
+ AliDielectron *die=0;
+ while ( (die=static_cast<AliDielectron*>(nextDie())) ){
+// printf("Processing '%s'\n",die->GetName());
+ die->Process(InputEvent());
+ die->FillHistograms();
+ }
+
+ PostData(1, &fListHistos);
+ PostData(2, &fListCF);
+}
+
--- /dev/null
+#ifndef ALIANALYSISTASKMULTIDIELECTRON_H
+#define ALIANALYSISTASKMULTIDIELECTRON_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#####################################################
+//# #
+//# Basic Analysis task for Dielectron #
+//# single event analysis #
+//# #
+//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#####################################################
+
+#include "TList.h"
+
+#include "AliAnalysisTaskSE.h"
+
+class AliDielectron;
+
+class AliAnalysisTaskMultiDielectron : public AliAnalysisTaskSE {
+
+public:
+ AliAnalysisTaskMultiDielectron();
+ AliAnalysisTaskMultiDielectron(const char *name);
+ virtual ~AliAnalysisTaskMultiDielectron(){}
+
+ virtual void UserExec(Option_t *option);
+ virtual void UserCreateOutputObjects();
+
+
+ void AddDielectron(AliDielectron * const die) { fListDielectron.Add(die); }
+
+private:
+
+ TList fListDielectron; // List of dielectron framework instances
+ TList fListHistos; //! List of histogram manager lists in the framework classes
+ TList fListCF; //! List with CF Managers
+
+ AliAnalysisTaskMultiDielectron(const AliAnalysisTaskMultiDielectron &c);
+ AliAnalysisTaskMultiDielectron& operator= (const AliAnalysisTaskMultiDielectron &c);
+
+ ClassDef(AliAnalysisTaskMultiDielectron, 1); //Analysis Task handling multiple instances of AliDielectron
+};
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Dielectron Analysis Main class //
+// //
+/*
+Framework to perform event selectoin, single track selection and track pair
+selection.
+
+Convention for the signs of the pair in fPairCandidates:
+The names are available via the function PairClassName(Int_t i)
+
+0: ev1+ ev1+ (same event like sign +)
+1: ev1+ ev1- (same event unlike sign)
+2: ev1- ev1- (same event like sign -)
+
+3: ev1+ ev2+ (mixed event like sign +)
+4: ev1- ev2+ (mixed event unlike sign -+)
+6: ev1+ ev2- (mixed event unlike sign +-)
+7: ev1- ev2- (mixed event like sign -)
+
+5: ev2+ ev2+ (same event like sign +)
+8: ev2+ ev2- (same event unlike sign)
+9: ev2- ev2- (same event like sign -)
+
+
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TString.h>
+#include <TList.h>
+#include <TMath.h>
+
+#include <AliESDEvent.h>
+#include <AliESDtrack.h>
+
+#include <AliVEvent.h>
+#include <AliVParticle.h>
+#include <AliVTrack.h>
+#include "AliDielectronPair.h"
+#include "AliDielectronHistos.h"
+#include "AliDielectronCF.h"
+#include "AliDielectronMC.h"
+#include "AliDielectronVarManager.h"
+#include "AliDielectron.h"
+
+ClassImp(AliDielectron)
+
+const char* AliDielectron::fgkTrackClassNames[4] = {
+ "ev1+",
+ "ev1-",
+ "ev2+",
+ "ev2-"
+};
+
+const char* AliDielectron::fgkPairClassNames[10] = {
+ "ev1+_ev1+",
+ "ev1+_ev1-",
+ "ev1-_ev1-",
+ "ev1+_ev2+",
+ "ev1-_ev2+",
+ "ev2+_ev2+",
+ "ev1+_ev2-",
+ "ev1-_ev2-",
+ "ev2+_ev2-",
+ "ev2-_ev2-"
+};
+
+//________________________________________________________________
+AliDielectron::AliDielectron() :
+ TNamed("AliDielectron","AliDielectron"),
+ fEventFilter("EventFilter"),
+ fTrackFilter("TrackFilter"),
+ fPairFilter("PairFilter"),
+ fPdgMother(443),
+ fHistos(0x0),
+ fPairCandidates(new TObjArray(10)),
+ fCfManagerPair(0x0)
+{
+ //
+ // Default constructor
+ //
+
+}
+
+//________________________________________________________________
+AliDielectron::AliDielectron(const char* name, const char* title) :
+ TNamed(name,title),
+ fEventFilter("EventFilter"),
+ fTrackFilter("TrackFilter"),
+ fPairFilter("PairFilter"),
+ fPdgMother(443),
+ fHistos(0x0),
+ fPairCandidates(new TObjArray(10)),
+ fCfManagerPair(0x0)
+{
+ //
+ // Named constructor
+ //
+
+}
+
+//________________________________________________________________
+AliDielectron::~AliDielectron()
+{
+ //
+ // Default destructor
+ //
+ if (fHistos) delete fHistos;
+ if (fPairCandidates) delete fPairCandidates;
+}
+
+//________________________________________________________________
+void AliDielectron::Init()
+{
+ //
+ // Initialise objects
+ //
+ if (fCfManagerPair) fCfManagerPair->InitialiseContainer(fPairFilter);
+}
+
+//________________________________________________________________
+void AliDielectron::Process(AliVEvent *ev1, AliVEvent *ev2)
+{
+ //
+ // Process the events
+ //
+
+ //in case we have MC load the MC event and process the MC particles
+ if (AliDielectronMC::Instance()->ConnectMCEvent()) ProcessMC();
+
+ //if candidate array doesn't exist, create it
+ if (!fPairCandidates->UncheckedAt(0)) {
+ InitPairCandidateArrays();
+ } else {
+ ClearArrays();
+ }
+
+ //mask used to require that all cuts are fulfilled
+ UInt_t selectedMask=(1<<fEventFilter.GetCuts()->GetEntries())-1;
+
+ //apply event cuts
+ if (ev1&&fEventFilter.IsSelected(ev1)!=selectedMask ||
+ ev2&&fEventFilter.IsSelected(ev2)!=selectedMask) return;
+
+ //fill track arrays for the first event
+ if (ev1) FillTrackArrays(ev1);
+
+ //fill track arrays for the second event
+ if (ev2) FillTrackArrays(ev2,1);
+
+ // create pairs and fill pair candidate arrays
+ for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
+ for (Int_t itrackArr2=itrackArr1; itrackArr2<4; ++itrackArr2){
+ FillPairArrays(itrackArr1, itrackArr2);
+ }
+ }
+}
+
+//________________________________________________________________
+void AliDielectron::ProcessMC()
+{
+ //
+ // Process the MC data
+ //
+
+ //loop over all MC data and Fill the CF container if it exist
+ if (!fCfManagerPair) return;
+ fCfManagerPair->SetPdgMother(fPdgMother);
+
+ AliDielectronMC *dieMC=AliDielectronMC::Instance();
+ for (Int_t ipart=0; ipart<dieMC->GetNMCTracks();++ipart){
+ //TODO: MC truth cut properly!!!
+ AliVParticle *mcPart=dieMC->GetMCTrackFromMCEvent(ipart);
+ if (!AliDielectronMC::Instance()->IsMCMotherToEE(mcPart, fPdgMother)) continue;
+ fCfManagerPair->FillMC(mcPart);
+ }
+}
+
+//________________________________________________________________
+void AliDielectron::FillHistograms()
+{
+ //
+ // Fill Histogram information for tracks and pairs
+ //
+
+ if (!fHistos) return;
+ TString className;
+
+ //Fill track information, separately for the track array candidates
+ Double_t trackValues[AliDielectronVarManager::kNMaxValues];
+ for (Int_t i=0; i<4; ++i){
+ className.Form("Track_%s",fgkTrackClassNames[i]);
+ Int_t ntracks=fTracks[i].GetEntriesFast();
+ for (Int_t itrack=0; itrack<ntracks; ++itrack){
+ AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), trackValues);
+ fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, trackValues);
+ }
+ }
+
+ //Fill Pair information, separately for all pair candidate arrays
+ Double_t pairValues[AliDielectronVarManager::kNMaxValues];
+ for (Int_t i=0; i<10; ++i){
+ className.Form("Pair_%s",fgkPairClassNames[i]);
+ Int_t ntracks=PairArray(i)->GetEntriesFast();
+ for (Int_t ipair=0; ipair<ntracks; ++ipair){
+ AliDielectronVarManager::Fill(PairArray(i)->UncheckedAt(ipair), pairValues);
+ fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, pairValues);
+ }
+ }
+
+}
+
+//________________________________________________________________
+void AliDielectron::FillTrackArrays(AliVEvent * const ev, Int_t eventNr)
+{
+ //
+ // select tracks and fill track candidate arrays
+ // eventNr = 0: First event, use track arrays 0 and 1
+ // eventNr = 1: Second event, use track arrays 2 and 3
+ //
+
+ Int_t ntracks=ev->GetNumberOfTracks();
+ UInt_t selectedMask=(1<<fTrackFilter.GetCuts()->GetEntries())-1;
+ for (Int_t itrack=0; itrack<ntracks; ++itrack){
+ //get particle
+ AliVParticle *particle=ev->GetTrack(itrack);
+ //TODO: temporary solution, perhaps think about a better implementation
+ // This is needed to use AliESDpidCuts, which relies on the ESD event
+ // is set as a AliESDtrack attribute... somehow ugly!
+ if (ev->IsA()==AliESDEvent::Class()){
+ AliESDtrack *track=static_cast<AliESDtrack*>(particle);
+ track->SetESDEvent(static_cast<AliESDEvent*>(ev)); //only in trunk...
+ }
+
+ //apply track cuts
+ if (fTrackFilter.IsSelected(particle)!=selectedMask) continue;
+
+ //fill selected particle into the corresponding track arrays
+ Short_t charge=particle->Charge();
+ if (charge>0) fTracks[eventNr*2].Add(particle);
+ else if (charge<0) fTracks[eventNr*2+1].Add(particle);
+ }
+}
+
+//________________________________________________________________
+void AliDielectron::FillPairArrays(Int_t arr1, Int_t arr2) {
+ //
+ // select pairs and fill pair candidate arrays
+ //
+ Int_t pairIndex=GetPairIndex(arr1,arr2);
+
+ Int_t ntrack1=fTracks[arr1].GetEntriesFast();
+ Int_t ntrack2=fTracks[arr2].GetEntriesFast();
+
+ AliDielectronPair *candidate=new AliDielectronPair;
+
+ UInt_t selectedMask=(1<<fPairFilter.GetCuts()->GetEntries())-1;
+
+ for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
+ Int_t end=ntrack2;
+ if (arr1==arr2) end=itrack1;
+ for (Int_t itrack2=0; itrack2<end; ++itrack2){
+ //create the pair TODO: change hardcoded PID of tracks
+ candidate->SetTracks(static_cast<AliVTrack*>(fTracks[arr1].UncheckedAt(itrack1)), 11,
+ static_cast<AliVTrack*>(fTracks[arr2].UncheckedAt(itrack2)), 11);
+ candidate->SetType(pairIndex);
+
+ //pair cuts
+ UInt_t cutMask=fPairFilter.IsSelected(candidate);
+
+ //CF manager for the pair
+ if (fCfManagerPair) fCfManagerPair->Fill(cutMask,candidate);
+
+ //apply cut
+ if (cutMask!=selectedMask) continue;
+
+ //add the candidate to the candidate array
+ PairArray(pairIndex)->Add(candidate);
+ //get a new candidate
+ candidate=new AliDielectronPair;
+ }
+ }
+ //delete the surplus candidate
+ delete candidate;
+}
+
+
+
+
--- /dev/null
+#ifndef ALIDIELECTRON_H
+#define ALIDIELECTRON_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#####################################################
+//# #
+//# Class AliDielectron #
+//# Main Class for e+e- analysis #
+//# #
+//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#####################################################
+
+
+#include <TNamed.h>
+#include <TObjArray.h>
+
+#include <AliAnalysisFilter.h>
+#include <AliKFParticle.h>
+
+#include "AliDielectronHistos.h"
+#include "AliDielectronPair.h"
+
+class AliVEvent;
+class THashList;
+class AliDielectronCF;
+
+//________________________________________________________________
+class AliDielectron : public TNamed {
+
+public:
+ enum ParticleValues { kPx=0, kPy, kPz, kPt, kP, kXv, kYv, kZv, kOneOverPt,
+ kPhi, kTheta, kE, kM, kEta, kY, kCharge, kNParticleValues };
+ enum PairValues { kChi2NDF=kNParticleValues, kDecayLength, kR, kOpeningAngle, kMerr, kNPairValues };
+
+ AliDielectron();
+ AliDielectron(const char* name, const char* title);
+ virtual ~AliDielectron();
+
+ void Init();
+
+ void Process(AliVEvent *ev1, AliVEvent *ev2=0);
+
+ void FillHistograms();
+
+ const AliAnalysisFilter& GetEventFilter() const { return fEventFilter; }
+ const AliAnalysisFilter& GetTrackFilter() const { return fTrackFilter; }
+ const AliAnalysisFilter& GetPairFilter() const { return fPairFilter; }
+
+ AliAnalysisFilter& GetEventFilter() { return fEventFilter; }
+ AliAnalysisFilter& GetTrackFilter() { return fTrackFilter; }
+ AliAnalysisFilter& GetPairFilter() { return fPairFilter; }
+
+ void SetMotherPdg( Int_t pdgMother ) { fPdgMother=pdgMother; }
+
+ const TObjArray* GetTrackArray(Int_t i) const {return (i>=0&&i<4)?&fTracks[i]:0;}
+ const TObjArray* GetPairArray(Int_t i) const {return (i>=0&&i<10)?
+ static_cast<TObjArray*>(fPairCandidates->UncheckedAt(i)):0;}
+
+ TObjArray** GetPairArraysPointer() { return &fPairCandidates; }
+
+ void SetHistogramManager(AliDielectronHistos * const histos) { fHistos=histos; }
+ const THashList * GetHistogramList() const { return fHistos?fHistos->GetHistogramList():0x0; }
+
+ Bool_t HasCandidates() const { return GetPairArray(1)?GetPairArray(1)->GetEntriesFast()>0:0; }
+
+ void SetCFManagerPair(AliDielectronCF * const cf) { fCfManagerPair=cf; }
+ AliDielectronCF* GetCFManagerPair() const { return fCfManagerPair; }
+
+ static const char* TrackClassName(Int_t i) { return (i>=0&&i<4)?fgkTrackClassNames[i]:""; }
+ static const char* PairClassName(Int_t i) { return (i>=0&&i<10)?fgkPairClassNames[i]:""; }
+
+private:
+
+
+ AliAnalysisFilter fEventFilter; // Event cuts
+ AliAnalysisFilter fTrackFilter; // leg cuts
+ AliAnalysisFilter fPairFilter; // pair cuts
+
+ Int_t fPdgMother; // pdg code of mother tracks
+
+ AliDielectronHistos *fHistos; // Histogram manager
+ // Streaming and merging should be handled
+ // by the analysis framework
+
+ TObjArray fTracks[4]; //! Selected track candidates
+ // 0: Event1, positive particles
+ // 1: Event1, negative particles
+ // 2: Event2, positive particles
+ // 3: Event2, negative particles
+
+ TObjArray *fPairCandidates; //! Pair candidate arrays
+ //TODO: better way to store it? TClonesArray?
+
+ AliDielectronCF *fCfManagerPair;//Correction Framework Manager for the Pair
+
+ void FillTrackArrays(AliVEvent * const ev, Int_t eventNr=0);
+ void FillPairArrays(Int_t arr1, Int_t arr2);
+
+ Int_t GetPairIndex(Int_t arr1, Int_t arr2) const {return arr1>=arr2?arr1*(arr1+1)/2+arr2:arr2*(arr2+1)/2+arr1;}
+
+ void InitPairCandidateArrays();
+ void ClearArrays();
+
+ TObjArray* PairArray(Int_t i);
+
+ static const char* fgkTrackClassNames[4]; //Names for track arrays
+ static const char* fgkPairClassNames[10]; //Names for pair arrays
+
+ void ProcessMC();
+
+ AliDielectron(const AliDielectron &c);
+ AliDielectron &operator=(const AliDielectron &c);
+
+ ClassDef(AliDielectron,1);
+};
+
+inline void AliDielectron::InitPairCandidateArrays()
+{
+ //
+ // initialise all pair candidate arrays
+ //
+ fPairCandidates->SetOwner();
+ for (Int_t i=0;i<10;++i){
+ TObjArray *arr=new TObjArray;
+ fPairCandidates->AddAt(arr,i);
+ arr->SetOwner();
+ }
+}
+
+inline TObjArray* AliDielectron::PairArray(Int_t i)
+{
+ //
+ // for internal use only: unchecked return of track array for fast access
+ //
+ return static_cast<TObjArray*>(fPairCandidates->UncheckedAt(i));
+}
+
+inline void AliDielectron::ClearArrays()
+{
+ //
+ // Reset the Arrays
+ //
+ for (Int_t i=0;i<4;++i){
+ fTracks[i].Clear();
+ }
+ for (Int_t i=0;i<10;++i){
+ PairArray(i)->Delete();
+ }
+}
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Dielectron Correction framework manager //
+// //
+/*
+
+
+
+
+
+
+
+
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TList.h>
+
+#include <AliCFContainer.h>
+#include <AliAnalysisFilter.h>
+#include <AliAnalysisCuts.h>
+#include <AliLog.h>
+
+#include "AliDielectronCF.h"
+#include "AliDielectronMC.h"
+
+ClassImp(AliDielectronCF)
+
+AliDielectronCF::AliDielectronCF() :
+ TNamed("DielectronCF","DielectronCF"),
+ fNSteps(0),
+ fNVars(0),
+ fNCuts(0),
+ fStepsForEachCut(kTRUE),
+ fStepsForCutsIncreasing(kFALSE),
+ fNStepMasks(0),
+ fPdgMother(-1),
+ fCfContainer(0x0)
+{
+ //
+ // Default constructor
+ //
+ for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
+ fVariables[i]=0;
+ }
+
+ for (Int_t i=0; i<kNmaxAddSteps; ++i){
+ fNBins[kNmaxAddSteps]=0;
+ fVarLoLimit[kNmaxAddSteps]=0.;
+ fVarUpLimit[kNmaxAddSteps]=0.;
+ }
+}
+
+//________________________________________________________________
+AliDielectronCF::AliDielectronCF(const char* name, const char* title) :
+ TNamed(name, title),
+ fNSteps(0),
+ fNVars(0),
+ fNCuts(0),
+ fStepsForEachCut(kTRUE),
+ fStepsForCutsIncreasing(kFALSE),
+ fNStepMasks(0),
+ fPdgMother(-1),
+ fCfContainer(0x0)
+{
+ //
+ // Named constructor
+ //
+ for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
+ fVariables[i]=0;
+ }
+
+ for (Int_t i=0; i<kNmaxAddSteps; ++i){
+ fNBins[kNmaxAddSteps]=0;
+ fVarLoLimit[kNmaxAddSteps]=0.;
+ fVarUpLimit[kNmaxAddSteps]=0.;
+ }
+}
+
+//________________________________________________________________
+AliDielectronCF::~AliDielectronCF()
+{
+ //
+ // Destructor
+ //
+
+}
+
+//________________________________________________________________
+void AliDielectronCF::AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins, Double_t min, Double_t max)
+{
+ //
+ // Add a variable to the CF configuration
+ //
+ fVariables[fNVars] = (UInt_t)type;
+ fVarLoLimit[fNVars] = min;
+ fVarUpLimit[fNVars] = max;
+ fNBins[fNVars] = nbins;
+ ++fNVars;
+}
+
+//________________________________________________________________
+void AliDielectronCF::InitialiseContainer(const AliAnalysisFilter& filter)
+{
+ //
+ // Initialise container based on the cuts in the analysis filter
+ //
+
+ fNCuts=filter.GetCuts()->GetEntries();
+
+ fNSteps=4; //defaults: 0: MC truth
+ // 1: no Cuts + MC
+ // 2: after all cuts
+ // 3: after all cuts + MC truth
+
+ if (fStepsForEachCut) fNSteps+=(2*fNCuts); //one step for each cut + MC truth
+ if (fStepsForCutsIncreasing) fNSteps+=(2*(fNCuts-2)); //one step for the increasing cuts + MC truth
+ // e.g. cut2&cut3, cut2&cut3&cut4
+ fNSteps+=(2*fNStepMasks); // cuts for the additional cut masks
+ // create the container
+ fCfContainer = new AliCFContainer(GetName(), GetTitle(), fNSteps, fNVars, fNBins);
+
+ // initialize the variables and their bin limits
+ for (Int_t iVar=0; iVar<fNVars; iVar++) {
+ UInt_t type=fVariables[iVar];
+ Int_t nBins = fNBins[iVar];
+ Double_t loLim = fVarLoLimit[iVar];
+ Double_t upLim = fVarUpLimit[iVar];
+ Double_t *binLim = new Double_t[nBins+1];
+
+ // set the bin limits
+ for(Int_t iBin=0; iBin<=nBins; iBin++) binLim[iBin] = loLim + (upLim-loLim) / nBins*(Double_t)iBin;
+
+ fCfContainer->SetBinLimits(iVar, binLim);
+ fCfContainer->SetVarTitle(iVar, AliDielectronVarManager::GetValueName(type));
+ delete binLim;
+ }
+
+ //=================//
+ // Set step titles //
+ //=================//
+ Int_t step=0;
+
+ //Pure MC truth
+ fCfContainer->SetStepTitle(step++,"MC truth");
+
+ //before cuts (MC truth)
+ fCfContainer->SetStepTitle(step++,"No cuts (MC truth)");
+
+ //After All cuts
+ TString cutName="All Cuts"; //TODO: User GetTitle???
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ cutName+=" (MC truth)";
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
+
+
+ //Steps for each of the cuts
+ if (fStepsForEachCut){
+ for (Int_t iCut=0; iCut<fNCuts;++iCut) {
+ TString cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ cutName+=" (MC truth)";
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
+ }
+ }
+
+ //Steps for increasing cut match
+ if (fStepsForCutsIncreasing){
+ TString cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
+ for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
+ cutName+="&";
+ cutName+=filter.GetCuts()->At(iCut)->GetName();
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ cutName+=" (MC truth)";
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
+ }
+ }
+
+ //Steps of user defined cut combinations
+ for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
+ TString cutName;
+ UInt_t mask=fStepMasks[iComb];
+ for (Int_t iCut=0; iCut<fNCuts;++iCut) {
+ if (mask&(1<<iCut)){
+ if (cutName.IsNull()){
+ cutName=filter.GetCuts()->At(iCut)->GetName();
+ }else{
+ cutName+="&";
+ cutName+=filter.GetCuts()->At(iCut)->GetName();
+ }
+ }
+ }
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ cutName+=" (MC truth)";
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut with MC truth
+ }
+
+ if (step!=fNSteps) {
+ AliError("Something went wrong in the naming of the steps!!!");
+ }
+}
+
+//________________________________________________________________
+void AliDielectronCF::Fill(UInt_t mask, const TObject *particle)
+{
+ //
+ // Fill the containers
+ //
+
+ Bool_t isMCTruth=kFALSE;
+ if (fPdgMother>=0) isMCTruth=AliDielectronMC::Instance()->IsMotherPdg(particle,fPdgMother);
+
+ Double_t valuesAll[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(particle,valuesAll);
+
+ Double_t values[AliDielectronVarManager::kNMaxValues];
+ for (Int_t iVar=0; iVar<fNVars; ++iVar){
+ Int_t var=fVariables[iVar];
+ values[iVar]=valuesAll[var];
+ }
+
+ UInt_t selectedMask=(1<<fNCuts)-1;
+
+ //============//
+ // Fill steps //
+ //============//
+ // step 0 would be full MC truth and is handled in FillMC
+ Int_t step=1;
+
+ //No cuts (MC truth)
+ if (isMCTruth) fCfContainer->Fill(values,step);
+ ++step;
+
+ //All cuts,
+ if (mask == selectedMask){
+ fCfContainer->Fill(values,step);
+ ++step;
+ if (isMCTruth) fCfContainer->Fill(values,step);
+ ++step;
+ } else {
+ step+=2;
+ }
+
+ //Steps for each of the cuts
+ if (fStepsForEachCut){
+ for (Int_t iCut=0; iCut<fNCuts;++iCut) {
+ if (mask&(1<<iCut)) {
+ fCfContainer->Fill(values,step);
+ ++step;
+ if (isMCTruth) fCfContainer->Fill(values,step);
+ ++step;
+ } else {
+ step+=2;
+ }
+ }
+ }
+
+ //Steps for increasing cut match
+ if (fStepsForCutsIncreasing){
+ for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
+ if (mask&(1<<((iCut+1)-1))) {
+ fCfContainer->Fill(values,step);
+ ++step;
+ if (isMCTruth) fCfContainer->Fill(values,step);
+ ++step;
+ } else {
+ step+=2;
+ }
+ }
+ }
+
+ //Steps of user defined cut combinations
+ for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
+ UInt_t userMask=fStepMasks[iComb];
+ if (mask&userMask) {
+ fCfContainer->Fill(values,step);
+ ++step;
+ if (isMCTruth) fCfContainer->Fill(values,step);
+ ++step;
+ } else {
+ step+=2;
+ }
+ }
+
+}
+
+//________________________________________________________________
+void AliDielectronCF::FillMC(const TObject *particle)
+{
+ //
+ // fill MC part of the Container
+ //
+ Double_t valuesAll[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(particle,valuesAll);
+
+ Double_t values[AliDielectronVarManager::kNMaxValues];
+ for (Int_t iVar=0; iVar<fNVars; ++iVar){
+ Int_t var=fVariables[iVar];
+ values[iVar]=valuesAll[var];
+ }
+ //TODO: temporary solution, set manually the pair type to 1: mixed e+-
+ values[AliDielectronVarManager::kPairType]=1;
+ fCfContainer->Fill(values,0);
+}
+
--- /dev/null
+#ifndef ALIDIELECTRONCF_H
+#define ALIDIELECTRONCF_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# Class AliDielectronCF #
+//# Dielectron Correction Framework Manager #
+//# #
+//# Authors: #
+//# Anton Andronic, GSI / A.Andronic@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Julian Book, Uni Ffm / Julian.Book@cern.ch #
+//# Frederick Kramer, Uni Ffm, / Frederick.Kramer@cern.ch #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+
+
+#include <TNamed.h>
+#include "AliDielectronVarManager.h"
+
+class AliAnalysisCuts;
+class AliAnalysisFilter;
+class AliCFContainer;
+
+class AliDielectronCF : public TNamed {
+public:
+ enum {kNmaxAddSteps=50};
+
+ AliDielectronCF();
+ AliDielectronCF(const char* name, const char* title);
+ virtual ~AliDielectronCF();
+
+ void SetStepsForEachCut(Bool_t steps=kTRUE) { fStepsForEachCut=steps; }
+ void SetStepsForCutsIncreasing(Bool_t steps=kTRUE) { fStepsForCutsIncreasing=steps; }
+
+ void SetPdgMother(Int_t pdg) { fPdgMother=pdg; }
+
+ void AddStepMask(UInt_t mask) { fStepMasks[fNStepMasks++]=mask; }
+
+ void AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins, Double_t min, Double_t max);
+
+ void InitialiseContainer(const AliAnalysisFilter& filter);
+
+ void Fill(UInt_t mask, const TObject *particle);
+ void FillMC(const TObject *particle);
+
+ AliCFContainer* GetContainer() const { return fCfContainer; }
+
+private:
+ UInt_t fVariables[AliDielectronVarManager::kNMaxValues]; //configured variables
+
+ Int_t fNSteps; // number of selection steps
+ Int_t fNVars; // number of variables
+ Int_t fNBins[kNmaxAddSteps]; // array of numbers ob bins of the vars
+ Double_t fVarLoLimit[kNmaxAddSteps]; // array of the lower limits of the vars
+ Double_t fVarUpLimit[kNmaxAddSteps]; // array of the upper limits of the vars
+
+ Int_t fNCuts; // Number of cuts in the filter concerned
+
+ Bool_t fStepsForEachCut; //create steps for each cut?
+ Bool_t fStepsForCutsIncreasing; //create steps for increasing cut combinatons?
+ //e.g. cut1&cut2, cut1&cut2&cut3 ...
+
+ UInt_t fStepMasks[kNmaxAddSteps]; //steps for additional cut combinatons
+ UInt_t fNStepMasks; //number of configured step masks
+
+ Int_t fPdgMother; //Pdg code of MCtruth validation
+ AliCFContainer* fCfContainer; //the CF container
+
+ AliDielectronCF(const AliDielectronCF &c);
+ AliDielectronCF &operator=(const AliDielectronCF &c);
+
+ ClassDef(AliDielectronCF,1) //Dielectron Correction Framework handler
+};
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+//
+// Generic Histogram container with support for groups and filling of groups by passing
+// a vector of data
+//
+// Authors:
+// Jens Wiechula <Jens.Wiechula@cern.ch>
+//
+
+#include <TH1.h>
+#include <TH1F.h>
+#include <TH2.h>
+#include <TH3.h>
+#include <TCollection.h>
+#include <THashList.h>
+#include <TString.h>
+#include <TObjArray.h>
+#include <TFile.h>
+#include <TError.h>
+#include <TCanvas.h>
+#include <TMath.h>
+#include <TROOT.h>
+#include <TLegend.h>
+#include <TKey.h>
+// #include <TVectorD.h>
+
+#include "AliDielectronHistos.h"
+
+
+ClassImp(AliDielectronHistos)
+
+
+AliDielectronHistos::AliDielectronHistos() :
+// TCollection(),
+ TNamed("AliDielectronHistos","Dielectron Histogram Container"),
+ fHistoList(),
+ fReservedWords(new TString)
+{
+ //
+ // Default constructor
+ //
+ fHistoList.SetOwner(kTRUE);
+ fHistoList.SetName("Dielectron_Histos");
+}
+
+//_____________________________________________________________________________
+AliDielectronHistos::AliDielectronHistos(const char* name, const char* title) :
+// TCollection(),
+ TNamed(name, title),
+ fHistoList(),
+ fReservedWords(new TString)
+{
+ //
+ // TNamed constructor
+ //
+ fHistoList.SetOwner(kTRUE);
+ fHistoList.SetName(name);
+}
+
+//_____________________________________________________________________________
+AliDielectronHistos::~AliDielectronHistos()
+{
+ //
+ // Destructor
+ //
+ fHistoList.Delete();
+ delete fReservedWords;
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ UInt_t valTypeX)
+{
+ //
+ // Default histogram creation 1D case
+ //
+ if (!IsHistogramOk(histClass,name)) return;
+
+ TH1* hist=new TH1F(name,title,nbinsX,xmin,xmax);
+ Bool_t isReserved=fReservedWords->Contains(histClass);
+ if (isReserved)
+ UserHistogramReservedWords(histClass, hist, valTypeX);
+ else
+ UserHistogram(histClass, hist, valTypeX);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ Int_t nbinsY, Double_t ymin, Double_t ymax,
+ UInt_t valTypeX, UInt_t valTypeY)
+{
+ //
+ // Default histogram creation 2D case
+ //
+ if (!IsHistogramOk(histClass,name)) return;
+
+ TH1* hist=new TH2F(name,title,nbinsX,xmin,xmax,nbinsY,ymin,ymax);
+ Bool_t isReserved=fReservedWords->Contains(histClass);
+ if (isReserved)
+ UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY);
+ else
+ UserHistogram(histClass, hist, valTypeX+100*valTypeY);
+}
+
+
+//_____________________________________________________________________________
+void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ Int_t nbinsY, Double_t ymin, Double_t ymax,
+ Int_t nbinsZ, Double_t zmin, Double_t zmax,
+ UInt_t valTypeX, UInt_t valTypeY, UInt_t valTypeZ)
+{
+ //
+ // Default histogram creation 3D case
+ //
+ if (!IsHistogramOk(histClass,name)) return;
+
+ TH1* hist=new TH3F(name,title,nbinsX,xmin,xmax,nbinsY,ymin,ymax,nbinsZ,zmin,zmax);
+ Bool_t isReserved=fReservedWords->Contains(histClass);
+ if (isReserved)
+ UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
+ else
+ UserHistogram(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::UserHistogram(const char* histClass, TH1* hist, UInt_t valTypes)
+{
+ //
+ // Add any type of user histogram
+ //
+
+ //special case for the calss Pair. where histograms will be created for all pair classes
+ Bool_t isReserved=fReservedWords->Contains(histClass);
+ if (isReserved) {
+ UserHistogramReservedWords(histClass, hist, valTypes);
+ return;
+ }
+
+ if (!IsHistogramOk(histClass,hist->GetName())) return;
+
+ THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
+ hist->SetDirectory(0);
+ hist->SetUniqueID(valTypes);
+ classTable->Add(hist);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::AddClass(const char* histClass)
+{
+ //
+ // Add a class of histograms
+ // Several classes can be added by separating them by a ';' e.g. 'class1;class2;class3'
+ //
+ TString hists(histClass);
+ TObjArray *arr=hists.Tokenize(";");
+ TIter next(arr);
+ TObject *o=0;
+ while ( (o=next()) ){
+ if (fHistoList.FindObject(o->GetName())){
+ Warning("AddClass","Cannot create class '%s' it already exists.",histClass);
+ continue;
+ }
+ if (fReservedWords->Contains(o->GetName())){
+ Error("AddClass","Pair is a reserved word, please use another name");
+ continue;
+ }
+ THashList *table=new THashList;
+ table->SetOwner(kTRUE);
+ table->SetName(o->GetName());
+ fHistoList.Add(table);
+ }
+ delete arr;
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval)
+{
+ //
+ // Fill function 1D case
+ //
+ THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
+ TH1* hist=0;
+ if (!classTable || !(hist=(TH1*)classTable->FindObject(name)) ){
+ Warning("Fill","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
+ return;
+ }
+ hist->Fill(xval);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval)
+{
+ //
+ // Fill function 2D case
+ //
+ THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
+ TH2* hist=0;
+ if (!classTable || !(hist=(TH2*)classTable->FindObject(name)) ){
+ Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
+ return;
+ }
+ hist->Fill(xval,yval);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval)
+{
+ //
+ // Fill function 3D case
+ //
+ THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
+ TH3* hist=0;
+ if (!classTable || !(hist=(TH3*)classTable->FindObject(name)) ){
+ Warning("UserHistogram","Cannot fill histogram. Either class '%s' or histogram '%s' not existing.",histClass,name);
+ return;
+ }
+ hist->Fill(xval,yval,zval);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::FillClass(const char* histClass, Int_t nValues, const Double_t *values)
+{
+ //
+ // Fill class 'histClass' (by name)
+ //
+
+ THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
+ if (!classTable){
+ Warning("FillClass","Cannot fill class '%s' its not defined.",histClass);
+ return;
+ }
+
+ TIter nextHist(classTable);
+ TH1 *hist=0;
+ while ( (hist=(TH1*)nextHist()) ){
+ UInt_t valueTypes=hist->GetUniqueID();
+ if (valueTypes==(UInt_t)kNoAutoFill) continue;
+ UInt_t value1=valueTypes%100; //last two digits
+ UInt_t value2=valueTypes/100%100; //second last two digits
+ UInt_t value3=valueTypes/10000%100; //third last two digits
+ if (value1>=(UInt_t)nValues||value2>=(UInt_t)nValues||value3>=(UInt_t)nValues) {
+ Warning("FillClass","One of the values is out of range. Not filling histogram '%s/%s'.", histClass, hist->GetName());
+ continue;
+ }
+ switch (hist->GetDimension()){
+ case 1:
+ hist->Fill(values[value1]);
+ break;
+ case 2:
+ ((TH2*)hist)->Fill(values[value1],values[value2]);
+ break;
+ case 3:
+ ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]);
+ break;
+ }
+ }
+}
+
+//_____________________________________________________________________________
+// void AliDielectronHistos::FillClass(const char* histClass, const TVectorD &vals)
+// {
+// //
+// //
+// //
+// FillClass(histClass, vals.GetNrows(), vals.GetMatrixArray());
+// }
+
+//_____________________________________________________________________________
+void AliDielectronHistos::UserHistogramReservedWords(const char* histClass, TH1 *hist, UInt_t valTypes)
+{
+ //
+ // Creation of histogram for all pair types
+ //
+ TString title(hist->GetTitle());
+ // Same Event Like Sign
+ TIter nextClass(&fHistoList);
+ THashList *l=0;
+ while ( (l=static_cast<THashList*>(nextClass())) ){
+ TString name(l->GetName());
+ if (name.Contains(histClass)){
+ TH1 *h=static_cast<TH1*>(hist->Clone());
+ h->SetDirectory(0);
+ h->SetTitle(Form("%s %s",title.Data(),l->GetName()));
+ UserHistogram(l->GetName(),h,valTypes);
+ }
+ }
+ delete hist;
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::DumpToFile(const char* file)
+{
+ //
+ // Dump the histogram list to a newly created root file
+ //
+ TFile f(file,"recreate");
+ fHistoList.Write(fHistoList.GetName(),TObject::kSingleKey);
+ f.Close();
+}
+
+//_____________________________________________________________________________
+TH1* AliDielectronHistos::GetHistogram(const char* histClass, const char* name) const
+{
+ //
+ // return histogram 'name' in 'histClass'
+ //
+ THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
+ if (!classTable) return 0x0;
+ return (TH1*)classTable->FindObject(name);
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::Draw(const Option_t* option)
+{
+ //
+ // Draw histograms
+ //
+
+ TString drawOpt(option);
+ drawOpt.ToLower();
+ //options
+// Bool_t same=drawOpt.Contains("same"); //FIXME not yet implemented
+
+ TIter nextClass(&fHistoList);
+ THashList *classTable=0;
+ while ( (classTable=(THashList*)nextClass()) ){
+ //optimised division
+ Int_t nPads = classTable->GetEntries();
+ Int_t nCols = (Int_t)TMath::Ceil( TMath::Sqrt(nPads) );
+ Int_t nRows = (Int_t)TMath::Ceil( (Double_t)nPads/(Double_t)nCols );
+
+ //create canvas
+ TString canvasName;
+ canvasName.Form("c%s",classTable->GetName());
+ TCanvas *c=(TCanvas*)gROOT->FindObject(canvasName.Data());
+ if (!c) c=new TCanvas(canvasName.Data(),classTable->GetName());
+ c->Clear();
+ c->Divide(nCols,nRows);
+
+ //loop over histograms and draw them
+ TIter nextHist(classTable);
+ Int_t iPad=0;
+ TH1 *h=0;
+ while ( (h=(TH1*)nextHist()) ){
+ TString drawOpt;
+ if ( (h->InheritsFrom(TH2::Class())) ) drawOpt="colz";
+ c->cd(++iPad);
+ h->Draw(drawOpt.Data());
+ }
+ }
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::Print(const Option_t* option) const
+{
+ //
+ // Print classes and histograms
+ //
+ TString optString(option);
+
+ if (optString.IsNull()) PrintStructure();
+
+
+
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::PrintStructure() const
+{
+ //
+ // Print classes and histograms in the class to stdout
+ //
+ TIter nextClass(&fHistoList);
+ THashList *classTable=0;
+ while ( (classTable=(THashList*)nextClass()) ){
+ TIter nextHist(classTable);
+ TObject *o=0;
+ printf("+ %s\n",classTable->GetName());
+ while ( (o=nextHist()) )
+ printf("| ->%s\n",o->GetName());
+ }
+
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::SetHistogramList(THashList &list)
+{
+ //
+ // set histogram classes and histograms to this instance. It will take onwnership!
+ //
+ TIter next(&list);
+ TObject *o;
+ while ( (o=next()) ){
+ fHistoList.Add(o);
+ }
+ list.SetOwner(kFALSE);
+ fHistoList.SetOwner(kTRUE);
+}
+
+//_____________________________________________________________________________
+Bool_t AliDielectronHistos::IsHistogramOk(const char* histClass, const char* name)
+{
+ //
+ // check whether the histogram class exists and the histogram itself does not exist yet
+ //
+ Bool_t isReserved=fReservedWords->Contains(histClass);
+ if (!fHistoList.FindObject(histClass)&&!isReserved){
+ Warning("IsHistogramOk","Cannot create histogram. Class '%s' not defined. Please create it using AddClass before.",histClass);
+ return kFALSE;
+ }
+ if (GetHistogram(histClass,name)){
+ Warning("IsHistogramOk","Cannot create histogram '%s' in class '%s': It already exists!",name,histClass);
+ return kFALSE;
+ }
+ return kTRUE;
+}
+
+// //_____________________________________________________________________________
+// TIterator* AliDielectronHistos::MakeIterator(Bool_t dir) const
+// {
+// //
+// //
+// //
+// return new TListIter(&fHistoList, dir);
+// }
+
+//_____________________________________________________________________________
+void AliDielectronHistos::ReadFromFile(const char* file)
+{
+ //
+ // Read histos from file
+ //
+ TFile f(file);
+ TIter nextKey(f.GetListOfKeys());
+ TKey *key=0;
+ while ( (key=(TKey*)nextKey()) ){
+ TObject *o=f.Get(key->GetName());
+ THashList *list=dynamic_cast<THashList*>(o);
+ if (!list) continue;
+ SetHistogramList(*list);
+ break;
+ }
+ f.Close();
+}
+
+void AliDielectronHistos::DrawSame(const char* histName, const Option_t *opt)
+{
+ //
+ // Draw all histograms with the same name into one canvas
+ // if option contains 'leg' a legend will be created with the class name as caption
+ // if option contains 'can' a new canvas is created
+ //
+
+ TString optString(opt);
+ optString.ToLower();
+ Bool_t optLeg=optString.Contains("leg");
+ Bool_t optCan=optString.Contains("can");
+
+ TLegend *leg=0;
+ TCanvas *c=0;
+ if (optCan){
+ c=(TCanvas*)gROOT->FindObject(Form("c%s",histName));
+ if (!c) c=new TCanvas(Form("c%s",histName),Form("All '%s' histograms",histName));
+ c->Clear();
+ c->cd();
+ }
+
+ if (optLeg) leg=new TLegend(.8,.3,.99,.9);
+
+ Int_t i=0;
+ TIter next(&fHistoList);
+ THashList *classTable=0;
+ Double_t max=-1e10;
+ TH1 *hFirst=0x0;
+ while ( (classTable=(THashList*)next()) ){
+ if ( TH1 *h=(TH1*)classTable->FindObject(histName) ){
+ if (i==0) hFirst=h;
+ h->SetLineColor(i+1);
+ h->SetMarkerColor(i+1);
+ h->Draw(i>0?"same":"");
+ if (leg) leg->AddEntry(h,classTable->GetName(),"lp");
+ ++i;
+ max=TMath::Max(max,h->GetMaximum());
+ }
+ }
+ if (leg){
+ leg->SetFillColor(10);
+ leg->SetY1(.9-i*.05);
+ leg->Draw();
+ }
+ if (hFirst&&(hFirst->GetYaxis()->GetXmax()<max)){
+ hFirst->SetMaximum(max);
+ }
+}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::SetReservedWords(const char* words)
+{
+ //
+ // set reserved words
+ //
+
+ (*fReservedWords)=words;
+}
+
--- /dev/null
+#ifndef ALIDIELECTRONHISTOS_H
+#define ALIDIELECTRONHISTOS_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+///////////////////////////////////////////////////////////////////////////////////////////
+// //
+// Generic Histogram container with support for groups and filling of groups by passing //
+// a vector of data //
+// //
+// Authors: //
+// Jens Wiechula <Jens.Wiechula@cern.ch> //
+// //
+///////////////////////////////////////////////////////////////////////////////////////////
+
+
+#include <TNamed.h>
+// #include <TCollection.h>
+#include <THashList.h>
+
+class TH1;
+class TString;
+// class TVectorT<double>;
+
+class AliDielectronHistos : public TNamed {
+public:
+ AliDielectronHistos();
+ AliDielectronHistos(const char* name, const char* title);
+ virtual ~AliDielectronHistos();
+
+
+ void UserHistogram(const char* histClass,const char *name, const char* title,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ UInt_t valTypeX=kNoAutoFill);
+ void UserHistogram(const char* histClass,const char *name, const char* title,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ Int_t nbinsY, Double_t ymin, Double_t ymax,
+ UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0);
+ void UserHistogram(const char* histClass,const char *name, const char* title,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ Int_t nbinsY, Double_t ymin, Double_t ymax,
+ Int_t nbinsZ, Double_t zmin, Double_t zmax,
+ UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0, UInt_t valTypeZ=0);
+
+ void UserHistogram(const char* histClass, TH1* hist, UInt_t valTypes=kNoAutoFill);
+
+
+ void Fill(const char* histClass, const char* name, Double_t xval);
+ void Fill(const char* histClass, const char* name, Double_t xval, Double_t yval);
+ void Fill(const char* histClass, const char* name, Double_t xval, Double_t yval, Double_t zval);
+
+// void FillClass(const char* histClass, const TVectorD &vals);
+ void FillClass(const char* histClass, Int_t nValues, const Double_t *values);
+
+
+ TH1* GetHistogram(const char* histClass, const char* name) const;
+
+ void SetHistogramList(THashList &list);
+ const THashList* GetHistogramList() const {return &fHistoList;}
+
+ void AddClass(const char* histClass);
+
+ void DumpToFile(const char* file="histos.root");
+ void ReadFromFile(const char* file="histos.root");
+
+ virtual void Print(const Option_t* option = "") const;
+ virtual void Draw(const Option_t* option = "");
+ virtual void DrawSame(const char* histName, const Option_t *opt="leg can");
+
+ void SetReservedWords(const char* words);
+// virtual void Add(TObject *obj) {};
+// virtual void Clear(Option_t *option="") {};
+// virtual void Delete(Option_t *option="") {};
+// virtual TObject **GetObjectRef(const TObject *obj) const { return 0; }
+// virtual TIterator *MakeIterator(Bool_t dir = kIterForward) const ;
+// virtual TObject *Remove(TObject *obj) { return 0; }
+
+private:
+ THashList fHistoList; //-> list of histograms
+
+ TString *fReservedWords; //! list of reserved words
+ void UserHistogramReservedWords(const char* histClass, TH1 *hist, UInt_t valTypes);
+ void FillClass(THashTable *classTable, Int_t nValues, Double_t *values);
+
+ void PrintPDF(Option_t* opt);
+ void PrintStructure() const;
+
+ Bool_t IsHistogramOk(const char* classTable, const char* name);
+
+ enum {kNoAutoFill=1000000000};
+
+ AliDielectronHistos(const AliDielectronHistos &hist);
+ AliDielectronHistos& operator = (const AliDielectronHistos &hist);
+
+ ClassDef(AliDielectronHistos,1)
+};
+
+#endif
+
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+//#####################################################
+//# #
+//# Class AliDielectronMC #
+//# Cut Class for Jpsi->e+e- analysis #
+//# #
+//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# #
+//#####################################################
+
+#include <AliAnalysisManager.h>
+#include <AliAODHandler.h>
+#include <AliESDInputHandler.h>
+#include <AliMCEventHandler.h>
+#include <AliMCEvent.h>
+#include <AliMCParticle.h>
+#include <AliAODMCParticle.h>
+#include <AliStack.h>
+#include <AliESDEvent.h>
+#include <AliESDtrack.h>
+#include <AliLog.h>
+
+#include "AliDielectronMC.h"
+
+AliDielectronMC* AliDielectronMC::fgInstance=0x0;
+
+//____________________________________________________________
+AliDielectronMC* AliDielectronMC::Instance()
+{
+ //
+ // return pointer to singleton implementation
+ //
+ if (fgInstance) return fgInstance;
+
+ AnalysisType type=kUNSET;
+ if (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()) type=kESD;
+ else if (AliAnalysisManager::GetAnalysisManager()->GetInputEventHandler()->IsA()==AliAODHandler::Class()) type=kAOD;
+
+ fgInstance=new AliDielectronMC(type);
+
+ return fgInstance;
+}
+
+//____________________________________________________________
+AliDielectronMC::AliDielectronMC(AnalysisType type):
+ fMCEvent(0x0),
+ fStack(0x0),
+ fAnaType(type)
+{
+ //
+ // default constructor
+ //
+}
+
+
+//____________________________________________________________
+AliDielectronMC::~AliDielectronMC()
+{
+ //
+ // default destructor
+ //
+
+}
+
+//____________________________________________________________
+void AliDielectronMC::Initialize()
+{
+ //
+ // initialize MC class
+ //
+ if (!ConnectMCEvent()) AliError("Initialization of MC object failed!");
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetNMCTracks()
+{
+ //
+ // return the number of generated tracks from MC event
+ //
+ if (!fMCEvent){ AliError("No fMCEvent"); return 0; }
+ return fMCEvent->GetNumberOfTracks();
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetNMCTracksFromStack()
+{
+ //
+ // return the number of generated tracks from stack
+ //
+ if (!fStack){ AliError("No fStack"); return -999; }
+ return fStack->GetNtrack();
+}
+
+//____________________________________________________________
+AliVParticle* AliDielectronMC::GetMCTrackFromMCEvent(Int_t _itrk)
+{
+ //
+ // return MC track directly from MC event
+ //
+ if (!fMCEvent){ AliError("No fMCEvent"); return NULL;}
+ AliVParticle * track = fMCEvent->GetTrack(_itrk); // tracks from MC event
+ return track;
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::ConnectMCEvent()
+{
+ //
+ // connect stack object from the mc handler
+ //
+ AliMCEventHandler* mcHandler = dynamic_cast<AliMCEventHandler*> (AliAnalysisManager::GetAnalysisManager()->GetMCtruthEventHandler());
+ if (!mcHandler){ AliError("Could not retrive MC event handler!"); return kFALSE; }
+
+ AliMCEvent* mcEvent = mcHandler->MCEvent();
+ if (!mcEvent){ AliError("Could not retrieve MC event!"); return kFALSE; }
+ fMCEvent = mcEvent;
+
+ if (!UpdateStack()) return kFALSE;
+ return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::UpdateStack()
+{
+ //
+ // update stack with new event
+ //
+ if (!fMCEvent){ AliError("No fMCEvent"); return kFALSE;}
+ AliStack* stack = fMCEvent->Stack();
+ if (!stack){ AliError("Could not retrive stack!"); return kFALSE; }
+ fStack = stack;
+ return kTRUE;
+}
+
+//____________________________________________________________
+AliMCParticle* AliDielectronMC::GetMCTrack(AliESDtrack* _track)
+{
+ //
+ // return MC track
+ //
+ Int_t label = TMath::Abs(_track->GetLabel());
+ AliMCParticle *mctrack = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(label));
+ return mctrack;
+}
+
+//____________________________________________________________
+TParticle* AliDielectronMC::GetMCTrackFromStack(AliESDtrack* _track)
+{
+ //
+ // return MC track from stack
+ //
+ Int_t label = TMath::Abs(_track->GetLabel());
+ if (!fStack) AliWarning("fStack is not available. Update stack first.");
+ TParticle* mcpart = fStack->Particle(label);
+ if (!mcpart) return NULL;
+ return mcpart;
+}
+
+//____________________________________________________________
+AliMCParticle* AliDielectronMC::GetMCTrackMother(AliESDtrack* _track)
+{
+ //
+ // return MC track mother
+ //
+ AliMCParticle* mcpart = GetMCTrack(_track);
+ if (!mcpart) return NULL;
+printf("mcpart->GetMother() : %d\n",mcpart->GetMother());
+ AliMCParticle* mcmother = dynamic_cast<AliMCParticle *>(fMCEvent->GetTrack(mcpart->GetMother()));
+ if (!mcmother) return NULL;
+ return mcmother;
+}
+
+//____________________________________________________________
+TParticle* AliDielectronMC::GetMCTrackMotherFromStack(AliESDtrack* _track)
+{
+ //
+ // return MC track mother from stack
+ //
+ TParticle* mcpart = GetMCTrackFromStack(_track);
+ if ( !mcpart || mcpart->GetFirstMother()<=0 ) return NULL;
+ TParticle* mcmother = fStack->Particle(mcpart->GetFirstMother());
+ if (!mcmother) return NULL;
+ return mcmother;
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMCPID(AliESDtrack* _track)
+{
+ //
+ // return PDG code of the track from the MC truth info
+ //
+ AliMCParticle* mcpart = GetMCTrack(_track);
+ if (!mcpart) return -999;
+ return mcpart->PdgCode();
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMCPIDFromStack(AliESDtrack* _track)
+{
+ //
+ // return MC PDG code from stack
+ //
+ TParticle* mcpart = GetMCTrackFromStack(_track);
+ if (!mcpart) return -999;
+ return mcpart->GetPdgCode();
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMotherPDG(AliESDtrack* _track)
+{
+ //
+ // return PDG code of the mother track from the MC truth info
+ //
+ AliMCParticle* mcmother = GetMCTrackMother(_track);
+ if (!mcmother) return -999;
+ return mcmother->PdgCode();
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMotherPDGFromStack(AliESDtrack* _track)
+{
+ //
+ // return PDG code of the mother track from stack
+ //
+ TParticle* mcmother = GetMCTrackMotherFromStack(_track);
+ if (!mcmother) return -999;
+ return mcmother->GetPdgCode();
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMCProcess(AliESDtrack* _track)
+{
+ //
+ // return process number of the track
+ //
+ AliMCParticle* mcpart = GetMCTrack(_track);
+ if (!mcpart) return -999;
+ return 0;
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMCProcessFromStack(AliESDtrack* _track)
+{
+ //
+ // return process number of the track
+ //
+ TParticle* mcpart = GetMCTrackFromStack(_track);
+ if (!mcpart) return -999;
+ return mcpart->GetUniqueID();
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMCProcessMother(AliESDtrack* _track)
+{
+ //
+ // return process number of the mother of the track
+ //
+ AliMCParticle* mcmother = GetMCTrackMother(_track);
+ if (!mcmother) return -999;
+ return 0;
+}
+
+//____________________________________________________________
+Int_t AliDielectronMC::GetMCProcessMotherFromStack(AliESDtrack* _track)
+{
+ //
+ // return process number of the mother of the track
+ //
+ TParticle* mcmother = GetMCTrackMotherFromStack(_track);
+ if (!mcmother) return -999;
+ return mcmother->GetUniqueID();
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::IsMCMotherToEE(const AliVParticle *particle, Int_t pdgMother)
+{
+ //
+ // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
+ //
+
+ if (!fMCEvent) return kFALSE;
+
+ if (particle->IsA()==AliMCParticle::Class()){
+ return IsMCMotherToEEesd(static_cast<const AliMCParticle*>(particle),pdgMother);
+ } else if (particle->IsA()==AliAODMCParticle::Class()){
+ return IsMCMotherToEEaod(static_cast<const AliAODMCParticle*>(particle),pdgMother);
+ } else {
+ AliError("Unknown particle type");
+ }
+ return kFALSE;
+
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::IsMCMotherToEEesd(const AliMCParticle *particle, Int_t pdgMother)
+{
+ //
+ // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
+ // ESD case
+ //
+
+ //check pdg code
+ if (particle->PdgCode()!=pdgMother) return kFALSE;
+ Int_t ifirst = particle->GetFirstDaughter();
+ Int_t ilast = particle->GetLastDaughter();
+
+ //check number of daughters
+ if ((ilast-ifirst)!=1) return kFALSE;
+ AliMCParticle *firstD=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(ifirst));
+ AliMCParticle *secondD=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(ilast));
+
+ if (firstD->Charge()>0){
+ if (firstD->PdgCode()!=-11) return kFALSE;
+ if (secondD->PdgCode()!=11) return kFALSE;
+ }else{
+ if (firstD->PdgCode()!=11) return kFALSE;
+ if (secondD->PdgCode()!=-11) return kFALSE;
+ }
+
+ return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::IsMCMotherToEEaod(const AliAODMCParticle *particle, Int_t pdgMother)
+{
+ //
+ // Check if the Mother 'particle' is of type pdgMother and decays to e+e-
+ // AOD case
+ //
+ if (particle->GetPdgCode()!=pdgMother) return kFALSE;
+ if (particle->GetNDaughters()!=2) return kFALSE;
+
+ Int_t ifirst = particle->GetDaughter(0);
+ Int_t ilast = particle->GetDaughter(1);
+
+ //check number of daughters
+ if ((ilast-ifirst)!=1) return kFALSE;
+ AliAODMCParticle *firstD=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(ifirst));
+ AliAODMCParticle *secondD=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(ilast));
+
+ if (firstD->Charge()>0){
+ if (firstD->GetPdgCode()!=11) return kFALSE;
+ if (secondD->GetPdgCode()!=-11) return kFALSE;
+ }else{
+ if (firstD->GetPdgCode()!=-11) return kFALSE;
+ if (secondD->GetPdgCode()!=11) return kFALSE;
+ }
+ return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::IsMotherPdg(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
+{
+ //
+ // test if mother of particle 1 and 2 has pdgCode pdgMother and is the same;
+ //
+ if (!fMCEvent) return kFALSE;
+
+ if (fAnaType==kESD) return IsMotherPdgESD(particle1, particle2, pdgMother);
+ else if (fAnaType==kAOD) return IsMotherPdgAOD(particle1, particle2, pdgMother);
+
+ return kFALSE;
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::IsMotherPdgESD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
+{
+ //
+ // test if mother of particle 1 and 2 has pdgCode pdgMother and is the same;
+ // ESD case
+ //
+
+ AliMCParticle *mcPart1=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(particle1->GetLabel()));
+ AliMCParticle *mcPart2=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(particle2->GetLabel()));
+
+ if (!mcPart1||!mcPart2) return kFALSE;
+
+ Int_t lblMother1=mcPart1->GetMother();
+ Int_t lblMother2=mcPart2->GetMother();
+
+ AliMCParticle *mcMother1=static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(lblMother1));
+ if (!mcMother1) return kFALSE;
+ if (lblMother1!=lblMother2) return kFALSE;
+ if (mcMother1->PdgCode()!=pdgMother) return kFALSE;
+
+ return kTRUE;
+}
+
+//____________________________________________________________
+Bool_t AliDielectronMC::IsMotherPdgAOD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother)
+{
+ //
+ // test if mother of particle 1 and 2 has pdgCode pdgMother and is the same;
+ // AOD case
+ //
+ AliAODMCParticle *mcPart1=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(particle1->GetLabel()));
+ AliAODMCParticle *mcPart2=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(particle2->GetLabel()));
+
+ if (!mcPart1||!mcPart2) return kFALSE;
+
+ Int_t lblMother1=mcPart1->GetMother();
+ Int_t lblMother2=mcPart2->GetMother();
+
+ AliAODMCParticle *mcMother1=static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(lblMother1));
+
+ if (!mcMother1) return kFALSE;
+ if (lblMother1!=lblMother2) return kFALSE;
+ if (mcMother1->GetPdgCode()!=pdgMother) return kFALSE;
+
+ return kTRUE;
+}
+
--- /dev/null
+#ifndef ALIDIELECTRONMC_H
+#define ALIDIELECTRONMC_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#####################################################
+//# #
+//# Class AliDielectronMC #
+//# Cut Class for Jpsi->e+e- analysis #
+//# #
+//# by WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# #
+//#####################################################
+
+#ifndef ROOT_TObject
+#include <TObject.h>
+#endif
+class AliESDEvent;
+class AliHFEpid;
+class AliStack;
+class AliMCEvent;
+class AliESDtrack;
+class TParticle;
+class AliMCParticle;
+class AliAODMCParticle;
+
+#include "AliDielectronPair.h"
+
+class AliDielectronMC : public TObject{
+
+public:
+ enum AnalysisType {kUNSET=0, kESD, kAOD};
+
+ AliDielectronMC(AnalysisType type=kUNSET);
+ virtual ~AliDielectronMC();
+
+ static AliDielectronMC* Instance();
+
+ void Initialize(); // initialization
+ Int_t GetNMCTracks(); // return number of generated tracks
+ Int_t GetNMCTracksFromStack(); // return number of generated tracks from stack
+ Int_t GetMCPID(AliESDtrack* _track); // return MC PID
+ Int_t GetMCPIDFromStack(AliESDtrack* _track); // return MC PID
+ Int_t GetMotherPDG(AliESDtrack* _track); // return mother PID from the MC stack
+ Int_t GetMotherPDGFromStack(AliESDtrack* _track); // return mother PID from the MC stack
+ Int_t GetMCProcess(AliESDtrack* _track); // return process number
+ Int_t GetMCProcessFromStack(AliESDtrack* _track); // return process number
+ Int_t GetMCProcessMother(AliESDtrack* _track); // return process number of the mother track
+ Int_t GetMCProcessMotherFromStack(AliESDtrack* _track); // return process number of the mother track
+
+ Bool_t ConnectMCEvent();
+ Bool_t UpdateStack();
+
+ Bool_t IsMotherPdg(const TObject* particle, Int_t pdgMother);
+ Bool_t IsMotherPdg(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother);
+ Bool_t IsMCMotherToEE(const AliVParticle *particle, Int_t pdgMother);
+
+ AliVParticle* GetMCTrackFromMCEvent(AliVParticle *track); // return MC track directly from MC event
+ AliVParticle* GetMCTrackFromMCEvent(Int_t _itrk); // return MC track directly from MC event
+ TParticle* GetMCTrackFromStack(AliESDtrack* _track); // return MC track from stack
+ AliMCParticle* GetMCTrack(AliESDtrack* _track); // return MC track associated with reco track
+ TParticle* GetMCTrackMotherFromStack(AliESDtrack* _track); // return MC mother track from stack
+ AliMCParticle* GetMCTrackMother(AliESDtrack* _track); // return MC mother track from stack
+
+private:
+ AliMCEvent *fMCEvent; // MC event object
+ AliStack *fStack; // MC stack
+
+ AnalysisType fAnaType; // Analysis type
+
+ static AliDielectronMC* fgInstance; //! singleton pointer
+
+ AliDielectronMC(const AliDielectronMC &c);
+ AliDielectronMC &operator=(const AliDielectronMC &c);
+
+ Bool_t IsMCMotherToEEesd(const AliMCParticle *particle, Int_t pdgMother);
+ Bool_t IsMCMotherToEEaod(const AliAODMCParticle *particle, Int_t pdgMother);
+
+ Bool_t IsMotherPdgESD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother);
+ Bool_t IsMotherPdgAOD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother);
+
+ ClassDef(AliDielectronMC, 0)
+};
+
+inline Bool_t AliDielectronMC::IsMotherPdg(const TObject* particle, Int_t pdgMother)
+{
+ //
+ //
+ //
+ if (particle->IsA()!=AliDielectronPair::Class()) return kFALSE;
+ const AliDielectronPair *pair=static_cast<const AliDielectronPair*>(particle);
+ return IsMotherPdg(pair->GetFirstDaughter(),pair->GetSecondDaughter(),pdgMother);
+}
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// Dielectron Pair class. Internally it makes use of AliKFParticle. //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "AliDielectronPair.h"
+#include "AliVTrack.h"
+
+ClassImp(AliDielectronPair)
+
+AliDielectronPair::AliDielectronPair() :
+ fOpeningAngle(-1),
+ fType(-1),
+ fPair(),
+ fRefD1(),
+ fRefD2()
+{
+ //
+ // Default Constructor
+ //
+
+}
+
+//______________________________________________
+AliDielectronPair::AliDielectronPair(AliVTrack * const particle1, Int_t pid1,
+ AliVTrack * const particle2, Int_t pid2, Char_t type) :
+ fOpeningAngle(-1),
+ fType(type),
+ fPair(),
+ fRefD1(),
+ fRefD2()
+{
+ //
+ // Constructor with tracks
+ //
+ SetTracks(particle1, pid1, particle2, pid2);
+}
+
+//______________________________________________
+AliDielectronPair::~AliDielectronPair()
+{
+ //
+ // Default Destructor
+ //
+
+}
+
+//______________________________________________
+void AliDielectronPair::SetTracks(AliVTrack * const particle1, Int_t pid1,
+ AliVTrack * const particle2, Int_t pid2)
+{
+ //
+ // Set the tracks to the pair KF particle
+ //
+ fPair.Initialize();
+
+ AliKFParticle kf1(*particle1,pid1);
+ AliKFParticle kf2(*particle2,pid2);
+
+ fPair.AddDaughter(kf1);
+ fPair.AddDaughter(kf2);
+
+ fRefD1 = particle1;
+ fRefD2 = particle2;
+
+ fOpeningAngle=kf1.GetAngle(kf2);
+}
+
--- /dev/null
+#ifndef ALIDIELECTRONPAIR_H
+#define ALIDIELECTRONPAIR_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# AliDielectronPair #
+//# Class to store pair information #
+//# #
+//# #
+//# Authors: #
+//# Anton Andronic, GSI / A.Andronic@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Julian Book, Uni Ffm / Julian.Book@cern.ch #
+//# Frederick Kramer, Uni Ffm, / Frederick.Kramer@cern.ch #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+#include <TMath.h>
+#include <TRef.h>
+#include <TLorentzVector.h>
+
+#include <AliKFParticle.h>
+#include <AliVParticle.h>
+
+class AliVTrack;
+
+//TODO
+//TODO: Should we inherit from AliVTrack in order to built another AliDielectronPair of KF with it?
+//TODO
+class AliDielectronPair : public AliVParticle {
+public:
+ AliDielectronPair();
+ virtual ~AliDielectronPair();
+
+ AliDielectronPair(AliVTrack * const particle1, Int_t pid1,
+ AliVTrack * const particle2, Int_t pid2, Char_t type);
+
+ //TODO: copy constructor + assignment operator
+
+ void SetTracks(AliVTrack * const particle1, Int_t pid1,
+ AliVTrack * const particle2, Int_t pid2);
+
+ //AliVParticle interface
+ // kinematics
+ virtual Double_t Px() const { return fPair.GetPx(); }
+ virtual Double_t Py() const { return fPair.GetPy(); }
+ virtual Double_t Pz() const { return fPair.GetPz(); }
+ virtual Double_t Pt() const { return fPair.GetPt(); }
+ virtual Double_t P() const { return fPair.GetP(); }
+ virtual Bool_t PxPyPz(Double_t p[3]) const { p[0]=Px(); p[1]=Py(); p[2]=Pz(); return kTRUE; }
+
+ virtual Double_t Xv() const { return fPair.GetX(); }
+ virtual Double_t Yv() const { return fPair.GetY(); }
+ virtual Double_t Zv() const { return fPair.GetZ(); }
+ virtual Bool_t XvYvZv(Double_t x[3]) const { x[0]=Xv(); x[1]=Xv(); x[2]=Zv(); return kTRUE; }
+
+ virtual Double_t OneOverPt() const { return Pt()>0.?1./Pt():0.; } //TODO: check
+ virtual Double_t Phi() const { return fPair.GetPhi();}
+ virtual Double_t Theta() const { return Pz()!=0?TMath::ATan(Pt()/Pz()):0.; } //TODO: check
+
+
+ virtual Double_t E() const { return fPair.GetE(); }
+ virtual Double_t M() const { return fPair.GetMass(); }
+
+ virtual Double_t Eta() const { return fPair.GetEta();}
+ virtual Double_t Y() const { return TLorentzVector(Px(),Py(),Pz(),E()).Y();}
+
+ virtual Short_t Charge() const { return fPair.GetQ();}
+ virtual Int_t GetLabel() const { return -1; } //TODO: check
+ // PID
+ virtual const Double_t *PID() const { return 0;} //TODO: check
+
+ Double_t OpeningAngle() const { return fOpeningAngle; }
+
+ UChar_t GetType() const { return fType; }
+ void SetType(Char_t type) { fType=type; }
+ // internal KF particle
+ const AliKFParticle& GetKFParticle() const { return fPair; }
+
+ // daughter references
+ AliVParticle* GetFirstDaughter() const { return dynamic_cast<AliVParticle*>(fRefD1.GetObject()); }
+ AliVParticle* GetSecondDaughter() const { return dynamic_cast<AliVParticle*>(fRefD2.GetObject()); }
+
+
+private:
+ Double_t fOpeningAngle; // opening angle of the pair
+ Char_t fType; // type of the pair e.g. like sign SE, unlike sign SE, ... see AliDielectron
+
+ AliKFParticle fPair; // KF particle internally used for pair calculation
+
+ TRef fRefD1; // Reference to first daughter
+ TRef fRefD2; // Reference to second daughter
+
+ ClassDef(AliDielectronPair,1)
+};
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Cut class providing cuts for both legs in the AliDielectronPair //
+// //
+// //
+/*
+Add any number of leg cuts using e.g. for leg 1
+GetFilterLeg1().AddCuts(mycut)
+where mycut has to inherit from AliAnalysisCuts
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TList.h>
+
+#include "AliDielectronPair.h"
+#include "AliVParticle.h"
+
+#include "AliDielectronPairLegCuts.h"
+
+ClassImp(AliDielectronPairLegCuts)
+
+
+AliDielectronPairLegCuts::AliDielectronPairLegCuts() :
+ AliAnalysisCuts(),
+ fFilterLeg1("PairFilterLeg1","PairFilterLeg1"),
+ fFilterLeg2("PairFilterLeg2","PairFilterLeg2"),
+ fCutType(kBothLegs)
+{
+ //
+ // Default contructor
+ //
+}
+
+//________________________________________________________________________
+AliDielectronPairLegCuts::AliDielectronPairLegCuts(const char* name, const char* title) :
+ AliAnalysisCuts(name,title),
+ fFilterLeg1("PairFilterLeg1","PairFilterLeg1"),
+ fFilterLeg2("PairFilterLeg2","PairFilterLeg2"),
+ fCutType(kBothLegs)
+{
+ //
+ // Named contructor
+ //
+}
+
+
+//________________________________________________________________________
+Bool_t AliDielectronPairLegCuts::IsSelected(TObject* track)
+{
+ //
+ // check if cuts are fulfilled
+ //
+
+ //check if we have a AliDielectronPair
+ AliDielectronPair *pair=dynamic_cast<AliDielectronPair*>(track);
+ if (!pair) return kFALSE;
+
+ //get both legs
+ AliVParticle *leg1=pair->GetFirstDaughter();
+ AliVParticle *leg2=pair->GetSecondDaughter();
+
+ //mask used to require that all cuts are fulfilled
+ UInt_t selectedMaskLeg1=(1<<fFilterLeg1.GetCuts()->GetEntries())-1;
+ UInt_t selectedMaskLeg2=(1<<fFilterLeg2.GetCuts()->GetEntries())-1;
+
+ //test cuts
+ Bool_t isLeg1selected=(fFilterLeg1.IsSelected(leg1)==selectedMaskLeg1);
+ Bool_t isLeg2selected=(fFilterLeg2.IsSelected(leg2)==selectedMaskLeg2);
+
+ Bool_t isSelected=isLeg1selected&&isLeg2selected;
+ if (fCutType==kAnyLeg)
+ isSelected=isLeg1selected||isLeg2selected;
+
+ SetSelected(isSelected);
+ return isSelected;
+}
+
+
+
--- /dev/null
+#ifndef ALIDIELECTRONPAIRLEGCUTS_H
+#define ALIDIELECTRONPAIRLEGCUTS_H
+
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# Class AliDielectronPairLegCuts #
+//# Manage Cuts on the legs of the pair #
+//# #
+//# Authors: #
+//# Anton Andronic, GSI / A.Andronic@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Julian Book, Uni Ffm / Julian.Book@cern.ch #
+//# Frederick Kramer, Uni Ffm, / Frederick.Kramer@cern.ch #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+#include <AliAnalysisFilter.h>
+
+#include <AliAnalysisCuts.h>
+
+class AliDielectronPairLegCuts : public AliAnalysisCuts {
+public:
+ enum CutType { kBothLegs=0, kAnyLeg };
+
+ AliDielectronPairLegCuts();
+ AliDielectronPairLegCuts(const char* name, const char* title);
+ virtual ~AliDielectronPairLegCuts() {;}
+ //TODO: make copy constructor and assignment operator public
+ // and implement them
+
+ //
+ //AliAnalysisCuts interface
+ //
+ virtual Bool_t IsSelected(TObject* track);
+ virtual Bool_t IsSelected(TList* /* list */ ) {return kFALSE;}
+// virtual Long64_t Merge(TCollection* /* list */) { return 0; }
+
+ AliAnalysisFilter& GetLeg1Filter() { return fFilterLeg1; }
+ AliAnalysisFilter& GetLeg2Filter() { return fFilterLeg2; }
+
+ void SetCutType(CutType type) {fCutType=type;}
+private:
+ AliAnalysisFilter fFilterLeg1; // Analysis Filter for leg1
+ AliAnalysisFilter fFilterLeg2; // Analysis Filter for leg2
+
+ CutType fCutType; // Type of the cut
+
+ AliDielectronPairLegCuts(const AliDielectronPairLegCuts &c);
+ AliDielectronPairLegCuts &operator=(const AliDielectronPairLegCuts &c);
+
+ ClassDef(AliDielectronPairLegCuts,1) //Cut class providing cuts for both legs of a pair
+};
+
+#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Cut class providing cuts to all infomation //
+// available for the AliVParticle interface // //
+// //
+// Authors: //
+// Jens Wiechula <Jens.Wiechula@cern.ch> //
+/*
+
+
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+
+#include "AliDielectronVarCuts.h"
+
+
+ClassImp(AliDielectronVarCuts)
+
+
+AliDielectronVarCuts::AliDielectronVarCuts() :
+ AliAnalysisCuts(),
+ fNActiveCuts(0),
+ fActiveCutsMask(0),
+ fSelectedCutsMask(0)
+{
+ //
+ // Default costructor
+ //
+ for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
+ fActiveCuts[i]=0;
+ fCutMin[i]=0;
+ fCutMax[i]=0;
+ }
+}
+
+//________________________________________________________________________
+AliDielectronVarCuts::AliDielectronVarCuts(const char* name, const char* title) :
+ AliAnalysisCuts(name,title),
+ fNActiveCuts(0),
+ fActiveCutsMask(0),
+ fSelectedCutsMask(0)
+{
+ //
+ // Named contructor
+ //
+ for (Int_t i=0; i<AliDielectronVarManager::kNMaxValues; ++i){
+ fActiveCuts[i]=0;
+ fCutMin[i]=0;
+ fCutMax[i]=0;
+ }
+}
+
+//________________________________________________________________________
+AliDielectronVarCuts::~AliDielectronVarCuts()
+{
+ //
+ // Destructor
+ //
+}
+
+//________________________________________________________________________
+Bool_t AliDielectronVarCuts::IsSelected(TObject* track)
+{
+ //
+ // Make cut decision
+ //
+
+ Double_t values[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(track,values);
+ fSelectedCutsMask=0;
+ SetSelected(kFALSE);
+
+ for (Int_t iCut=0; iCut<fNActiveCuts; ++iCut){
+ Int_t cut=fActiveCuts[iCut];
+ SETBIT(fSelectedCutsMask,cut);
+ if ( (values[cut]<fCutMin[cut]) || (values[cut]>fCutMax[cut]) ) CLRBIT(fSelectedCutsMask,cut);
+ }
+ Bool_t isSelected=(fSelectedCutsMask==fActiveCutsMask);
+ SetSelected(isSelected);
+ return isSelected;
+}
+//________________________________________________________________________
+void AliDielectronVarCuts::ActivateCut(AliDielectronVarManager::ValueTypes cutName)
+{
+ //
+ // Add the cut to the list of active cuts
+ //
+
+ if (IsCutActive(cutName)) return;
+ fActiveCuts[fNActiveCuts++]=(UChar_t)cutName;
+ SETBIT(fActiveCutsMask,cutName);
+}
+
+
--- /dev/null
+#ifndef ALIDIELECTRONVARCUTS_H
+#define ALIDIELECTRONVARCUTS_H
+
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# Class AliDielectronVarCuts #
+//# Provide cuts for all variables handled in #
+//# AliDielectronVarManager #
+//# #
+//# Authors: #
+//# Anton Andronic, GSI / A.Andronic@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Julian Book, Uni Ffm / Julian.Book@cern.ch #
+//# Frederick Kramer, Uni Ffm, / Frederick.Kramer@cern.ch #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+#include <Rtypes.h>
+#include <AliAnalysisCuts.h>
+#include <AliDielectronVarManager.h>
+
+class AliDielectronVarCuts : public AliAnalysisCuts {
+public:
+ AliDielectronVarCuts();
+ AliDielectronVarCuts(const char* name, const char* title);
+ virtual ~AliDielectronVarCuts();
+ //TODO: make copy constructor and assignment operator public
+ void AddCut(Double_t min, Double_t max, AliDielectronVarManager::ValueTypes type);
+
+ //
+ //Analysis cuts interface
+ //
+ virtual Bool_t IsSelected(TObject* track);
+ virtual Bool_t IsSelected(TList* /* list */ ) {return kFALSE;}
+
+// virtual Bool_t IsSelected(TObject* track, TObject */*event*/=0);
+// virtual Long64_t Merge(TCollection* /* list */) { return 0; }
+
+ //
+ // Cut information
+ //
+ virtual UInt_t GetSelectedCutsMask() const { return fSelectedCutsMask; }
+ Bool_t IsCutActive(AliDielectronVarManager::ValueTypes cut) { return TESTBIT(fActiveCutsMask,cut); }
+
+private:
+
+ UChar_t fActiveCuts[AliDielectronVarManager::kNMaxValues]; // list of activated cuts
+ UChar_t fNActiveCuts; // number of acive cuts
+ UInt_t fActiveCutsMask; // maks of active cuts
+
+ UInt_t fSelectedCutsMask; // Maks of selected cuts, is available after calling IsSelected
+
+ Double_t fCutMin[AliDielectronVarManager::kNMaxValues]; // minimum values for the cuts
+ Double_t fCutMax[AliDielectronVarManager::kNMaxValues]; // maximum values for the cuts
+
+ void ActivateCut(AliDielectronVarManager::ValueTypes cutName);
+
+ AliDielectronVarCuts(const AliDielectronVarCuts &c);
+ AliDielectronVarCuts &operator=(const AliDielectronVarCuts &c);
+
+ ClassDef(AliDielectronVarCuts,1) //Cut class providing cuts to all infomation available for the AliVParticle interface
+};
+
+
+//
+//Inline functions
+//
+inline void AliDielectronVarCuts::AddCut(Double_t min, Double_t max, AliDielectronVarManager::ValueTypes type)
+{
+ //
+ // Set cut range and activate it
+ //
+ fCutMin[type]=min;
+ fCutMax[type]=max;
+ ActivateCut(type);
+}
+
+#endif
+
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Dielectron Variables Manager class //
+// //
+/*
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include "AliDielectronVarManager.h"
+
+ClassImp(AliDielectronVarManager)
+
+const char* AliDielectronVarManager::fgkParticleNames[AliDielectronVarManager::kNMaxValues] = {
+ "Px",
+ "Py",
+ "Pz",
+ "Pt",
+ "P",
+ "Xv",
+ "Yv",
+ "Zv",
+ "OneOverPt",
+ "Phi",
+ "Theta",
+ "Eta",
+ "Y",
+ "E",
+ "M",
+ "Charge",
+ "NclsITS",
+ "NclsTPC",
+ "NFclsTPC",
+ "TPCsignalN",
+ "NclsTRD",
+ "TRDntracklets",
+ "TRDpidQuality",
+ "ImpactParXY",
+ "ImpactParZ",
+ "TrackLength",
+ "PdgCode",
+ "P from InnerParam",
+ "TPC signal"
+ //
+ "Chi2NDF",
+ "DecayLength",
+ "R",
+ "OpeningAngle",
+ "Merr",
+ "DCA",
+ "PairType",
+ //
+ "X",
+ "Y",
+ "Z",
+ "XRes",
+ "YRes",
+ "ZRes",
+ "NTrk",
+ "Tracks"
+};
+
+
+//________________________________________________________________
+AliDielectronVarManager::AliDielectronVarManager() :
+ TNamed("AliDielectronVarManager","AliDielectronVarManager")
+{
+ //
+ // Default constructor
+ //
+
+}
+
+//________________________________________________________________
+AliDielectronVarManager::AliDielectronVarManager(const char* name, const char* title) :
+ TNamed(name,title)
+{
+ //
+ // Named constructor
+ //
+
+}
+
+//________________________________________________________________
+AliDielectronVarManager::~AliDielectronVarManager()
+{
+ //
+ // Default destructor
+ //
+}
+
--- /dev/null
+#ifndef ALIDIELECTRONVARMANAGER_H
+#define ALIDIELECTRONVARMANAGER_H
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# Class AliDielectronVarManager #
+//# Class for management of available variables #
+//# #
+//# Authors: #
+//# Anton Andronic, GSI / A.Andronic@gsi.de #
+//# Ionut C. Arsene, GSI / I.C.Arsene@gsi.de #
+//# Julian Book, Uni Ffm / Julian.Book@cern.ch #
+//# Frederick Kramer, Uni Ffm, / Frederick.Kramer@cern.ch #
+//# Magnus Mager, CERN / Magnus.Mager@cern.ch #
+//# WooJin J. Park, GSI / W.J.Park@gsi.de #
+//# Jens Wiechula, Uni HD / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+
+#include <TNamed.h>
+
+#include <AliVEvent.h>
+#include <AliESDEvent.h>
+
+#include <AliVParticle.h>
+#include <AliExternalTrackParam.h>
+#include <AliESDtrack.h>
+#include <AliAODTrack.h>
+#include <AliKFParticle.h>
+#include <AliMCParticle.h>
+#include <AliAODMCParticle.h>
+#include <AliVTrack.h> // ?
+
+#include "AliDielectronPair.h"
+
+class AliVEvent;
+
+//________________________________________________________________
+class AliDielectronVarManager : public TNamed {
+
+public:
+
+ // Particle specific variables
+ enum ValueTypes {
+ kPx = 0, // px
+ kPy, // py
+ kPz, // pz
+ kPt, // transverse momentum
+ kP, // momentum
+ kXv, // vertex position in x
+ kYv, // vertex position in y
+ kZv, // vertex position in z
+ kOneOverPt, // 1/pt
+ kPhi, // phi angle
+ kTheta, // theta angle
+ kEta, // pseudo-rapidity
+ kY, // rapidity
+ kE, // energy
+ kM, // mass
+ kCharge, // charge
+ kNclsITS, // number of clusters assigned in the ITS
+ kNclsTPC, // number of clusters assigned in the TPC
+ kNFclsTPC, // number of findable clusters in the TPC
+ kTPCsignalN, // number of points used for dEdx
+ kNclsTRD, // number of clusters assigned in the TRD
+ kTRDntracklets, // number of TRD tracklets used for tracking/PID TODO: correct getter
+ kTRDpidQuality, // number of TRD tracklets used for PID
+ kImpactParXY, // Impact parameter in XY plane
+ kImpactParZ, // Impact parameter in Z
+ kTrackLength, // Track length
+ kPdgCode, // PDG code
+ kPIn, // momentum at inner wall of TPC (if available), used for PID
+ kTPCsignal, // TPC dE/dx signal
+ kParticleMax, //
+ // TODO: kRNClusters ??
+ // AliDielectronPair specific variables
+ kChi2NDF = kParticleMax, // Chi^2/NDF
+ kDecayLength, // decay length
+ kR, // distance to the origin
+ kOpeningAngle, // opening angle
+ kMerr, // error of mass calculation
+ kDCA, // distance of closest approach TODO: not implemented yet
+ kPairType, // type of the pair, like like sign ++ unlikesign ...
+ kPairMax, //
+ // Event specific variables
+ kXvPrim=kPairMax, // TODO: prim vertex
+ kYvPrim, // TODO: prim vertex
+ kZvPrim, // TODO: prim vertex
+ kXRes, // primary vertex x-resolution (AliESDVertex)
+ kYRes, // primary vertex y-resolution (AliESDVertex)
+ kZRes, // primary vertex z-resolution (AliESDVertex)
+ kNTrk, // number of tracks (or tracklets)
+ kTracks, // ESD tracks (AliESDEvent)
+ kNMaxValues //
+ // TODO: (for A+A) ZDCEnergy, impact parameter, Iflag??
+ };
+
+
+ AliDielectronVarManager();
+ AliDielectronVarManager(const char* name, const char* title);
+ virtual ~AliDielectronVarManager();
+ static void Fill(const TObject* particle, Double_t * const values);
+
+ static const char* GetValueName(Int_t i) { return (i>=0&&i<kNMaxValues)?fgkParticleNames[i]:""; }
+private:
+
+ static const char* fgkParticleNames[kNMaxValues]; //variable names
+
+ static void FillVarVParticle(const AliVParticle *particle, Double_t * const values);
+ static void FillVarESDtrack(const AliESDtrack *particle, Double_t * const values);
+ static void FillVarAODTrack(const AliAODTrack *particle, Double_t * const values);
+ static void FillVarMCParticle(const AliMCParticle *particle, Double_t * const values);
+ static void FillVarAODMCParticle(const AliAODMCParticle *particle, Double_t * const values);
+ static void FillVarDielectronPair(const AliDielectronPair *pair, Double_t * const values);
+
+ AliDielectronVarManager(const AliDielectronVarManager &c);
+ AliDielectronVarManager &operator=(const AliDielectronVarManager &c);
+
+ ClassDef(AliDielectronVarManager,1);
+};
+
+
+//Inline functions
+inline void AliDielectronVarManager::Fill(const TObject* particle, Double_t * const values)
+{
+ //
+ // Main function to fill all available variables according to the type of particle
+ //
+
+ if (particle->IsA() == AliESDtrack::Class()) FillVarESDtrack(static_cast<const AliESDtrack*>(particle), values);
+ else if (particle->IsA() == AliAODTrack::Class()) FillVarAODTrack(static_cast<const AliAODTrack*>(particle), values);
+ else if (particle->IsA() == AliMCParticle::Class()) FillVarMCParticle(static_cast<const AliMCParticle*>(particle), values);
+ else if (particle->IsA() == AliAODMCParticle::Class()) FillVarAODMCParticle(static_cast<const AliAODMCParticle*>(particle), values);
+ else if (particle->IsA() == AliDielectronPair::Class()) FillVarDielectronPair(static_cast<const AliDielectronPair*>(particle), values);
+// else Error("Fill",Form("Type %s is not supported by AliDielectronVarManager!", particle->ClassName())); //TODO: implement without object needed
+}
+
+inline void AliDielectronVarManager::FillVarVParticle(const AliVParticle *particle, Double_t * const values)
+{
+ //
+ // Fill track information available in AliVParticle into an array
+ //
+ values[AliDielectronVarManager::kPx] = particle->Px();
+ values[AliDielectronVarManager::kPy] = particle->Py();
+ values[AliDielectronVarManager::kPz] = particle->Pz();
+ values[AliDielectronVarManager::kPt] = particle->Pt();
+ values[AliDielectronVarManager::kP] = particle->P();
+
+ values[AliDielectronVarManager::kXv] = particle->Xv();
+ values[AliDielectronVarManager::kYv] = particle->Yv();
+ values[AliDielectronVarManager::kZv] = particle->Zv();
+
+ values[AliDielectronVarManager::kOneOverPt] = particle->OneOverPt();
+ values[AliDielectronVarManager::kPhi] = particle->Phi();
+ values[AliDielectronVarManager::kTheta] = particle->Theta();
+ values[AliDielectronVarManager::kEta] = particle->Eta();
+ values[AliDielectronVarManager::kY] = particle->Y();
+
+ values[AliDielectronVarManager::kE] = particle->E();
+ values[AliDielectronVarManager::kM] = particle->M();
+ values[AliDielectronVarManager::kCharge] = particle->Charge();
+}
+
+inline void AliDielectronVarManager::FillVarESDtrack(const AliESDtrack *particle, Double_t * const values)
+{
+ //
+ // Fill track information available for histogramming into an array
+ //
+
+ // Fill common AliVParticle interface information
+ FillVarVParticle(particle, values);
+
+ // Fill AliESDtrack interface specific information
+ values[AliDielectronVarManager::kNclsITS] = particle->GetNcls(0); // TODO: get rid of the plain numbers
+ values[AliDielectronVarManager::kNclsTPC] = particle->GetNcls(1); // TODO: get rid of the plain numbers
+ values[AliDielectronVarManager::kNFclsTPC] = particle->GetTPCNclsF();
+ values[AliDielectronVarManager::kTPCsignalN] = particle->GetTPCsignalN();
+ values[AliDielectronVarManager::kNclsTRD] = particle->GetNcls(2); // TODO: get rid of the plain numbers
+ values[AliDielectronVarManager::kTRDntracklets] = particle->GetTRDntracklets(); // TODO: GetTRDtracklets/GetTRDntracklets?
+ values[AliDielectronVarManager::kTRDpidQuality] = particle->GetTRDpidQuality();
+
+ Float_t impactParXY, impactParZ;
+ particle->GetImpactParameters(impactParXY, impactParZ);
+ values[AliDielectronVarManager::kImpactParXY] = impactParXY;
+ values[AliDielectronVarManager::kImpactParZ] = impactParZ;
+
+ values[AliDielectronVarManager::kTrackLength] = particle->GetIntegratedLength();
+
+ //dEdx information
+ Double_t mom = particle->GetP();
+ const AliExternalTrackParam *in=particle->GetInnerParam();
+ if (in) mom = in->GetP();
+ values[AliDielectronVarManager::kPIn]=mom;
+ values[AliDielectronVarManager::kTPCsignal]=particle->GetTPCsignal();
+
+}
+
+inline void AliDielectronVarManager::FillVarAODTrack(const AliAODTrack *particle, Double_t * const values)
+{
+ //
+ // Fill track information available for histogramming into an array
+ //
+
+ // Fill common AliVParticle interface information
+ FillVarVParticle(particle, values);
+ // Fill AliAODTrack interface information
+ // ...
+
+}
+
+inline void AliDielectronVarManager::FillVarMCParticle(const AliMCParticle *particle, Double_t * const values)
+{
+ //
+ // Fill track information available for histogramming into an array
+ //
+
+ // Fill common AliVParticle interface information
+ FillVarVParticle(particle, values);
+
+ // Fill AliMCParticle interface specific information
+ values[AliDielectronVarManager::kPdgCode] = particle->PdgCode();
+}
+
+inline void AliDielectronVarManager::FillVarAODMCParticle(const AliAODMCParticle *particle, Double_t * const values)
+{
+ //
+ // Fill track information available for histogramming into an array
+ //
+
+ // Fill common AliVParticle interface information
+ FillVarVParticle(particle, values);
+
+ // Fill AliAODMCParticle interface specific information
+ values[AliDielectronVarManager::kPdgCode] = particle->GetPdgCode();
+}
+
+inline void AliDielectronVarManager::FillVarDielectronPair(const AliDielectronPair *pair, Double_t * const values)
+{
+ //
+ // Fill pair information available for histogramming into an array
+ //
+
+ // Fill common AliVParticle interface information
+ FillVarVParticle(pair, values);
+
+ // Fill AliDielectronPair specific information
+ const AliKFParticle &kfPair = pair->GetKFParticle();
+
+ values[AliDielectronVarManager::kChi2NDF] = kfPair.GetChi2()/kfPair.GetNDF();
+ values[AliDielectronVarManager::kDecayLength] = kfPair.GetDecayLength();
+ values[AliDielectronVarManager::kR] = kfPair.GetR();
+ values[AliDielectronVarManager::kOpeningAngle] = pair->OpeningAngle();
+ values[AliDielectronVarManager::kMerr] = kfPair.GetErrMass()>0?kfPair.GetErrMass()/kfPair.GetMass():1000000;
+ values[AliDielectronVarManager::kPairType] = pair->GetType();
+}
+
+/*
+inline void AliDielectronVarManager::FillValues(const TParticle *particle, Double_t *values)
+{
+ //
+ // Fill track information available for histogramming into an array
+ //
+
+ // Fill TParticle interface information
+ values[AliDielectronVarManager::kPx] = particle->Px();
+ values[AliDielectronVarManager::kPy] = particle->Py();
+ values[AliDielectronVarManager::kPz] = particle->Pz();
+ values[AliDielectronVarManager::kPt] = particle->Pt();
+ values[AliDielectronVarManager::kP] = particle->P();
+
+ values[AliDielectronVarManager::kXv] = particle->Vx();
+ values[AliDielectronVarManager::kYv] = particle->Vy();
+ values[AliDielectronVarManager::kZv] = particle->Vz();
+
+ values[AliDielectronVarManager::kOneOverPt] = 1./particle->Pt();
+ values[AliDielectronVarManager::kPhi] = particle->Phi();
+ values[AliDielectronVarManager::kTheta] =
+ values[AliDielectronVarManager::kEta] = particle->Eta();
+ values[AliDielectronVarManager::kY] =
+
+ values[AliDielectronVarManager::kE] = particle->Energy();
+ values[AliDielectronVarManager::kM] = particle->GetMass();
+
+ values[AliDielectronVarManager::kCharge] = particle->GetPDG()->Charge()/3; // uggly
+
+}*/
+
+#endif
--- /dev/null
+#-*- Mode: Makefile -*-
+
+SRCS= dielectron/AliDielectron.cxx \
+ dielectron/AliDielectronPair.cxx \
+ dielectron/AliDielectronHistos.cxx \
+ dielectron/AliDielectronCF.cxx \
+ dielectron/AliDielectronMC.cxx \
+ dielectron/AliDielectronVarManager.cxx \
+ dielectron/AliAnalysisTaskDielectronSE.cxx \
+ dielectron/AliAnalysisTaskDielectronFilter.cxx \
+ dielectron/AliAnalysisTaskDielectronEfficiency.cxx \
+ dielectron/AliAnalysisTaskMultiDielectron.cxx \
+ dielectron/AliDielectronVarCuts.cxx \
+ dielectron/AliDielectronPairLegCuts.cxx
+
+HDRS= $(SRCS:.cxx=.h)
+
+DHDR= PWG3dielectronLinkDef.h
+
+EINCLUDE:= PWG3/dielectron STEER CORRFW
+
+ifeq (win32gcc,$(ALICE_TARGET))
+PACKSOFLAGS:= $(SOFLAGS) -L$(ALICE_ROOT)/lib/tgt_$(ALICE_TARGET) -lSTEERBase \
+-lESD -lSTEER -lANALYSISalice -lANALYSIS -lCORRFW
+endif