Add dielectron framework to PWG3
authorandronic <andronic@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 16 Feb 2010 19:21:28 +0000 (19:21 +0000)
committerandronic <andronic@f7af4fe6-9843-0410-8265-dc069ae4e863>
Tue, 16 Feb 2010 19:21:28 +0000 (19:21 +0000)
28 files changed:
PWG3/PROOF-INF.PWG3dielectron/BUILD.sh [new file with mode: 0755]
PWG3/PROOF-INF.PWG3dielectron/SETUP.C [new file with mode: 0644]
PWG3/PWG3dielectronLinkDef.h [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskDielectronEfficiency.cxx [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskDielectronEfficiency.h [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskDielectronFilter.cxx [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskDielectronFilter.h [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskDielectronSE.cxx [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskDielectronSE.h [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskMultiDielectron.cxx [new file with mode: 0644]
PWG3/dielectron/AliAnalysisTaskMultiDielectron.h [new file with mode: 0644]
PWG3/dielectron/AliDielectron.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectron.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronCF.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronCF.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronHistos.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronHistos.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronMC.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronMC.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronPair.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronPair.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronPairLegCuts.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronPairLegCuts.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronVarCuts.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronVarCuts.h [new file with mode: 0644]
PWG3/dielectron/AliDielectronVarManager.cxx [new file with mode: 0644]
PWG3/dielectron/AliDielectronVarManager.h [new file with mode: 0644]
PWG3/libPWG3dielectron.pkg [new file with mode: 0644]

diff --git a/PWG3/PROOF-INF.PWG3dielectron/BUILD.sh b/PWG3/PROOF-INF.PWG3dielectron/BUILD.sh
new file mode 100755 (executable)
index 0000000..becb7e5
--- /dev/null
@@ -0,0 +1,3 @@
+#! /bin/bash
+
+make
diff --git a/PWG3/PROOF-INF.PWG3dielectron/SETUP.C b/PWG3/PROOF-INF.PWG3dielectron/SETUP.C
new file mode 100644 (file)
index 0000000..e6041ba
--- /dev/null
@@ -0,0 +1,9 @@
+{
+  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");
+  
+}
diff --git a/PWG3/PWG3dielectronLinkDef.h b/PWG3/PWG3dielectronLinkDef.h
new file mode 100644 (file)
index 0000000..a514fd4
--- /dev/null
@@ -0,0 +1,21 @@
+#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
diff --git a/PWG3/dielectron/AliAnalysisTaskDielectronEfficiency.cxx b/PWG3/dielectron/AliAnalysisTaskDielectronEfficiency.cxx
new file mode 100644 (file)
index 0000000..ed8e58c
--- /dev/null
@@ -0,0 +1,572 @@
+/*************************************************************************
+* 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()));
+}
+
diff --git a/PWG3/dielectron/AliAnalysisTaskDielectronEfficiency.h b/PWG3/dielectron/AliAnalysisTaskDielectronEfficiency.h
new file mode 100644 (file)
index 0000000..902104b
--- /dev/null
@@ -0,0 +1,70 @@
+#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
diff --git a/PWG3/dielectron/AliAnalysisTaskDielectronFilter.cxx b/PWG3/dielectron/AliAnalysisTaskDielectronFilter.cxx
new file mode 100644 (file)
index 0000000..6037fec
--- /dev/null
@@ -0,0 +1,106 @@
+/*************************************************************************
+* 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()));
+}
+
diff --git a/PWG3/dielectron/AliAnalysisTaskDielectronFilter.h b/PWG3/dielectron/AliAnalysisTaskDielectronFilter.h
new file mode 100644 (file)
index 0000000..167d595
--- /dev/null
@@ -0,0 +1,52 @@
+#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
diff --git a/PWG3/dielectron/AliAnalysisTaskDielectronSE.cxx b/PWG3/dielectron/AliAnalysisTaskDielectronSE.cxx
new file mode 100644 (file)
index 0000000..0fef414
--- /dev/null
@@ -0,0 +1,94 @@
+/*************************************************************************
+* 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()));
+  }
+}
+
diff --git a/PWG3/dielectron/AliAnalysisTaskDielectronSE.h b/PWG3/dielectron/AliAnalysisTaskDielectronSE.h
new file mode 100644 (file)
index 0000000..f5503d7
--- /dev/null
@@ -0,0 +1,43 @@
+#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
diff --git a/PWG3/dielectron/AliAnalysisTaskMultiDielectron.cxx b/PWG3/dielectron/AliAnalysisTaskMultiDielectron.cxx
new file mode 100644 (file)
index 0000000..db99c11
--- /dev/null
@@ -0,0 +1,107 @@
+/*************************************************************************
+* 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);
+}
+
diff --git a/PWG3/dielectron/AliAnalysisTaskMultiDielectron.h b/PWG3/dielectron/AliAnalysisTaskMultiDielectron.h
new file mode 100644 (file)
index 0000000..7762bf2
--- /dev/null
@@ -0,0 +1,48 @@
+#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
diff --git a/PWG3/dielectron/AliDielectron.cxx b/PWG3/dielectron/AliDielectron.cxx
new file mode 100644 (file)
index 0000000..c9a46d0
--- /dev/null
@@ -0,0 +1,305 @@
+/*************************************************************************
+* 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;
+}
+
+
+
+
diff --git a/PWG3/dielectron/AliDielectron.h b/PWG3/dielectron/AliDielectron.h
new file mode 100644 (file)
index 0000000..19e0c91
--- /dev/null
@@ -0,0 +1,156 @@
+#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
diff --git a/PWG3/dielectron/AliDielectronCF.cxx b/PWG3/dielectron/AliDielectronCF.cxx
new file mode 100644 (file)
index 0000000..e1e1298
--- /dev/null
@@ -0,0 +1,321 @@
+/*************************************************************************
+* 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);
+}
+
diff --git a/PWG3/dielectron/AliDielectronCF.h b/PWG3/dielectron/AliDielectronCF.h
new file mode 100644 (file)
index 0000000..0e252ad
--- /dev/null
@@ -0,0 +1,82 @@
+#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
diff --git a/PWG3/dielectron/AliDielectronHistos.cxx b/PWG3/dielectron/AliDielectronHistos.cxx
new file mode 100644 (file)
index 0000000..4d9343f
--- /dev/null
@@ -0,0 +1,522 @@
+/*************************************************************************
+* 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;
+}
+
diff --git a/PWG3/dielectron/AliDielectronHistos.h b/PWG3/dielectron/AliDielectronHistos.h
new file mode 100644 (file)
index 0000000..1be96be
--- /dev/null
@@ -0,0 +1,99 @@
+#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
+
diff --git a/PWG3/dielectron/AliDielectronMC.cxx b/PWG3/dielectron/AliDielectronMC.cxx
new file mode 100644 (file)
index 0000000..b2fcaf5
--- /dev/null
@@ -0,0 +1,426 @@
+/*************************************************************************
+* 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;
+}
+
diff --git a/PWG3/dielectron/AliDielectronMC.h b/PWG3/dielectron/AliDielectronMC.h
new file mode 100644 (file)
index 0000000..17231af
--- /dev/null
@@ -0,0 +1,95 @@
+#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 
diff --git a/PWG3/dielectron/AliDielectronPair.cxx b/PWG3/dielectron/AliDielectronPair.cxx
new file mode 100644 (file)
index 0000000..882ead3
--- /dev/null
@@ -0,0 +1,85 @@
+/*************************************************************************
+* 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);
+}
+
diff --git a/PWG3/dielectron/AliDielectronPair.h b/PWG3/dielectron/AliDielectronPair.h
new file mode 100644 (file)
index 0000000..4c93cc8
--- /dev/null
@@ -0,0 +1,102 @@
+#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
diff --git a/PWG3/dielectron/AliDielectronPairLegCuts.cxx b/PWG3/dielectron/AliDielectronPairLegCuts.cxx
new file mode 100644 (file)
index 0000000..0ed9120
--- /dev/null
@@ -0,0 +1,95 @@
+/*************************************************************************
+* 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;
+}
+
+
+
diff --git a/PWG3/dielectron/AliDielectronPairLegCuts.h b/PWG3/dielectron/AliDielectronPairLegCuts.h
new file mode 100644 (file)
index 0000000..c242a38
--- /dev/null
@@ -0,0 +1,60 @@
+#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
diff --git a/PWG3/dielectron/AliDielectronVarCuts.cxx b/PWG3/dielectron/AliDielectronVarCuts.cxx
new file mode 100644 (file)
index 0000000..a858815
--- /dev/null
@@ -0,0 +1,111 @@
+/*************************************************************************
+* 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);
+}
+
+
diff --git a/PWG3/dielectron/AliDielectronVarCuts.h b/PWG3/dielectron/AliDielectronVarCuts.h
new file mode 100644 (file)
index 0000000..a283c02
--- /dev/null
@@ -0,0 +1,85 @@
+#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
+
diff --git a/PWG3/dielectron/AliDielectronVarManager.cxx b/PWG3/dielectron/AliDielectronVarManager.cxx
new file mode 100644 (file)
index 0000000..5dee706
--- /dev/null
@@ -0,0 +1,106 @@
+/*************************************************************************
+* 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
+  //
+}
+
diff --git a/PWG3/dielectron/AliDielectronVarManager.h b/PWG3/dielectron/AliDielectronVarManager.h
new file mode 100644 (file)
index 0000000..c57f34d
--- /dev/null
@@ -0,0 +1,291 @@
+#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
diff --git a/PWG3/libPWG3dielectron.pkg b/PWG3/libPWG3dielectron.pkg
new file mode 100644 (file)
index 0000000..bceb528
--- /dev/null
@@ -0,0 +1,25 @@
+#-*- 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