#--------------------------------------------------------------------------------#
set ( SRCS
- dielectron/AliDielectron.cxx
- dielectron/AliDielectronPair.cxx
- dielectron/AliDielectronHistos.cxx
- dielectron/AliDielectronCF.cxx
- dielectron/AliDielectronCFdraw.cxx
- dielectron/AliDielectronMC.cxx
- dielectron/AliDielectronVarManager.cxx
- dielectron/AliAnalysisTaskDielectronSE.cxx
- dielectron/AliAnalysisTaskDielectronME.cxx
- dielectron/AliAnalysisTaskDielectronFilter.cxx
- dielectron/AliAnalysisTaskDielectronEfficiency.cxx
- dielectron/AliAnalysisTaskMultiDielectron.cxx
- dielectron/AliDielectronVarCuts.cxx
- dielectron/AliDielectronTrackCuts.cxx
- dielectron/AliDielectronPairLegCuts.cxx
- dielectron/AliDielectronSignalBase.cxx
- dielectron/AliDielectronSignalFunc.cxx
- dielectron/AliDielectronSignalExt.cxx
- dielectron/AliDielectronSpectrum.cxx
- dielectron/AliDielectronDebugTree.cxx
- dielectron/AliDielectronTrackRotator.cxx
- dielectron/AliDielectronPID.cxx
- dielectron/AliDielectronCutGroup.cxx
- dielectron/AliDielectronEventCuts.cxx
+ dielectron/AliDielectron.cxx
+ dielectron/AliDielectronPair.cxx
+ dielectron/AliDielectronHistos.cxx
+ dielectron/AliDielectronCF.cxx
+ dielectron/AliDielectronCFdraw.cxx
+ dielectron/AliDielectronMC.cxx
+ dielectron/AliDielectronVarManager.cxx
+ dielectron/AliAnalysisTaskDielectronSE.cxx
+ dielectron/AliAnalysisTaskDielectronME.cxx
+ dielectron/AliAnalysisTaskDielectronFilter.cxx
+ dielectron/AliAnalysisTaskDielectronEfficiency.cxx
+ dielectron/AliAnalysisTaskMultiDielectron.cxx
+ dielectron/AliAnalysisTaskDielectronReadAODBranch.cxx
+ dielectron/AliAnalysisTaskSingleParticle.cxx
+ dielectron/AliDielectronVarCuts.cxx
+ dielectron/AliDielectronTrackCuts.cxx
+ dielectron/AliDielectronPairLegCuts.cxx
+ dielectron/AliDielectronSignalBase.cxx
+ dielectron/AliDielectronSignalFunc.cxx
+ dielectron/AliDielectronSignalExt.cxx
+ dielectron/AliDielectronSpectrum.cxx
+ dielectron/AliDielectronDebugTree.cxx
+ dielectron/AliDielectronTrackRotator.cxx
+ dielectron/AliDielectronPID.cxx
+ dielectron/AliDielectronCutGroup.cxx
+ dielectron/AliDielectronEventCuts.cxx
dielectron/AliDielectronHelper.cxx
dielectron/AliDielectronBtoJPSItoEleCDFfitFCN.cxx
dielectron/AliDielectronBtoJPSItoEleCDFfitHandler.cxx
dielectron/AliDielectronBtoJPSItoEle.cxx
- dielectron/AliAnalysisTaskDielectronReadAODBranch.cxx
dielectron/AliDielectronTRDpidCut.cxx
dielectron/AliDielectronSignalMC.cxx
+ dielectron/AliDielectronEvent.cxx
+ dielectron/AliDielectronMixingHandler.cxx
)
string(REPLACE ".cxx" ".h" HDRS "${SRCS}")
#pragma link C++ class AliAnalysisTaskDielectronEfficiency+;
#pragma link C++ class AliAnalysisTaskMultiDielectron+;
#pragma link C++ class AliAnalysisTaskDielectronReadAODBranch+;
+#pragma link C++ class AliAnalysisTaskSingleParticle+;
#pragma link C++ class AliDielectronVarCuts+;
#pragma link C++ class AliDielectronTrackCuts+;
#pragma link C++ class AliDielectronPairLegCuts+;
#pragma link C++ class AliDielectronBtoJPSItoEle+;
#pragma link C++ class AliDielectronTRDpidCut+;
#pragma link C++ class AliDielectronSignalMC+;
+#pragma link C++ class AliDielectronEvent+;
+#pragma link C++ class AliDielectronMixingHandler+;
#endif
#include <AliAnalysisManager.h>
#include <AliVEvent.h>
#include <AliInputEventHandler.h>
-#include <AliESDInputHandler.h>
#include <AliAODInputHandler.h>
#include "AliDielectron.h"
fSelectPhysics(kTRUE),
fTriggerMask(AliVEvent::kMB),
fEventStat(0x0),
-fStoreLikeSign(kFALSE)
+fStoreLikeSign(kFALSE),
+fStoreRotatedPairs(kFALSE),
+fEventFilter(0x0)
{
//
// Constructor
fSelectPhysics(kTRUE),
fTriggerMask(AliVEvent::kMB),
fEventStat(0x0),
-fStoreLikeSign(kFALSE)
+fStoreLikeSign(kFALSE),
+fStoreRotatedPairs(kFALSE),
+fEventFilter(0x0)
{
//
// Constructor
AliFatal("Dielectron framework class required. Please create and instance with proper cuts and set it via 'SetDielectron' before executing this task!!!");
return;
}
+ if(fStoreRotatedPairs) fDielectron->SetStoreRotatedPairs(kTRUE);
fDielectron->Init();
if (!fEventStat){
- fEventStat=new TH1D("hEventStat","Event statistics",5,0,5);
+ fEventStat=new TH1D("hEventStat","Event statistics",6,0,6);
fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
- fEventStat->GetXaxis()->SetBinLabel(3,"After Cand. Sel.");
+ fEventStat->GetXaxis()->SetBinLabel(3,"After Phys. Sel.");
+ fEventStat->GetXaxis()->SetBinLabel(4,"After Cand. Sel.");
}
PostData(2,fEventStat);
if (!fDielectron) return;
AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
- AliESDInputHandler *esdHandler=0x0;
- if ( (esdHandler=dynamic_cast<AliESDInputHandler*>(man->GetInputEventHandler())) && esdHandler->GetESDpid() ){
- AliDielectronVarManager::SetESDpid(esdHandler->GetESDpid());
+
+ AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+ if (!inputHandler) return;
+
+ if ( inputHandler->GetPIDResponse() ){
+ AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
} else {
- //load esd pid bethe bloch parameters depending on the existance of the MC handler
- // yes: MC parameters
- // no: data parameters
-
- //ESD case
- if (man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()){
- if (!AliDielectronVarManager::GetESDpid()){
-
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitESDpid();
- } else {
- AliDielectronVarManager::InitESDpid(1);
- }
- }
- }
- //AOD case
- if (man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
- if (!AliDielectronVarManager::GetAODpidUtil()){
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitAODpidUtil();
- } else {
- AliDielectronVarManager::InitAODpidUtil(1);
- }
- }
- }
+ AliFatal("This task needs the PID response attached to the input event handler!");
}
// Was event selected ?
- AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
UInt_t isSelected = AliVEvent::kAny;
if( fSelectPhysics && inputHandler && inputHandler->GetEventSelection() ) {
isSelected = inputHandler->IsEventSelected();
}
//after physics selection
fEventStat->Fill(1.);
-
+
+ //event filter
+ if (fEventFilter) {
+ if (!fEventFilter->IsSelected(InputEvent())) return;
+ }
+ fEventStat->Fill(2.);
+
//bz for AliKF
Double_t bz = InputEvent()->GetMagneticField();
AliKFParticle::SetField( bz );
Bool_t hasCand = kFALSE;
if(fStoreLikeSign) hasCand = (fDielectron->HasCandidates() || fDielectron->HasCandidatesLikeSign());
else hasCand = (fDielectron->HasCandidates());
+
+ if(fStoreRotatedPairs) hasCand = (hasCand || fDielectron->HasCandidatesTR());
if(hasCand){
AliAODHandler *aodH=(AliAODHandler*)((AliAnalysisManager::GetAnalysisManager())->GetOutputEventHandler());
//replace the references of the legs with the AOD references
TObjArray *obj = 0x0;
- for(Int_t i=0; i < 10; i++ ){
+ for(Int_t i=0; i < 11; i++ ){
obj = (TObjArray*)((*(fDielectron->GetPairArraysPointer()))->UncheckedAt(i));
if(!obj) continue;
for(int j=0;j<obj->GetEntriesFast();j++){
AliAODExtension *extDielectron = aodH->GetFilteredAOD("AliAOD.Dielectron.root");
extDielectron->SelectEvent();
//after candidate selection
- fEventStat->Fill(2.);
+ fEventStat->Fill(3.);
//see if dielectron candidate branch exists, if not create is
TTree *t=extDielectron->GetTree();
void SetDielectron(AliDielectron * const die) { fDielectron = die; }
void SetStoreLikeSignCandidates(Bool_t storeLS) { fStoreLikeSign = storeLS; }
+ void SetStoreRotatedPairs(Bool_t storeTR) { fStoreRotatedPairs = storeTR; }
+
+ void SetEventFilter(AliAnalysisCuts * const filter) {fEventFilter=filter;}
+
private:
AliDielectron *fDielectron; // J/psi framework object
UInt_t fTriggerMask; // Event trigger mask
TH1D *fEventStat; //! Histogram with event statistics
+
Bool_t fStoreLikeSign; // flag to store like-sign candidates
+ Bool_t fStoreRotatedPairs; // flag to store rotation
+
+ AliAnalysisCuts *fEventFilter; // event filter
AliAnalysisTaskDielectronFilter(const AliAnalysisTaskDielectronFilter &c);
AliAnalysisTaskDielectronFilter& operator= (const AliAnalysisTaskDielectronFilter &c);
#include <AliCFContainer.h>
#include <AliInputEventHandler.h>
-#include <AliESDInputHandler.h>
#include <AliAnalysisManager.h>
#include <AliVEvent.h>
if (fListHistos.IsEmpty()&&fListCF.IsEmpty()) return;
AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
- AliESDInputHandler *esdHandler=0x0;
- if ( (esdHandler=dynamic_cast<AliESDInputHandler*>(man->GetInputEventHandler())) && esdHandler->GetESDpid() ){
- AliDielectronVarManager::SetESDpid(esdHandler->GetESDpid());
+ AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+ if (!inputHandler) return;
+
+ if ( inputHandler->GetPIDResponse() ){
+ AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
} else {
- //load esd pid bethe bloch parameters depending on the existance of the MC handler
- // yes: MC parameters
- // no: data parameters
- if (!AliDielectronVarManager::GetESDpid()){
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitESDpid();
- } else {
- AliDielectronVarManager::InitESDpid(1);
- }
- }
- }
+ AliFatal("This task needs the PID response attached to the input event handler!");
+ }
+
// Was event selected ?
- AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
UInt_t isSelected = AliVEvent::kAny;
if( fSelectPhysics && inputHandler && inputHandler->GetEventSelection() ) {
isSelected = inputHandler->IsEventSelected();
#include <AliESDInputHandler.h>
#include <AliAnalysisManager.h>
#include <AliAODInputHandler.h>
+#include <AliTriggerAnalysis.h>
#include "AliDielectron.h"
#include "AliDielectronHistos.h"
fDielectron(0),
fSelectPhysics(kFALSE),
fTriggerMask(AliVEvent::kMB),
+ fTriggerOnV0AND(kFALSE),
+ fRejectPileup(kFALSE),
+ fTriggerAnalysis(0x0),
+ fEventFilter(0x0),
fEventStat(0x0)
{
//
fDielectron(0),
fSelectPhysics(kFALSE),
fTriggerMask(AliVEvent::kMB),
+ fTriggerOnV0AND(kFALSE),
+ fRejectPileup(kFALSE),
+ fTriggerAnalysis(0x0),
+ fEventFilter(0x0),
fEventStat(0x0)
{
//
fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
}
+ Int_t nbins=kNbinsEvent+2;
+ if (!fEventStat){
+ fEventStat=new TH1D("hEventStat","Event statistics",nbins,0,nbins);
+ fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
+ fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
+
+ //default names
+ fEventStat->GetXaxis()->SetBinLabel(3,"Bin3 not used");
+ fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
+ fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
+
+ if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
+ if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
+ if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
+
+ fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+1),Form("#splitline{1 candidate}{%s}",fDielectron->GetName()));
+ fEventStat->GetXaxis()->SetBinLabel((kNbinsEvent+2),Form("#splitline{With >1 candidate}{%s}",fDielectron->GetName()));
+
+ }
+
+ if (!fTriggerAnalysis) fTriggerAnalysis=new AliTriggerAnalysis;
+ fTriggerAnalysis->EnableHistograms();
+ fTriggerAnalysis->SetAnalyzeMC(AliDielectronMC::Instance()->HasMC());
PostData(3,fEventStat);
if (!fDielectron) return;
AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
- AliESDInputHandler *esdHandler=0x0;
- if ( (esdHandler=dynamic_cast<AliESDInputHandler*>(man->GetInputEventHandler())) && esdHandler->GetESDpid() ){
- AliDielectronVarManager::SetESDpid(esdHandler->GetESDpid());
+ Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
+ Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
+
+ AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+ if (!inputHandler) return;
+
+ if ( inputHandler->GetPIDResponse() ){
+ AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
} else {
- //load esd pid bethe bloch parameters depending on the existance of the MC handler
- // yes: MC parameters
- // no: data parameters
-
- //ESD case
- if (man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class()){
- if (!AliDielectronVarManager::GetESDpid()){
-
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitESDpid();
- } else {
- AliDielectronVarManager::InitESDpid(1);
- }
- }
- }
- //AOD case
- if (man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class()){
- if (!AliDielectronVarManager::GetAODpidUtil()){
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitAODpidUtil();
- } else {
- AliDielectronVarManager::InitAODpidUtil(1);
- }
- }
- }
+ AliFatal("This task needs the PID response attached to the input event handler!");
}
+
// Was event selected ?
- AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
UInt_t isSelected = AliVEvent::kAny;
- if( fSelectPhysics && inputHandler && inputHandler->GetEventSelection() ) {
- isSelected = inputHandler->IsEventSelected();
- isSelected&=fTriggerMask;
- }
-
+ if( fSelectPhysics && inputHandler){
+ if((isESD && inputHandler->GetEventSelection()) || isAOD){
+ isSelected = inputHandler->IsEventSelected();
+ isSelected&=fTriggerMask;
+ }
+ }
+
+
//Before physics selection
- fEventStat->Fill(0.);
+ fEventStat->Fill(kAllEvents);
if (isSelected==0) {
PostData(3,fEventStat);
return;
}
//after physics selection
- fEventStat->Fill(1.);
+ fEventStat->Fill(kSelectedEvents);
+
+ //V0and
+ if(fTriggerOnV0AND){
+ if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
+ return;}
+ if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
+ (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
+ return;}
+ }
+
+
+ fEventStat->Fill(kV0andEvents);
+
+ //Fill Event histograms before the event filter
+ Double_t values[AliDielectronVarManager::kNMaxValues]={0};
+ Double_t valuesMC[AliDielectronVarManager::kNMaxValues]={0};
+ AliDielectronVarManager::Fill(InputEvent(),values);
+ Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
+ if (hasMC) {
+ if (AliDielectronMC::Instance()->ConnectMCEvent())
+ AliDielectronVarManager::Fill(AliDielectronMC::Instance()->GetMCEvent(),valuesMC);
+ }
+
+ AliDielectronHistos *h=fDielectron->GetHistoManager();
+ if (h){
+ if (h->GetHistogramList()->FindObject("Event_noCuts"))
+ h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
+ if (hasMC && h->GetHistogramList()->FindObject("MCEvent_noCuts"))
+ h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,valuesMC);
+ }
+
+ //event filter
+ if (fEventFilter) {
+ if (!fEventFilter->IsSelected(InputEvent())) return;
+ }
+ fEventStat->Fill(kFilteredEvents);
+
+ //pileup
+ if (fRejectPileup){
+ if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) return;
+ }
+ fEventStat->Fill(kPileupEvents);
//bz for AliKF
Double_t bz = InputEvent()->GetMagneticField();
AliKFParticle::SetField( bz );
-
+
+ // make an artificial shift in the electron nsigma. Configured in the Config file
+ AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
+
+ //
+ // Actual data processing
+ //
fDielectron->Process(InputEvent());
+ //statistics for number of selected candidates
+ Int_t ncandidates=fDielectron->GetPairArray(1)->GetEntriesFast();
+ if (ncandidates==1) fEventStat->Fill((kNbinsEvent));
+ else if (ncandidates>1) fEventStat->Fill((kNbinsEvent+1));
+
+ //Publish the data
if (fDielectron->GetHistogramList()){
PostData(1, const_cast<THashList*>(fDielectron->GetHistogramList()));
}
//#####################################################
#include "AliAnalysisTaskSE.h"
-#include "AliDielectronPID.h"
class AliDielectron;
+class AliTriggerAnalysis;
class TH1D;
class AliAnalysisTaskDielectronSE : public AliAnalysisTaskSE {
virtual void UserExec(Option_t *option);
virtual void UserCreateOutputObjects();
- //temporary
- virtual void NotifyRun(){AliDielectronPID::SetCorrVal((Double_t)fCurrentRunNumber);}
void UsePhysicsSelection(Bool_t phy=kTRUE) {fSelectPhysics=phy;}
void SetTriggerMask(UInt_t mask) {fTriggerMask=mask;}
UInt_t GetTriggerMask() const { return fTriggerMask; }
+
+ void SetEventFilter(AliAnalysisCuts * const filter) {fEventFilter=filter;}
+ void SetTriggerOnV0AND(Bool_t v0and=kTRUE) { fTriggerOnV0AND=v0and; }
+ void SetRejectPileup(Bool_t pileup=kTRUE) { fRejectPileup=pileup; }
void SetDielectron(AliDielectron * const die) { fDielectron = die; }
private:
+ enum {kAllEvents=0, kSelectedEvents, kV0andEvents, kFilteredEvents, kPileupEvents, kNbinsEvent};
AliDielectron *fDielectron; // Dielectron framework object
Bool_t fSelectPhysics; // Whether to use physics selection
UInt_t fTriggerMask; // Event trigger mask
-
+ Bool_t fTriggerOnV0AND; // if to trigger on V0and
+ Bool_t fRejectPileup; // pileup rejection wanted
+
+ AliTriggerAnalysis *fTriggerAnalysis; //! trigger analysis class
+
+ AliAnalysisCuts *fEventFilter; // event filter
+
TH1D *fEventStat; //! Histogram with event statistics
AliAnalysisTaskDielectronSE(const AliAnalysisTaskDielectronSE &c);
#include <AliAnalysisManager.h>
#include <AliVEvent.h>
#include <AliTriggerAnalysis.h>
+#include <AliPIDResponse.h>
+#include <AliTPCPIDResponse.h>
#include "AliDielectron.h"
#include "AliDielectronHistos.h"
#include "AliDielectronCF.h"
#include "AliDielectronMC.h"
+#include "AliDielectronMixingHandler.h"
#include "AliAnalysisTaskMultiDielectron.h"
ClassImp(AliAnalysisTaskMultiDielectron)
fListCF(),
fSelectPhysics(kFALSE),
fTriggerMask(AliVEvent::kMB),
+ fExcludeTriggerMask(0),
fTriggerOnV0AND(kFALSE),
fRejectPileup(kFALSE),
+ fTriggerLogic(kAny),
fTriggerAnalysis(0x0),
fEventFilter(0x0),
fEventStat(0x0)
fListCF(),
fSelectPhysics(kFALSE),
fTriggerMask(AliVEvent::kMB),
+ fExcludeTriggerMask(0),
fTriggerOnV0AND(kFALSE),
fRejectPileup(kFALSE),
+ fTriggerLogic(kAny),
fTriggerAnalysis(0x0),
fEventFilter(0x0),
fEventStat(0x0)
fListCF.SetOwner();
}
+//_________________________________________________________________________________
+AliAnalysisTaskMultiDielectron::~AliAnalysisTaskMultiDielectron()
+{
+ //
+ // Destructor
+ //
+ //histograms and CF are owned by the dielectron framework.
+ //however they are streamed to file, so in the first place the
+ //lists need to be owner...
+ fListHistos.SetOwner(kFALSE);
+ fListCF.SetOwner(kFALSE);
+
+}
//_________________________________________________________________________________
void AliAnalysisTaskMultiDielectron::UserCreateOutputObjects()
{
if (!fListHistos.IsEmpty()||!fListCF.IsEmpty()) return; //already initialised
- AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
- Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
+// AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
+// Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
// Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
TIter nextDie(&fListDielectron);
fEventStat->GetXaxis()->SetBinLabel(4,"Bin4 not used");
fEventStat->GetXaxis()->SetBinLabel(5,"Bin5 not used");
- if (fTriggerOnV0AND&&isESD) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
+ if(fTriggerOnV0AND) fEventStat->GetXaxis()->SetBinLabel(3,"V0and triggers");
if (fEventFilter) fEventStat->GetXaxis()->SetBinLabel(4,"After Event Filter");
if (fRejectPileup) fEventStat->GetXaxis()->SetBinLabel(5,"After Pileup rejection");
AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
if (!inputHandler) return;
+// AliPIDResponse *pidRes=inputHandler->GetPIDResponse();
if ( inputHandler->GetPIDResponse() ){
+ // for the 2.76 pass2 MC private train. Together with a sigma shift of -0.169
+// pidRes->GetTPCResponse().SetSigma(4.637e-3,2.41332105409873257e+04);
AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
} else {
- //load esd pid bethe bloch parameters depending on the existance of the MC handler
- // yes: MC parameters
- // no: data parameters
-
- //ESD case
- if (isESD){
- if (!AliDielectronVarManager::GetESDpid()){
-
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitESDpid();
- } else {
- AliDielectronVarManager::InitESDpid(1);
- }
- }
- }
- //AOD case
- if (isAOD){
- if (!AliDielectronVarManager::GetAODpidUtil()){
- if (AliDielectronMC::Instance()->HasMC()) {
- AliDielectronVarManager::InitAODpidUtil();
- } else {
- AliDielectronVarManager::InitAODpidUtil(1);
- }
- }
- }
- }
- // Was event selected ?
- UInt_t isSelected = AliVEvent::kAny;
- if( fSelectPhysics && inputHandler && inputHandler->GetEventSelection() ) {
- isSelected = inputHandler->IsEventSelected();
- isSelected&=fTriggerMask;
+ AliFatal("This task needs the PID response attached to the input event handler!");
}
+ // Was event selected ?
+ ULong64_t isSelected = AliVEvent::kAny;
+ Bool_t isRejected = kFALSE;
+ if( fSelectPhysics && inputHandler){
+ if((isESD && inputHandler->GetEventSelection()) || isAOD){
+ isSelected = inputHandler->IsEventSelected();
+ if (fExcludeTriggerMask && (isSelected&fExcludeTriggerMask)) isRejected=kTRUE;
+ if (fTriggerLogic==kAny) isSelected&=fTriggerMask;
+ else if (fTriggerLogic==kExact) isSelected=((isSelected&fTriggerMask)==fTriggerMask);
+ }
+ }
+
+
//Before physics selection
fEventStat->Fill(kAllEvents);
- if (isSelected==0) {
+ if (isSelected==0||isRejected) {
PostData(3,fEventStat);
return;
}
fEventStat->Fill(kSelectedEvents);
//V0and
- if (fTriggerOnV0AND&&isESD){
- if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND)) return;
- }
+ if(fTriggerOnV0AND){
+ if(isESD){if (!fTriggerAnalysis->IsOfflineTriggerFired(static_cast<AliESDEvent*>(InputEvent()), AliTriggerAnalysis::kV0AND))
+ return;}
+ if(isAOD){if(!((static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0ADecision() == AliVVZERO::kV0BB &&
+ (static_cast<AliAODEvent*>(InputEvent()))->GetVZEROData()->GetV0CDecision() == AliVVZERO::kV0BB) )
+ return;}
+ }
+
+
fEventStat->Fill(kV0andEvents);
+
+ //Fill Event histograms before the event filter
+ TIter nextDie(&fListDielectron);
+ AliDielectron *die=0;
+ Double_t values[AliDielectronVarManager::kNMaxValues]={0};
+ Double_t valuesMC[AliDielectronVarManager::kNMaxValues]={0};
+ AliDielectronVarManager::Fill(InputEvent(),values);
+ AliDielectronVarManager::Fill(InputEvent(),valuesMC);
+ Bool_t hasMC=AliDielectronMC::Instance()->HasMC();
+ if (hasMC) {
+ if (AliDielectronMC::Instance()->ConnectMCEvent())
+ AliDielectronVarManager::Fill(AliDielectronMC::Instance()->GetMCEvent(),valuesMC);
+ }
+
+ while ( (die=static_cast<AliDielectron*>(nextDie())) ){
+ AliDielectronHistos *h=die->GetHistoManager();
+ if (h){
+ if (h->GetHistogramList()->FindObject("Event_noCuts"))
+ h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,values);
+ if (hasMC && h->GetHistogramList()->FindObject("MCEvent_noCuts"))
+ h->FillClass("Event_noCuts",AliDielectronVarManager::kNMaxValues,valuesMC);
+ }
+ }
+ nextDie.Reset();
//event filter
if (fEventFilter) {
AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
//Process event in all AliDielectron instances
- TIter nextDie(&fListDielectron);
- AliDielectron *die=0;
+ // TIter nextDie(&fListDielectron);
+ // AliDielectron *die=0;
Int_t idie=0;
while ( (die=static_cast<AliDielectron*>(nextDie())) ){
die->Process(InputEvent());
AliDielectron *die=0;
while ( (die=static_cast<AliDielectron*>(nextDie())) ){
die->SaveDebugTree();
+ AliDielectronMixingHandler *mix=die->GetMixingHandler();
+// printf("\n\n\n===============\ncall mix in Terminate: %p (%p)\n=================\n\n",mix,die);
+ if (mix) mix->MixRemaining(die);
}
+ PostData(1, &fListHistos);
+ PostData(2, &fListCF);
}
public:
AliAnalysisTaskMultiDielectron();
AliAnalysisTaskMultiDielectron(const char *name);
- virtual ~AliAnalysisTaskMultiDielectron(){ }
+ virtual ~AliAnalysisTaskMultiDielectron();
+
+ enum ETriggerLogig {kAny, kExact};
virtual void UserExec(Option_t *option);
virtual void UserCreateOutputObjects();
// virtual void NotifyRun(){AliDielectronPID::SetCorrVal((Double_t)fCurrentRunNumber);}
void UsePhysicsSelection(Bool_t phy=kTRUE) {fSelectPhysics=phy;}
- void SetTriggerMask(UInt_t mask) {fTriggerMask=mask;}
+ void SetTriggerMask(ULong64_t mask) {fTriggerMask=mask;}
UInt_t GetTriggerMask() const { return fTriggerMask; }
+ void SetExcludeTriggerMask(ULong64_t mask) {fExcludeTriggerMask=mask;}
+ UInt_t GetExcludeTriggerMask() const { return fExcludeTriggerMask; }
+ void SetTriggerLogic(ETriggerLogig log) {fTriggerLogic=log;}
+ ETriggerLogig GetTriggerLogic() const {return fTriggerLogic;}
void SetEventFilter(AliAnalysisCuts * const filter) {fEventFilter=filter;}
void SetTriggerOnV0AND(Bool_t v0and=kTRUE) { fTriggerOnV0AND=v0and; }
Bool_t fSelectPhysics; // Whether to use physics selection
UInt_t fTriggerMask; // Event trigger mask
+ UInt_t fExcludeTriggerMask; // Triggers to exclude from the analysis
Bool_t fTriggerOnV0AND; // if to trigger on V0and
Bool_t fRejectPileup; // pileup rejection wanted
+
+ ETriggerLogig fTriggerLogic; // trigger logic: any or all bits need to be matching
AliTriggerAnalysis *fTriggerAnalysis; //! trigger analysis class
AliAnalysisTaskMultiDielectron(const AliAnalysisTaskMultiDielectron &c);
AliAnalysisTaskMultiDielectron& operator= (const AliAnalysisTaskMultiDielectron &c);
- ClassDef(AliAnalysisTaskMultiDielectron, 1); //Analysis Task handling multiple instances of AliDielectron
+ ClassDef(AliAnalysisTaskMultiDielectron, 2); //Analysis Task handling multiple instances of AliDielectron
};
#endif
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// //
+// Analysis task for computing single particle efficiencies //
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TChain.h>
+#include <TH1D.h>
+#include <TList.h>
+#include <THashList.h>
+#include <TString.h>
+
+#include <AliPID.h>
+#include <AliCFContainer.h>
+#include <AliInputEventHandler.h>
+#include <AliESDInputHandler.h>
+#include <AliAODInputHandler.h>
+#include <AliAnalysisManager.h>
+#include <AliVEvent.h>
+#include <AliESDEvent.h>
+#include <AliESDv0.h>
+#include <AliESDv0Cuts.h>
+#include <AliESDv0KineCuts.h>
+#include <AliKFVertex.h>
+#include <AliESDfriendTrack.h>
+#include <AliESDfriend.h>
+#include <../TRD/AliTRDseedV1.h>
+#include <../TRD/AliTRDcluster.h>
+#include <../TRD/AliTRDtrackV1.h>
+
+#include "AliDielectron.h"
+#include "AliDielectronHistos.h"
+#include "AliDielectronPair.h"
+#include "AliDielectronCF.h"
+#include "AliDielectronMC.h"
+#include "AliDielectronHistos.h"
+#include "AliAnalysisTaskSingleParticle.h"
+
+#include <iostream>
+using namespace std;
+
+ClassImp(AliAnalysisTaskSingleParticle)
+
+//_________________________________________________________________________________
+AliAnalysisTaskSingleParticle::AliAnalysisTaskSingleParticle() :
+ AliAnalysisTaskSE(),
+ fCfContainer(0x0),
+ fHistos(0x0),
+ fHistogramList(),
+ fSelectPhysics(kTRUE),
+ fTriggerMask(AliVEvent::kMB),
+ fRejectPileup(kFALSE),
+ fFillTRDfriendPH(kFALSE),
+ fEventFilter(0x0),
+ fTrackFilter(0x0),
+ fPairFilter(0x0),
+ fV0Cuts(0x0),
+ fLambdaFilter(0x0),
+ fK0sFilter(0x0),
+ fV0KineCuts(0x0),
+ fCFNVars(0),
+ fEventStat(0x0)
+{
+ //
+ // Constructor
+ //
+ for(Int_t i=0; i<kNMaxDimensions; ++i) {
+ fCFVarsEnabled[i] = -1; fCFVarsNbins[i] = 0;
+ fCFVarRanges[i][0] = 0.0; fCFVarRanges[i][1] = -1.0;
+ fCFVarBins[i] = "";
+ }
+}
+
+//_________________________________________________________________________________
+AliAnalysisTaskSingleParticle::AliAnalysisTaskSingleParticle(const char *name) :
+ AliAnalysisTaskSE(name),
+ fCfContainer(0x0),
+ fHistos(0x0),
+ fHistogramList(),
+ fSelectPhysics(kTRUE),
+ fTriggerMask(AliVEvent::kMB),
+ fRejectPileup(kFALSE),
+ fFillTRDfriendPH(kFALSE),
+ fEventFilter(0x0),
+ fTrackFilter(0x0),
+ fPairFilter(0x0),
+ fV0Cuts(0x0),
+ fLambdaFilter(0x0),
+ fK0sFilter(0x0),
+ fV0KineCuts(0x0),
+ fCFNVars(0),
+ fEventStat(0x0)
+{
+ //
+ // Constructor
+ //
+ for(Int_t i=0; i<kNMaxDimensions; ++i) {
+ fCFVarsEnabled[i] = -1; fCFVarsNbins[i] = 0;
+ fCFVarRanges[i][0] = 0.0; fCFVarRanges[i][1] = -1.0;
+ fCFVarBins[i] = "";
+ }
+ fHistogramList.SetName("QAhistos");
+ fHistogramList.SetOwner();
+ DefineInput(0, TChain::Class());
+ DefineOutput(1, AliCFContainer::Class());
+ DefineOutput(2, TList::Class());
+ DefineOutput(3, TH1D::Class());
+}
+
+
+//____________________________________________________________________
+AliAnalysisTaskSingleParticle::~AliAnalysisTaskSingleParticle()
+{
+ //
+ // Destructor
+ //
+ fHistogramList.SetOwner(kFALSE);
+ if(fHistos) delete fHistos;
+ delete fCfContainer;
+}
+
+
+//____________________________________________________________________
+void AliAnalysisTaskSingleParticle::AddCFVar(Int_t var, Int_t nbins, Double_t lowLim, Double_t highLim) {
+ //
+ // Configure variables for the CF container
+ //
+ if(fCFNVars>=kNMaxDimensions) return;
+ fCFVarsEnabled[fCFNVars] = var;
+ fCFVarsNbins[fCFNVars] = nbins;
+ fCFVarRanges[fCFNVars][0] = lowLim;
+ fCFVarRanges[fCFNVars][1] = highLim;
+ ++fCFNVars;
+}
+
+
+//____________________________________________________________________
+void AliAnalysisTaskSingleParticle::AddCFVar(Int_t var, const Char_t* bins) {
+ //
+ // Configure variables for the CF container
+ //
+ if(fCFNVars>=kNMaxDimensions) return;
+ fCFVarsEnabled[fCFNVars] = var;
+ fCFVarBins[fCFNVars] = bins;
+ ++fCFNVars;
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskSingleParticle::UserCreateOutputObjects()
+{
+ //
+ // Initialize CF container
+ //
+ if(fCfContainer) return;
+ if(!fHistogramList.IsEmpty()) return;
+
+ if (!fEventStat){
+ fEventStat=new TH1D("hEventStat","Event statistics",4,-0.5,3.5);
+ fEventStat->GetXaxis()->SetBinLabel(1,"Before Phys. Sel.");
+ fEventStat->GetXaxis()->SetBinLabel(2,"After Phys. Sel.");
+ fEventStat->GetXaxis()->SetBinLabel(3,"After event filter");
+ fEventStat->GetXaxis()->SetBinLabel(4,"After pileup rejection");
+ }
+
+ //Bool_t hasMC = AliDielectronMC::Instance()->HasMC();
+
+ if(!fCfContainer) {
+ for(Int_t ivar=0; ivar<fCFNVars; ++ivar) {
+ if(fCFVarBins[ivar][0]!='\0') {
+ TObjArray* arr = fCFVarBins[ivar].Tokenize(",");
+ fCFVarsNbins[ivar] = arr->GetEntries()-1;
+ }
+ }
+ fCFVarsNbins[fCFNVars] = AliPID::kSPECIES;
+ //
+ // If fFillTRDfriendPH is toggled then add some predefined variables to the CF
+ // Hardcoded variables and binning !! TODO: Implement them in the VarManager ??
+ // This container is filled for every TRD time bin, and every tracklet from a track
+ Double_t phLimits[2] = {0.0, 2000.}; Int_t phBins = 200;
+ Double_t detLimits[2] = {-0.5, 539.5}; Int_t detBins = 540;
+ const Int_t kNTrdMomBins = 17;
+ Double_t trdMomLimits[kNTrdMomBins+1] = {0.0, 0.5, 0.7, 0.9, 1.1, 1.3, 1.5, 1.7, 1.9, 2.1, 2.5, 3.0, 3.5, 4.0, 5.0, 6.0, 8.0, 10.0};
+ Int_t trdNtb = 30; Double_t trdTbLims[2] = {0.5, 30.5};
+ Int_t trdQtotNbins = 200; Double_t trdQtotLims[2] = {0.0, 10000.};
+ fCFVarsNbins[fCFNVars+1] = kNTrdMomBins;
+ fCFVarsNbins[fCFNVars+2] = detBins;
+ fCFVarsNbins[fCFNVars+3] = trdNtb;
+ fCFVarsNbins[fCFNVars+4] = phBins;
+ fCFVarsNbins[fCFNVars+5] = trdQtotNbins;
+
+ if(fCFNVars>0 || fFillTRDfriendPH) {
+ fCfContainer = new AliCFContainer("SingleParticle", "Single Particle CF", 1, (fFillTRDfriendPH ? fCFNVars+6 : fCFNVars+1), fCFVarsNbins);
+ for(Int_t ivar=0; ivar<fCFNVars; ++ivar) {
+ if(fCFVarBins[ivar][0]=='\0')
+ fCfContainer->SetBinLimits(ivar, fCFVarRanges[ivar][0], fCFVarRanges[ivar][1]);
+ else {
+ TObjArray* arr = fCFVarBins[ivar].Tokenize(",");
+ if(arr->GetEntries()-1>0) {
+ Double_t* binLims = new Double_t[arr->GetEntries()];
+ for(Int_t ib=0;ib<arr->GetEntries();++ib) {
+ TString binStr = arr->At(ib)->GetName();
+ binLims[ib] = binStr.Atof();
+ }
+ fCfContainer->SetBinLimits(ivar, binLims);
+ }
+ }
+ fCfContainer->SetVarTitle(ivar, AliDielectronVarManager::GetValueName(fCFVarsEnabled[ivar]));
+ }
+ fCfContainer->SetBinLimits(fCFNVars, -0.5+AliPID::kElectron, 0.5+AliPID::kProton);
+ fCfContainer->SetVarTitle(fCFNVars, "specie");
+ if(fFillTRDfriendPH) {
+ fCfContainer->SetBinLimits(fCFNVars+1, trdMomLimits);
+ fCfContainer->SetVarTitle(fCFNVars+1, "TRD_trackletMom");
+ fCfContainer->SetBinLimits(fCFNVars+2, detLimits[0], detLimits[1]);
+ fCfContainer->SetVarTitle(fCFNVars+2, "TRD_detector");
+ fCfContainer->SetBinLimits(fCFNVars+3, trdTbLims[0], trdTbLims[1]);
+ fCfContainer->SetVarTitle(fCFNVars+3, "TRD_tb");
+ fCfContainer->SetBinLimits(fCFNVars+4, phLimits[0], phLimits[1]);
+ fCfContainer->SetVarTitle(fCFNVars+4, "TRD_PH");
+ fCfContainer->SetBinLimits(fCFNVars+5, trdQtotLims[0], trdQtotLims[1]);
+ fCfContainer->SetVarTitle(fCFNVars+5, "TRD_Qtot");
+ }
+ fCfContainer->SetStepTitle(0, "Tracking");
+ }
+ }
+
+ if(fHistos) {
+ fHistogramList.Add(const_cast<THashList*>(fHistos->GetHistogramList()));
+ }
+
+ if(fCfContainer) PostData(1, fCfContainer);
+ if(fHistos) PostData(2, &fHistogramList);
+ PostData(3, fEventStat);
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskSingleParticle::UserExec(Option_t *)
+{
+ //
+ // Main loop. Called for every event
+ //
+
+ AliAnalysisManager *man=AliAnalysisManager::GetAnalysisManager();
+ //Bool_t isESD=man->GetInputEventHandler()->IsA()==AliESDInputHandler::Class();
+ //Bool_t isAOD=man->GetInputEventHandler()->IsA()==AliAODInputHandler::Class();
+
+ AliInputEventHandler* inputHandler = (AliInputEventHandler*) (man->GetInputEventHandler());
+ if (!inputHandler) return;
+
+ if ( inputHandler->GetPIDResponse() ){
+ AliDielectronVarManager::SetPIDResponse( inputHandler->GetPIDResponse() );
+ } else {
+ AliFatal("This task needs the PID response attached to the input event handler!");
+ }
+ // Was event selected ?
+ UInt_t isSelected = AliVEvent::kAny;
+ if( fSelectPhysics && inputHandler && inputHandler->GetEventSelection() ) {
+ isSelected = inputHandler->IsEventSelected();
+ isSelected&=fTriggerMask;
+ }
+
+ //Before physics selection
+ fEventStat->Fill(0);
+ if (isSelected==0) {
+ PostData(3,fEventStat);
+ return;
+ }
+ //after physics selection
+ fEventStat->Fill(1);
+
+ //event filter
+ if (fEventFilter) {
+ if (!fEventFilter->IsSelected(InputEvent())) {PostData(3, fEventStat); return;}
+ }
+ fEventStat->Fill(2);
+
+ //pileup
+ if (fRejectPileup){
+ if (InputEvent()->IsPileupFromSPD(3,0.8,3.,2.,5.)) {PostData(3, fEventStat); return;}
+ }
+ fEventStat->Fill(3);
+
+ if(!fCfContainer) {PostData(3, fEventStat); return;}
+ //bz for AliKF
+ Double_t bz = InputEvent()->GetMagneticField();
+ AliKFParticle::SetField( bz );
+
+ AliDielectronPID::SetCorrVal((Double_t)InputEvent()->GetRunNumber());
+
+ AliESDEvent* esd = (AliESDEvent*)InputEvent();
+ AliDielectronVarManager::SetEvent(esd);
+
+ Double_t valuesPos[AliDielectronVarManager::kNMaxValues];
+ Double_t valuesNeg[AliDielectronVarManager::kNMaxValues];
+ Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(esd, valuesPos);
+ AliDielectronVarManager::Fill(esd, valuesNeg);
+ AliDielectronVarManager::Fill(esd, valuesPair);
+
+ if(fHistos && fHistos->GetHistogramList()->FindObject("Event"))
+ fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, valuesPos);
+
+ const AliESDVertex *primaryVertex = esd->GetPrimaryVertex();
+ AliKFVertex primaryVertexKF(*primaryVertex);
+
+ fV0KineCuts->SetEvent(esd);
+ fV0KineCuts->SetPrimaryVertex(&primaryVertexKF);
+
+ Int_t pdgV0=0; Int_t pdgP=0; Int_t pdgN=0;
+ for(Int_t iV0=0; iV0<InputEvent()->GetNumberOfV0s(); ++iV0) { // loop over V0s
+ //cout << "iV0 = " << iV0 << endl;
+ AliESDv0 *v0 = esd->GetV0(iV0);
+
+ AliESDtrack* legPos = esd->GetTrack(v0->GetPindex());
+ AliESDtrack* legNeg = esd->GetTrack(v0->GetNindex());
+
+ if(legPos->GetSign() == legNeg->GetSign()) {
+ //cout << "V0 rejected: same sign legs" << endl;
+ continue;
+ }
+
+ //To avoid ghosts test of trunk for the refit
+ if(!(legPos->GetStatus() & AliESDtrack::kTPCrefit)) {
+ //cout << "pos leg rejected: no TPCrefit" << endl;
+ continue;
+ }
+ if(!(legNeg->GetStatus() & AliESDtrack::kTPCrefit)) {
+ //cout << "neg leg rejected: no TPCrefit" << endl;
+ continue;
+ }
+
+ Bool_t v0ChargesAreCorrect = (legPos->GetSign()==+1 ? kTRUE : kFALSE);
+ legPos = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetNindex()) : legPos);
+ legNeg = (!v0ChargesAreCorrect ? esd->GetTrack(v0->GetPindex()) : legNeg);
+
+ Bool_t good = fV0KineCuts->ProcessV0(v0, pdgV0, pdgP, pdgN);
+ if(!good) {
+ //cout << "V0KineCuts rejected V0" << endl;
+ continue;
+ }
+
+ if(!fFillTRDfriendPH) {
+ //cout << "No TRD friend filling" << endl;
+ if(pdgV0!=22) continue;
+ if(TMath::Abs(pdgN)!=11) continue;
+ if(TMath::Abs(pdgP)!=11) continue;
+ }
+ /*
+ // V0 standard cuts
+ if(fV0Cuts) {
+ TList v0List;
+ v0List.Add(v0);
+ v0List.Add(legPos); v0List.Add(legNeg);
+ v0List.Add(const_cast<AliESDVertex*>(primaryVertex));
+ if(!fV0Cuts->IsSelected(&v0List)) continue;
+ }*/
+
+ // additional track filtering
+ if(fTrackFilter && !fTrackFilter->IsSelected(legPos)) {
+ //cout << "pos leg rejected: track filter" << endl;
+ continue;
+ }
+ if(fTrackFilter && !fTrackFilter->IsSelected(legNeg)) {
+ //cout << "neg leg rejected: track filter" << endl;
+ continue;
+ }
+
+ AliKFParticle* posKF = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),pdgP) : new AliKFParticle(*(v0->GetParamN()),pdgN));
+ AliKFParticle* negKF = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),pdgN) : new AliKFParticle(*(v0->GetParamP()),pdgP));
+ AliDielectronPair pair;
+ pair.SetTracks(posKF, negKF, legPos, legNeg);
+ pair.SetType(1);
+ if(fPairFilter && !fPairFilter->IsSelected(&pair)) {
+ //cout << "diele pair rejected: pair filter" << endl;
+ continue;
+ }
+
+ // additional filtering on the KF pair (mass, chi2, etc.)
+ // Gamma conversion inclusion cuts
+ /*
+ AliKFParticle* posKFGammaEle = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),-11) : new AliKFParticle(*(v0->GetParamN()),-11));
+ AliKFParticle* negKFGammaEle = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),+11) : new AliKFParticle(*(v0->GetParamP()),+11));
+ AliDielectronPair gammaPair;
+ gammaPair.SetTracks(posKFGammaEle, negKFGammaEle, legPos, legNeg);
+ gammaPair.SetType(1);
+ if(fPairFilter && !fPairFilter->IsSelected(&gammaPair)) continue;
+ */
+ /*
+ // Lambda exclusion cuts
+ AliKFParticle* posKFLambdaPro = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),2212) : new AliKFParticle(*(v0->GetParamN()),2212));
+ AliKFParticle* negKFLambdaPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),-211) : new AliKFParticle(*(v0->GetParamP()),-211));
+ AliDielectronPair lambdaPair;
+ lambdaPair.SetTracks(posKFLambdaPro, negKFLambdaPio, legPos, legNeg);
+ lambdaPair.SetType(1);
+ if(fLambdaFilter && fLambdaFilter->IsSelected(&lambdaPair)) continue;
+ // Anti-Lambda exclusion cuts
+ AliKFParticle* posKFALambdaPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),211) : new AliKFParticle(*(v0->GetParamN()),211));
+ AliKFParticle* negKFALambdaPro = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),-2212) : new AliKFParticle(*(v0->GetParamP()),-2212));
+ AliDielectronPair alambdaPair;
+ alambdaPair.SetTracks(posKFALambdaPio, negKFALambdaPro, legPos, legNeg);
+ alambdaPair.SetType(1);
+ if(fLambdaFilter && fLambdaFilter->IsSelected(&alambdaPair)) continue;
+ // K0s exclusion cuts
+ AliKFParticle* posKFK0sPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamP()),211) : new AliKFParticle(*(v0->GetParamN()),211));
+ AliKFParticle* negKFK0sPio = (v0ChargesAreCorrect ? new AliKFParticle(*(v0->GetParamN()),-211) : new AliKFParticle(*(v0->GetParamP()),-211));
+ AliDielectronPair k0sPair;
+ k0sPair.SetTracks(posKFK0sPio, negKFK0sPio, legPos, legNeg);
+ k0sPair.SetType(1);
+ if(fK0sFilter && fK0sFilter->IsSelected(&k0sPair)) continue;
+ */
+
+ // Fill histograms and the CF container
+ AliDielectronVarManager::Fill(legPos, valuesPos);
+ AliDielectronVarManager::Fill(legNeg, valuesNeg);
+
+ if(fHistos && fHistos->GetHistogramList()->FindObject("Track_Pos"))
+ fHistos->FillClass("Track_Pos", AliDielectronVarManager::kNMaxValues, valuesPos);
+ if(fHistos && fHistos->GetHistogramList()->FindObject("Track_Neg"))
+ fHistos->FillClass("Track_Neg", AliDielectronVarManager::kNMaxValues, valuesNeg);
+
+ AliDielectronVarManager::Fill(&pair, valuesPair);
+ if(fHistos && fHistos->GetHistogramList()->FindObject(Form("Pair_%s",AliDielectron::PairClassName(1))))
+ fHistos->FillClass(Form("Pair_%s",AliDielectron::PairClassName(1)), AliDielectronVarManager::kNMaxValues, valuesPair);
+
+ if(valuesPos[AliDielectronVarManager::kPOut]>=0.5)
+ FillContainer(0, valuesPos, (v0ChargesAreCorrect ? v0->GetPindex() : v0->GetNindex()), (v0ChargesAreCorrect ? pdgP : pdgN));
+ if(valuesNeg[AliDielectronVarManager::kPOut]>=0.5)
+ FillContainer(0, valuesNeg, (v0ChargesAreCorrect ? v0->GetNindex() : v0->GetPindex()), (v0ChargesAreCorrect ? pdgN : pdgP));
+ } // end loop over online V0s
+
+ //delete gammaPair;
+
+ PostData(1, fCfContainer);
+ PostData(2, &fHistogramList);
+ PostData(3, fEventStat);
+}
+
+//_________________________________________________________________________________
+void AliAnalysisTaskSingleParticle::FinishTaskOutput()
+{
+ //
+ //
+ //
+}
+
+
+//_________________________________________________________________________________
+void AliAnalysisTaskSingleParticle::FillContainer(Int_t step, const Double_t* values, Int_t trackId, Int_t pdg) {
+ //
+ // Fill the CF container
+ //
+ Double_t valuesCF[kNMaxDimensions];
+ for(Int_t i=0; i<fCFNVars; ++i) valuesCF[i] = values[fCFVarsEnabled[i]];
+
+ Double_t pid = -1.0;
+ if(TMath::Abs(pdg)==11) pid = AliPID::kElectron;
+ if(TMath::Abs(pdg)==13) pid = AliPID::kMuon;
+ if(TMath::Abs(pdg)==211) pid = AliPID::kPion;
+ if(TMath::Abs(pdg)==321) pid = AliPID::kKaon;
+ if(TMath::Abs(pdg)==2212) pid = AliPID::kProton;
+ valuesCF[fCFNVars] = pid;
+
+ if(fFillTRDfriendPH) {
+ AliESDfriendTrack* friendTrk = fESDfriend->GetTrack(trackId);
+ if(!friendTrk) return;
+ if(values[AliDielectronVarManager::kTRDntracklets]>0.001) {
+ TObject* o=0x0; Int_t ical = 0;
+ AliTRDtrackV1* trdTrack=0x0;
+ while(1) {
+ o = friendTrk->GetCalibObject(ical++);
+ if(!o) break;
+ TString objName = o->IsA()->GetName();
+ if(!objName.Contains("AliTRDtrackV1")) continue;
+ trdTrack = dynamic_cast<AliTRDtrackV1*>(o);
+ break;
+ }
+ if(!trdTrack) return;
+
+ Double_t charge = 0.0;
+ for(Int_t ipl = 0; ipl < 6; ipl++) { // loop over TRD layers
+ AliTRDseedV1 *tracklet = trdTrack->GetTracklet(ipl);
+ if(!tracklet) continue;
+ if(!tracklet->IsOK()) continue;
+ valuesCF[fCFNVars+1] = tracklet->GetMomentum();
+ valuesCF[fCFNVars+2] = tracklet->GetDetector();
+ charge = 0.0;
+ for(Int_t itb = 0; itb < AliTRDseedV1::kNtb; itb++){
+ AliTRDcluster *c = tracklet->GetClusters(itb);
+ AliTRDcluster *c1 = tracklet->GetClusters(itb + AliTRDseedV1::kNtb); // second pad row
+ if(c) charge += TMath::Abs(c->GetQ()); //
+ if(c1) charge += TMath::Abs(c1->GetQ());
+ }
+ valuesCF[fCFNVars+5] = charge;
+
+ for(Int_t itb = 0; itb < AliTRDseedV1::kNtb; itb++){
+ AliTRDcluster *c = tracklet->GetClusters(itb);
+ AliTRDcluster *c1 = tracklet->GetClusters(itb + AliTRDseedV1::kNtb); // second pad row
+ if(!(c || c1)) continue;
+ AliTRDcluster *cptr = (c ? c : c1);
+ Int_t tcal = cptr->GetLocalTimeBin();
+ Float_t sig = 0;
+ if(c) sig += TMath::Abs(c->GetQ()); //
+ if(c1) sig += TMath::Abs(c1->GetQ());
+ valuesCF[fCFNVars+3] = tcal;
+ valuesCF[fCFNVars+4] = sig;
+
+ fCfContainer->Fill(valuesCF, step);
+ } // end loop over time bins
+ } // end loop over tracklets
+ } // end if track has TRD tracklets
+ } // end if fill TRD friend PH
+ if(!fFillTRDfriendPH)
+ fCfContainer->Fill(valuesCF, step);
+}
+
--- /dev/null
+#ifndef ALIANALYSISTASKSINGLEPARTICLE_H
+#define ALIANALYSISTASKSINGLEPARTICLE_H
+
+//===============================================================
+//
+// Analysis task for constructing MC or data driven single particle efficiencies
+//
+// Ionut C. Arsene, EMMI-GSI, 2011/12/07
+//
+//===============================================================
+
+#include "TList.h"
+
+#include "AliAnalysisTaskSE.h"
+
+class TH1D;
+class TList;
+class AliAnalysisCuts;
+class AliCFContainer;
+class AliVEvent;
+class AliDielectronHistos;
+class AliESDv0Cuts;
+class AliESDv0KineCuts;
+
+class AliAnalysisTaskSingleParticle : public AliAnalysisTaskSE {
+
+public:
+ enum { kNMaxDimensions = 20 };
+
+ AliAnalysisTaskSingleParticle();
+ AliAnalysisTaskSingleParticle(const char *name);
+ virtual ~AliAnalysisTaskSingleParticle();
+
+ virtual void UserExec(Option_t *option);
+ virtual void UserCreateOutputObjects();
+ virtual void FinishTaskOutput();
+
+ void SetFillTRDfriendPH(Bool_t fill=kTRUE) {fFillTRDfriendPH = fill;}
+ void UsePhysicsSelection(Bool_t phy=kTRUE) {fSelectPhysics=phy;}
+ void SetTriggerMask(UInt_t mask) {fTriggerMask=mask;}
+ UInt_t GetTriggerMask() const { return fTriggerMask; }
+ void SetRejectPileup(Bool_t pileup=kTRUE) { fRejectPileup=pileup; }
+
+ void SetEventFilter(AliAnalysisCuts * const filter) {fEventFilter=filter;}
+ void SetTrackFilter(AliAnalysisCuts * const filter) {fTrackFilter=filter;}
+ void SetPairFilter(AliAnalysisCuts* const filter) {fPairFilter=filter;}
+ void SetV0Cuts(AliESDv0Cuts* const cuts) {fV0Cuts = cuts;}
+ void SetLambdaFilter(AliAnalysisCuts* const filter) {fLambdaFilter = filter;}
+ void SetK0sFilter(AliAnalysisCuts* const filter) {fK0sFilter = filter;}
+ void SetHistogramManager(AliDielectronHistos * const histos) { fHistos=histos; }
+ void SetV0KineCuts(AliESDv0KineCuts* const v0cuts) {fV0KineCuts = v0cuts;}
+
+ void AddCFVar(Int_t var, Int_t nbins, Double_t lowLim, Double_t highLim);
+ void AddCFVar(Int_t var, const Char_t* bins);
+
+protected:
+// enum {kAllEvents=0, kPhysicsSelectionEvents, kFilteredEvents, kEventStatBins};
+// enum {kEventVtxZ=0, kNTracklets, kCentrality, kPt, kPin, kPhi, kEta, kDeltaPt, kDeltaPhi, kDeltaEta, kTPCnCls, kTPCnSigEle, kTPCnSigPio, kTPCnSigPro, kNVariables};
+
+ AliCFContainer* fCfContainer; // CF container
+ AliDielectronHistos *fHistos; // Histogram manager
+ TList fHistogramList; // histogram list from the manager
+
+ Bool_t fSelectPhysics; // Whether to use physics selection
+ UInt_t fTriggerMask; // Event trigger mask
+ Bool_t fRejectPileup; // pileup rejection wanted
+ Bool_t fFillTRDfriendPH; // use the task to fill a TRD tracklet PH container
+
+ AliAnalysisCuts* fEventFilter; // event filter
+ AliAnalysisCuts* fTrackFilter; // tracking filter
+ AliAnalysisCuts* fPairFilter; // pair filter
+ AliESDv0Cuts* fV0Cuts; // v0 standard filter
+ AliAnalysisCuts* fLambdaFilter; // additional cuts for lambda v0 exclusion
+ AliAnalysisCuts* fK0sFilter; // additional cuts for K0s v0 exclusion
+ AliESDv0KineCuts* fV0KineCuts; // V0 kine cuts
+
+ Int_t fCFNVars; // number of CF variables
+ Int_t fCFVarsEnabled[kNMaxDimensions]; // id for every dimension
+ Int_t fCFVarsNbins[kNMaxDimensions]; // number of bins for every CF dimension
+ Double_t fCFVarRanges[kNMaxDimensions][2]; // range for CF dimensions
+ TString fCFVarBins[kNMaxDimensions]; // bin limits for CF dimensions
+
+ TH1D *fEventStat; //! Histogram with event statistics
+
+ void FillContainer(Int_t step, const Double_t* values, Int_t trackId, Int_t pdg);
+
+ AliAnalysisTaskSingleParticle(const AliAnalysisTaskSingleParticle &c);
+ AliAnalysisTaskSingleParticle& operator= (const AliAnalysisTaskSingleParticle &c);
+
+ ClassDef(AliAnalysisTaskSingleParticle, 2); //Analysis Task handling single particle cuts
+};
+#endif
#include <TString.h>
#include <TList.h>
#include <TMath.h>
+#include <TObject.h>
#include <AliESDEvent.h>
#include <AliESDtrack.h>
+#include <AliKFParticle.h>
+#include <AliEventplane.h>
#include <AliVEvent.h>
#include <AliVParticle.h>
#include <AliVTrack.h>
#include "AliDielectronTrackRotator.h"
#include "AliDielectronDebugTree.h"
#include "AliDielectronSignalMC.h"
+#include "AliDielectronMixingHandler.h"
#include "AliDielectron.h"
fPairPreFilter("PairPreFilter"),
fPairPreFilterLegs("PairPreFilterLegs"),
fPairFilter("PairFilter"),
+ fEventPlanePreFilter("EventPlanePreFilter"),
+ fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
fPdgMother(443),
fPdgLeg1(11),
fPdgLeg2(11),
fSignalsMC(0x0),
fNoPairing(kFALSE),
fHistos(0x0),
- fPairCandidates(new TObjArray(10)),
+ fPairCandidates(new TObjArray(11)),
fCfManagerPair(0x0),
fTrackRotator(0x0),
fDebugTree(0x0),
+ fMixing(0x0),
+ fPreFilterEventPlane(kFALSE),
+ fLikeSignSubEvents(kFALSE),
fPreFilterUnlikeOnly(kFALSE),
fPreFilterAllSigns(kFALSE),
- fHasMC(kFALSE)
+ fHasMC(kFALSE),
+ fStoreRotatedPairs(kFALSE),
+ fEstimatorFilename(""),
+ fTRDpidCorrectionFilename("")
{
//
// Default constructor
fPairPreFilter("PairPreFilter"),
fPairPreFilterLegs("PairPreFilterLegs"),
fPairFilter("PairFilter"),
+ fEventPlanePreFilter("EventPlanePreFilter"),
+ fEventPlanePOIPreFilter("EventPlanePOIPreFilter"),
fPdgMother(443),
fPdgLeg1(11),
fPdgLeg2(11),
fSignalsMC(0x0),
fNoPairing(kFALSE),
fHistos(0x0),
- fPairCandidates(new TObjArray(10)),
+ fPairCandidates(new TObjArray(11)),
fCfManagerPair(0x0),
fTrackRotator(0x0),
fDebugTree(0x0),
+ fMixing(0x0),
+ fPreFilterEventPlane(kFALSE),
+ fLikeSignSubEvents(kFALSE),
fPreFilterUnlikeOnly(kFALSE),
fPreFilterAllSigns(kFALSE),
- fHasMC(kFALSE)
+ fHasMC(kFALSE),
+ fStoreRotatedPairs(kFALSE),
+ fEstimatorFilename(""),
+ fTRDpidCorrectionFilename("")
{
//
// Named constructor
if (fHistos) delete fHistos;
if (fPairCandidates) delete fPairCandidates;
if (fDebugTree) delete fDebugTree;
+ if (fMixing) delete fMixing;
if (fSignalsMC) delete fSignalsMC;
+ if (fCfManagerPair) delete fCfManagerPair;
}
//________________________________________________________________
//
if(GetHasMC()) AliDielectronMC::Instance()->SetHasMC(GetHasMC());
-
+
+ InitPairCandidateArrays();
+
if (fCfManagerPair) {
fCfManagerPair->SetSignalsMC(fSignalsMC);
fCfManagerPair->InitialiseContainer(fPairFilter);
fTrackRotator->SetPdgLegs(fPdgLeg1,fPdgLeg2);
}
if (fDebugTree) fDebugTree->SetDielectron(this);
+ if(fEstimatorFilename.Contains(".root")) AliDielectronVarManager::InitEstimatorAvg(fEstimatorFilename.Data());
+ if(fTRDpidCorrectionFilename.Contains(".root")) AliDielectronVarManager::InitTRDpidEffHistograms(fTRDpidCorrectionFilename.Data());
+
+ if (fMixing) fMixing->Init(this);
}
//________________________________________________________________
AliError("At least first event must be set!");
return;
}
-
AliDielectronVarManager::SetEvent(ev1);
-
+
//in case we have MC load the MC event and process the MC particles
if (AliDielectronMC::Instance()->HasMC()) {
if (!AliDielectronMC::Instance()->ConnectMCEvent()){
AliError("Could not properly connect the MC event, skipping this event!");
return;
}
- ProcessMC();
+ ProcessMC(ev1);
}
//if candidate array doesn't exist, create it
(ev2&&fEventFilter.IsSelected(ev2)!=selectedMask)) return;
AliDielectronVarManager::SetEvent(ev1);
-
+
//fill track arrays for the first event
if (ev1){
FillTrackArrays(ev1);
if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(0, 1, fTracks[0], fTracks[1]);
- if ((fPreFilterAllSigns) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) {
- PairPreFilter(0, 0, fTracks[0], fTracks[0]);
- PairPreFilter(1, 1, fTracks[1], fTracks[1]);
- }
}
if (ev2) {
FillTrackArrays(ev2,1);
if (((fPreFilterAllSigns)||(fPreFilterUnlikeOnly)) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) PairPreFilter(2, 3, fTracks[2], fTracks[3]);
- if ((fPreFilterAllSigns) && ( fPairPreFilter.GetCuts()->GetEntries()>0 )) {
- PairPreFilter(2, 2, fTracks[2], fTracks[2]);
- PairPreFilter(3, 3, fTracks[3], fTracks[3]);
- }
}
+ // TPC event plane correction
+ AliEventplane *cevplane = new AliEventplane();
+ if (ev1 && fPreFilterEventPlane && ( fEventPlanePreFilter.GetCuts()->GetEntries()>0 || fEventPlanePOIPreFilter.GetCuts()->GetEntries()>0))
+ EventPlanePreFilter(0, 1, fTracks[0], fTracks[1], ev1, cevplane);
+
if (!fNoPairing){
// create pairs and fill pair candidate arrays
for (Int_t itrackArr1=0; itrackArr1<4; ++itrackArr1){
FillPairArrayTR();
}
}
-
- //in case there is a histogram manager, fill the QA histograms
- if (fHistos) FillHistograms(ev1);
//fill debug tree if a manager is attached
if (fDebugTree) FillDebugTree();
+
+ //process event mixing
+ if (fMixing) {
+ fMixing->Fill(ev1,this);
+// FillHistograms(0x0,kTRUE);
+ }
+
+ //in case there is a histogram manager, fill the QA histograms
+ if (fHistos) FillHistograms(ev1);
+
+ // clear arrays
+// ClearArrays();
+ AliDielectronVarManager::SetTPCEventPlane(0x0);
+ delete cevplane;
}
//________________________________________________________________
-void AliDielectron::ProcessMC()
+void AliDielectron::ProcessMC(AliVEvent *ev1)
{
//
// Process the MC data
AliDielectronMC *dieMC=AliDielectronMC::Instance();
- if (fHistos) FillHistogramsMC(dieMC->GetMCEvent());
+ if (fHistos) FillHistogramsMC(dieMC->GetMCEvent(), ev1);
if(!fSignalsMC) return;
//loop over all MC data and Fill the CF container if it exist
//________________________________________________________________
-void AliDielectron::FillHistogramsMC(const AliMCEvent *ev)
+void AliDielectron::FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1)
{
//
// Fill Histogram information for MCEvents
//
- Double_t values[AliDielectronVarManager::kNMaxValues];
+ Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
// Fill event information
- AliDielectronVarManager::Fill(ev, values);
+ AliDielectronVarManager::Fill(ev1, values); // ESD/AOD information
+ AliDielectronVarManager::Fill(ev, values); // MC truth info
if (fHistos->GetHistogramList()->FindObject("MCEvent"))
fHistos->FillClass("MCEvent", AliDielectronVarManager::kNMaxValues, values);
}
//________________________________________________________________
-void AliDielectron::FillHistograms(const AliVEvent *ev)
+void AliDielectron::FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly)
{
//
// Fill Histogram information for tracks and pairs
//
TString className,className2;
- Double_t values[AliDielectronVarManager::kNMaxValues];
+ Double_t values[AliDielectronVarManager::kNMaxValues]={0.};
//Fill event information
- AliDielectronVarManager::Fill(ev, values);
- if (fHistos->GetHistogramList()->FindObject("Event"))
- fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values);
+ if (ev){
+ AliDielectronVarManager::Fill(ev, values);
+ if (fHistos->GetHistogramList()->FindObject("Event"))
+ fHistos->FillClass("Event", AliDielectronVarManager::kNMaxValues, values);
+ }
//Fill track information, separately for the track array candidates
- for (Int_t i=0; i<4; ++i){
- className.Form("Track_%s",fgkTrackClassNames[i]);
- if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
- Int_t ntracks=fTracks[i].GetEntriesFast();
- for (Int_t itrack=0; itrack<ntracks; ++itrack){
- AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
- fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
+ if (!pairInfoOnly){
+ for (Int_t i=0; i<4; ++i){
+ className.Form("Track_%s",fgkTrackClassNames[i]);
+ if (!fHistos->GetHistogramList()->FindObject(className.Data())) continue;
+ Int_t ntracks=fTracks[i].GetEntriesFast();
+ for (Int_t itrack=0; itrack<ntracks; ++itrack){
+ AliDielectronVarManager::Fill(fTracks[i].UncheckedAt(itrack), values);
+ fHistos->FillClass(className, AliDielectronVarManager::kNMaxValues, values);
+ }
}
}
//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);
}
//________________________________________________________________
-void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
+void AliDielectron::EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev, AliEventplane *cevplane)
{
//
- // Prefilter tracks from pairs
- // Needed for datlitz rejections
- // remove all tracks from the Single track arrays that pass the cuts in this filter
+ // Prefilter tracks and tracks from pairs
+ // Needed for rejection in the Q-Vector of the event plane
+ // remove contribution of all tracks to the Q-vector that are in invariant mass window
//
+ AliEventplane *evplane = const_cast<AliVEvent *>(ev)->GetEventplane();
+ if(!evplane) return;
+
+ // do not change these vectors qref
+ TVector2 *qref = evplane->GetQVector();
+ if(!qref) return;
+ // random subevents
+ TVector2 *qrsub1 = evplane->GetQsub1();
+ TVector2 *qrsub2 = evplane->GetQsub2();
+
+ // copy references
+ TVector2 *qstd = dynamic_cast<TVector2 *>(qref->Clone());
+ TVector2 *qssub1 = dynamic_cast<TVector2 *>(qrsub1->Clone());
+ TVector2 *qssub2 = dynamic_cast<TVector2 *>(qrsub2->Clone());
+
+ // subevents by charge separation sub1+ sub2-
+ if(fLikeSignSubEvents) {
+ qssub1 = dynamic_cast<TVector2 *>(qstd->Clone());
+ qssub2 = dynamic_cast<TVector2 *>(qstd->Clone());
+
+ Int_t ntracks=ev->GetNumberOfTracks();
+
+ // track removals
+ for (Int_t itrack=0; itrack<ntracks; ++itrack){
+ AliVParticle *particle=ev->GetTrack(itrack);
+ AliVTrack *track= static_cast<AliVTrack*>(particle);
+ if (!track) continue;
+
+ Double_t cQX = evplane->GetQContributionX(track);
+ Double_t cQY = evplane->GetQContributionY(track);
+
+ Short_t charge=track->Charge();
+ if (charge<0) qssub1->Set(qssub1->X()-cQX, qssub1->Y()-cQY);
+ if (charge>0) qssub2->Set(qssub2->X()-cQX, qssub2->Y()-cQY);
+ }
+ }
+
+ // subevents eta division sub1+ sub2-
+ Bool_t etagap = kFALSE;
+ for (Int_t iCut=0; iCut<fEventPlanePreFilter.GetCuts()->GetEntries();++iCut) {
+ TString cutName=fEventPlanePreFilter.GetCuts()->At(iCut)->GetName();
+ if(cutName.Contains("eta") || cutName.Contains("Eta")) {
+ etagap=kTRUE;
+
+ qssub1 = dynamic_cast<TVector2 *>(qstd->Clone());
+ qssub2 = dynamic_cast<TVector2 *>(qstd->Clone());
+
+ Int_t ntracks=ev->GetNumberOfTracks();
+
+ // track removals
+ for (Int_t itrack=0; itrack<ntracks; ++itrack){
+ AliVParticle *particle=ev->GetTrack(itrack);
+ AliVTrack *track= static_cast<AliVTrack*>(particle);
+ if (!track) continue;
+
+ Double_t cQX = evplane->GetQContributionX(track);
+ Double_t cQY = evplane->GetQContributionY(track);
+
+ Double_t eta=track->Eta();
+ if (eta<0.0) qssub1->Set(qssub1->X()-cQX, qssub1->Y()-cQY);
+ if (eta>0.0) qssub2->Set(qssub2->X()-cQX, qssub2->Y()-cQY);
+ }
+ }
+ }
+
+ // apply cuts, e.g. etagap
+ if(fEventPlanePreFilter.GetCuts()->GetEntries()) {
+ UInt_t selectedMask=(1<<fEventPlanePreFilter.GetCuts()->GetEntries())-1;
+ Int_t ntracks=ev->GetNumberOfTracks();
+ for (Int_t itrack=0; itrack<ntracks; ++itrack){
+ AliVParticle *particle=ev->GetTrack(itrack);
+ AliVTrack *track= static_cast<AliVTrack*>(particle);
+ if (!track) continue;
+
+ //event plane cuts
+ UInt_t cutMask=fEventPlanePreFilter.IsSelected(track);
+ //apply cut
+ if (cutMask==selectedMask) continue;
+
+ Double_t cQX = 0.0;
+ Double_t cQY = 0.0;
+ if(!etagap) {
+ cQX = evplane->GetQContributionX(track);
+ cQY = evplane->GetQContributionY(track);
+ }
+ Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
+ Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
+ Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
+ Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
+
+ // update Q vectors
+ qstd->Set(qstd->X()-cQX, qstd->Y()-cQY);
+ qssub1->Set(qssub1->X()-cQXsub1, qssub1->Y()-cQYsub1);
+ qssub2->Set(qssub2->X()-cQXsub2, qssub2->Y()-cQYsub2);
+ }
+ }
+
+ if(!qstd || !qssub1 || !qssub2) return;
+
+ TVector2 *qcorr = dynamic_cast<TVector2 *>(qstd->Clone());
+ TVector2 *qcsub1 = dynamic_cast<TVector2 *>(qssub1->Clone());
+ TVector2 *qcsub2 = dynamic_cast<TVector2 *>(qssub2->Clone());
+
+
+ // POI (particle of interest) rejection
Int_t pairIndex=GetPairIndex(arr1,arr2);
Int_t ntrack1=arrTracks1.GetEntriesFast();
Int_t ntrack2=arrTracks2.GetEntriesFast();
-
AliDielectronPair candidate;
- UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
- UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
-
+ UInt_t selectedMask=(1<<fEventPlanePOIPreFilter.GetCuts()->GetEntries())-1;
for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
Int_t end=ntrack2;
if (arr1==arr2) end=itrack1;
Bool_t accepted=kFALSE;
for (Int_t itrack2=0; itrack2<end; ++itrack2){
- AliVTrack *track1=static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1));
- AliVTrack *track2=static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2));
+ TObject *track1=arrTracks1.UncheckedAt(itrack1);
+ TObject *track2=arrTracks2.UncheckedAt(itrack2);
if (!track1 || !track2) continue;
//create the pair
- candidate.SetTracks(track1, fPdgLeg1,
- track2, fPdgLeg2);
+ candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
+ static_cast<AliVTrack*>(track2), fPdgLeg2);
+
candidate.SetType(pairIndex);
candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
- //relate to the production vertex
-// if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
-
- //pair cuts
- UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
+ //event plane cuts
+ UInt_t cutMask=fEventPlanePOIPreFilter.IsSelected(&candidate);
//apply cut
- if (cutMask!=selectedMask) continue;
- if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
+ if (cutMask==selectedMask) continue;
+
accepted=kTRUE;
- if (fHistos) FillHistogramsPair(&candidate,kTRUE);
//remove the tracks from the Track arrays
arrTracks2.AddAt(0x0,itrack2);
- //in case of like sign remove the track from both arrays!
- if (arr1==arr2) arrTracks1.AddAt(0x0, itrack2);
}
- if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
+ if ( accepted ) arrTracks1.AddAt(0x0,itrack1);
}
//compress the track arrays
+ arrTracks1.Compress();
+ arrTracks2.Compress();
+
+ //Modify the components: subtract the tracks
+ ntrack1=arrTracks1.GetEntriesFast();
+ ntrack2=arrTracks2.GetEntriesFast();
+
+ // remove leg1 contribution
+ for (Int_t itrack=0; itrack<ntrack1; ++itrack){
+ AliVTrack *track= static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack));
+ if (!track) continue;
+
+ Double_t cQX = evplane->GetQContributionX(track);
+ Double_t cQY = evplane->GetQContributionY(track);
+ Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
+ Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
+ Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
+ Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
+
+ // update Q vectors
+ qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
+ qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
+ qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
+ }
+ // remove leg2 contribution
+ for (Int_t itrack=0; itrack<ntrack2; ++itrack){
+ AliVTrack *track= static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack));
+ if (!track) continue;
+
+ Double_t cQX = evplane->GetQContributionX(track);
+ Double_t cQY = evplane->GetQContributionY(track);
+ Double_t cQXsub1 = evplane->GetQContributionXsub1(track);
+ Double_t cQYsub1 = evplane->GetQContributionYsub1(track);
+ Double_t cQXsub2 = evplane->GetQContributionXsub2(track);
+ Double_t cQYsub2 = evplane->GetQContributionYsub2(track);
+
+ // update Q vectors
+ qcorr->Set(qcorr->X()-cQX, qcorr->Y()-cQY);
+ qcsub1->Set(qcsub1->X()-cQXsub1, qcsub1->Y()-cQYsub1);
+ qcsub2->Set(qcsub2->X()-cQXsub2, qcsub2->Y()-cQYsub2);
+ }
+ // set AliEventplane with corrected values
+ cevplane->SetQVector(qcorr);
+ cevplane->SetQsub(qcsub1, qcsub2);
+ AliDielectronVarManager::SetTPCEventPlane(cevplane);
+}
+//________________________________________________________________
+void AliDielectron::PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2)
+{
+ //
+ // Prefilter tracks from pairs
+ // Needed for datlitz rejections
+ // remove all tracks from the Single track arrays that pass the cuts in this filter
+ //
+
+ Int_t ntrack1=arrTracks1.GetEntriesFast();
+ Int_t ntrack2=arrTracks2.GetEntriesFast();
+ AliDielectronPair candidate;
+
+ // flag arrays for track removal
+ Bool_t *bTracks1 = new Bool_t[ntrack1];
+ for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1) bTracks1[itrack1]=kFALSE;
+ Bool_t *bTracks2 = new Bool_t[ntrack2];
+ for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2) bTracks2[itrack2]=kFALSE;
+
+ UInt_t selectedMask=(1<<fPairPreFilter.GetCuts()->GetEntries())-1;
+ UInt_t selectedMaskPair=(1<<fPairFilter.GetCuts()->GetEntries())-1;
+
+ Int_t nRejPasses = 1; //for fPreFilterUnlikeOnly and no set flag
+ if (fPreFilterAllSigns) nRejPasses = 3;
+
+ for (Int_t iRP=0; iRP < nRejPasses; ++iRP) {
+ Int_t arr1RP=arr1, arr2RP=arr2;
+ TObjArray *arrTracks1RP=&arrTracks1;
+ TObjArray *arrTracks2RP=&arrTracks2;
+ Bool_t *bTracks1RP = bTracks1;
+ Bool_t *bTracks2RP = bTracks2;
+ switch (iRP) {
+ case 1: arr1RP=arr1;arr2RP=arr1;
+ arrTracks1RP=&arrTracks1;
+ arrTracks2RP=&arrTracks1;
+ bTracks1RP = bTracks1;
+ bTracks2RP = bTracks1;
+ break;
+ case 2: arr1RP=arr2;arr2RP=arr2;
+ arrTracks1RP=&arrTracks2;
+ arrTracks2RP=&arrTracks2;
+ bTracks1RP = bTracks2;
+ bTracks2RP = bTracks2;
+ break;
+ default: ;//nothing to do
+ }
+ Int_t ntrack1RP=(*arrTracks1RP).GetEntriesFast();
+ Int_t ntrack2RP=(*arrTracks2RP).GetEntriesFast();
+
+ Int_t pairIndex=GetPairIndex(arr1RP,arr2RP);
+
+ for (Int_t itrack1=0; itrack1<ntrack1RP; ++itrack1){
+ Int_t end=ntrack2RP;
+ if (arr1RP==arr2RP) end=itrack1;
+ for (Int_t itrack2=0; itrack2<end; ++itrack2){
+ TObject *track1=(*arrTracks1RP).UncheckedAt(itrack1);
+ TObject *track2=(*arrTracks2RP).UncheckedAt(itrack2);
+ if (!track1 || !track2) continue;
+ //create the pair
+ candidate.SetTracks(static_cast<AliVTrack*>(track1), fPdgLeg1,
+ static_cast<AliVTrack*>(track2), fPdgLeg2);
+
+ candidate.SetType(pairIndex);
+ candidate.SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(&candidate,fPdgMother));
+ //relate to the production vertex
+ // if (AliDielectronVarManager::GetKFVertex()) candidate.SetProductionVertex(*AliDielectronVarManager::GetKFVertex());
+
+ //pair cuts
+ UInt_t cutMask=fPairPreFilter.IsSelected(&candidate);
+
+ //apply cut
+ if (cutMask!=selectedMask) continue;
+ if (fCfManagerPair) fCfManagerPair->Fill(selectedMaskPair+1 ,&candidate);
+ if (fHistos) FillHistogramsPair(&candidate,kTRUE);
+ //set flags for track removal
+ bTracks1RP[itrack1]=kTRUE;
+ bTracks2RP[itrack2]=kTRUE;
+ }
+ }
+ }
+
+ //remove the tracks from the Track arrays
+ for (Int_t itrack1=0; itrack1<ntrack1; ++itrack1){
+ if(bTracks1[itrack1]) arrTracks1.AddAt(0x0, itrack1);
+ }
+ for (Int_t itrack2=0; itrack2<ntrack2; ++itrack2){
+ if(bTracks2[itrack2]) arrTracks2.AddAt(0x0, itrack2);
+ }
+
+ // clean up
+ delete [] bTracks1;
+ delete [] bTracks2;
+
+ //compress the track arrays
arrTracks1.Compress();
arrTracks2.Compress();
for (Int_t itrack2=0; itrack2<end; ++itrack2){
//create the pair
candidate->SetTracks(static_cast<AliVTrack*>(arrTracks1.UncheckedAt(itrack1)), fPdgLeg1,
- static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
+ static_cast<AliVTrack*>(arrTracks2.UncheckedAt(itrack2)), fPdgLeg2);
candidate->SetType(pairIndex);
candidate->SetLabel(AliDielectronMC::Instance()->GetLabelMotherWithPdg(candidate,fPdgMother));
if (fCfManagerPair) fCfManagerPair->Fill(cutMask,&candidate);
//apply cut
- if (cutMask==selectedMask&&fHistos) FillHistogramsPair(&candidate);
+ if (cutMask==selectedMask) {
+ if(fHistos) FillHistogramsPair(&candidate);
+ if(fStoreRotatedPairs) PairArray(10)->Add(new AliDielectronPair(candidate));
+ }
}
}
#include "AliDielectronHistos.h"
+class AliEventplane;
class AliVEvent;
class AliMCEvent;
class THashList;
class AliDielectronTrackRotator;
class AliDielectronPair;
class AliDielectronSignalMC;
+class AliDielectronMixingHandler;
//________________________________________________________________
class AliDielectron : public TNamed {
-
+
+ friend class AliDielectronMixingHandler; //mixing as friend class
+
public:
enum EPairType { kEv1PP=0, kEv1PM, kEv1MM,
kEv1PEv2P, kEv1MEv2P, kEv2PP,
AliAnalysisFilter& GetPairFilter() { return fPairFilter; }
AliAnalysisFilter& GetPairPreFilter() { return fPairPreFilter; }
AliAnalysisFilter& GetPairPreFilterLegs() { return fPairPreFilterLegs; }
-
+ AliAnalysisFilter& GetEventPlanePreFilter(){ return fEventPlanePreFilter; }
+ AliAnalysisFilter& GetEventPlanePOIPreFilter(){ return fEventPlanePOIPreFilter; }
+
void SetMotherPdg( Int_t pdgMother ) { fPdgMother=pdgMother; }
void SetLegPdg(Int_t pdgLeg1, Int_t pdgLeg2) { fPdgLeg1=pdgLeg1; fPdgLeg2=pdgLeg2; }
Int_t GetMotherPdg() const { return fPdgMother; }
void SetNoPairing(Bool_t noPairing=kTRUE) { fNoPairing=noPairing; }
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)?
+ const TObjArray* GetPairArray(Int_t i) const {return (i>=0&&i<11)?
static_cast<TObjArray*>(fPairCandidates->UncheckedAt(i)):0;}
TObjArray** GetPairArraysPointer() { return &fPairCandidates; }
return (GetPairArray(0)&&GetPairArray(2)) ? (GetPairArray(0)->GetEntriesFast()>0 || GetPairArray(2)->GetEntriesFast()>0) : 0;
}
+ Bool_t HasCandidatesTR() const {return GetPairArray(10)?GetPairArray(10)->GetEntriesFast()>0:0;}
void SetCFManagerPair(AliDielectronCF * const cf) { fCfManagerPair=cf; }
AliDielectronCF* GetCFManagerPair() const { return fCfManagerPair; }
+ void SetPreFilterEventPlane(Bool_t setValue=kTRUE){fPreFilterEventPlane=setValue;};
+ void SetLikeSignSubEvents(Bool_t setValue=kTRUE){fLikeSignSubEvents=setValue;};
void SetPreFilterUnlikeOnly(Bool_t setValue=kTRUE){fPreFilterUnlikeOnly=setValue;};
void SetPreFilterAllSigns(Bool_t setValue=kTRUE){fPreFilterAllSigns=setValue;};
void SetTrackRotator(AliDielectronTrackRotator * const rot) { fTrackRotator=rot; }
AliDielectronTrackRotator* GetTrackRotator() const { return fTrackRotator; }
+ void SetMixingHandler(AliDielectronMixingHandler *mix) { fMixing=mix; }
+ AliDielectronMixingHandler* GetMixingHandler() const { return fMixing; }
+
void SetHasMC(Bool_t hasMC) { fHasMC = hasMC; }
Bool_t GetHasMC() const { return fHasMC; }
+ void SetStoreRotatedPairs(Bool_t storeTR) {fStoreRotatedPairs = storeTR;}
+
void AddSignalMC(AliDielectronSignalMC* signal);
void SetDebugTree(AliDielectronDebugTree * const tree) { fDebugTree=tree; }
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<11)?fgkPairClassNames[i]:""; }
+ void SetEstimatorFilename(const Char_t* filename) {fEstimatorFilename = filename;}
+ void SetTRDcorrectionFilename(const Char_t* filename) {fTRDpidCorrectionFilename = filename;}
+
+
void SaveDebugTree();
-
-private:
+private:
AliAnalysisFilter fEventFilter; // Event cuts
AliAnalysisFilter fTrackFilter; // leg cuts
AliAnalysisFilter fPairPreFilter; // pair prefilter cuts
AliAnalysisFilter fPairPreFilterLegs; // Leg filter after the pair prefilter cuts
AliAnalysisFilter fPairFilter; // pair cuts
-
+ AliAnalysisFilter fEventPlanePreFilter; // event plane prefilter cuts
+ AliAnalysisFilter fEventPlanePOIPreFilter; // PoI cuts in the event plane prefilter
+
Int_t fPdgMother; // pdg code of mother tracks
Int_t fPdgLeg1; // pdg code leg1
Int_t fPdgLeg2; // pdg code leg2
AliDielectronCF *fCfManagerPair;//Correction Framework Manager for the Pair
AliDielectronTrackRotator *fTrackRotator; //Track rotator
AliDielectronDebugTree *fDebugTree; // Debug tree output
+ AliDielectronMixingHandler *fMixing; // handler for event mixing
+ Bool_t fPreFilterEventPlane; //Filter for the Eventplane determination in TPC
+ Bool_t fLikeSignSubEvents; //Option for dividing into subevents, sub1 ++ sub2 --
Bool_t fPreFilterUnlikeOnly; //Apply PreFilter either in +- or to ++/--/+- individually
- Bool_t fPreFilterAllSigns; //Apply PreFilter find in ++/--/+- and remove from all
+ Bool_t fPreFilterAllSigns; //Apply PreFilter find in ++/--/+- and remove from all
Bool_t fHasMC; //If we run with MC, at the moment only needed in AOD
-
+ Bool_t fStoreRotatedPairs; //It the rotated pairs should be stored in the pair array
+
void FillTrackArrays(AliVEvent * const ev, Int_t eventNr=0);
+ void EventPlanePreFilter(Int_t arr1, Int_t arr2, TObjArray arrTracks1, TObjArray arrTracks2, const AliVEvent *ev, AliEventplane *cevplane);
void PairPreFilter(Int_t arr1, Int_t arr2, TObjArray &arrTracks1, TObjArray &arrTracks2);
void FillPairArrays(Int_t arr1, Int_t arr2);
void FillPairArrayTR();
static const char* fgkTrackClassNames[4]; //Names for track arrays
static const char* fgkPairClassNames[11]; //Names for pair arrays
- void ProcessMC();
+ TString fEstimatorFilename; // name for the pp multiplicity estimators filename
+ TString fTRDpidCorrectionFilename; // name for the file containing the single particle TRD pid corrections
+
+ void ProcessMC(AliVEvent *ev1);
- void FillHistograms(const AliVEvent *ev);
- void FillHistogramsMC(const AliMCEvent *ev);
+ void FillHistograms(const AliVEvent *ev, Bool_t pairInfoOnly=kFALSE);
+ void FillHistogramsMC(const AliMCEvent *ev, AliVEvent *ev1);
void FillHistogramsPair(AliDielectronPair *pair,Bool_t fromPreFilter=kFALSE);
void FillHistogramsTracks(TObjArray **tracks);
void FillDebugTree();
-
+
AliDielectron(const AliDielectron &c);
AliDielectron &operator=(const AliDielectron &c);
// initialise all pair candidate arrays
//
fPairCandidates->SetOwner();
- for (Int_t i=0;i<10;++i){
+ for (Int_t i=0;i<11;++i){
TObjArray *arr=new TObjArray;
fPairCandidates->AddAt(arr,i);
arr->SetOwner();
for (Int_t i=0;i<4;++i){
fTracks[i].Clear();
}
- for (Int_t i=0;i<10;++i){
- PairArray(i)->Delete();
+ for (Int_t i=0;i<11;++i){
+ if (PairArray(i)) PairArray(i)->Delete();
}
}
AliDielectronBtoJPSItoEle::AliDielectronBtoJPSItoEle() :
fFCNfunction(0),
fPtBin(0),
-fMCtemplate(0)
+fMCtemplate(0),
+fResType("FF")
{
//
// default constructor
TNamed(source),
fFCNfunction(source.fFCNfunction),
fPtBin(source.fPtBin),
-fMCtemplate(source.fMCtemplate)
+fMCtemplate(source.fMCtemplate),
+fResType(source.fResType)
{
//
// copy constructor
delete fMCtemplate;
}
//_________________________________________________________________________________________________
-Int_t AliDielectronBtoJPSItoEle::DoMinimization()
+Int_t AliDielectronBtoJPSItoEle::DoMinimization(Int_t step)
{
//
// performs the minimization
//
- Int_t iret=fFCNfunction->DoMinimization();
+ Int_t iret=fFCNfunction->DoMinimization(step);
return iret;
}
//_________________________________________________________________________________________________
-void AliDielectronBtoJPSItoEle::ReadCandidates(TNtuple* nt, Double_t* &pseudoproper,Double_t* &invmass, Int_t& ncand)
+void AliDielectronBtoJPSItoEle::ReadCandidates(TNtuple* nt, Double_t* &pseudoproper, Double_t* &invmass, Int_t * &typeCand, Int_t& ncand)
{
//
// Read N-tuple with X and M values
//
- Float_t mJPSI = 0; Float_t x = 0;
+ Float_t mJPSI = 0; Float_t x = 0; Float_t type = 0;
Int_t nentries = 0;
ncand=0;
+ TString arrType[] = {"SS","FS","FF"};
nt->SetBranchAddress("Mass",&mJPSI);
nt->SetBranchAddress("Xdecaytime",&x);
+ //
+ if(!nt->GetListOfBranches()->At(2)) {AliInfo("ERROR: branch with candidate type doesn't exist! \n"); return;}
+ nt->SetBranchAddress("Type",&type);
+ //
nentries = (Int_t)nt->GetEntries();
pseudoproper = new Double_t[nentries];
invmass = new Double_t[nentries];
+ typeCand = new Int_t[nentries];
+
for(Int_t i = 0; i < nentries; i++) {
nt->GetEntry(i);
+ if(!fResType.Contains(arrType[(Int_t)type])) continue;
+ pseudoproper[ncand]=(Double_t)x;
+ invmass[ncand]=(Double_t)mJPSI;
+ typeCand[ncand] = (Int_t)type;
ncand++;
- pseudoproper[i]=(Double_t)(10000*x);
- invmass[i]=(Double_t)mJPSI;
- }
-
+ }
return;
}
//_________________________________________________________________________________________________
return;
}
//_________________________________________________________________________________________________
-void AliDielectronBtoJPSItoEle::SetFitHandler(Double_t* x /*pseudoproper*/, Double_t* m /*inv mass*/, Int_t ncand /*candidates*/)
+void AliDielectronBtoJPSItoEle::SetFitHandler(Double_t* x /*pseudoproper*/, Double_t* m /*inv mass*/, Int_t* type /*type*/, Int_t ncand /*candidates*/)
{
//
// Create the fit handler object to play with different params of the fitting function
//
- fFCNfunction = new AliDielectronBtoJPSItoEleCDFfitHandler(x,m,ncand);
+ fFCNfunction = new AliDielectronBtoJPSItoEleCDFfitHandler(x,m,type,ncand);
if(!fFCNfunction) {
AliInfo("fFCNfunction not istanziated ---> nothing done");
AliDielectronBtoJPSItoEle& operator=(const AliDielectronBtoJPSItoEle& source);\r
virtual ~AliDielectronBtoJPSItoEle();\r
\r
- Int_t DoMinimization();\r
- void ReadCandidates(TNtuple* nt, Double_t* &x, Double_t* &m, Int_t& n); // primary JPSI + secondary JPSI + bkg couples\r
+ Int_t DoMinimization(Int_t step = 0);\r
+ void ReadCandidates(TNtuple* nt, Double_t* &x, Double_t* &m, Int_t * &typeCand, Int_t& n); // primary JPSI + secondary JPSI + bkg couples\r
\r
void SetPtBin(Int_t BinNum) { fPtBin = BinNum ; }\r
void SetCsiMC();\r
- void SetFitHandler(Double_t* x /*pseudoproper*/, Double_t* m /*inv mass*/, Int_t ncand /*candidates*/); \r
+ void SetFitHandler(Double_t* x /*pseudoproper*/, Double_t* m /*inv mass*/, Int_t *type /*type*/, Int_t ncand /*candidates*/); \r
void CloneMCtemplate(const TH1F* MCtemplate) {fMCtemplate = (TH1F*)MCtemplate->Clone("fMCtemplate");}\r
- Double_t* GetResolutionConstants(Double_t* resolutionConst);\r
+ void SetResTypeAnalysis(TString resType){fResType = resType;}\r
+ Double_t* GetResolutionConstants(Double_t* resolutionConst);\r
AliDielectronBtoJPSItoEleCDFfitHandler* GetCDFFitHandler() const { return fFCNfunction ; }\r
Int_t GetPtBin() const { return fPtBin ; }\r
\r
//\r
AliDielectronBtoJPSItoEleCDFfitHandler* fFCNfunction; //! pointer to the interface class\r
Int_t fPtBin; // number of pt bin in which the analysis is performes\r
- TH1F* fMCtemplate; //! template of the MC distribution for the x distribution of the secondary J/psi\r
+ TH1F* fMCtemplate; //! template of the MC distribution for the x distribution of the secondary J/psi\r
+ TString fResType; // string with candidate's types considered\r
\r
ClassDef(AliDielectronBtoJPSItoEle,1); // AliDielectronBtoJPSItoEle class\r
};\r
* about the suitability of this software for any purpose. It is *
* provided "as is" without express or implied warranty. *
**************************************************************************/
-#include <TFormula.h>
-#include <TF1.h>
-#include <TCanvas.h>
-#include <TMath.h>
-
-#include <AliLog.h>
-
+#include "AliLog.h"
#include "AliDielectronBtoJPSItoEleCDFfitFCN.h"
+#include "TFormula.h"
+#include "TF1.h"
+#include "TCanvas.h"
+#include "TMath.h"
//_________________________________________________________________________
// Class AliDielectronBtoJPSItoEleCDFfitFCN
SetCrystalBallFunction(kFALSE);
SetMassWndHigh(0.2);
SetMassWndLow(0.5);
- for(Int_t iPar = 0; iPar < 20; iPar++) fParameters[iPar] = 0.;
- fParameters[9] = 1.;fParameters[11] = 1.;fParameters[12] = 1.;
- for(Int_t index=0; index<4; index++) fResolutionConstants[index] = 0.;
+ fWeightType[0] = 1.; fWeightType[1] = 1.; fWeightType[2] = 1.;
+ for(Int_t iPar = 0; iPar < 45; iPar++) fParameters[iPar] = 0.;
+ fParameters[9] = 1.;fParameters[11] = 1.;fParameters[12] = 1.;
AliInfo("Instance of AliDielectronBtoJPSItoEleCDFfitFCN-class created");
}
//_________________________________________________________________________________________________
fhCsiMC(source.fhCsiMC),
fMassWndHigh(source.fMassWndHigh),
fMassWndLow(source.fMassWndLow),
- fCrystalBallParam(source.fCrystalBallParam)
+ fCrystalBallParam(source.fCrystalBallParam)
{
//
// Copy constructor
//
- for(Int_t iPar = 0; iPar < 20; iPar++) fParameters[iPar] = source.fParameters[iPar];
- for(Int_t index=0; index<4; index++) fResolutionConstants[index] = source.fResolutionConstants[index];
+ for(Int_t iPar = 0; iPar < 45; iPar++) fParameters[iPar] = source.fParameters[iPar];
+ for(Int_t iW=0; iW<2; iW++) fWeightType[iW] = source.fWeightType[iW];
}
//_________________________________________________________________________________________________
AliDielectronBtoJPSItoEleCDFfitFCN& AliDielectronBtoJPSItoEleCDFfitFCN::operator=(const AliDielectronBtoJPSItoEleCDFfitFCN& source)
fhCsiMC = source.fhCsiMC;
fCrystalBallParam = source.fCrystalBallParam;
- for(Int_t iPar = 0; iPar < 20; iPar++) fParameters[iPar] = source.fParameters[iPar];
- for(Int_t index=0; index<4; index++) fResolutionConstants[index] = source.fResolutionConstants[index];
-
+ for(Int_t iPar = 0; iPar < 45; iPar++) fParameters[iPar] = source.fParameters[iPar];
return *this;
}
//_________________________________________________________________________________________________
//
delete fhCsiMC;
- for(Int_t iPar = 0; iPar < 20; iPar++) fParameters[iPar] = 0.;
- for(Int_t index=0; index<4; index++) fResolutionConstants[index] = 0.;
+ for(Int_t iPar = 0; iPar < 45; iPar++) fParameters[iPar] = 0.;
}
//_________________________________________________________________________________________________
Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateLikelihood(const Double_t* pseudoproperdecaytime,
- const Double_t* invariantmass, const Int_t ncand) const
+ const Double_t* invariantmass, const Int_t *type, const Int_t ncand) const
{
//
// This function evaluates the Likelihood fnction
Double_t ret = 0.;
for(Int_t i=0; i < ncand; i++) {
- f = EvaluateCDFfuncNorm(pseudoproperdecaytime[i],invariantmass[i]);
+ f = EvaluateCDFfuncNorm(pseudoproperdecaytime[i],invariantmass[i],type[i]);
if(f <= 0.) continue;
- ret += -1*TMath::Log(f);
+ ret += -1*TMath::Log(f);
}
- return ret;
+ return ret;
}
//_________________________________________________________________________________________________
void AliDielectronBtoJPSItoEleCDFfitFCN::SetAllParameters(const Double_t* parameters)
//
// Sets array of FCN parameters
//
- for(Int_t index = 0; index < 20; index++) fParameters[index] = parameters[index];
+ for(Int_t index = 0; index < 45; index++) fParameters[index] = parameters[index];
}
//_________________________________________________________________________________________________
void AliDielectronBtoJPSItoEleCDFfitFCN::ComputeMassIntegral()
summMassBkg += EvaluateCDFInvMassBkgDistr(mx);
}
intmMassBkg = summMassBkg*stepm;
- SetIntegralMassBkg(intmMassBkg);
+ if(intmMassBkg < 1.e-05) intmMassBkg = 1.;
+ SetIntegralMassBkg(intmMassBkg);
}
//_________________________________________________________________________________________________
void AliDielectronBtoJPSItoEleCDFfitFCN::PrintStatus()
printf("actual value of meanBkg ----------------------------------------->> | %f \n", GetBkgInvMassMean());
printf("actual value of slopeBkg ---------------------------------------->> | %f \n", GetBkgInvMassSlope());
printf("actual value of constBkg ---------------------------------------->> | %f \n", GetBkgInvMassConst());
- // resolution func
- printf("actual value of norm1Gauss -------------------------------------->> | %f \n",GetNormGaus1ResFunc());
- printf("actual value of norm2Gauss -------------------------------------->> | %f \n",GetNormGaus2ResFunc());
-
- printf("\n");
+ // resolution func (First-First)
+ printf("actual value of norm1Gauss (FF) --------------------------------->> | %f \n", GetNormGaus1ResFunc(2));
+ printf("actual value of norm2Gauss (FF) --------------------------------->> | %f \n", GetNormGaus2ResFunc(2));
+ printf("actual value of fMean1Res (FF) ---------------------------------->> | %f \n", GetResMean1(2));
+ printf("actual value of fSigma1Res (FF) --------------------------------->> | %f \n", GetResSigma1(2));
+ printf("actual value of fMean2Res (FF) ---------------------------------->> | %f \n", GetResMean2(2));
+ printf("actual value of fSigma2Res (FF) --------------------------------->> | %f \n", GetResSigma2(2));
+
+ printf("actual value of alfaRes (FF) ------------------------------------>> | %f \n", GetResAlfa(2));
+ printf("actual value of lambdaRes (FF) ---------------------------------->> | %f \n", GetResLambda(2));
+ printf("actual value of normExpRes (FF) --------------------------------->> | %f \n", GetResNormExp(2));
+
+ // resolution func (First-Second)
+ printf("actual value of norm1Gauss (FS) --------------------------------->> | %f \n", GetNormGaus1ResFunc(1));
+ printf("actual value of norm2Gauss (FS) --------------------------------->> | %f \n", GetNormGaus2ResFunc(1));
+ printf("actual value of fMean1Res (FS) ---------------------------------->> | %f \n", GetResMean1(1));
+ printf("actual value of fSigma1Res (FS) --------------------------------->> | %f \n", GetResSigma1(1));
+ printf("actual value of fMean2Res (FS) ---------------------------------->> | %f \n", GetResMean2(1));
+ printf("actual value of fSigma2Res (FS) --------------------------------->> | %f \n", GetResSigma2(1));
+
+ printf("actual value of alfaRes (FS) ------------------------------------>> | %f \n", GetResAlfa(1));
+ printf("actual value of lambdaRes (FS) ---------------------------------->> | %f \n", GetResLambda(1));
+ printf("actual value of normExpRes (FS) --------------------------------->> | %f \n", GetResNormExp(1));
+
+ // resolution func (Second-Second)
+ printf("actual value of norm1Gauss (SS) --------------------------------->> | %f \n", GetNormGaus1ResFunc(0));
+ printf("actual value of norm2Gauss (SS) --------------------------------->> | %f \n", GetNormGaus2ResFunc(0));
+ printf("actual value of fMean1Res (SS) ---------------------------------->> | %f \n", GetResMean1(0));
+ printf("actual value of fSigma1Res (SS) --------------------------------->> | %f \n", GetResSigma1(0));
+ printf("actual value of fMean2Res (SS) ---------------------------------->> | %f \n", GetResMean2(0));
+ printf("actual value of fSigma2Res (SS) --------------------------------->> | %f \n", GetResSigma2(0));
+
+ printf("actual value of alfaRes (SS) ------------------------------------>> | %f \n", GetResAlfa(0));
+ printf("actual value of lambdaRes (SS) ---------------------------------->> | %f \n", GetResLambda(0));
+ printf("actual value of normExpRes (SS) --------------------------------->> | %f \n", GetResNormExp(0));
+
+ printf("\n");
// integrals constants
printf("Actual value of normalization integral for MassSig ---------------->> | %f \n", GetIntegralMassSig());
printf("Actual value of normalization integral for MassBkg ---------------->> | %f \n", GetIntegralMassBkg());
printf("\n");
}
//_________________________________________________________________________________________________
-void AliDielectronBtoJPSItoEleCDFfitFCN::SetResolutionConstants(Double_t* resolutionConst)
+void AliDielectronBtoJPSItoEleCDFfitFCN::SetResolutionConstants(Double_t* resolutionConst, Int_t type)
{
//
// Resolution function is parametrized as the sum of two gaussian
//
- fResolutionConstants[0] = resolutionConst[0]; // mean 1
- fResolutionConstants[1] = resolutionConst[1]; // sigma 1
- fResolutionConstants[2] = resolutionConst[2]; // mean 2
- fResolutionConstants[3] = resolutionConst[3]; // sigma 2
+ Int_t index = (2-type)*9;
+ fParameters[20+index]=resolutionConst[1]; //mean1
+ fParameters[22+index]=resolutionConst[4]; //mean2
+ fParameters[18+index]=resolutionConst[0]; //norm1
+ fParameters[21+index]=resolutionConst[2]; //sigma1
+ fParameters[23+index]=resolutionConst[5]; //sigma2
+ fParameters[19+index]=resolutionConst[3]; //norm2
+
+ //exp values
+ fParameters[24+index]=resolutionConst[6]; //alfa
+ fParameters[25+index]=resolutionConst[7]; //lambda
+ fParameters[26+index]=resolutionConst[8]; //norm3
+ return;
}
-//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfunc(Double_t x, Double_t m) const
+//________________________________________________________________________________________________
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfunc(Double_t x, Double_t m, Int_t type) const
{
- return fParameters[8]*EvaluateCDFfuncSignalPart(x,m) + (1. - fParameters[8])*EvaluateCDFfuncBkgPart(x,m);
+ // evaluate likelihood function
+ return fParameters[8]*EvaluateCDFfuncSignalPart(x,m,type) + (1. - fParameters[8])*EvaluateCDFfuncBkgPart(x,m,type);
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfuncNorm(Double_t x, Double_t m) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfuncNorm(Double_t x, Double_t m, Int_t type) const
{
- return EvaluateCDFfunc(x,m);
+ // evaluate likelihood function
+ return EvaluateCDFfunc(x,m,type);
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfuncSignalPart(Double_t x, Double_t m) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfuncSignalPart(Double_t x, Double_t m, Int_t type) const
{
- return EvaluateCDFDecayTimeSigDistr(x)*(EvaluateCDFInvMassSigDistr(m)/fintmMassSig);
+ // evaluate psproper signal
+ return EvaluateCDFDecayTimeSigDistr(x,type)*(EvaluateCDFInvMassSigDistr(m)/fintmMassSig);
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeSigDistr(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeSigDistr(Double_t x, Int_t type) const
{
//
// Implementation of the Background part of the Likelyhood function
//
-
Double_t retvalue = 0.;
- Double_t funBnorm = FunB(x);
- Double_t funPnorm = ResolutionFunc(x);
+ Double_t funBnorm = FunB(x,type);
+ Double_t funPnorm = ResolutionFunc(x,type);
retvalue = fParameters[7]*funBnorm + (1. - fParameters[7])*funPnorm;
return retvalue;
}
// Parametrization of signal part invariant mass distribution
// It can be either Crystal Ball function or sum of two Landau
//
-
Double_t fitval = 0.;
if(fCrystalBallParam){
Double_t t = (m-fParameters[9])/fParameters[11]; ;
if (fParameters[12] < 0) t = -t;
-
Double_t absAlpha = TMath::Abs((Double_t)fParameters[12]);
if (t >= -absAlpha) {
}
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunB(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunB(Double_t x, Int_t type) const
{
//
// Parameterisation of the fit function for the x part of the Background
xprime = xlow + (i-.5) * step;
csiMCxprime = CsiMC(xprime);
xdiff = xprime - x;
- resolutionxdiff = ResolutionFunc(xdiff); // normalized value
+ resolutionxdiff = ResolutionFunc(xdiff, type); // normalized value
sum += csiMCxprime * resolutionxdiff;
}
return step * sum ;
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunP(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunP(Double_t x, Int_t type) const
{
//
// Parameterisation of the Prompt part for the x distribution
//
- return ResolutionFunc(x);
+ return ResolutionFunc(x,type);
}
Double_t returnvalue = 0.;
if((fhCsiMC->FindBin(x) > 0) && (fhCsiMC->FindBin(x) < fhCsiMC->GetNbinsX()+1))
- returnvalue = fhCsiMC->Interpolate(x);
+ returnvalue = fhCsiMC->Interpolate(x);
return returnvalue;
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfuncBkgPart(Double_t x,Double_t m) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFfuncBkgPart(Double_t x,Double_t m, Int_t type) const
{
//
// Return the part of the likelihood function for the background hypothesis
//
- return EvaluateCDFDecayTimeBkgDistr(x)*(EvaluateCDFInvMassBkgDistr(m)/fintmMassBkg);
+ return EvaluateCDFDecayTimeBkgDistr(x,type)*(EvaluateCDFInvMassBkgDistr(m)/fintmMassBkg);
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeBkgDistr(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeBkgDistr(Double_t x, Int_t type) const
{
//
// it returns the value of the probability to have a given x for the background
//
- Double_t ret = fParameters[0]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*ResolutionFunc(x) + fParameters[1]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*FunBkgPos(x) + fParameters[2]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*FunBkgNeg(x) + fParameters[3]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*FunBkgSym(x);
+ Double_t ret = fParameters[0]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*ResolutionFunc(x,type) + fParameters[1]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*FunBkgPos(x,type) + fParameters[2]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*FunBkgNeg(x,type) + fParameters[3]/(fParameters[0]+fParameters[1]+fParameters[2]+fParameters[3])*FunBkgSym(x,type);
return ret;
}
return value;
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunBkgPos(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunBkgPos(Double_t x,Int_t type) const
{
//
// exponential with positive slopes for the background part (x)
//
-
Double_t np = 1000.0;
Double_t sc = 10.;
Double_t sigma3 = 1000.; // valore usato nella macro
for(i=1.0; i<=np/2; i++) {
xprime = xlow + (i-.5) * step;
- if (xprime > 0) {sum += fParameters[4] * TMath::Exp(-1*xprime*fParameters[4])*(ResolutionFunc(xprime-x));}
+ if (xprime > 0) {sum += fParameters[4] * TMath::Exp(-1*xprime*fParameters[4])*(ResolutionFunc(xprime-x,type));}
xprime = xupp - (i-.5) * step;
- if (xprime > 0) {sum += fParameters[4] * TMath::Exp(-1*xprime*fParameters[4])*(ResolutionFunc(xprime-x));}
+ if (xprime > 0) {sum += fParameters[4] * TMath::Exp(-1*xprime*fParameters[4])*(ResolutionFunc(xprime-x,type));}
}
return step * sum ;
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunBkgNeg(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunBkgNeg(Double_t x, Int_t type) const
{
//
// exponential with negative slopes for the background part (x)
for(i=1.0; i<=np/2; i++) {
xprime = xlow + (i-.5) * step;
- if (xprime < 0) {sum += fParameters[5] * TMath::Exp(xprime*fParameters[5]) * (ResolutionFunc(xprime-x));}
+ if (xprime < 0) {sum += fParameters[5] * TMath::Exp(xprime*fParameters[5]) * (ResolutionFunc(xprime-x,type));}
xprime = xupp - (i-.5) * step;
- if (xprime < 0) {sum += fParameters[5] * TMath::Exp(xprime*fParameters[5]) * (ResolutionFunc(xprime-x));}
+ if (xprime < 0) {sum += fParameters[5] * TMath::Exp(xprime*fParameters[5]) * (ResolutionFunc(xprime-x,type));}
}
return step * sum ;
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunBkgSym(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::FunBkgSym(Double_t x, Int_t type) const
{
//
// exponential with both positive and negative slopes for the background part (x)
for(i=1.0; i<=np/2; i++) {
xprime = xlow + (i-.5) * step;
- if (xprime > 0) {sum1 += 0.5 * fParameters[6]*TMath::Exp(-1*xprime*fParameters[6]) * (ResolutionFunc(xprime-x));}
- if (xprime < 0) {sum2 += 0.5 * fParameters[6]*TMath::Exp(xprime*fParameters[6]) * (ResolutionFunc(xprime-x));}
+ if (xprime > 0) {sum1 += 0.5 * fParameters[6]*TMath::Exp(-1*xprime*fParameters[6]) * (ResolutionFunc(xprime-x,type));}
+ if (xprime < 0) {sum2 += 0.5 * fParameters[6]*TMath::Exp(xprime*fParameters[6]) * (ResolutionFunc(xprime-x,type));}
xprime = xupp - (i-.5) * step;
- if (xprime > 0) {sum1 += 0.5 * fParameters[6]*TMath::Exp(-1*xprime*fParameters[6]) * (ResolutionFunc(xprime-x));}
- if (xprime < 0) {sum2 += 0.5 * fParameters[6]*TMath::Exp(xprime*fParameters[6]) * (ResolutionFunc(xprime-x));}
+ if (xprime > 0) {sum1 += 0.5 * fParameters[6]*TMath::Exp(-1*xprime*fParameters[6]) * (ResolutionFunc(xprime-x,type));}
+ if (xprime < 0) {sum2 += 0.5 * fParameters[6]*TMath::Exp(xprime*fParameters[6]) * (ResolutionFunc(xprime-x,type));}
}
return step*(sum1 + sum2) ;
}
//_________________________________________________________________________________________________
-Double_t AliDielectronBtoJPSItoEleCDFfitFCN::ResolutionFunc(Double_t x) const
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::ResolutionFunc(Double_t x, Int_t type) const
{
//
// parametrization with 2 gaus
//
- Double_t ret = 0.;
- Double_t mean1 = fResolutionConstants[0];
- Double_t mean2 = fResolutionConstants[2];
- Double_t norm1 = fParameters[18];
- Double_t sigma1 = fResolutionConstants[1];
- Double_t sigma2 = fResolutionConstants[3];
- Double_t norm2 = fParameters[19];
-
- ret = (norm1/(norm1+norm2))*((1/(sigma1*TMath::Sqrt(2*TMath::Pi())))*TMath::Exp(-0.5*((x-mean1)/sigma1)*((x-mean1)/sigma1)))+(norm2/(norm1+norm2))*((1/(sigma2*TMath::Sqrt(2*TMath::Pi())))*TMath::Exp(-0.5*((x-mean2)/sigma2)*((x-mean2)/sigma2)));
-
- return ret;
-}
+ Int_t index = (2-type)*9;
+ Double_t mean1 = fParameters[20+index];
+ Double_t mean2 = fParameters[22+index];
+ Double_t norm1 = fParameters[18+index];
+ Double_t sigma1 = fParameters[21+index];
+ Double_t sigma2 = fParameters[23+index];
+ Double_t norm2 = fParameters[19+index];
+ //exp values
+ Double_t alfa = fParameters[24+index];
+ Double_t lambda = fParameters[25+index];
+ Double_t norm3 = fParameters[26+index];
+
+ Double_t ret = 0.; Double_t fitval = 0;
+ if(TMath::Abs(x)<=alfa) fitval = (lambda-1)/(2*alfa*lambda);
+ else fitval = ((lambda-1)/(2*alfa*lambda))*TMath::Power(alfa,lambda)*(TMath::Power(TMath::Abs(x),-1*lambda));
+
+ ret = (norm1/(norm1+norm2+norm3))*((1/(sigma1*TMath::Sqrt(2*TMath::Pi())))*TMath::Exp(-0.5*((x-mean1)/sigma1)*((x-mean1)/sigma1))) + (norm2/(norm1+norm2+norm3))*((1/(sigma2*TMath::Sqrt(2*TMath::Pi())))*TMath::Exp(-0.5*((x-mean2)/sigma2)*((x-mean2)/sigma2))) + (norm3/(norm1+norm2+norm3))*fitval;
+
+ return ret;
+}
//_________________________________________________________________________________________________
-TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetCsiMC(Double_t xmin, Double_t xmax)
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetCsiMC(Double_t xmin, Double_t xmax, Double_t normalization)
{
// return the pointer to the templateMC function
- TF1* templateMC = new TF1("MCtemplate",this,&AliDielectronBtoJPSItoEleCDFfitFCN::CsiMCfunc,xmin,xmax,0);
- templateMC->SetNpx(5000);
+ TF1* templateMC = new TF1("MCtemplate",this,&AliDielectronBtoJPSItoEleCDFfitFCN::CsiMCfunc,xmin,xmax,1);
+ templateMC->SetParameter(0,normalization);
+ templateMC->SetNpx(5000);
return (TF1*)templateMC->Clone();
}
//__________________________________________________________________________________________________
-TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetResolutionFunc(Double_t xmin, Double_t xmax){
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetResolutionFunc(Double_t xmin, Double_t xmax, Double_t normalization, Double_t type){
// return the pointer to the resolution function
- TF1* resFunc = new TF1("resolutionFunc",this,&AliDielectronBtoJPSItoEleCDFfitFCN::ResolutionFuncf,xmin,xmax,0);
+ TF1* resFunc = new TF1(Form("resolutionFunc_%f",type),this,&AliDielectronBtoJPSItoEleCDFfitFCN::ResolutionFuncf,xmin,xmax,2);
+ resFunc->SetParameter(0,normalization);
+ resFunc->SetParameter(1,type);
resFunc->SetNpx(5000);
return (TF1*)resFunc->Clone();
}
+//__________________________________________________________________________________________________
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetResolutionFuncAllTypes(Double_t xmin, Double_t xmax, Double_t normalization){
+ // return the pointer to the resolution function
+ TF1* resFunc = new TF1(Form("resolutionFunc"),this,&AliDielectronBtoJPSItoEleCDFfitFCN::ResolutionFuncAllTypes,xmin,xmax,1);
+ resFunc->SetParameter(0,normalization);
+ resFunc->SetNpx(5000);
+ return (TF1*)resFunc->Clone();
+}
+
//___________________________________________________________________________________________________
-TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeBkgDistr(Double_t xmin, Double_t xmax){
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeBkgDistr(Double_t xmin, Double_t xmax, Double_t normalization, Double_t type){
// return the pointer to the background x distribution function
- TF1 *backFunc = new TF1("backFunc",this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeBkgDistrFunc,xmin,xmax,0);
+ TF1 *backFunc = new TF1(Form("backFunc_%f",type),this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeBkgDistrFunc,xmin,xmax,2);
+ backFunc->SetParameter(0,normalization);
+ backFunc->SetParameter(1,type);
backFunc->SetNpx(5000);
return (TF1*)backFunc->Clone();
}
+//___________________________________________________________________________________________________
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeBkgDistrAllTypes(Double_t xmin, Double_t xmax, Double_t normalization){
+ // return the pointer to the background x distribution function
+ TF1 *backFunc = new TF1(Form("backFunc"),this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeBkgDistrFuncAllTypes,xmin,xmax,1);
+ backFunc->SetParameter(0,normalization);
+ backFunc->SetNpx(5000);
+ return (TF1*)backFunc->Clone();
+}
+
//__________________________________________________________________________________________________
-TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeSigDistr(Double_t xmin, Double_t xmax){
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeSigDistr(Double_t xmin, Double_t xmax, Double_t normalization, Double_t type){
// return the pointer to the signal x distribution function
- TF1 *signFunc = new TF1("signalFunc",this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeSigDistrFunc,xmin,xmax,0);
+ TF1 *signFunc = new TF1("signalFunc",this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeSigDistrFunc,xmin,xmax,2);
+ signFunc->SetParameter(0,normalization);
+ signFunc->SetParameter(1,type);
signFunc->SetNpx(5000);
return (TF1*)signFunc->Clone();
}
+
+//____________________________________________________________________________________________________
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFInvMassBkgDistr(Double_t mMin, Double_t mMax, Double_t normalization){
+ // return the pointer to the invariant mass distribution for the background
+ TF1 * invMassBkg = new TF1("invMassBkg",this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFInvMassBkgDistrFunc,mMin,mMax,1);
+ invMassBkg->SetParameter(0,normalization);
+ invMassBkg->SetNpx(5000);
+ return (TF1*)invMassBkg->Clone();
+}
+
+
+//____________________________________________________________________________________________________
+TF1* AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFInvMassSigDistr(Double_t mMin, Double_t mMax, Double_t normalization){
+ // return the pointer to the invariant mass distribution for the signal
+ TF1 * invMassSig = new TF1("invMassSig",this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFInvMassSigDistrFunc,mMin,mMax,1);
+ invMassSig->SetParameter(0,normalization);
+ invMassSig->SetNpx(5000);
+ return (TF1*)invMassSig->Clone();
+}
+
+//____________________________________________________________________________________________________
+TF1 *AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFInvMassTotalDistr(Double_t mMin, Double_t mMax, Double_t normalization){
+ // return the pointer to the invariant mass distribution
+ TF1 * invMassTot = new TF1("invMassTot",this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFInvMassTotalDistr,mMin,mMax,1);
+ invMassTot->SetParameter(0,normalization);
+ invMassTot->SetNpx(5000);
+ return (TF1*)invMassTot->Clone();
+}
+
+//____________________________________________________________________________________________________
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFInvMassTotalDistr(const Double_t* x, const Double_t *par) const
+{
+ // evaluate invariant mass total distribution
+ Double_t value = 0;
+ Double_t xx = x[0];
+ value = ((EvaluateCDFInvMassSigDistr(xx)/fintmMassSig)*fParameters[8] + (1-fParameters[8])*(EvaluateCDFInvMassBkgDistr(xx)/fintmMassBkg))*par[0];
+ return value;
+}
+
+//____________________________________________________________________________________________________
+TF1 *AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeTotalDistr(Double_t xMin, Double_t xMax, Double_t normalization,Double_t type){
+ // return the pointer to the pseudoproper distribution for the background
+ TF1 *decayTimeTot = new TF1(Form("decayTimeTot_%f",type),this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeTotalDistr,xMin,xMax,2);
+ decayTimeTot->SetParameter(0,normalization);
+ decayTimeTot->SetParameter(1,type);
+ decayTimeTot->SetNpx(5000);
+ return (TF1*)decayTimeTot->Clone();
+}
+
+//____________________________________________________________________________________________________
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeTotalDistr(const Double_t* x, const Double_t *par) const
+{
+ // evaluate the total pseudoproper distribution for a given candidate's type. par[1] should be the candidate's type.
+ Double_t value = 0;
+ Double_t xx = x[0];
+ value = (fParameters[8]*EvaluateCDFDecayTimeSigDistr(xx,(Int_t)par[1]) + (1-fParameters[8])*EvaluateCDFDecayTimeBkgDistr(xx,(Int_t)par[1]))*par[0];
+ return value;
+}
+
+//____________________________________________________________________________________________________
+Double_t AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeTotalDistrAllTypes(const Double_t* x, const Double_t *par) const
+{
+ // evaluate the total pseudoproper distribution considering all candidate's types
+ Double_t value = 0;
+ Double_t xx = x[0];
+
+ value = (fParameters[8]*(fWeightType[2]*EvaluateCDFDecayTimeSigDistr(xx,2)+fWeightType[1]*EvaluateCDFDecayTimeSigDistr(xx,1)+fWeightType[0]*EvaluateCDFDecayTimeSigDistr(xx,0)))+((1-fParameters[8])*(fWeightType[2]*EvaluateCDFDecayTimeBkgDistr(xx,2) + fWeightType[1]*EvaluateCDFDecayTimeBkgDistr(xx,1)+fWeightType[0]*EvaluateCDFDecayTimeBkgDistr(xx,0)));
+
+ return value*par[0];
+}
+
+//____________________________________________________________________________________________________
+TF1 *AliDielectronBtoJPSItoEleCDFfitFCN::GetEvaluateCDFDecayTimeTotalDistrAllTypes(Double_t xMin, Double_t xMax, Double_t normalization){
+ // return the pointer to the pseudoproper function for the background considering all candidate's types
+ TF1 *decayTimeTot = new TF1(Form("decayTimeTot"),this,&AliDielectronBtoJPSItoEleCDFfitFCN::EvaluateCDFDecayTimeTotalDistrAllTypes,xMin,xMax,1);
+ decayTimeTot->SetParameter(0,normalization);
+ decayTimeTot->SetNpx(5000);
+ return (TF1*)decayTimeTot->Clone();
+}
+
+
+//____________________________________________________________________________________________________
+TF1 * AliDielectronBtoJPSItoEleCDFfitFCN::GetFunB(Double_t xmin, Double_t xmax, Double_t normalization, Double_t type){
+ // return the pointer to the function that describe secondary jpsi pseudoproper distribution for a given candidate's type
+ TF1* funb = new TF1(Form("secondaryJpsiConvolution_%f",type),this,&AliDielectronBtoJPSItoEleCDFfitFCN::FunBfunc,xmin,xmax,2);
+ funb->SetParameter(0,normalization);
+ funb->SetParameter(1,type);
+ funb->SetNpx(5000);
+ return (TF1*)funb->Clone();
+ }
+
+//____________________________________________________________________________________________________
+TF1 * AliDielectronBtoJPSItoEleCDFfitFCN::GetFunBAllTypes(Double_t xmin, Double_t xmax, Double_t normalization){
+// return the pointer to the function that describe secondary jpsi pseudoproper distribution for all types
+ TF1* funb = new TF1(Form("secondaryJpsiConvolution"),this,&AliDielectronBtoJPSItoEleCDFfitFCN::FunBfuncAllTypes,xmin,xmax,1);
+ funb->SetParameter(0,normalization);
+ funb->SetNpx(5000);
+ return (TF1*)funb->Clone();
+ }
+
+
\r
#include <TNamed.h>\r
#include <TDatabasePDG.h>\r
-#include <TH1F.h>\r
+#include "TH1F.h"\r
\r
class TRandom3;\r
class TF1;\r
virtual ~AliDielectronBtoJPSItoEleCDFfitFCN();\r
\r
Double_t EvaluateLikelihood(const Double_t* pseudoproperdecaytime,\r
- const Double_t* invariantmass, const Int_t ncand) const;\r
+ const Double_t* invariantmass, const Int_t* type, const Int_t ncand) const;\r
\r
Double_t GetResWeight() const { return fParameters[0]; }\r
Double_t GetFPlus() const { return fParameters[1]; }\r
Double_t GetBkgInvMassMean() const { return fParameters[15]; }\r
Double_t GetBkgInvMassSlope() const { return fParameters[16]; } \r
Double_t GetBkgInvMassConst() const { return fParameters[17]; } \r
- Double_t GetNormGaus1ResFunc() const { return fParameters[18]; }\r
- Double_t GetNormGaus2ResFunc() const { return fParameters[19]; }\r
+ Double_t GetNormGaus1ResFunc(Int_t type) const { return fParameters[18+(2-type)*9]; }\r
+ Double_t GetNormGaus2ResFunc(Int_t type) const { return fParameters[19+(2-type)*9]; }\r
Double_t GetIntegralMassSig() const { return fintmMassSig; }\r
Double_t GetIntegralMassBkg() const { return fintmMassBkg; }\r
- const Double_t* GetResolutionConstants() const { return fResolutionConstants; }\r
- Bool_t GetCrystalBallParam() const { return fCrystalBallParam; }\r
+ Double_t GetResMean1(Int_t type) const { return fParameters[20+(2-type)*9]; } \r
+ Double_t GetResSigma1(Int_t type) const { return fParameters[21+(2-type)*9]; }\r
+ Double_t GetResMean2(Int_t type) const { return fParameters[22+(2-type)*9]; }\r
+ Double_t GetResSigma2(Int_t type) const { return fParameters[23+(2-type)*9]; }\r
+ \r
+ Double_t GetResAlfa(Int_t type) const { return fParameters[24+(2-type)*9]; } \r
+ Double_t GetResLambda(Int_t type) const { return fParameters[25+(2-type)*9]; } \r
+ Double_t GetResNormExp(Int_t type) const { return fParameters[26+(2-type)*9]; }\r
+\r
+ Bool_t GetCrystalBallParam() const { return fCrystalBallParam; }\r
TH1F * GetCsiMcHisto() const { return fhCsiMC; }\r
+ Double_t GetResWeight(Int_t iW) const { return fWeightType[iW]; }\r
\r
// return pointer to likelihood functions \r
- TF1* GetCsiMC(Double_t xmin, Double_t xmax);\r
- TF1* GetResolutionFunc(Double_t xmin, Double_t xmax);\r
- TF1* GetEvaluateCDFDecayTimeBkgDistr(Double_t xmin, Double_t xmax);\r
- TF1* GetEvaluateCDFDecayTimeSigDistr(Double_t xmin, Double_t xmax);\r
-\r
- void SetResWeight (Double_t resWgt) {fParameters[0] = resWgt;}\r
+ TF1* GetCsiMC(Double_t xmin, Double_t xmax,Double_t normalization);\r
+ TF1* GetResolutionFunc(Double_t xmin, Double_t xmax,Double_t normalization, Double_t type=2);\r
+ TF1* GetResolutionFuncAllTypes(Double_t xmin, Double_t xmax,Double_t normalization);\r
+ TF1* GetFunB(Double_t xmin, Double_t xmax, Double_t normalization, Double_t type=2);\r
+ TF1* GetFunBAllTypes(Double_t xmin, Double_t xmax, Double_t normalization);\r
+ TF1* GetEvaluateCDFDecayTimeBkgDistr(Double_t xmin, Double_t xmax, Double_t normalization,Double_t type = 2);\r
+ TF1* GetEvaluateCDFDecayTimeBkgDistrAllTypes(Double_t xmin, Double_t xmax, Double_t normalization);\r
+ TF1* GetEvaluateCDFDecayTimeSigDistr(Double_t xmin, Double_t xmax, Double_t normalization, Double_t type);\r
+ TF1* GetEvaluateCDFInvMassBkgDistr(Double_t mMin, Double_t mMax, Double_t normalization);\r
+ TF1* GetEvaluateCDFInvMassSigDistr(Double_t mMin, Double_t mMax, Double_t normalization);\r
+ TF1* GetEvaluateCDFInvMassTotalDistr(Double_t mMin, Double_t mMax, Double_t normalization);\r
+ TF1* GetEvaluateCDFDecayTimeTotalDistr(Double_t xMin, Double_t xMax, Double_t normalization, Double_t type=2);\r
+ TF1 *GetEvaluateCDFDecayTimeTotalDistrAllTypes(Double_t xMin, Double_t xMax, Double_t normalization);\r
+\r
+ void SetResWeight(Double_t resWgt) {fParameters[0] = resWgt;}\r
void SetFPlus(Double_t plus) {fParameters[1] = plus;}\r
void SetFMinus(Double_t minus) {fParameters[2] = minus;}\r
void SetFSym(Double_t sym) {fParameters[3] = sym;}\r
void SetIntegralMassBkg(Double_t integral) { fintmMassBkg = integral; }\r
void SetCsiMC(const TH1F* MCtemplate) {fhCsiMC = (TH1F*)MCtemplate->Clone("fhCsiMC");}\r
\r
- void SetResolutionConstants(Double_t* resolutionConst);\r
+ void SetResolutionConstants(Double_t* resolutionConst, Int_t type);\r
void SetMassWndHigh(Double_t limit) { fMassWndHigh = TDatabasePDG::Instance()->GetParticle(443)->Mass() + limit ;}\r
void SetMassWndLow(Double_t limit) { fMassWndLow = TDatabasePDG::Instance()->GetParticle(443)->Mass() - limit ;}\r
void SetCrystalBallFunction(Bool_t okCB) {fCrystalBallParam = okCB;}\r
-\r
+ \r
+ void SetWeightType(Double_t wFF, Double_t wFS, Double_t wSS) {fWeightType[0]= wSS; fWeightType[1]= wFS; fWeightType[2]= wFF;}\r
void ComputeMassIntegral(); \r
\r
void ReadMCtemplates(Int_t BinNum);\r
void PrintStatus();\r
\r
private: \r
- //\r
- Double_t fParameters[20]; /* par[0] = weightRes; \r
- par[1] = fPos;\r
+ Double_t fParameters[45]; /* par[0] = weightRes; \r
+ par[1] = fPos;\r
par[2] = fNeg;\r
par[3] = fSym\r
par[4] = fOneOvLamPlus;\r
par[15] = fBkgMean; \r
par[16] = fBkgSlope;\r
par[17] = fBkgConst;\r
- par[18] = norm1Gaus;\r
- par[19] = norm2Gaus;*/\r
-\r
+ par[18] = norm1Gaus; // resolution param used for First-First\r
+ par[19] = norm2Gaus;\r
+ par[20] = fMean1ResFunc;\r
+ par[21] = fSigma1ResFunc;\r
+ par[22] = fMean2ResFunc;\r
+ par[23] = fSigma2ResFunc;\r
+ par[24] = fResAlfa; \r
+ par[25] = fResLambda;\r
+ par[26] = fResNormExp;\r
+ par[27] = norm1Gaus; // resolution param used for First-Second\r
+ par[28] = norm2Gaus;\r
+ par[29] = fMean1ResFunc;\r
+ par[30] = fSigma1ResFunc;\r
+ par[31] = fMean2ResFunc;\r
+ par[32] = fSigma2ResFunc;\r
+ par[33] = fResAlfa; \r
+ par[34] = fResLambda;\r
+ par[35] = fResNormExp;\r
+ par[36] = norm1Gaus; // resolution param used for Second-Second\r
+ par[37] = norm2Gaus;\r
+ par[38] = fMean1ResFunc;\r
+ par[39] = fSigma1ResFunc;\r
+ par[40] = fMean2ResFunc;\r
+ par[41] = fSigma2ResFunc;\r
+ par[42] = fResAlfa; \r
+ par[43] = fResLambda;\r
+ par[44] = fResNormExp;\r
+ */\r
\r
Double_t fFPlus; // parameters of the log-likelihood function\r
Double_t fFMinus; // Slopes of the x distributions of the background \r
Double_t fintmMassBkg; // integral of invariant mass distribution for the bkg\r
\r
TH1F *fhCsiMC; // X distribution used as MC template for JPSI from B\r
- Double_t fResolutionConstants[4]; // constants for the parametrized resolution function R(X)\r
Double_t fMassWndHigh; // JPSI Mass window higher limit\r
Double_t fMassWndLow; // JPSI Mass window lower limit\r
Bool_t fCrystalBallParam; // Boolean to switch to Crystall Ball parameterisation\r
\r
- ////\r
+ Double_t fWeightType[3]; // vector with weights of candidates types (used to draw functions) \r
+ ////\r
\r
- Double_t EvaluateCDFfunc(Double_t x, Double_t m) const ;\r
- Double_t EvaluateCDFfuncNorm(Double_t x, Double_t m) const ;\r
+ Double_t EvaluateCDFfunc(Double_t x, Double_t m, Int_t type) const ;\r
+ Double_t EvaluateCDFfuncNorm(Double_t x, Double_t m, Int_t type) const ;\r
\r
////\r
\r
- Double_t EvaluateCDFfuncSignalPart(Double_t x, Double_t m) const ; // Signal part \r
- Double_t EvaluateCDFDecayTimeSigDistr(Double_t x) const ;\r
- Double_t EvaluateCDFDecayTimeSigDistrFunc(const Double_t* x, const Double_t */*par*/) const { return EvaluateCDFDecayTimeSigDistr(x[0]);}\r
+ Double_t EvaluateCDFfuncSignalPart(Double_t x, Double_t m, Int_t type) const ; // Signal part \r
+ Double_t EvaluateCDFDecayTimeSigDistr(Double_t x, Int_t type) const ;\r
+ Double_t EvaluateCDFDecayTimeSigDistrFunc(const Double_t* x, const Double_t *par) const { return par[0]*EvaluateCDFDecayTimeSigDistr(x[0],(Int_t)par[1]);}\r
Double_t EvaluateCDFInvMassSigDistr(Double_t m) const ;\r
- Double_t EvaluateCDFfuncBkgPart(Double_t x,Double_t m) const ; // Background part\r
- Double_t EvaluateCDFDecayTimeBkgDistr(Double_t x) const ;\r
- Double_t EvaluateCDFDecayTimeBkgDistrFunc(const Double_t* x, const Double_t */*par*/) const { return EvaluateCDFDecayTimeBkgDistr(x[0]);}\r
- Double_t EvaluateCDFInvMassBkgDistr(Double_t m) const ;\r
-\r
- ////\r
-\r
- Double_t FunB(Double_t x) const;\r
- Double_t FunP(Double_t x) const ;\r
+ Double_t EvaluateCDFInvMassSigDistrFunc(const Double_t* x, const Double_t *par) const {return par[0]*EvaluateCDFInvMassSigDistr(x[0])/fintmMassSig;}\r
+ Double_t EvaluateCDFfuncBkgPart(Double_t x,Double_t m,Int_t type) const ; // Background part\r
+ Double_t EvaluateCDFDecayTimeBkgDistr(Double_t x, Int_t type) const ;\r
+ Double_t EvaluateCDFDecayTimeBkgDistrFunc(const Double_t* x, const Double_t *par) const { return EvaluateCDFDecayTimeBkgDistr(x[0],(Int_t)par[1])*par[0];}\r
+ Double_t EvaluateCDFDecayTimeBkgDistrFuncAllTypes(const Double_t* x, const Double_t *par) const {return (fWeightType[2]*EvaluateCDFDecayTimeBkgDistr(x[0],2)+fWeightType[1]*EvaluateCDFDecayTimeBkgDistr(x[0],1)+fWeightType[0]*EvaluateCDFDecayTimeBkgDistr(x[0],0))*par[0];}\r
+ Double_t EvaluateCDFInvMassBkgDistr(Double_t m) const;\r
+ Double_t EvaluateCDFInvMassBkgDistrFunc(const Double_t* x, const Double_t *par) const {return par[0]*EvaluateCDFInvMassBkgDistr(x[0])/fintmMassBkg;} \r
+ \r
+ Double_t EvaluateCDFInvMassTotalDistr(const Double_t* x, const Double_t *par) const;\r
+ Double_t EvaluateCDFDecayTimeTotalDistr(const Double_t* x, const Double_t *par) const; \r
+ ////\r
+ Double_t EvaluateCDFDecayTimeTotalDistrAllTypes(const Double_t* x, const Double_t *par) const;\r
+\r
+ Double_t FunB(Double_t x, Int_t type) const;\r
+ Double_t FunBfunc(const Double_t *x, const Double_t *par) const {return FunB(x[0],(Int_t)par[1])*par[0];}\r
+ Double_t FunBfuncAllTypes(const Double_t *x, const Double_t *par) const {return (fWeightType[2]*FunB(x[0],2)+fWeightType[1]*FunB(x[0],1)+fWeightType[0]*FunB(x[0],0))*par[0];}\r
+ Double_t FunP(Double_t x, Int_t type) const ;\r
Double_t CsiMC(Double_t x) const;\r
- Double_t CsiMCfunc(const Double_t* x, const Double_t */*par*/) const { return CsiMC(x[0]);}\r
- Double_t FunBkgPos(Double_t x) const ;\r
- Double_t FunBkgNeg(Double_t x) const ;\r
- Double_t FunBkgSym(Double_t x) const ;\r
- Double_t ResolutionFunc(Double_t x) const ;\r
- Double_t ResolutionFuncf(const Double_t* x, const Double_t */*par*/) const { return ResolutionFunc(x[0]);}\r
+ Double_t CsiMCfunc(const Double_t* x, const Double_t *par) const { return CsiMC(x[0])*par[0];}\r
+ Double_t FunBkgPos(Double_t x, Int_t type) const ;\r
+ Double_t FunBkgNeg(Double_t x, Int_t type) const ;\r
+ Double_t FunBkgSym(Double_t x, Int_t type) const ;\r
+ Double_t ResolutionFunc(Double_t x, Int_t type) const;\r
+ Double_t ResolutionFuncf(const Double_t* x, const Double_t *par) const { return ResolutionFunc(x[0],(Int_t)par[1])*par[0];}\r
+ Double_t ResolutionFuncAllTypes(const Double_t* x, const Double_t *par) const { return (fWeightType[2]*ResolutionFunc(x[0],2)+fWeightType[1]*ResolutionFunc(x[0],1)+fWeightType[0]*ResolutionFunc(x[0],0))*par[0]; } \r
+ \r
\r
ClassDef (AliDielectronBtoJPSItoEleCDFfitFCN,1); // Unbinned log-likelihood fit \r
\r
* provided "as is" without express or implied warranty. *
**************************************************************************/
#include <TVirtualFitter.h>
+#include <TFitter.h>
+#include <TMinuit.h>
#include <TStopwatch.h>
+#include <TCanvas.h>
#include "AliLog.h"
#include "AliDielectronBtoJPSItoEleCDFfitHandler.h"
#include "AliDielectronBtoJPSItoEleCDFfitFCN.h"
//_________________________________________________________________________________________________
AliDielectronBtoJPSItoEleCDFfitHandler::AliDielectronBtoJPSItoEleCDFfitHandler():
- fIsParamFixed(20),
+ fIsParamFixed(45),
fPrintStatus(kFALSE),
fUp(0),
fX(0x0),
fM(0x0),
- fLikely(0x0),
- fNcand(0)
+ fType(0x0),
+ fLikely(0x0),
+ fNcand(0),
+ fContPlot1(0x0),
+ fContPlot2(0x0),
+ fContPlot3(0x0),
+ fitter(0)
{
//
// default constructor
//
- for (Int_t i=0; i<20; ++i) fParamStartValues[i]=0x0;
}
//_________________________________________________________________________________________________
AliDielectronBtoJPSItoEleCDFfitHandler::AliDielectronBtoJPSItoEleCDFfitHandler(Double_t* decaytime,
- Double_t* invariantmass, Int_t ncand) :
- fIsParamFixed(20),
+ Double_t* invariantmass, Int_t *type, Int_t ncand) :
+ fIsParamFixed(45),
fPrintStatus(kFALSE),
fUp(0),
fX(decaytime),
fM(invariantmass),
+ fType(type),
fLikely(0x0),
- fNcand(ncand)
+ fNcand(ncand),
+ fContPlot1(0x0),
+ fContPlot2(0x0),
+ fContPlot3(0x0),
+ fitter(0)
{
//
// constructor
//
- for (Int_t i=0; i<20; ++i) fParamStartValues[i]=0x0;
-
AliInfo("\n+++\n+++ Minimization object AliDielectronBtoJPSItoEleCDFfitHandler created\n+++\n");
fLikely = new AliDielectronBtoJPSItoEleCDFfitFCN();
AliInfo("\n+++\n+++ CDF fit function object AliDielectronBtoJPSItoEleCDFfitFCN created\n+++\n");
AliInfo("Parameter 15 ----> fBkgMean");
AliInfo("Parameter 16 ----> fBkgSlope");
AliInfo("Parameter 17 ----> fBkgConst");
- AliInfo("Parameter 18 ----> fNormGaus1");
- AliInfo("Parameter 19 ----> fNormGaus2");
+ AliInfo("Parameter 18 ----> fNormGaus1 (FF)");
+ AliInfo("Parameter 19 ----> fNormGaus2 (FF)");
+ AliInfo("Parameter 20 ----> fMean1Res (FF)");
+ AliInfo("Parameter 21 ----> fsigma1Res (FF)");
+ AliInfo("Parameter 22 ----> fMean2Res (FF)");
+ AliInfo("Parameter 23 ----> fsigma2Res (FF)");
+ AliInfo("Parameter 24 ----> fAlfaRes (FF)");
+ AliInfo("Parameter 25 ----> fLambdaRes (FF)");
+ AliInfo("Parameter 26 ----> fNormResExp (FF)");
+ AliInfo("Parameter 27 ----> fNormGaus1 (FS)");
+ AliInfo("Parameter 28 ----> fNormGaus2 (FS)");
+ AliInfo("Parameter 29 ----> fMean1Res (FS)");
+ AliInfo("Parameter 30 ----> fsigma1Res (FS)");
+ AliInfo("Parameter 31 ----> fMean2Res (FS)");
+ AliInfo("Parameter 32 ----> fsigma2Res (FS)");
+ AliInfo("Parameter 33 ----> fAlfaRes (FS)");
+ AliInfo("Parameter 34 ----> fLambdaRes (FS)");
+ AliInfo("Parameter 35 ----> fNormResExp (FS)");
+ AliInfo("Parameter 36 ----> fNormGaus1 (SS)");
+ AliInfo("Parameter 37 ----> fNormGaus2 (SS)");
+ AliInfo("Parameter 38 ----> fMean1Res (SS)");
+ AliInfo("Parameter 39 ----> fsigma1Res (SS)");
+ AliInfo("Parameter 40 ----> fMean2Res (SS)");
+ AliInfo("Parameter 41 ----> fsigma2Res (SS)");
+ AliInfo("Parameter 42 ----> fAlfaRes (SS)");
+ AliInfo("Parameter 43 ----> fLambdaRes (SS)");
+ AliInfo("Parameter 44 ----> fNormResExp (SS)");
AliInfo(Form("\n+++\n+++ Number of candidates ---> %d\n+++\n ", ncand));
}
// Assignment operator
//
if (this!=&c) {
- for (Int_t i=0; i<20; ++i) fParamStartValues[i]=c.fParamStartValues[i];
fIsParamFixed = c.fIsParamFixed;
fPrintStatus = c.fPrintStatus;
fUp = c.fUp;
fX = c.fX;
fM = c.fM;
- fLikely = c.fLikely;
+ fType = c.fType;
+ fLikely = c.fLikely;
fNcand = c.fNcand;
+ fContPlot1 = c.fContPlot1;
+ fContPlot2 = c.fContPlot2;
+ fContPlot3 = c.fContPlot3;
}
return *this;
}
fUp(c.fUp),
fX(c.fX),
fM(c.fM),
- fLikely(c.fLikely),
- fNcand(c.fNcand)
+ fType(c.fType),
+ fLikely(c.fLikely),
+ fNcand(c.fNcand),
+ fContPlot1(c.fContPlot1),
+ fContPlot2(c.fContPlot2),
+ fContPlot3(c.fContPlot3),
+ fitter(c.fitter)
{
//
// Copy Constructor
//
- for (Int_t i=0; i<20; ++i) fParamStartValues[i]=c.fParamStartValues[i];
}
//_______________________________________________________________________________________
AliDielectronBtoJPSItoEleCDFfitHandler::~AliDielectronBtoJPSItoEleCDFfitHandler()
delete fLikely;
}
//_______________________________________________________________________________________
-Int_t AliDielectronBtoJPSItoEleCDFfitHandler::DoMinimization()
+Int_t AliDielectronBtoJPSItoEleCDFfitHandler::DoMinimization(Int_t step)
{
//
// performs the minimization
//
- static TVirtualFitter *fitter = TVirtualFitter::Fitter(this,20);
- fitter->SetFCN(CDFFunction);
-
- fitter->SetParameter(0,"fWeightRes",fParamStartValues[0], 1.e-08, 0., 1.e+06);
- fitter->SetParameter(1,"fPos",fParamStartValues[1], 1.e-08, 0.,1.e+06);
- fitter->SetParameter(2,"fNeg",fParamStartValues[2], 1.e-08, 0.,1.e+06);
- fitter->SetParameter(3,"fSym",fParamStartValues[3], 1.e-08, 0.,1.e+06);
- fitter->SetParameter(4,"fOneOvLamPlus",fParamStartValues[4], 1.e-10, 0.0000001, 5.e+01);
- fitter->SetParameter(5,"fOneOvLamMinus",fParamStartValues[5], 1.e-10, 0.00000001, 5.e+01);
- fitter->SetParameter(6,"fOneOvLamSym",fParamStartValues[6], 1.e-10, 0.00000001, 5.e+01);
- fitter->SetParameter(7,"fB",fParamStartValues[7], 1.e-10, 0., 1.);
- fitter->SetParameter(8,"fFsig",fParamStartValues[8], 1.e-10, 0., 1.);
- fitter->SetParameter(9,"fMmean",fParamStartValues[9], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(10,"fNexp",fParamStartValues[10], 1.e-08, 0., 1.e+02);
- fitter->SetParameter(11,"fSigma",fParamStartValues[11], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(12,"fAlpha",fParamStartValues[12], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(13,"fNorm",fParamStartValues[13], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(14,"fBkgNorm",fParamStartValues[14], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(15,"fBkgMean",fParamStartValues[15], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(16,"fBkgSlope",fParamStartValues[16], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(17,"fBkgSlope",fParamStartValues[17], 1.e-08, 0., 1.e+04);
- fitter->SetParameter(18,"fNormGaus1",fParamStartValues[18], 1.e-08, 0., 1.e+05);
- fitter->SetParameter(19,"fNormGaus2",fParamStartValues[19], 1.e-08, 0., 1.e+05);
-
- for(UInt_t indexparam = 0; indexparam < 20; indexparam++){
- if(IsParamFixed(indexparam))fitter->FixParameter((Int_t)indexparam);
- }
+ if(step == 0){
+ //fitter = TVirtualFitter::Fitter(this,20);
+ fitter = (TFitter*)TVirtualFitter::Fitter(this,45);
+ fitter->SetFCN(CDFFunction);
+ fitter->SetParameter(0,"fWeightRes",fParamStartValues[0], 1.e-08, 0., 1.e+06);
+ fitter->SetParameter(1,"fPos",fParamStartValues[1], 1.e-08, 0.,1.e+06);
+ fitter->SetParameter(2,"fNeg",fParamStartValues[2], 1.e-08, 0.,1.e+06);
+ fitter->SetParameter(3,"fSym",fParamStartValues[3], 1.e-08, 0.,1.e+06);
+ fitter->SetParameter(4,"fOneOvLamPlus",fParamStartValues[4], 1.e-10, 0.0000001, 5.e+01);
+ fitter->SetParameter(5,"fOneOvLamMinus",fParamStartValues[5], 1.e-10, 0.00000001, 5.e+01);
+ fitter->SetParameter(6,"fOneOvLamSym",fParamStartValues[6], 1.e-10, 0.00000001, 5.e+01);
+ fitter->SetParameter(7,"fB",fParamStartValues[7], 1.e-10, 0., 1.);
+ fitter->SetParameter(8,"fFsig",fParamStartValues[8], 1.e-10, 0., 1.);
+ fitter->SetParameter(9,"fMmean",fParamStartValues[9], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(10,"fNexp",fParamStartValues[10], 1.e-08, 0., 1.e+02);
+ fitter->SetParameter(11,"fSigma",fParamStartValues[11], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(12,"fAlpha",fParamStartValues[12], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(13,"fNorm",fParamStartValues[13], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(14,"fBkgNorm",fParamStartValues[14], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(15,"fBkgMean",fParamStartValues[15], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(16,"fBkgSlope",fParamStartValues[16], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(17,"fBkgConst",fParamStartValues[17], 1.e-08, 0., 1.e+04);
+ fitter->SetParameter(18,"fNormGaus1FF",fParamStartValues[18], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(19,"fNormGaus2FF",fParamStartValues[19], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(20,"fMean1ResFF",fParamStartValues[20], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(21,"fSigma1ResFF",fParamStartValues[21], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(22,"fMean2ResFF",fParamStartValues[22], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(23,"fSigma2ResFF",fParamStartValues[23], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(24,"fAlfaResFF",fParamStartValues[24], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(25,"fLambdaResFF",fParamStartValues[25], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(26,"fResNormExpFF",fParamStartValues[26], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(27,"fNormGaus1FS",fParamStartValues[27], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(28,"fNormGaus2FS",fParamStartValues[28], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(29,"fMean1ResFS",fParamStartValues[29], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(30,"fSigma1ResFS",fParamStartValues[30], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(31,"fMean2ResFS",fParamStartValues[31], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(32,"fSigma2ResFS",fParamStartValues[32], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(33,"fAlfaResFS",fParamStartValues[33], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(34,"fLambdaResFS",fParamStartValues[34], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(35,"fResNormExpFS",fParamStartValues[35], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(36,"fNormGaus1SS",fParamStartValues[36], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(37,"fNormGaus2SS",fParamStartValues[37], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(38,"fMean1ResSS",fParamStartValues[38], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(39,"fSigma1ResSS",fParamStartValues[39], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(40,"fMean2ResSS",fParamStartValues[40], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(41,"fSigma2ResSS",fParamStartValues[41], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(42,"fAlfaResSS",fParamStartValues[42], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(43,"fLambdaResSS",fParamStartValues[43], 1.e-08, 0., 1.e+05);
+ fitter->SetParameter(44,"fResNormExpSS",fParamStartValues[44], 1.e-08, 0., 1.e+05);
+ }
- Double_t arglist[2]={10000,1.0};
+ for(UInt_t indexparam = 0; indexparam < 45; indexparam++){
+ if(IsParamFixed(indexparam)) fitter->FixParameter((Int_t)indexparam);
+ else fitter->ReleaseParameter((Int_t)indexparam);
+ }
+ Double_t arglist[2]={10000,0.1};
+ if(step == 2) {Int_t iret1 = fitter->ExecuteCommand("MINOS", arglist ,1); return iret1;}
Int_t iret=fitter->ExecuteCommand("MIGRAD", arglist ,2);
fitter->PrintResults(4,0);
- AliInfo("Minimization procedure finished\n");
+ if(step == 3) {
+
+ TMinuit* minuitPoint = fitter->GetMinuit();
+ TCanvas *c2 = new TCanvas("c2","contours",800,800);
+
+ //68.27% (1 sigma) confidence level for 2 parameters (fSIG versus fB)
+ minuitPoint->SetErrorDef(1.15); // 2.3/2
+ fContPlot1 = (TGraph*)minuitPoint->Contour(100,7,8);
+ fContPlot1->GetXaxis()->SetRange(0,1);
+ fContPlot1->GetYaxis()->SetRange(0,1);
+ fContPlot1->SetLineColor(42);
+ fContPlot1->SetLineWidth(3);
+
+ //95% (2 sigma) confidence level for 2 parameters (fSIG versus fB)
+ minuitPoint->SetErrorDef(2.995); // 5.99/2
+ fContPlot2 = (TGraph*)minuitPoint->Contour(100,7,8);
+ fContPlot2->GetXaxis()->SetRange(0,1);
+ fContPlot2->GetYaxis()->SetRange(0,1);
+ fContPlot2->SetLineColor(38);
+ fContPlot2->SetLineWidth(3);
+
+ //99.73% (3 sigma) confidence level for 2 parameters (fSIG versus fB)
+ minuitPoint->SetErrorDef(5.915); // 11.83/2
+ fContPlot3 = (TGraph*)minuitPoint->Contour(100,7,8);
+ fContPlot3->GetXaxis()->SetRange(0,1);
+ fContPlot3->GetXaxis()->SetTitle("f_{B}");
+ fContPlot3->GetYaxis()->SetTitle("f_{Sig}[2.4-4]");
+ fContPlot3->GetYaxis()->SetRange(0,1);
+ fContPlot3->SetLineColor(34);
+ fContPlot3->SetLineWidth(3);
+
+ fContPlot3->Draw("al");
+ fContPlot2->Draw("l");
+ fContPlot1->Draw("l");
+
+ c2->Draw();
+ }
+
+ AliInfo("Minimization procedure finished\n");
return iret;
}
//_______________________________________________________________________________________
TStopwatch t;
t.Start();
- f = fLikely->EvaluateLikelihood(fX,fM,fNcand);
+ f = fLikely->EvaluateLikelihood(fX,fM,fType,fNcand);
t.Stop();
AliDebug(2,Form("Real time spent to calculate function == %f \n", t.RealTime()));
return;
}
//_______________________________________________________________________________________
-void AliDielectronBtoJPSItoEleCDFfitHandler::SetParamStartValues(Double_t inputparamvalues[20])
+void AliDielectronBtoJPSItoEleCDFfitHandler::SetParamStartValues(Double_t inputparamvalues[45])
{
- for(Int_t index=0; index < 20; index++) fParamStartValues[index] = inputparamvalues[index];
+ for(Int_t index=0; index < 45; index++) fParamStartValues[index] = inputparamvalues[index];
}
//_______________________________________________________________________________________
-void AliDielectronBtoJPSItoEleCDFfitHandler::SetResolutionConstants(Double_t* resolutionConst)
+void AliDielectronBtoJPSItoEleCDFfitHandler::SetResolutionConstants(Double_t* resolutionConst, Int_t type)
{
//
// Sets constants for the resolution function
//
- fLikely->SetResolutionConstants(resolutionConst);
+ fLikely->SetResolutionConstants(resolutionConst,type);
}
//_______________________________________________________________________________________
\r
#include <TNamed.h>\r
#include <TBits.h>\r
+#include <TGraph.h>\r
+#include <TFitter.h>\r
\r
-class AliDielectronBtoJPSItoEleCDFfitFCN;\r
+class AliDielectronBtoJPSItoEleCDFfitFCN ;\r
\r
class AliDielectronBtoJPSItoEleCDFfitHandler : public TNamed {\r
public:\r
AliDielectronBtoJPSItoEleCDFfitHandler();\r
AliDielectronBtoJPSItoEleCDFfitHandler& operator= (const AliDielectronBtoJPSItoEleCDFfitHandler& c);\r
AliDielectronBtoJPSItoEleCDFfitHandler(const AliDielectronBtoJPSItoEleCDFfitHandler& c);\r
- AliDielectronBtoJPSItoEleCDFfitHandler(Double_t* decaytime, Double_t* invariantmass, Int_t ncand);\r
+ AliDielectronBtoJPSItoEleCDFfitHandler(Double_t* decaytime, Double_t* invariantmass, Int_t *type, Int_t ncand);\r
~AliDielectronBtoJPSItoEleCDFfitHandler(); \r
Double_t Up() const { return fUp; }\r
void SetErrorDef(Double_t up) {fUp = up;}\r
void SetParamStartValues (Double_t*);\r
Double_t* GetStartParamValues() { return fParamStartValues; }\r
TBits GetFixedParamList() const { return fIsParamFixed; }\r
- void FixParam(UInt_t param, Bool_t value) { fIsParamFixed.SetBitNumber(param,value); }\r
- void FixAllParam(Bool_t value) { for(UInt_t par=0;par<20;par++) fIsParamFixed.SetBitNumber(par,value); }\r
+ TFitter *GetFitter() const {return fitter;}\r
+ Double_t GetParameter(Int_t numPar) const {return fitter->GetParameter(numPar);}\r
+ Double_t GetParameterError(Int_t numPar) const {return fitter->GetParError(numPar);} \r
+\r
+ void FixParam(UInt_t param, Bool_t value) { fIsParamFixed.SetBitNumber(param,value); }\r
+ void FixAllParam(Bool_t value) { for(UInt_t par=0;par<45;par++) fIsParamFixed.SetBitNumber(par,value); }\r
Bool_t IsParamFixed(UInt_t param) { return fIsParamFixed.TestBitNumber(param); }\r
- void SetResolutionConstants(Double_t* resolutionConst);\r
+ void SetResolutionConstants(Double_t* resolutionConst, Int_t type);\r
void SetCrystalBallFunction(Bool_t okCB);\r
void SetMassWndHigh(Double_t limit);\r
void SetMassWndLow(Double_t limit);\r
\r
Double_t* Decaytime() const { return fX; }\r
Double_t* InvariantMass() const { return fM; }\r
- AliDielectronBtoJPSItoEleCDFfitFCN* LikelihoodPointer() const { return fLikely; }\r
- Int_t DoMinimization();\r
+ Int_t* TypeCand() const { return fType;}\r
+ AliDielectronBtoJPSItoEleCDFfitFCN* LikelihoodPointer() const { return fLikely; }\r
+ Int_t DoMinimization(Int_t step = 0);\r
+ \r
\r
private:\r
//\r
TBits fIsParamFixed; //array of bits: 0 = param free; 1 = param fixed;\r
Bool_t fPrintStatus; //flag to enable the prit out of the algorithm at each step\r
- Double_t fParamStartValues[20]; //array of parameters input value\r
+ Double_t fParamStartValues[45]; //array of parameters input value\r
Double_t fUp; //error definition \r
- Double_t* fX; //pseudo-proper decay time X\r
+ Double_t* fX; //pseudo-proper decay time X\r
Double_t* fM; //invariant mass M\r
- AliDielectronBtoJPSItoEleCDFfitFCN* fLikely; //Log likelihood function\r
+ Int_t* fType; //candidate type\r
+ AliDielectronBtoJPSItoEleCDFfitFCN* fLikely; //Log likelihood function\r
Int_t fNcand; //number of candidates\r
+ TGraph* fContPlot1; //contour plot \r
+ TGraph* fContPlot2; //contour plot \r
+ TGraph* fContPlot3; //contour plot \r
+ TFitter *fitter; //pointer to TFitter object \r
//\r
ClassDef(AliDielectronBtoJPSItoEleCDFfitHandler,1);\r
\r
+
/*************************************************************************
* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
* *
fStepsForCutsIncreasing(kFALSE),
fStepsForSignal(kTRUE),
fStepsForBackground(kFALSE),
+ fStepsForMCtruthOnly(kFALSE),
fNStepMasks(0),
fPdgMother(-1),
fSignalsMC(0x0),
fStepsForCutsIncreasing(kFALSE),
fStepsForSignal(kTRUE),
fStepsForBackground(kFALSE),
+ fStepsForMCtruthOnly(kFALSE),
fNStepMasks(0),
fPdgMother(-1),
fSignalsMC(0x0),
if (fHasMC){
if (fStepsForSignal && fSignalsMC) fNAddSteps+=fSignalsMC->GetEntries();
if (fStepsForBackground) ++fNAddSteps;
+ if (fStepsForMCtruthOnly) --fNAddSteps; // No Step for Pair information
} else {
//if
fStepForMCtruth=kFALSE;
fStepsForSignal=kFALSE;
fStepsForBackground=kFALSE;
}
-
+ // consitency checks to not duplicate steps
+ if (fStepsForCutsIncreasing) fStepForAfterAllCuts=kFALSE;
+ if (fStepsForEachCut&&fNCuts==1) fStepForAfterAllCuts=kFALSE;
+
fNSteps=0;
- if (fStepForMCtruth && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
+ if (fStepForMCtruth && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
if (fStepForNoCutsMCmotherPid && fSignalsMC) fNSteps+=fSignalsMC->GetEntries();
- if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
-
- if (fStepsForEachCut&&fNCuts>1) fNSteps+=(fNAddSteps*fNCuts); //one step for each cut + Signal (MC)
- if (fStepsForCutsIncreasing&&fNCuts>2) fNSteps+=(fNAddSteps*(fNCuts-2)); //one step for the increasing cuts + Signal (MC)
- // e.g. cut2&cut3, cut2&cut3&cut4
- fNSteps+=(fNAddSteps*fNStepMasks); // cuts for the additional cut masks
+ if (fStepForAfterAllCuts) fNSteps+=fNAddSteps;
+
+ if (fStepsForEachCut) fNSteps+=(fNAddSteps*fNCuts); //one step for each cut + Signal (MC)
+ if (fStepsForCutsIncreasing) fNSteps+=(fNAddSteps*fNCuts); //one step for the increasing cuts + Signal (MC)
+ // e.g. cut1, cut1&cut2, cut1&cut2&cut3, ...
+
+ fNSteps+=(fNAddSteps*fNStepMasks); // cuts for the additional cut masks
if (fStepForPreFilter) fNSteps+=fNAddSteps; //Add at the end for Prefilter (maxcutmask+1)
-
+
// create the container
Int_t *nbins=new Int_t[fNVars+2*fNVarsLeg];
TString cutName;
//Steps for each of the cuts
- if (fStepsForEachCut&&fNCuts>1){
+ if (fStepsForEachCut){
for (Int_t iCut=0; iCut<fNCuts;++iCut) {
cutName=filter.GetCuts()->At(iCut)->GetName(); //TODO: User GetTitle???
-
- fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
-
+ if (!fStepsForMCtruthOnly) {
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ }
if (fHasMC){
- if (fStepsForSignal && fSignalsMC) {
- for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
- fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
- }
- }
- if (fStepsForBackground)
+ if (fStepsForSignal && fSignalsMC) {
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
+ fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
+ }
+ }
+ if (fStepsForBackground)
fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
}
}
}
//Steps for increasing cut match
- if (fStepsForCutsIncreasing&&fNCuts>2){
- cutName=filter.GetCuts()->At(0)->GetName(); //TODO: User GetTitle???
- for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
- cutName+="&";
+ if (fStepsForCutsIncreasing){
+ cutName=""; //TODO: User GetTitle???
+ for (Int_t iCut=0; iCut<fNCuts;++iCut) {
+ if (!cutName.IsNull()) cutName+="&";
cutName+=filter.GetCuts()->At(iCut)->GetName();
-
- fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
-
+ if (!fStepsForMCtruthOnly) {
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ }
if (fHasMC){
- if (fStepsForSignal && fSignalsMC)
- for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
- fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
- }
- if (fStepsForBackground)
- fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
+ if (fStepsForSignal && fSignalsMC)
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
+ fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
+ }
+ if (fStepsForBackground)
+ fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
}
}
}
if (fHasMC){
if (fStepsForSignal && fSignalsMC)
- for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
- fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
- }
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
+ fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
+ }
if (fStepsForBackground)
fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
}
cutName+=filter.GetCuts()->At(iCut)->GetName();
}
}
- fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ if (!fStepsForMCtruthOnly) {
+ fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
+ }
if (fHasMC){
if (fStepsForSignal && fSignalsMC)
- for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
- fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
- }
- if (fStepsForBackground)
- fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
+ fCfContainer->SetStepTitle(step++, Form("%s (Signal: %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
+ }
+ if (fStepsForBackground)
+ fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
}
}
fCfContainer->SetStepTitle(step++, cutName.Data()); //Step for the cut
if (fHasMC){
if (fStepsForSignal && fSignalsMC)
- for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
- fCfContainer->SetStepTitle(step++, Form("%s (Signal %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
- }
- if (fStepsForBackground)
- fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) {
+ fCfContainer->SetStepTitle(step++, Form("%s (Signal %s)", cutName.Data(), fSignalsMC->At(i)->GetTitle())); //Step for the cut with MC truth
+ }
+ if (fStepsForBackground)
+ fCfContainer->SetStepTitle(step++, (cutName+" (Background)").Data()); //Step for the cut with MC truth
}
}
for(Int_t i=0; i<fSignalsMC->GetEntries(); i++) isMCTruth[i]=kFALSE;
}
+ //TODO: for the moment don't fill truth information for mixed event paris. No valid MC info is available
+ // in the mixing handler
+ Bool_t isMixedPair=(particle->GetType()>2&&particle->GetType()<10);
+
Bool_t isBackground = kFALSE;
- if(fHasMC && isMCTruth) {
+ if(fHasMC && isMCTruth && !isMixedPair) {
for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
isMCTruth[i] = AliDielectronMC::Instance()->IsMCTruth(particle, (AliDielectronSignalMC*)fSignalsMC->At(i));
isBackground = (isBackground || isMCTruth[i]);
}
if (fNVarsLeg>0){
- Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues];
+ Double_t valuesLeg1[AliDielectronVarManager::kNMaxValues]={0};
AliDielectronVarManager::Fill(particle->GetFirstDaughter(),valuesLeg1);
- Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues];
+ Double_t valuesLeg2[AliDielectronVarManager::kNMaxValues]={0};
AliDielectronVarManager::Fill(particle->GetSecondDaughter(),valuesLeg2);
for (Int_t iVar=0; iVar<fNVarsLeg; ++iVar){
if (fStepForNoCutsMCmotherPid && isMCTruth){
for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
if(isMCTruth[i]) {
- fCfContainer->Fill(fValues,step);
+ fCfContainer->Fill(fValues,step);
}
++step;
}
}
//Steps for each of the cuts
- if (fStepsForEachCut&&fNCuts>1){
+ if (fStepsForEachCut){
for (Int_t iCut=0; iCut<fNCuts;++iCut) {
- if (mask&(1<<iCut)) {
- fCfContainer->Fill(fValues,step);
- ++step;
-
+ UInt_t cutMask=1<<iCut;
+ if ((mask&cutMask)==cutMask) {
+ if(!fStepsForMCtruthOnly) {
+ fCfContainer->Fill(fValues,step);
+ ++step;
+ }
if (fHasMC){
if ( fStepsForSignal && isMCTruth){
- for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
- if(isMCTruth[i]) {
- fCfContainer->Fill(fValues,step);
- }
- ++step;
- }
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
+ if(isMCTruth[i]) {
+ fCfContainer->Fill(fValues,step);
+ }
+ ++step;
+ }
}
if ( fStepsForBackground ){
if (isBackground) fCfContainer->Fill(fValues,step);
}
}
}
-
+
//Steps for increasing cut match
if (fStepsForCutsIncreasing&&fNCuts>2){
- for (Int_t iCut=1; iCut<fNCuts-1;++iCut) {
- if (mask&(1<<((iCut+1)-1))) {
- fCfContainer->Fill(fValues,step);
- ++step;
-
+ for (Int_t iCut=0; iCut<fNCuts;++iCut) {
+ UInt_t cutMask=(1<<(iCut+1))-1;
+ if ((mask&cutMask)==cutMask) {
+ if(!fStepsForMCtruthOnly) {
+ fCfContainer->Fill(fValues,step);
+ ++step;
+ }
+
if (fHasMC){
- if ( fStepsForSignal && isMCTruth){
- for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
- if(isMCTruth[i]) {
- fCfContainer->Fill(fValues,step);
- }
- ++step;
- }
+ if ( fStepsForSignal && isMCTruth){
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
+ if(isMCTruth[i]) {
+ fCfContainer->Fill(fValues,step);
+ }
+ ++step;
+ }
}
if ( fStepsForBackground ){
if (isBackground) fCfContainer->Fill(fValues,step);
//Steps of user defined cut combinations
for (UInt_t iComb=0; iComb<fNStepMasks; ++iComb){
UInt_t userMask=fStepMasks[iComb];
- if (mask&userMask) {
- fCfContainer->Fill(fValues,step);
- ++step;
-
+ if ((mask&userMask)==userMask) {
+ if(!fStepsForMCtruthOnly) {
+ fCfContainer->Fill(fValues,step);
+ ++step;
+ }
if (fHasMC){
if ( fStepsForSignal && isMCTruth){
- for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
- if(isMCTruth[i]) {
- fCfContainer->Fill(fValues,step);
- }
- ++step;
- }
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
+ if(isMCTruth[i]) {
+ fCfContainer->Fill(fValues,step);
+ }
+ ++step;
+ }
}
if ( fStepsForBackground ){
if (isBackground) fCfContainer->Fill(fValues,step);
//All cuts
if (fStepForAfterAllCuts){
if (mask == selectedMask){
- fCfContainer->Fill(fValues,step);
- ++step;
-
+ if(!fStepsForMCtruthOnly) {
+ fCfContainer->Fill(fValues,step);
+ ++step;
+ }
+
if (fHasMC){
if ( fStepsForSignal && isMCTruth){
- for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
- if(isMCTruth[i]) {
- fCfContainer->Fill(fValues,step);
- }
- ++step;
- }
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
+ if(isMCTruth[i]) {
+ fCfContainer->Fill(fValues,step);
+ }
+ ++step;
+ }
}
if ( fStepsForBackground ){
if (isBackground) fCfContainer->Fill(fValues,step);
step+=fNAddSteps;
}
}
+
+ //prefilter
if (fStepForPreFilter) {
- if (mask&(1<<fNCuts)) {
- fCfContainer->Fill(fValues,step);
- ++step;
-
- if (fHasMC){
- if ( fStepsForSignal && isMCTruth){
- for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
- if(isMCTruth[i]) {
- fCfContainer->Fill(fValues,step);
- }
- ++step;
- }
- }
- if ( fStepsForBackground ){
- if (isBackground) fCfContainer->Fill(fValues,step);
- ++step;
- }
- }
- }
- else {
- step+=fNAddSteps;
- }
- }
+ if (mask&(1<<fNCuts)) {
+ if(!fStepsForMCtruthOnly) {
+ fCfContainer->Fill(fValues,step);
+ ++step;
+ }
+ if (fHasMC){
+ if ( fStepsForSignal && isMCTruth){
+ for(Int_t i=0; i<fSignalsMC->GetEntries(); ++i) {
+ if(isMCTruth[i]) {
+ fCfContainer->Fill(fValues,step);
+ }
+ ++step;
+ }
+ }
+ if ( fStepsForBackground ){
+ if (isBackground) fCfContainer->Fill(fValues,step);
+ ++step;
+ }
+ }
+ }
+ else {
+ step+=fNAddSteps;
+ }
+ }
+
if (step!=fNSteps) {
AliError("Something went wrong in the step filling!!!");
}
- if(isMCTruth) delete [] isMCTruth;
+ if(isMCTruth) delete [] isMCTruth;
}
//________________________________________________________________
AliVParticle *d2=0x0;
AliDielectronMC::Instance()->GetDaughters(particle,d1,d2);
- valuesPair[AliDielectronVarManager::kThetaHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kTRUE);
- valuesPair[AliDielectronVarManager::kPhiHE]=AliDielectronPair::ThetaPhiCM(d1,d2,kTRUE,kFALSE);
- valuesPair[AliDielectronVarManager::kThetaCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kTRUE);
- valuesPair[AliDielectronVarManager::kPhiCS]=AliDielectronPair::ThetaPhiCM(d1,d2,kFALSE,kFALSE);
-
//TODO: temporary solution, set manually the pair type to 1: unlikesign SE
valuesPair[AliDielectronVarManager::kPairType]=1;
}
Double_t valuesPair[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(dieMC->GetMCEvent(), valuesPair);
AliDielectronVarManager::FillVarMCParticle2(part1,part2,valuesPair);
- valuesPair[AliDielectronVarManager::kThetaHE]=AliDielectronPair::ThetaPhiCM(part1,part2,kTRUE,kTRUE);
- valuesPair[AliDielectronVarManager::kPhiHE]=AliDielectronPair::ThetaPhiCM(part1,part2,kTRUE,kFALSE);
- valuesPair[AliDielectronVarManager::kThetaCS]=AliDielectronPair::ThetaPhiCM(part1,part2,kFALSE,kTRUE);
- valuesPair[AliDielectronVarManager::kPhiCS]=AliDielectronPair::ThetaPhiCM(part1,part2,kFALSE,kFALSE);
-
if(part1->Charge()*part2->Charge()<0)
valuesPair[AliDielectronVarManager::kPairType]=1;
else if(part1->Charge()>0)
valuesPair[AliDielectronVarManager::kPairType]=0;
else
- valuesPair[AliDielectronVarManager::kPairType]=2;
+ valuesPair[AliDielectronVarManager::kPairType]=2; // if one of the two particles is neutral, the pair will go here
for(Int_t iVar=0; iVar<fNVars; ++iVar){
Int_t var=fVariables[iVar];
void SetStepsForCutsIncreasing(Bool_t steps=kTRUE) { fStepsForCutsIncreasing=steps; }
void SetStepsForSignal(Bool_t steps=kTRUE) { fStepsForSignal=steps; }
void SetStepsForBackground(Bool_t steps=kTRUE) { fStepsForBackground=steps; }
+ void SetStepsForMCtruthOnly(Bool_t steps=kTRUE) { fStepsForMCtruthOnly=steps; }
void SetPdgMother(Int_t pdg) { fPdgMother=pdg; }
void SetSignalsMC(TObjArray* array) {fSignalsMC = array;}
void AddVariable(AliDielectronVarManager::ValueTypes type, TVectorD *binLimits, Bool_t leg=kFALSE);
void InitialiseContainer(const AliAnalysisFilter& filter);
-
+
+ Int_t GetNvarsPair() const {return fNVars;}
+ Int_t GetNvarsLeg() const {return fNVarsLeg;}
+
+ UInt_t GetVariablePair(UInt_t var) const {return (var>(UInt_t)AliDielectronVarManager::kNMaxValues)? (UInt_t)AliDielectronVarManager::kNMaxValues+1:fVariables[var];}
+ UInt_t GetVariableLeg(UInt_t var) const {return (var>(UInt_t)AliDielectronVarManager::kNMaxValues)? (UInt_t)AliDielectronVarManager::kNMaxValues+1:fVariablesLeg[var];}
+
// void Fill(UInt_t mask, const TObject *particle);
void Fill(UInt_t mask, const AliDielectronPair *particle);
void FillMC(const TObject *particle);
//e.g. cut1&cut2, cut1&cut2&cut3 ...
Bool_t fStepsForSignal; //steps for pure signal
Bool_t fStepsForBackground; //steps for pure background
+ Bool_t fStepsForMCtruthOnly; //Switch off all pair steps, allow only MC truth Class
UInt_t fStepMasks[kNmaxAddSteps]; //steps for additional cut combinatons
UInt_t fNStepMasks; //number of configured step masks
delete arrVars;
return 0x0;
}
-
+
+ TIter next(arrVars);
TObjString *ostr=0x0;
Int_t ivar[3]={-1,-1,-1};
for (Int_t i=entries-1; i>=0; --i){
- ostr=static_cast<TObjString*>(arrVars->At(i));
+ ostr=static_cast<TObjString*>(next());
if (ostr->GetString().IsDigit()){
ivar[i]=ostr->GetString().Atoi();
} else {
TIter next(arrVars);
TObjString *ostr=0x0;
Int_t ivar[3]={-1,-1,-1};
- for (Int_t i=0; i<entries; ++i){
+ for (Int_t i=entries-1; i>=0; --i){
ostr=static_cast<TObjString*>(next());
if (ostr->GetString().IsDigit()){
ivar[i]=ostr->GetString().Atoi();
TString optStr(opt);
if (optStr.Contains("2")) type=1;
- DrawEfficiency(ivar[2],ivar[1],ivar[0],numerators, denominator,opt,type);
+ DrawEfficiency(ivar[0],ivar[1],ivar[2],numerators, denominator,opt,type);
delete arrVars;
}
void UnsetRangeUser(const char* varname, const char* slices="");
virtual void Draw(const Option_t* varnames = "") { Draw(varnames,"");}
+ virtual void Print(const Option_t*) const { if (fCfContainer) fCfContainer->Print(""); }
//Draw Projections
void Draw(const Option_t* varnames, const char* opt, const char* slices="");
void Draw(Int_t var, const char* opt="", const char* slices="");
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Dielectron Event //
+// //
+// //
+/*
+Detailed description
+
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TObjArray.h>
+
+#include <AliVTrack.h>
+#include <AliESDtrack.h>
+#include <AliAODTrack.h>
+
+#include "AliDielectronEvent.h"
+
+ClassImp(AliDielectronEvent)
+
+AliDielectronEvent::AliDielectronEvent() :
+ TNamed(),
+ fArrTrackP("AliESDtrack",1000),
+ fArrTrackN("AliESDtrack",1000),
+ fArrPairs("AliKFParticle",0),
+ fNTracksP(0),
+ fNTracksN(0),
+ fIsAOD(kFALSE),
+ fEventData()
+{
+ //
+ // Default Constructor
+ //
+
+}
+
+//______________________________________________
+AliDielectronEvent::AliDielectronEvent(const char* name, const char* title) :
+ TNamed(name, title),
+ fArrTrackP("AliESDtrack",1000),
+ fArrTrackN("AliESDtrack",1000),
+ fArrPairs("AliKFParticle",0),
+ fNTracksP(0),
+ fNTracksN(0),
+ fIsAOD(kFALSE),
+ fEventData()
+{
+ //
+ // Named Constructor
+ //
+}
+
+//______________________________________________
+AliDielectronEvent::~AliDielectronEvent()
+{
+ //
+ // Default Destructor
+ //
+ fArrTrackP.Delete();
+ fArrTrackN.Delete();
+ fArrPairs.Delete();
+}
+
+//______________________________________________
+void AliDielectronEvent::SetTracks(const TObjArray &arrP, const TObjArray &arrN, const TObjArray &/*arrPairs*/)
+{
+ //
+ // Setup AliKFParticles
+ // assumes that the objects in arrP and arrN are AliVTracks
+ //
+
+ //Clear out old entries before filling new ones
+ Clear();
+ // we keep the tracks buffered to minimise new / delete operations
+ fNTracksN=0;
+ fNTracksP=0;
+
+ //check size of the arrays
+ if (fArrTrackP.GetSize()<arrP.GetSize()) fArrTrackP.Expand(arrP.GetSize());
+ if (fArrTrackN.GetSize()<arrN.GetSize()) fArrTrackN.Expand(arrN.GetSize());
+
+ // fill particles
+ Int_t tracks=0;
+ for (Int_t itrack=0; itrack<arrP.GetEntriesFast(); ++itrack){
+ if (!fIsAOD){
+ AliESDtrack *track=dynamic_cast<AliESDtrack*>(arrP.At(itrack));
+ if (!track) continue;
+ new (fArrTrackP[tracks]) AliESDtrack(*track);
+ ++tracks;
+ } else {
+ AliAODTrack *track=dynamic_cast<AliAODTrack*>(arrP.At(itrack));
+ if (!track) continue;
+ new (fArrTrackP[tracks]) AliAODTrack(*track);
+ ++tracks;
+ }
+ }
+ fNTracksP=tracks;
+
+ tracks=0;
+ for (Int_t itrack=0; itrack<arrN.GetEntriesFast(); ++itrack){
+ if (!fIsAOD){
+ AliESDtrack *track=dynamic_cast<AliESDtrack*>(arrN.At(itrack));
+ if (!track) continue;
+ new (fArrTrackN[tracks]) AliESDtrack(*track);
+ ++tracks;
+ } else {
+ AliAODTrack *track=dynamic_cast<AliAODTrack*>(arrN.At(itrack));
+ if (!track) continue;
+ new (fArrTrackN[tracks]) AliAODTrack(*track);
+ ++tracks;
+ }
+ }
+ fNTracksN=tracks;
+
+ //TODO: pair arrays
+}
+
+//______________________________________________
+void AliDielectronEvent::Clear(Option_t *opt)
+{
+ //
+ // clear arrays
+ //
+// fArrTrackP.Clear(opt);
+// fArrTrackN.Clear(opt);
+
+ for (Int_t i=fArrTrackP.GetEntriesFast()-1; i>=0; --i){
+ delete fArrTrackP.RemoveAt(i);
+ }
+
+ for (Int_t i=fArrTrackN.GetEntriesFast()-1; i>=0; --i){
+ delete fArrTrackN.RemoveAt(i);
+ }
+
+ fArrPairs.Clear(opt);
+
+}
+
+//______________________________________________
+void AliDielectronEvent::SetAOD()
+{
+ //
+ // use AOD as input
+ //
+ fArrTrackP.SetClass("AliAODTrack");
+ fArrTrackN.SetClass("AliAODTrack");
+ fIsAOD=kTRUE;
+}
+
+//______________________________________________
+void AliDielectronEvent::SetEventData(const Double_t data[AliDielectronVarManager::kNMaxValues])
+{
+ //
+ // copy only evnet variables
+ //
+ for (Int_t i=AliDielectronVarManager::kPairMax; i<AliDielectronVarManager::kNMaxValues;++i) fEventData[i]=data[i];
+}
\ No newline at end of file
--- /dev/null
+#ifndef ALIDIELECTRONEVENT_H
+#define ALIDIELECTRONEVENT_H
+
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# Class AliDielectronEvent #
+//# #
+//# Authors: #
+//# Jens Wiechula, Uni Tübingen / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+#include <TNamed.h>
+#include <TClonesArray.h>
+
+#include "AliDielectronVarManager.h"
+
+
+class TObjArray;
+
+class AliDielectronEvent : public TNamed {
+public:
+ AliDielectronEvent();
+ AliDielectronEvent(const char*name, const char* title);
+
+ virtual ~AliDielectronEvent();
+
+ void SetAOD();
+
+ void SetTracks(const TObjArray &arrP, const TObjArray &arrN, const TObjArray &arrPairs);
+ void SetEventData(const Double_t data[AliDielectronVarManager::kNMaxValues]);
+ const Double_t* GetEventData() const {return fEventData;}
+
+
+ const TClonesArray* GetTrackArrayP() const { return &fArrTrackP; }
+ const TClonesArray* GetTrackArrayN() const { return &fArrTrackN; }
+
+ Int_t GetNTracksP() const { return fNTracksP; }
+ Int_t GetNTracksN() const { return fNTracksN; }
+
+virtual void Clear(Option_t *opt="C");
+
+
+private:
+ TClonesArray fArrTrackP; //positive tracks
+ TClonesArray fArrTrackN; //negative tracks
+
+ TClonesArray fArrPairs; //Pair array
+
+ Int_t fNTracksP; //number of positive tracks
+ Int_t fNTracksN; //number of negative tracks
+
+ Bool_t fIsAOD; // if we deal with AODs
+
+ Double_t fEventData[AliDielectronVarManager::kNMaxValues]; // event informaion from the var manager
+
+ AliDielectronEvent(const AliDielectronEvent &c);
+ AliDielectronEvent &operator=(const AliDielectronEvent &c);
+
+
+ ClassDef(AliDielectronEvent,1) // Dielectron Event
+};
+
+
+
+#endif
// //
///////////////////////////////////////////////////////////////////////////
+
#include <AliTriggerAnalysis.h>
#include <AliESDVertex.h>
#include <AliESDEvent.h>
}
fkVertex=0x0;
+
switch(fVtxType){
case kVtxTracks:
case kVtxTracksOrSPD:
#include <TObjString.h>
#include <TObjArray.h>
#include <TVectorD.h>
+#include <TF1.h>
+#include <TRandom.h>
+#include <TProfile.h>
#include <AliVEvent.h>
#include <AliVParticle.h>
#include <AliMultiplicity.h>
#include <AliStack.h>
+#include "AliDielectronVarManager.h"
#include "AliDielectronHelper.h"
//_____________________________________________________________________________
//_____________________________________________________________________________
-Int_t AliDielectronHelper::GetNaccTrcklts(const AliVEvent *ev){
+Int_t AliDielectronHelper::GetNaccTrcklts(const AliVEvent *ev, Double_t etaRange){
// Compute the collision multiplicity based on AOD or ESD tracklets
// Code taken from: AliAnalysisTaskMuonCollisionMultiplicity::ComputeMultiplicity()
Int_t nTracklets = 0;
Int_t nAcc = 0;
- Double_t etaRange = 1.6;
if (ev->IsA() == AliAODEvent::Class()) {
AliAODTracklets *tracklets = ((AliAODEvent*)ev)->GetTracklets();
}
+
+//________________________________________________________________
+Double_t AliDielectronHelper::GetNaccTrckltsCorrected(const AliVEvent *event, Double_t uncorrectedNacc, Double_t vtxZ, Int_t type) {
+ //
+ // Correct the number of accepted tracklets based on the period and event vertex
+ //
+
+ Int_t runNo = event->GetRunNumber();
+
+ Int_t period = -1; // 0-LHC10b, 1-LHC10c, 2-LHC10d, 3-LHC10e
+ Double_t refMult = 0.0; // reference multiplicity
+
+ if(runNo>114930 && runNo<117223) period = 0;
+ if(runNo>119158 && runNo<120830) period = 1;
+ if(runNo>122373 && runNo<126438) period = 2;
+ if(runNo>127711 && runNo<130841) period = 3;
+ if(period<0 || period>3) return uncorrectedNacc;
+
+ if(type<0 || type>8) return uncorrectedNacc;
+ if(type == 0) refMult = 5.0; // SPD tracklets in |eta|<0.5
+ if(type == 1) refMult = 9.5; // SPD tracklets in |eta|<1.0
+ if(type == 2) refMult = 13.0; // SPD tracklets in |eta|<1.6
+ if(type == 3) refMult = 6.0; // ITSTPC+ in |eta|<0.5
+ if(type == 4) refMult = 12.0; // ITSTPC+ in |eta|<1.0
+ if(type == 5) refMult = 16.0; // ITSTPC+ in |eta|<1.6
+ if(type == 6) refMult = 6.0; // ITSSA+ in |eta|<0.5
+ if(type == 7) refMult = 12.0; // ITSSA+ in |eta|<1.0
+ if(type == 8) refMult = 15.0; // ITSSA+ in |eta|<1.6
+
+ if(TMath::Abs(vtxZ)>10.0) return uncorrectedNacc;
+
+ TProfile* estimatorAvg = AliDielectronVarManager::GetEstimatorHistogram(period, type);
+ if(!estimatorAvg) return uncorrectedNacc;
+
+ Double_t localAvg = estimatorAvg->GetBinContent(estimatorAvg->FindBin(vtxZ));
+
+ Double_t deltaM = uncorrectedNacc*(refMult/localAvg - 1);
+
+ Double_t correctedNacc = uncorrectedNacc + (deltaM>0 ? 1 : -1) * gRandom->Poisson(TMath::Abs(deltaM));
+
+ return correctedNacc;
+}
+
//_____________________________________________________________________________
Int_t AliDielectronHelper::GetNacc(const AliVEvent */*ev*/){
// put a robust Nacc definition here
}
+//_____________________________________________________________________________
+Int_t AliDielectronHelper::GetNMothers(const AliMCEvent *ev, Double_t etaRange, Int_t pdgMother, Int_t pdgDaughter, Int_t prim){
+ // counting number of mother particles generated in given eta range and 2 particle decay
+ if (!ev || ev->IsA()!=AliMCEvent::Class()) return -1;
+
+ AliStack *stack = ((AliMCEvent*)ev)->Stack();
+
+ if (!stack) return -1;
+
+ Int_t nParticles = stack->GetNtrack();
+ Int_t nMothers = 0;
+
+ // count..
+ for (Int_t iMc = 0; iMc < nParticles; ++iMc) {
+
+ TParticle* particle = stack->Particle(iMc);
+ if (!particle) continue;
+ if (particle->GetPdgCode() != pdgMother) continue;
+ if (TMath::Abs(particle->Eta()) > TMath::Abs(etaRange)) continue;
+
+ if (particle->GetNDaughters() != 2) continue;
+ // 1st daugther
+ if (particle->GetFirstDaughter()>=nParticles ||
+ particle->GetFirstDaughter()<0 ) continue;
+
+ TParticle* dau1 = stack->Particle(particle->GetFirstDaughter());
+ if (TMath::Abs(dau1->GetPdgCode()) != pdgDaughter) continue;
+ if (TMath::Abs(dau1->Eta()) > TMath::Abs(etaRange)) continue;
+
+ // 2nd daughter
+ if (particle->GetLastDaughter()>=nParticles ||
+ particle->GetLastDaughter()<0 ) continue;
+
+ TParticle* dau2 = stack->Particle(particle->GetLastDaughter());
+ if (TMath::Abs(dau2->GetPdgCode()) != pdgDaughter) continue;
+ if (TMath::Abs(dau2->Eta()) > TMath::Abs(etaRange)) continue;
+
+ // primary
+ if (prim != -1) {
+ if(particle->IsPrimary() != prim) continue;
+ }
+ nMothers++;
+ }
+ return nMothers;
+}
+
+
Int_t GetNch(const AliMCEvent *ev=0x0, Double_t eta=0.9);
Int_t GetNacc(const AliVEvent *ev=0x0);
-Int_t GetNaccTrcklts(const AliVEvent *ev=0x0);
+Int_t GetNaccTrcklts(const AliVEvent *ev=0x0, Double_t etaRange=1.6);
+Double_t GetNaccTrckltsCorrected(const AliVEvent *event, Double_t uncorrectedNacc, Double_t vtxZ, Int_t type);
void RotateKFParticle(AliKFParticle * kfParticle,Double_t angle, const AliVEvent * const ev=0x0);
+Int_t GetNMothers(const AliMCEvent *ev=0x0, Double_t etaRange=0.9, Int_t pdgMother=-999, Int_t pdgDaughter=-999, Int_t prim=-1);
}
//
// Authors:
// Jens Wiechula <Jens.Wiechula@cern.ch>
+// Julian Book <Julian.Book@cern.ch>
//
#include <TH1.h>
#include <TH1F.h>
#include <TH2.h>
#include <TH3.h>
+#include <TProfile.h>
+#include <TProfile2D.h>
+#include <TProfile3D.h>
#include <TCollection.h>
#include <THashList.h>
#include <TString.h>
}
//_____________________________________________________________________________
-void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
- Int_t nbinsX, Double_t xmin, Double_t xmax,
- UInt_t valTypeX, Bool_t logBinX)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ UInt_t valTypeX, Bool_t logBinX)
{
//
// Default histogram creation 1D case
} else {
binLimX=AliDielectronHelper::MakeLinBinning(nbinsX, xmin, xmax);
}
-
- UserHistogram(histClass,name,title,binLimX,valTypeX);
+ UserProfile(histClass,name,title,valTypeP,binLimX,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,
- Bool_t logBinX, Bool_t logBinY)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ Int_t nbinsY, Double_t ymin, Double_t ymax,
+ UInt_t valTypeX, UInt_t valTypeY,
+ Bool_t logBinX, Bool_t logBinY)
{
//
// Default histogram creation 2D case
} else {
binLimY=AliDielectronHelper::MakeLinBinning(nbinsY, ymin, ymax);
}
-
- UserHistogram(histClass,name,title,binLimX,binLimY,valTypeX,valTypeY);
+ UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,valTypeX,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,
- Bool_t logBinX, Bool_t logBinY, Bool_t logBinZ)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ 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,
+ Bool_t logBinX, Bool_t logBinY, Bool_t logBinZ)
{
//
// Default histogram creation 3D case
binLimZ=AliDielectronHelper::MakeLinBinning(nbinsZ, zmin, zmax);
}
- UserHistogram(histClass,name,title,binLimX,binLimY,binLimZ,valTypeX,valTypeY,valTypeZ);
+ UserProfile(histClass,name,title,valTypeP,binLimX,binLimY,binLimZ,valTypeX,valTypeY,valTypeZ);
}
//_____________________________________________________________________________
-void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
- const char* binning,
- UInt_t valTypeX)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const char* binning,
+ UInt_t valTypeX)
{
//
// Histogram creation 1D case with arbitraty binning
//
TVectorD *binLimX=AliDielectronHelper::MakeArbitraryBinning(binning);
- UserHistogram(histClass,name,title,binLimX,valTypeX);
+ UserProfile(histClass,name,title,valTypeP,binLimX,valTypeX);
}
//_____________________________________________________________________________
-void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
- const TVectorD * const binsX,
- UInt_t valTypeX/*=kNoAutoFill*/)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const TVectorD * const binsX,
+ UInt_t valTypeX/*=kNoAutoFill*/)
{
//
// Histogram creation 1D case with arbitraty binning X
Bool_t isOk=kTRUE;
isOk&=IsHistogramOk(histClass,name);
isOk&=(binsX!=0x0);
-
- if (isOk){
- TH1* hist=new TH1F(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
+ TH1 *hist=0x0;
+ if (isOk){
+ if(valTypeP==999)
+ hist=new TH1F(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
+ else {
+ hist=new TProfile(name,title,binsX->GetNrows()-1,binsX->GetMatrixArray());
+ }
+
+ // store var for profile in fBits
+ StoreVarForProfile(hist,valTypeP);
+
Bool_t isReserved=fReservedWords->Contains(histClass);
+ UInt_t uniqueID = valTypeX;
+ if(valTypeP!=999) uniqueID |= 0x80000000; // set last bit to 1 (for profiles only)
if (isReserved)
- UserHistogramReservedWords(histClass, hist, valTypeX);
+ UserHistogramReservedWords(histClass, hist, uniqueID);
else
- UserHistogram(histClass, hist, valTypeX);
+ UserHistogram(histClass, hist, uniqueID);
}
delete binsX;
}
//_____________________________________________________________________________
-void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
- const TVectorD * const binsX, const TVectorD * const binsY,
- UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const TVectorD * const binsX, const TVectorD * const binsY,
+ UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/)
{
//
- // Histogram creation 1D case with arbitraty binning X
+ // Histogram creation 2D case with arbitraty binning X
// the TVectorD is assumed to be surplus after the creation and will be deleted!!!
//
isOk&=IsHistogramOk(histClass,name);
isOk&=(binsX!=0x0);
isOk&=(binsY!=0x0);
+ TH1 *hist=0x0;
if (isOk){
- TH1* hist=new TH2F(name,title,
- binsX->GetNrows()-1,binsX->GetMatrixArray(),
- binsY->GetNrows()-1,binsY->GetMatrixArray());
-
+ if(valTypeP==999) {
+ hist=new TH2F(name,title,
+ binsX->GetNrows()-1,binsX->GetMatrixArray(),
+ binsY->GetNrows()-1,binsY->GetMatrixArray());
+ }
+ else
+ hist=new TProfile2D(name,title,
+ binsX->GetNrows()-1,binsX->GetMatrixArray(),
+ binsY->GetNrows()-1,binsY->GetMatrixArray());
+
+ // store var for profile in fBits
+ StoreVarForProfile(hist,valTypeP);
+
Bool_t isReserved=fReservedWords->Contains(histClass);
+ // switched from 2 digits encoding to 3 digits
+ UInt_t uniqueID = valTypeX+1000*valTypeY;
+ if(valTypeP!=999) uniqueID |= 0x80000000; // set last bit to 1 (for profiles only)
+
if (isReserved)
- UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY);
+ UserHistogramReservedWords(histClass, hist, uniqueID);
else
- UserHistogram(histClass, hist, valTypeX+100*valTypeY);
+ UserHistogram(histClass, hist, uniqueID);
}
delete binsX;
}
//_____________________________________________________________________________
-void AliDielectronHistos::UserHistogram(const char* histClass,const char *name, const char* title,
- const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
- UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, UInt_t valTypeZ/*=0*/)
+void AliDielectronHistos::UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
+ UInt_t valTypeX/*=kNoAutoFill*/, UInt_t valTypeY/*=0*/, UInt_t valTypeZ/*=0*/)
{
//
- // Histogram creation 1D case with arbitraty binning X
+ // Histogram creation 3D case with arbitraty binning X
// the TVectorD is assumed to be surplus after the creation and will be deleted!!!
//
isOk&=(binsX!=0x0);
isOk&=(binsY!=0x0);
isOk&=(binsZ!=0x0);
+ TH1 *hist=0x0;
if (isOk){
- TH1* hist=new TH3F(name,title,
- binsX->GetNrows()-1,binsX->GetMatrixArray(),
- binsY->GetNrows()-1,binsY->GetMatrixArray(),
- binsZ->GetNrows()-1,binsZ->GetMatrixArray());
-
+ if(valTypeP==999)
+ hist=new TH3F(name,title,
+ binsX->GetNrows()-1,binsX->GetMatrixArray(),
+ binsY->GetNrows()-1,binsY->GetMatrixArray(),
+ binsZ->GetNrows()-1,binsZ->GetMatrixArray());
+ else
+ hist=new TProfile3D(name,title,
+ binsX->GetNrows()-1,binsX->GetMatrixArray(),
+ binsY->GetNrows()-1,binsY->GetMatrixArray(),
+ binsZ->GetNrows()-1,binsZ->GetMatrixArray());
+
+ // store var for profile in fBits
+ StoreVarForProfile(hist,valTypeP);
+
Bool_t isReserved=fReservedWords->Contains(histClass);
+ // switched from 2 digits encoding to 3 digits
+ UInt_t uniqueID = valTypeX+1000*valTypeY+1000000*valTypeZ;
+ if(valTypeP!=999) uniqueID |= 0x80000000; // set last bit to 1 (for profiles only)
+
if (isReserved)
- UserHistogramReservedWords(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
+ UserHistogramReservedWords(histClass, hist, uniqueID);
else
- UserHistogram(histClass, hist, valTypeX+100*valTypeY+10000*valTypeZ);
+ UserHistogram(histClass, hist, uniqueID);
}
delete binsX;
THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
hist->SetDirectory(0);
hist->SetUniqueID(valTypes);
+
classTable->Add(hist);
}
{
//
// Fill class 'histClass' (by name)
- //
+ //
THashList *classTable=(THashList*)fHistoList.FindObject(histClass);
if (!classTable){
TIter nextHist(classTable);
TH1 *hist=0;
while ( (hist=(TH1*)nextHist()) ){
- UInt_t valueTypes=hist->GetUniqueID();
+ UInt_t value4=hist->TestBits(0x00ffffff)>>14; // get profile var stored in fBits
+ UInt_t valueTypes=hist->GetUniqueID()&0x7fffffff; // ignore "boolean" bit for profiles
+
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());
+ UInt_t value1=valueTypes%1000; //last three digits
+ UInt_t value2=valueTypes/1000%1000; //second last three digits
+ UInt_t value3=valueTypes/1000000%1000; //third last three digits
+
+ if (value1>=(UInt_t)nValues||value2>=(UInt_t)nValues||value3>=(UInt_t)nValues||(value4>=(UInt_t)nValues && value4!=999)) {
+ 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]);
+ if(value4==999) hist->Fill(values[value1]); // histograms
+ else ((TProfile*)hist)->Fill(values[value1],values[value4]); // profiles
break;
case 2:
- ((TH2*)hist)->Fill(values[value1],values[value2]);
+ if(value4==999) ((TH2*)hist)->Fill(values[value1],values[value2]);
+ else ((TProfile2D*)hist)->Fill(values[value1],values[value2],values[value4]);
break;
case 3:
- ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]);
+ if(value4==999) ((TH3*)hist)->Fill(values[value1],values[value2],values[value3]);
+ else ((TProfile3D*)hist)->Fill(values[value1],values[value2],values[value3],values[value4]);
break;
}
}
TH1 *h=static_cast<TH1*>(hist->Clone());
h->SetDirectory(0);
h->SetTitle(Form("%s %s",title.Data(),l->GetName()));
+
UserHistogram(l->GetName(),h,valTypes);
}
}
(*fReservedWords)=words;
}
+
+//_____________________________________________________________________________
+void AliDielectronHistos::StoreVarForProfile(TObject *obj, UInt_t valType)
+{
+ //
+ // store var for TProfiles in TObject::fBits [14-23]
+ //
+
+ for(UInt_t i=14; i < sizeof(UInt_t)*8; i++) {
+ if(TESTBIT(valType,i-14)) {
+ obj->SetBit(1<<i,kTRUE);
+ }
+ }
+
+ return;
+}
+
+
// //
///////////////////////////////////////////////////////////////////////////////////////////
+#include <Rtypes.h>
#include <TNamed.h>
// #include <TCollection.h>
class AliDielectronHistos : public TNamed {
public:
+
AliDielectronHistos();
AliDielectronHistos(const char* name, const char* title);
virtual ~AliDielectronHistos();
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ Int_t nbinsX, Double_t xmin, Double_t xmax,
+ UInt_t valTypeX=kNoAutoFill, Bool_t logBinX=kFALSE);
+
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ 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,
+ Bool_t logBinX=kFALSE, Bool_t logBinY=kFALSE);
+
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ 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,
+ Bool_t logBinX=kFALSE, Bool_t logBinY=kFALSE, Bool_t logBinZ=kFALSE);
+
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const char* binning, UInt_t valTypeX=kNoAutoFill);
+
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const TVectorD * const binsX, UInt_t valTypeX=kNoAutoFill);
+
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const TVectorD * const binsX, const TVectorD * const binsY,
+ UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0);
+
+ void UserProfile(const char* histClass,const char *name, const char* title,
+ UInt_t valTypeP,
+ const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
+ UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0, UInt_t valTypeZ=0);
+
+
void UserHistogram(const char* histClass,const char *name, const char* title,
- Int_t nbinsX, Double_t xmin, Double_t xmax,
- UInt_t valTypeX=kNoAutoFill, Bool_t logBinX=kFALSE);
+ Int_t nbinsX, Double_t xmin, Double_t xmax, UInt_t valTypeX=kNoAutoFill, Bool_t logBinX=kFALSE)
+ { UserProfile(histClass,name,title,999,nbinsX,xmin,xmax,valTypeX,logBinX); }
+
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,
- Bool_t logBinX=kFALSE, Bool_t logBinY=kFALSE);
+ 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, Bool_t logBinX=kFALSE, Bool_t logBinY=kFALSE)
+ { UserProfile(histClass,name,title,999,nbinsX,xmin,xmax,nbinsY,ymin,ymax,valTypeX,valTypeY,logBinX,logBinY); }
+
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,
- Bool_t logBinX=kFALSE, Bool_t logBinY=kFALSE, Bool_t logBinZ=kFALSE);
-
+ 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,
+ Bool_t logBinX=kFALSE, Bool_t logBinY=kFALSE, Bool_t logBinZ=kFALSE)
+ { UserProfile(histClass,name,title,999,nbinsX,xmin,xmax,nbinsY,ymin,ymax,nbinsZ,zmin,zmax,valTypeX,valTypeY,valTypeZ,logBinX,logBinY,logBinZ); }
+
void UserHistogram(const char* histClass,const char *name, const char* title,
- const char* binning,
- UInt_t valTypeX=kNoAutoFill);
+ const char* binning, UInt_t valTypeX=kNoAutoFill)
+ { UserProfile(histClass,name,title,999,binning,valTypeX); }
void UserHistogram(const char* histClass,const char *name, const char* title,
- const TVectorD * const binsX,
- UInt_t valTypeX=kNoAutoFill);
+ const TVectorD * const binsX, UInt_t valTypeX=kNoAutoFill)
+ { UserProfile(histClass,name,title,999,binsX,valTypeX); }
+
void UserHistogram(const char* histClass,const char *name, const char* title,
- const TVectorD * const binsX, const TVectorD * const binsY,
- UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0);
+ const TVectorD * const binsX, const TVectorD * const binsY, UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0)
+ { UserProfile(histClass,name,title,999,binsX,binsY,valTypeX,valTypeY); }
+
void UserHistogram(const char* histClass,const char *name, const char* title,
const TVectorD * const binsX, const TVectorD * const binsY, const TVectorD * const binsZ,
- UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0, UInt_t valTypeZ=0);
+ UInt_t valTypeX=kNoAutoFill, UInt_t valTypeY=0, UInt_t valTypeZ=0)
+ { UserProfile(histClass,name,title,999,binsX,binsY,binsZ,valTypeX,valTypeY,valTypeZ); }
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);
virtual void DrawSame(const char* histName, const Option_t *opt="leg can");
void SetReservedWords(const char* words);
+ void StoreVarForProfile(TObject *obj, UInt_t valType);
// virtual void Add(TObject *obj) {};
// virtual void Clear(Option_t *option="") {};
// virtual void Delete(Option_t *option="") {};
#include <AliLog.h>
#include <TClonesArray.h>
+#include <TParticle.h>
#include "AliDielectronSignalMC.h"
#include "AliDielectronMC.h"
//________________________________________________________________________________
-Bool_t AliDielectronMC::ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t checkBothCharges) const {
+Bool_t AliDielectronMC::ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t pdgExclusion, Bool_t checkBothCharges) const {
//
// Test the PDG codes of particles with the required ones
//
Bool_t result = kTRUE;
Int_t absRequiredPDG = TMath::Abs(requiredPDG);
+
switch(absRequiredPDG) {
case 0:
result = kTRUE; // PDG not required (any code will do fine)
break;
- case 100: // all light flavoured mesons
+ case 100: // light flavoured mesons
if(checkBothCharges)
- result = TMath::Abs(particlePDG)>=100 && TMath::Abs(particlePDG)<=299;
+ result = TMath::Abs(particlePDG)>=100 && TMath::Abs(particlePDG)<=199;
else {
- if(requiredPDG>0) result = particlePDG>=100 && particlePDG<=299;
- if(requiredPDG<0) result = particlePDG>=-299 && particlePDG<=-100;
+ if(requiredPDG>0) result = particlePDG>=100 && particlePDG<=199;
+ if(requiredPDG<0) result = particlePDG>=-199 && particlePDG<=-100;
}
break;
- case 1000: // all light flavoured baryons
+ case 1000: // light flavoured baryons
if(checkBothCharges)
- result = TMath::Abs(particlePDG)>=1000 && TMath::Abs(particlePDG)<=2999;
+ result = TMath::Abs(particlePDG)>=1000 && TMath::Abs(particlePDG)<=1999;
else {
- if(requiredPDG>0) result = particlePDG>=1000 && particlePDG<=2999;
- if(requiredPDG<0) result = particlePDG>=-2999 && particlePDG<=-1000;
+ if(requiredPDG>0) result = particlePDG>=1000 && particlePDG<=1999;
+ if(requiredPDG<0) result = particlePDG>=-1999 && particlePDG<=-1000;
}
break;
- case 200: // all light flavoured mesons (as for the 100 case)
+ case 200: // light flavoured mesons
if(checkBothCharges)
- result = TMath::Abs(particlePDG)>=100 && TMath::Abs(particlePDG)<=299;
+ result = TMath::Abs(particlePDG)>=200 && TMath::Abs(particlePDG)<=299;
else {
- if(requiredPDG>0)result = particlePDG>=100 && particlePDG<=299;
- if(requiredPDG<0)result = particlePDG>=-299 && particlePDG<=-100;
+ if(requiredPDG>0)result = particlePDG>=200 && particlePDG<=299;
+ if(requiredPDG<0)result = particlePDG>=-299 && particlePDG<=-200;
}
break;
- case 2000: // all light flavoured baryons (as for the 1000 case)
+ case 2000: // light flavoured baryons
if(checkBothCharges)
- result = TMath::Abs(particlePDG)>=1000 && TMath::Abs(particlePDG)<=2999;
+ result = TMath::Abs(particlePDG)>=2000 && TMath::Abs(particlePDG)<=2999;
else {
- if(requiredPDG>0) result = particlePDG>=1000 && particlePDG<=2999;
- if(requiredPDG<0) result = particlePDG>=-2999 && particlePDG<=-1000;
+ if(requiredPDG>0) result = particlePDG>=2000 && particlePDG<=2999;
+ if(requiredPDG<0) result = particlePDG>=-2999 && particlePDG<=-2000;
}
break;
case 300: // all strange mesons
if(requiredPDG<0) result = particlePDG>=-499 && particlePDG<=-400;
}
break;
+ case 401: // open charm mesons
+ if(checkBothCharges)
+ result = TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439;
+ else {
+ if(requiredPDG>0) result = particlePDG>=400 && particlePDG<=439;
+ if(requiredPDG<0) result = particlePDG>=-439 && particlePDG<=-400;
+ }
+ break;
+ case 402: // open charm mesons and baryons together
+ if(checkBothCharges)
+ result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=439) ||
+ (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399);
+ else {
+ if(requiredPDG>0) result = (particlePDG>=400 && particlePDG<=439) ||
+ (particlePDG>=4000 && particlePDG<=4399);
+ if(requiredPDG<0) result = (particlePDG>=-439 && particlePDG<=-400) ||
+ (particlePDG>=-4399 && particlePDG<=-4000);
+ }
+ break;
+ case 403: // all charm hadrons
+ if(checkBothCharges)
+ result = (TMath::Abs(particlePDG)>=400 && TMath::Abs(particlePDG)<=499) ||
+ (TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4999);
+ else {
+ if(requiredPDG>0) result = (particlePDG>=400 && particlePDG<=499) ||
+ (particlePDG>=4000 && particlePDG<=4999);
+ if(requiredPDG<0) result = (particlePDG>=-499 && particlePDG<=-400) ||
+ (particlePDG>=-4999 && particlePDG<=-4000);
+ }
+ break;
case 4000: // all charmed baryons
if(checkBothCharges)
result = TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4999;
if(requiredPDG<0) result = particlePDG>=-4999 && particlePDG<=-4000;
}
break;
+ case 4001: // open charm baryons
+ if(checkBothCharges)
+ result = TMath::Abs(particlePDG)>=4000 && TMath::Abs(particlePDG)<=4399;
+ else {
+ if(requiredPDG>0) result = particlePDG>=4000 && particlePDG<=4399;
+ if(requiredPDG<0) result = particlePDG>=-4399 && particlePDG<=-4000;
+ }
+ break;
case 500: // all beauty mesons
if(checkBothCharges)
result = TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=599;
if(requiredPDG<0) result = particlePDG>=-599 && particlePDG<=-500;
}
break;
+ case 501: // open beauty mesons
+ if(checkBothCharges)
+ result = TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549;
+ else {
+ if(requiredPDG>0) result = particlePDG>=500 && particlePDG<=549;
+ if(requiredPDG<0) result = particlePDG>=-549 && particlePDG<=-500;
+ }
+ break;
+ case 502: // open beauty mesons and baryons
+ if(checkBothCharges)
+ result = (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=549) ||
+ (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499);
+ else {
+ if(requiredPDG>0) result = (particlePDG>=500 && particlePDG<=549) ||
+ (particlePDG>=5000 && particlePDG<=5499);
+ if(requiredPDG<0) result = (particlePDG>=-549 && particlePDG<=-500) ||
+ (particlePDG>=-5499 && particlePDG<=-5000);
+ }
+ break;
+ case 503: // all beauty hadrons
+ if(checkBothCharges)
+ result = (TMath::Abs(particlePDG)>=500 && TMath::Abs(particlePDG)<=599) ||
+ (TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5999);
+ else {
+ if(requiredPDG>0) result = (particlePDG>=500 && particlePDG<=599) ||
+ (particlePDG>=5000 && particlePDG<=5999);
+ if(requiredPDG<0) result = (particlePDG>=-599 && particlePDG<=-500) ||
+ (particlePDG>=-5999 && particlePDG<=-5000);
+ }
+ break;
case 5000: // all beauty baryons
if(checkBothCharges)
result = TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5999;
if(requiredPDG<0) result = particlePDG>=-5999 && particlePDG<=-5000;
}
break;
+ case 5001: // open beauty baryons
+ if(checkBothCharges)
+ result = TMath::Abs(particlePDG)>=5000 && TMath::Abs(particlePDG)<=5499;
+ else {
+ if(requiredPDG>0) result = particlePDG>=5000 && particlePDG<=5499;
+ if(requiredPDG<0) result = particlePDG>=-5499 && particlePDG<=-5000;
+ }
+ break;
default: // all specific cases
if(checkBothCharges)
result = (absRequiredPDG==TMath::Abs(particlePDG));
result = (requiredPDG==particlePDG);
}
+ if(absRequiredPDG!=0 && pdgExclusion) result = !result;
return result;
}
+//________________________________________________________________________________
+Bool_t AliDielectronMC::IsPhysicalPrimary(Int_t label) const {
+ //
+ // Check if the particle with label "label" is a physical primary according to the
+ // definition in AliStack::IsPhysicalPrimary(Int_t label)
+ // Convention for being physical primary:
+ // 1.) particles produced in the collision
+ // 2.) stable particles with respect to strong and electromagnetic interactions
+ // 3.) excludes initial state particles
+ // 4.) includes products of directly produced Sigma0 hyperon decay
+ // 5.) includes products of directly produced pi0 decays
+ // 6.) includes products of directly produced beauty hadron decays
+ //
+ if(label<0) return kFALSE;
+ if(fAnaType==kAOD) {
+ if(!fMcArray) return kFALSE;
+ return (static_cast<AliAODMCParticle*>(GetMCTrackFromMCEvent(label)))->IsPhysicalPrimary();
+ } else if(fAnaType==kESD) {
+ if (!fMCEvent) return kFALSE;
+ return fStack->IsPhysicalPrimary(label);
+ }
+ return kFALSE;
+}
+
+
//________________________________________________________________________________
Bool_t AliDielectronMC::CheckParticleSource(Int_t label, AliDielectronSignalMC::ESource source) const {
//
case AliDielectronSignalMC::kDontCare :
return kTRUE;
break;
- case AliDielectronSignalMC::kPrimary :
- if(label>=0 && label<GetNPrimary()) return kTRUE;
- else return kFALSE;
+ case AliDielectronSignalMC::kPrimary :
+ // true if label is in the list of particles from physics generator
+ // NOTE: This includes all physics event history (initial state particles,
+ // exchange bosons, quarks, di-quarks, strings, un-stable particles, final state particles)
+ // Only the final state particles make it to the detector!!
+ return (label>=0 && label<=GetNPrimary());
break;
- case AliDielectronSignalMC::kSecondary :
- if(label>=GetNPrimary()) return kTRUE;
- else return kFALSE;
+ case AliDielectronSignalMC::kFinalState :
+ // primary particles created in the collision which reach the detectors
+ // These would be:
+ // 1.) particles produced in the collision
+ // 2.) stable particles with respect to strong and electromagnetic interactions
+ // 3.) excludes initial state particles
+ // 4.) includes products of directly produced Sigma0 hyperon decay
+ // 5.) includes products of directly produced pi0 decays
+ // 6.) includes products of directly produced beauty hadron decays
+ return IsPhysicalPrimary(label);
break;
case AliDielectronSignalMC::kDirect :
- if(label>=0 && GetMothersLabel(label)<0) return kTRUE;
- else return kFALSE;
- break;
- case AliDielectronSignalMC::kDecayProduct :
- if(label>=0 && GetMothersLabel(label)>=0) return kTRUE;
- else return kFALSE;
+ // Primary particles which do not have any mother
+ // This is the case for:
+ // 1.) Initial state particles (the 2 protons in Pythia pp collisions)
+ // 2.) In some codes, with sudden freeze-out, all particles generated from the fireball are direct.
+ // There is no history for these particles.
+ // 3.) Certain particles added via MC generator cocktails (e.g. J/psi added to pythia MB events)
+ return (label>=0 && GetMothersLabel(label)<0);
+ break;
+ case AliDielectronSignalMC::kSecondary :
+ // particles which are created by the interaction of final state primaries with the detector
+ // or particles from strange weakly decaying particles (e.g. lambda, kaons, etc.)
+ return (label>=GetNPrimary() && !IsPhysicalPrimary(label));
break;
default :
return kFALSE;
// between the ESD and the MC track. The negative labels indicate a poor matching quality
//if(label<0) return kFALSE;
if(label<0) label *= -1;
+
AliVParticle* part = GetMCTrackFromMCEvent(label);
if (!part) {
AliError(Form("Could not find MC particle with label %d",label));
return kFALSE;
}
+
// check the leg
- if(!ComparePDG(part->PdgCode(),signalMC->GetLegPDG(branch),signalMC->GetCheckBothChargesLegs(branch))) return kFALSE;
+ if(!ComparePDG(part->PdgCode(),signalMC->GetLegPDG(branch),signalMC->GetLegPDGexclude(branch),signalMC->GetCheckBothChargesLegs(branch))) return kFALSE;
if(!CheckParticleSource(label, signalMC->GetLegSource(branch))) return kFALSE;
// check the mother
mLabel = GetMothersLabel(label);
mcMother = GetMCTrackFromMCEvent(mLabel);
}
- if(!mcMother) return kFALSE;
+ if(!mcMother && !signalMC->GetMotherPDGexclude(branch)) return kFALSE;
- if(!ComparePDG(mcMother->PdgCode(),signalMC->GetMotherPDG(branch),signalMC->GetCheckBothChargesMothers(branch))) return kFALSE;
+ if(!ComparePDG((mcMother ? mcMother->PdgCode() : 0),signalMC->GetMotherPDG(branch),signalMC->GetMotherPDGexclude(branch),signalMC->GetCheckBothChargesMothers(branch))) return kFALSE;
if(!CheckParticleSource(mLabel, signalMC->GetMotherSource(branch))) return kFALSE;
}
-
+
// check the grandmother
+ AliVParticle* mcGrandMother=0x0;
if(signalMC->GetGrandMotherPDG(branch)!=0 || signalMC->GetGrandMotherSource(branch)!=AliDielectronSignalMC::kDontCare) {
- AliVParticle* mcGrandMother=0x0;
Int_t gmLabel = -1;
if(mcMother) {
gmLabel = GetMothersLabel(mLabel);
mcGrandMother = static_cast<AliMCParticle*>(GetMCTrackFromMCEvent(gmLabel));
}
- if(!mcGrandMother) return kFALSE;
+ if(!mcGrandMother && !signalMC->GetGrandMotherPDGexclude(branch)) return kFALSE;
- if(!ComparePDG(mcGrandMother->PdgCode(),signalMC->GetGrandMotherPDG(branch),signalMC->GetCheckBothChargesGrandMothers(branch))) return kFALSE;
+ if(!ComparePDG((mcGrandMother ? mcGrandMother->PdgCode() : 0),signalMC->GetGrandMotherPDG(branch),signalMC->GetGrandMotherPDGexclude(branch),signalMC->GetCheckBothChargesGrandMothers(branch))) return kFALSE;
if(!CheckParticleSource(gmLabel, signalMC->GetGrandMotherSource(branch))) return kFALSE;
}
}
+
//________________________________________________________________________________
Bool_t AliDielectronMC::IsMCTruth(const AliDielectronPair* pair, const AliDielectronSignalMC* signalMC) const {
//
// make direct(1-1 and 2-2) and cross(1-2 and 2-1) comparisons for the whole branch
Bool_t directTerm = kTRUE;
// daughters
- directTerm = directTerm && mcD1 && ComparePDG(d1Pdg,signalMC->GetLegPDG(1),signalMC->GetCheckBothChargesLegs(1))
+ directTerm = directTerm && mcD1 && ComparePDG(d1Pdg,signalMC->GetLegPDG(1),signalMC->GetLegPDGexclude(1),signalMC->GetCheckBothChargesLegs(1))
&& CheckParticleSource(labelD1, signalMC->GetLegSource(1));
- directTerm = directTerm && mcD2 && ComparePDG(d2Pdg,signalMC->GetLegPDG(2),signalMC->GetCheckBothChargesLegs(2))
+ directTerm = directTerm && mcD2 && ComparePDG(d2Pdg,signalMC->GetLegPDG(2),signalMC->GetLegPDGexclude(2),signalMC->GetCheckBothChargesLegs(2))
&& CheckParticleSource(labelD2, signalMC->GetLegSource(2));
// mothers
if(signalMC->GetMotherPDG(1)!=0 || signalMC->GetMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
labelM1 = GetMothersLabel(labelD1);
if(labelD1>-1 && labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
- directTerm = directTerm && mcM1
- && ComparePDG(mcM1->PdgCode(),signalMC->GetMotherPDG(1),signalMC->GetCheckBothChargesMothers(1))
+ directTerm = directTerm && (mcM1 || signalMC->GetMotherPDGexclude(1))
+ && ComparePDG((mcM1 ? mcM1->PdgCode() : 0),signalMC->GetMotherPDG(1),signalMC->GetMotherPDGexclude(1),signalMC->GetCheckBothChargesMothers(1))
&& CheckParticleSource(labelM1, signalMC->GetMotherSource(1));
}
if(signalMC->GetMotherPDG(2)!=0 || signalMC->GetMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
labelM2 = GetMothersLabel(labelD2);
if(labelD2>-1 && labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
- directTerm = directTerm && mcM2
- && ComparePDG(mcM2->PdgCode(),signalMC->GetMotherPDG(2),signalMC->GetCheckBothChargesMothers(2))
+ directTerm = directTerm && (mcM2 || signalMC->GetMotherPDGexclude(2))
+ && ComparePDG((mcM2 ? mcM2->PdgCode() : 0),signalMC->GetMotherPDG(2),signalMC->GetMotherPDGexclude(2),signalMC->GetCheckBothChargesMothers(2))
&& CheckParticleSource(labelM2, signalMC->GetMotherSource(2));
}
if(signalMC->GetGrandMotherPDG(1)!=0 || signalMC->GetGrandMotherSource(1)!=AliDielectronSignalMC::kDontCare) {
labelG1 = GetMothersLabel(labelM1);
if(mcM1 && labelG1>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
- directTerm = directTerm && mcG1
- && ComparePDG(mcG1->PdgCode(),signalMC->GetGrandMotherPDG(1),signalMC->GetCheckBothChargesGrandMothers(1))
+ directTerm = directTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(1))
+ && ComparePDG((mcG1 ? mcG1->PdgCode() : 0),signalMC->GetGrandMotherPDG(1),signalMC->GetGrandMotherPDGexclude(1),signalMC->GetCheckBothChargesGrandMothers(1))
&& CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(1));
}
if(signalMC->GetGrandMotherPDG(2)!=0 || signalMC->GetGrandMotherSource(2)!=AliDielectronSignalMC::kDontCare) {
labelG2 = GetMothersLabel(labelM2);
if(mcM2 && labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
- directTerm = directTerm && mcG2
- && ComparePDG(mcG2->PdgCode(),signalMC->GetGrandMotherPDG(2),signalMC->GetCheckBothChargesGrandMothers(2))
+ directTerm = directTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(2))
+ && ComparePDG((mcG2 ? mcG2->PdgCode() : 0),signalMC->GetGrandMotherPDG(2),signalMC->GetGrandMotherPDGexclude(2),signalMC->GetCheckBothChargesGrandMothers(2))
&& CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(2));
}
Bool_t crossTerm = kTRUE;
// daughters
crossTerm = crossTerm && mcD2
- && ComparePDG(d2Pdg,signalMC->GetLegPDG(1),signalMC->GetCheckBothChargesLegs(1))
+ && ComparePDG(d2Pdg,signalMC->GetLegPDG(1),signalMC->GetLegPDGexclude(1),signalMC->GetCheckBothChargesLegs(1))
&& CheckParticleSource(labelD2, signalMC->GetLegSource(1));
crossTerm = crossTerm && mcD1
- && ComparePDG(d1Pdg,signalMC->GetLegPDG(2),signalMC->GetCheckBothChargesLegs(2))
+ && ComparePDG(d1Pdg,signalMC->GetLegPDG(2),signalMC->GetLegPDGexclude(2),signalMC->GetCheckBothChargesLegs(2))
&& CheckParticleSource(labelD1, signalMC->GetLegSource(2));
// mothers
labelM2 = GetMothersLabel(labelD2);
if(labelM2>-1) mcM2 = GetMCTrackFromMCEvent(labelM2);
}
- crossTerm = crossTerm && mcM2
- && ComparePDG(mcM2->PdgCode(),signalMC->GetMotherPDG(1),signalMC->GetCheckBothChargesMothers(1))
+ crossTerm = crossTerm && (mcM2 || signalMC->GetMotherPDGexclude(1))
+ && ComparePDG((mcM2 ? mcM2->PdgCode() : 0),signalMC->GetMotherPDG(1),signalMC->GetMotherPDGexclude(1),signalMC->GetCheckBothChargesMothers(1))
&& CheckParticleSource(labelM2, signalMC->GetMotherSource(1));
}
labelM1 = GetMothersLabel(labelD1);
if(labelM1>-1) mcM1 = GetMCTrackFromMCEvent(labelM1);
}
- crossTerm = crossTerm && mcM1
- && ComparePDG(mcM1->PdgCode(),signalMC->GetMotherPDG(2),signalMC->GetCheckBothChargesMothers(2))
+ crossTerm = crossTerm && (mcM1 || signalMC->GetMotherPDGexclude(2))
+ && ComparePDG((mcM1 ? mcM1->PdgCode() : 0),signalMC->GetMotherPDG(2),signalMC->GetMotherPDGexclude(2),signalMC->GetCheckBothChargesMothers(2))
&& CheckParticleSource(labelM1, signalMC->GetMotherSource(2));
}
labelG2 = GetMothersLabel(labelM2);
if(labelG2>-1) mcG2 = GetMCTrackFromMCEvent(labelG2);
}
- crossTerm = crossTerm && mcG2
- && ComparePDG(mcG2->PdgCode(),signalMC->GetGrandMotherPDG(1),signalMC->GetCheckBothChargesGrandMothers(1))
+ crossTerm = crossTerm && (mcG2 || signalMC->GetGrandMotherPDGexclude(1))
+ && ComparePDG((mcG2 ? mcG2->PdgCode() : 0),signalMC->GetGrandMotherPDG(1),signalMC->GetGrandMotherPDGexclude(1),signalMC->GetCheckBothChargesGrandMothers(1))
&& CheckParticleSource(labelG2, signalMC->GetGrandMotherSource(1));
}
labelG1 = GetMothersLabel(labelM1);
if(labelG2>-1) mcG1 = GetMCTrackFromMCEvent(labelG1);
}
- crossTerm = crossTerm && mcG1
- && ComparePDG(mcG1->PdgCode(),signalMC->GetGrandMotherPDG(2),signalMC->GetCheckBothChargesGrandMothers(2))
+ crossTerm = crossTerm && (mcG1 || signalMC->GetGrandMotherPDGexclude(2))
+ && ComparePDG((mcG1 ? mcG1->PdgCode() : 0),signalMC->GetGrandMotherPDG(2),signalMC->GetGrandMotherPDGexclude(2),signalMC->GetCheckBothChargesGrandMothers(2))
&& CheckParticleSource(labelG1, signalMC->GetGrandMotherSource(2));
}
const AliVParticle * daughter1 = pair->GetFirstDaughter();
const AliVParticle * daughter2 = pair->GetSecondDaughter();
+ if (!daughter1 || !daughter2) return 0;
AliVParticle *mcDaughter1=GetMCTrackFromMCEvent(daughter1->GetLabel());
AliVParticle *mcDaughter2=GetMCTrackFromMCEvent(daughter2->GetLabel());
Int_t GetMothersLabel(Int_t daughterLabel) const;
Int_t GetPdgFromLabel(Int_t label) const;
+ Bool_t IsPhysicalPrimary(Int_t label) const; // checks if a particle is physical primary
+
Bool_t HaveSameMother(const AliDielectronPair *pair) const;
Int_t GetLabelMotherWithPdg(const AliDielectronPair* pair, Int_t pdgMother);
Int_t GetLabelMotherWithPdg(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother);
- AliVParticle* GetMCTrackFromMCEvent(AliVParticle *track); // return MC track directly from MC event
+// AliVParticle* GetMCTrackFromMCEvent(const AliVParticle *track); // return MC track directly from MC event
AliVParticle* GetMCTrackFromMCEvent(Int_t itrk) const; // return MC track directly from MC event
TParticle* GetMCTrackFromStack(const AliESDtrack* _track); // return MC track from stack
AliMCParticle* GetMCTrack(const AliESDtrack* _track); // return MC track associated with reco track
Int_t GetLabelMotherWithPdgESD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother);
Int_t GetLabelMotherWithPdgAOD(const AliVParticle *particle1, const AliVParticle *particle2, Int_t pdgMother);
- Bool_t ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t checkBothCharges) const;
+ Bool_t ComparePDG(Int_t particlePDG, Int_t requiredPDG, Bool_t pdgExclusion, Bool_t checkBothCharges) const;
Bool_t CheckParticleSource(Int_t label, AliDielectronSignalMC::ESource source) const;
ClassDef(AliDielectronMC, 0)
};
--- /dev/null
+/*************************************************************************
+* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+* *
+* Author: The ALICE Off-line Project. *
+* Contributors are mentioned in the code where appropriate. *
+* *
+* Permission to use, copy, modify and distribute this software and its *
+* documentation strictly for non-commercial purposes is hereby granted *
+* without fee, provided that the above copyright notice appears in all *
+* copies and that both the copyright notice and this permission notice *
+* appear in the supporting documentation. The authors make no claims *
+* about the suitability of this software for any purpose. It is *
+* provided "as is" without express or implied warranty. *
+**************************************************************************/
+
+///////////////////////////////////////////////////////////////////////////
+// Dielectron MixingHandler //
+// //
+// //
+/*
+Detailed description
+
+
+*/
+// //
+///////////////////////////////////////////////////////////////////////////
+
+#include <TVectorD.h>
+#include <TH1.h>
+#include <TAxis.h>
+
+#include <AliLog.h>
+#include <AliVTrack.h>
+
+#include "AliDielectron.h"
+#include "AliDielectronHelper.h"
+#include "AliDielectronHistos.h"
+#include "AliDielectronEvent.h"
+
+#include "AliDielectronMixingHandler.h"
+
+ClassImp(AliDielectronMixingHandler)
+
+AliDielectronMixingHandler::AliDielectronMixingHandler() :
+ TNamed(),
+ fDepth(10),
+ fArrPools("TClonesArray"),
+ fAxes(kMaxCuts),
+ fMixType(kOSonly),
+ fMixIncomplete(kTRUE),
+ fMoveToSameVertex(kFALSE)
+{
+ //
+ // Default Constructor
+ //
+ for (Int_t i=0; i<kMaxCuts; ++i){
+ fEventCuts[i]=0;
+ }
+ fAxes.SetOwner(kTRUE);
+}
+
+//______________________________________________
+AliDielectronMixingHandler::AliDielectronMixingHandler(const char* name, const char* title) :
+ TNamed(name, title),
+ fDepth(10),
+ fArrPools("TClonesArray"),
+ fAxes(kMaxCuts),
+ fMixType(kOSonly),
+ fMixIncomplete(kTRUE),
+ fMoveToSameVertex(kFALSE)
+{
+ //
+ // Named Constructor
+ //
+ for (Int_t i=0; i<kMaxCuts; ++i){
+ fEventCuts[i]=0;
+ }
+ fAxes.SetOwner(kTRUE);
+}
+
+//______________________________________________
+AliDielectronMixingHandler::~AliDielectronMixingHandler()
+{
+ //
+ // Default Destructor
+ //
+ fAxes.Delete();
+}
+
+//________________________________________________________________
+void AliDielectronMixingHandler::AddVariable(AliDielectronVarManager::ValueTypes type,
+ Int_t nbins, Double_t min, Double_t max, Bool_t log)
+{
+ //
+ // Add a variable to the mixing handler
+ //
+
+ // limit number of variables to kMaxCuts
+ if (fAxes.GetEntriesFast()>=kMaxCuts) return;
+
+ TVectorD *binLimits=0x0;
+ if (!log) binLimits=AliDielectronHelper::MakeLinBinning(nbins,min,max);
+ else binLimits=AliDielectronHelper::MakeLogBinning(nbins,min,max);
+ if (!binLimits) return;
+
+ Int_t size=fAxes.GetEntriesFast();
+ fEventCuts[size]=(UShort_t)type;
+ fAxes.Add(binLimits);
+}
+
+//________________________________________________________________
+void AliDielectronMixingHandler::AddVariable(AliDielectronVarManager::ValueTypes type,
+ const char* binLimitStr)
+{
+ //
+ // Add a variable to the mixing handler with arbitrary binning
+ //
+
+ // limit number of variables to kMaxCuts
+ if (fAxes.GetEntriesFast()>=kMaxCuts) return;
+
+ TVectorD *binLimits=AliDielectronHelper::MakeArbitraryBinning(binLimitStr);
+ if (!binLimits) return;
+
+ Int_t size=fAxes.GetEntriesFast();
+ fEventCuts[size]=(UShort_t)type;
+ fAxes.Add(binLimits);
+}
+
+//______________________________________________
+void AliDielectronMixingHandler::Fill(const AliVEvent *ev, AliDielectron *diele)
+{
+ //
+ // fill event buffers and perform mixing if the pool depth is reached
+ //
+
+ //check if there are tracks available
+ if (diele->GetTrackArray(0)->GetEntriesFast()==0 && diele->GetTrackArray(1)->GetEntriesFast()==0) return;
+
+ //find mixing bin
+ Double_t values[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(ev,values);
+
+ TString dim;
+ Int_t bin=FindBin(values,&dim);
+
+ if (bin<0){
+ AliDebug(5,Form("Bin outside range: %s",dim.Data()));
+ return;
+ }
+
+ // get mixing pool, create it if it does not yet exist.
+ TClonesArray *poolp=static_cast<TClonesArray*>(fArrPools.At(bin));
+ if (!poolp){
+ AliDebug(10,Form("New pool at %d (%s)\n",bin,dim.Data()));
+ poolp=new(fArrPools[bin]) TClonesArray("AliDielectronEvent",fDepth);
+ }
+ TClonesArray &pool=*poolp;
+
+ AliDebug(10,Form("new event at %d: %d",bin,pool.GetEntriesFast()));
+ AliDielectronEvent *event=new(pool[pool.GetEntriesFast()]) AliDielectronEvent();
+
+ event->SetTracks(*diele->GetTrackArray(0), *diele->GetTrackArray(1), *diele->GetPairArray(1));
+ event->SetEventData(values);
+
+ // check if pool depth is reached.
+ if (pool.GetEntriesFast()<fDepth) return;
+
+ // pool depth reached, do mixing
+ DoMixing(pool,diele);
+
+ // increase counter for full bins
+ if (diele->fHistos) {
+ diele->fHistos->Fill("Mixing","Stats",0);
+ diele->fHistos->Fill("Mixing","CompletePools",bin);
+ }
+
+ //clear the current pool
+ pool.Clear("C");
+}
+
+//______________________________________________
+void AliDielectronMixingHandler::DoMixing(TClonesArray &pool, AliDielectron *diele)
+{
+ //
+ // perform the mixing
+ //
+
+ //buffer track arrays and copy them back afterwards
+ TObjArray arrTrDummy[4];
+ for (Int_t i=0; i<4; ++i) arrTrDummy[i]=diele->fTracks[i];
+
+ //buffer also global event data
+ Double_t values[AliDielectronVarManager::kNMaxValues]={0};
+ for (Int_t i=AliDielectronVarManager::kPairMax; i<AliDielectronVarManager::kNMaxValues; ++i)
+ values[i]=AliDielectronVarManager::GetValue((AliDielectronVarManager::ValueTypes)i);
+
+ for (Int_t i1=0; i1<pool.GetEntriesFast(); ++i1){
+ AliDielectronEvent *ev1=static_cast<AliDielectronEvent*>(pool.At(i1));
+ //use event data from the first event
+ //both events are in the same mixing bin anyhow...
+ AliDielectronVarManager::SetEventData(ev1->GetEventData());
+
+ TObject *o=0x0;
+ TIter ev1P(ev1->GetTrackArrayP());
+ TIter ev1N(ev1->GetTrackArrayN());
+
+ for (Int_t i2=i1+1; i2<pool.GetEntriesFast(); ++i2){
+ //clear arryas
+ diele->fTracks[0].Clear();
+ diele->fTracks[1].Clear();
+ diele->fTracks[2].Clear();
+ diele->fTracks[3].Clear();
+
+ //setup track arrays
+ AliDielectronEvent *ev2=static_cast<AliDielectronEvent*>(pool.At(i2));
+
+ ev1P.Reset();
+ ev1N.Reset();
+ TIter ev2P(ev2->GetTrackArrayP());
+ TIter ev2N(ev2->GetTrackArrayN());
+
+ //
+ //move tracks to the same vertex (vertex of the first event), if requested
+ //
+ if (fMoveToSameVertex){
+ const Double_t *varsFirst=ev1->GetEventData();
+ const Double_t *varsMix=ev2->GetEventData();
+
+ const Double_t vFirst[3]={varsFirst[AliDielectronVarManager::kXvPrim],
+ varsFirst[AliDielectronVarManager::kYvPrim],
+ varsFirst[AliDielectronVarManager::kZvPrim]};
+
+ const Double_t vMix[3] ={varsMix[AliDielectronVarManager::kXvPrim],
+ varsMix[AliDielectronVarManager::kYvPrim],
+ varsMix[AliDielectronVarManager::kZvPrim]};
+
+ //loop over all tracks from the second event and move them to the vertex of the first
+ AliVTrack *vtrack=0x0;
+ while ( ( vtrack=(AliVTrack*)ev2P() ) ){
+ MoveToSameVertex(vtrack, vFirst, vMix);
+ }
+
+
+ while ( ( vtrack=(AliVTrack*)ev2N() ) ){
+ MoveToSameVertex(vtrack, vFirst, vMix);
+ }
+
+
+ ev2P.Reset();
+ ev2N.Reset();
+ }
+
+ //mixing of ev1- ev2+ (pair type4). This is common for all mixing types
+ while ( (o=ev1N()) ) diele->fTracks[1].Add(o);
+ while ( (o=ev2P()) ) diele->fTracks[2].Add(o);
+ diele->FillPairArrays(1,2);
+
+ if (fMixType==kAll || fMixType==kOSandLS){
+ // all 4 pair arrays will be filled
+ while ( (o=ev1P()) ) diele->fTracks[0].Add(o);
+ while ( (o=ev2N()) ) diele->fTracks[3].Add(o);
+ diele->FillPairArrays(0,2);
+ diele->FillPairArrays(1,3);
+ if (fMixType==kAll) diele->FillPairArrays(0,3);
+ }
+
+ if (fMixType==kOSonly || fMixType==kOSandLS){
+ //use the pair type of ev1- ev1+ also for ev1+ ev1-
+ diele->fTracks[1].Clear();
+ diele->fTracks[2].Clear();
+ while ( (o=ev1P()) ) diele->fTracks[1].Add(o);
+ while ( (o=ev2N()) ) diele->fTracks[2].Add(o);
+ diele->FillPairArrays(1,2);
+ }
+ }
+ }
+
+ //copy back the tracks
+ for (Int_t i=0; i<4; ++i) {
+ diele->fTracks[i].Clear();
+ diele->fTracks[i]=arrTrDummy[i];
+ }
+
+ //set back global event values
+ AliDielectronVarManager::SetEventData(values);
+}
+
+//______________________________________________
+void AliDielectronMixingHandler::MixRemaining(AliDielectron *diele)
+{
+ //
+ // mix all pools even if they are incomplete
+ //
+
+ //Check if there was any processed data and it is requested to mix incomplete bins
+ if (!diele->PairArray(0) || !fMixIncomplete ) return;
+
+
+ for (Int_t ipool=0; ipool<fArrPools.GetSize(); ++ipool){
+ TClonesArray *poolp=static_cast<TClonesArray*>(fArrPools.At(ipool));
+ if (!poolp) continue;
+ //clear the arrays before the final processing"
+ AliDebug(10,Form("Incomplete: Bin %d (%d)\n",ipool,poolp->GetEntriesFast()));
+ diele->ClearArrays();
+ DoMixing(*poolp,diele);
+
+ diele->FillHistograms(0x0, kTRUE);
+
+ // increase counter for incomplete bins
+ if (diele->fHistos) {
+ diele->fHistos->Fill("Mixing","Stats",1);
+ diele->fHistos->Fill("Mixing","InCompletePools",ipool);
+ diele->fHistos->Fill("Mixing","Entries_InCompletePools",poolp->GetEntriesFast());
+ }
+
+ }
+}
+
+
+//______________________________________________
+void AliDielectronMixingHandler::Init(const AliDielectron *diele)
+{
+ //
+ // initialise event buffers
+ //
+
+ Int_t size=1;
+ for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i)
+ size*=((static_cast<TVectorD*>(fAxes.At(i)))->GetNrows()-1);
+
+ AliDebug(10,Form("Creating a pool array with size %d \n",size));
+
+ fArrPools.Expand(size);
+
+ //add statics histogram if we have a histogram manager
+ if (diele && diele->fHistos) {
+ diele->fHistos->AddClass("Mixing");
+ diele->fHistos->UserHistogram("Mixing","Stats","Mixing Statistics;;#called bins",2,0,2);
+ TH1* h=diele->fHistos->GetHistogram("Mixing","Stats");
+ h->GetXaxis()->SetBinLabel(1,"Complete");
+ h->GetXaxis()->SetBinLabel(2,"Incomplete");
+
+ diele->fHistos->UserHistogram("Mixing","CompletePools","Mixing Statistics compete pools;bin;#fills",size,0,size);
+ diele->fHistos->UserHistogram("Mixing","InCompletePools","Mixing Statistics incomplete pools;bin;#fills",size,0,size);
+ diele->fHistos->UserHistogram("Mixing","Entries_InCompletePools","#entries in incomplete pools;entries;#fills",fDepth,0,fDepth);
+ }
+
+ TString values;
+ for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i){
+ TVectorD *bins=static_cast<TVectorD*>(fAxes.At(i));
+ Int_t nRows=bins->GetNrows();
+ values+=Form("%s: ",AliDielectronVarManager::GetValueName(fEventCuts[i]));
+ for (Int_t irow=0; irow<nRows; ++irow){
+ values+=Form("%.2f, ",(*bins)[irow]);
+ }
+ }
+
+ AliDebug(10,values.Data());
+}
+
+//______________________________________________
+Int_t AliDielectronMixingHandler::FindBin(const Double_t values[], TString *dim)
+{
+ //
+ // bin bin in mixing stack described by 'values'
+ // if the values are outside the binning range -1 is returned
+ // if dim is non NULL debug info will be stored in the variable
+ //
+
+ if (fAxes.GetEntriesFast()==0) {
+ if (dim) (*dim)="single bin";
+ return 0;
+ }
+ if (dim) (*dim)="";
+ Int_t sizeAdd=1;
+ Int_t bin=0;
+ for (Int_t i=0; i<fAxes.GetEntriesFast(); ++i){
+ Double_t val=values[fEventCuts[i]];
+ TVectorD *bins=static_cast<TVectorD*>(fAxes.At(i));
+ Int_t nRows=bins->GetNrows();
+ if ( (val<(*bins)[0]) || (val>(*bins)[nRows-1]) ) {
+ return -1;
+ }
+
+ Int_t pos=TMath::BinarySearch(nRows,bins->GetMatrixArray(),val);
+ bin+=sizeAdd*pos;
+ if (dim) (*dim)+=Form("%s: %f; ",AliDielectronVarManager::GetValueName(fEventCuts[i]),val);
+ sizeAdd*=nRows;
+ }
+
+ return bin;
+}
+
+//______________________________________________
+void AliDielectronMixingHandler::MoveToSameVertex(AliVTrack * const vtrack, const Double_t *vFirst, const Double_t* vMix)
+{
+ //
+ // move 'track' which belongs to the vertex information of vMix to the vertex of vFirst
+ //
+
+ static Bool_t printed=kFALSE;
+
+ if (vtrack->IsA()==AliESDtrack::Class()){
+ AliESDtrack *track=(AliESDtrack*)vtrack;
+
+ //get track information
+ Double_t x = track->GetX();
+ Double_t alpha = track->GetAlpha();
+ Double_t param[5] = {0};
+ Double_t cov[15] = {0};
+
+ for (Int_t i=0; i<5; ++i) param[i]=track->GetParameter()[i];
+ for (Int_t i=0; i<15; ++i) cov[i] =track->GetCovariance()[i];
+
+ //translation
+ Double_t vt[3] = {vMix[0]-vFirst[0],vMix[1]-vFirst[1],vMix[2]-vFirst[2]};
+ //rotate to the track frame
+ track->Global2LocalPosition(vt,track->GetAlpha());
+
+ //add to track position
+ x = x -vt[0];
+ param[0] = param[0]-vt[1];
+ param[1] = param[1]-vt[2];
+
+ //set updated track information
+ track->Set(x, alpha, param, cov);
+ } else {
+ // AliAODTrack *track=(AliAODTrack*)vtrack;
+ // Double_t pos[3]={0};
+ // track->GetPosition(pos);
+ // if (pos[0]>-999.){
+ // pos[0]=pos[0]-vMix[AliDielectronVarManager::kXvPrim]+vFirst[AliDielectronVarManager::kXvPrim];
+ // pos[1]=pos[1]-vMix[AliDielectronVarManager::kYvPrim]+vFirst[AliDielectronVarManager::kYvPrim];
+ // pos[2]=pos[2]-vMix[AliDielectronVarManager::kZvPrim]+vFirst[AliDielectronVarManager::kZvPrim];
+ // track->SetPosition(pos);
+// AliError("Move To same vertex not yet implemented for AOD!");
+ if (!printed) {
+// Error("AliDielectronMixingHandler::MoveToSameVertex","Move To same vertex not yet implemented for AOD!");
+ printed=kTRUE;
+ }
+ //
+ // Not that clear how to do it. In AOD track there is fPosition, fPositionAtDCA and "TRef fProdVertex"
+ // where Xv(), Yv(), Zv() returns the position of fProdVertex
+ //
+ }
+
+}
--- /dev/null
+#ifndef ALIDIELECTRONMIXINGHANDLER_H
+#define ALIDIELECTRONMIXINGHANDLER_H
+
+/* Copyright(c) 1998-2009, ALICE Experiment at CERN, All rights reserved. *
+ * See cxx source for full Copyright notice */
+
+//#############################################################
+//# #
+//# Class AliDielectronMixingHandler #
+//# #
+//# Authors: #
+//# Jens Wiechula, Uni-Tübingen / Jens.Wiechula@cern.ch #
+//# #
+//#############################################################
+
+#include <TNamed.h>
+#include <TObjArray.h>
+#include <TClonesArray.h>
+
+#include "AliDielectronVarManager.h"
+
+class AliDielectron;
+class AliVTrack;
+class AliVEvent;
+
+class AliDielectronMixingHandler : public TNamed {
+public:
+ enum { kMaxCuts=10 };
+ enum EMixType {
+ kOSonly=0,
+ kOSandLS,
+ kAll
+ };
+ AliDielectronMixingHandler();
+ AliDielectronMixingHandler(const char*name, const char* title);
+
+ virtual ~AliDielectronMixingHandler();
+
+ void AddVariable(AliDielectronVarManager::ValueTypes type, Int_t nbins,
+ Double_t min, Double_t max, Bool_t log=kFALSE);
+ void AddVariable(AliDielectronVarManager::ValueTypes type, const char* binLimitStr);
+
+ void SetDepth(UShort_t depth) { fDepth=depth; }
+ UShort_t GetDepth() const { return fDepth; }
+
+ void SetMixType(EMixType type) { fMixType=type; }
+ EMixType GetMixType() const { return fMixType; }
+
+ void SetMixUncomplete(Bool_t mix) { fMixIncomplete=mix; }
+ Bool_t GetMixUncomplete() const { return fMixIncomplete; }
+
+ void SetMoveToSameVertex(Bool_t move) { fMoveToSameVertex=move; }
+ Bool_t GetMoveToSameVertex() const { return fMoveToSameVertex; }
+
+ Int_t FindBin(const Double_t values[], TString *dim=0x0);
+ void Fill(const AliVEvent *ev, AliDielectron *diele);
+
+ void MixRemaining(AliDielectron *diele);
+
+ void Init(const AliDielectron *diele=0x0);
+ static void MoveToSameVertex(AliVTrack * const vtrack, const Double_t vFirst[3], const Double_t vMix[3]);
+
+private:
+ UShort_t fDepth; //Number of events per bin to start the merging
+ TClonesArray fArrPools; //Array of events in bins
+
+ UShort_t fEventCuts[kMaxCuts]; //cut variables
+ TObjArray fAxes; //Axis descriptions of the event binning
+
+ EMixType fMixType; // which combinations to include in the mixing
+
+ Bool_t fMixIncomplete; // whether to mix uncomplete bins at the end of the processing
+ Bool_t fMoveToSameVertex; //whether to move the mixed tracks to the same vertex position
+
+ void DoMixing(TClonesArray &pool, AliDielectron *diele);
+
+ AliDielectronMixingHandler(const AliDielectronMixingHandler &c);
+ AliDielectronMixingHandler &operator=(const AliDielectronMixingHandler &c);
+
+
+ ClassDef(AliDielectronMixingHandler,1) // Dielectron MixingHandler
+};
+
+
+
+#endif
#include <TGraph.h>
#include <AliVTrack.h>
+#include <AliVCluster.h>
#include <AliLog.h>
#include <AliExternalTrackParam.h>
-#include <AliESDtrack.h>
-#include <AliESDpid.h>
-#include <AliAODpidUtil.h>
-#include <AliAODPid.h>
+#include <AliPIDResponse.h>
+#include <AliESDtrack.h> //!!!!! Remove once Eta correction is treated in the tender
#include "AliDielectronVarManager.h"
TGraph *AliDielectronPID::fgFitCorr=0x0;
Double_t AliDielectronPID::fgCorr=0.0;
+TF1 *AliDielectronPID::fgFunEtaCorr=0x0;
AliDielectronPID::AliDielectronPID() :
AliAnalysisCuts(),
fNcuts(0),
- fESDpid(0x0),
- fAODpidUtil(0x0)
+ fPIDResponse(0x0)
{
//
// Default Constructor
fPartType[icut]=AliPID::kPion;
fNsigmaLow[icut]=0;
fNsigmaUp[icut]=0;
- fPmin[icut]=0;
- fPmax[icut]=0;
+ fmin[icut]=0;
+ fmax[icut]=0;
fExclude[icut]=kFALSE;
fFunUpperCut[icut]=0x0;
fFunLowerCut[icut]=0x0;
fRequirePIDbit[icut]=0;
+ fActiveCuts[icut]=-1;
}
}
AliDielectronPID::AliDielectronPID(const char* name, const char* title) :
AliAnalysisCuts(name, title),
fNcuts(0),
- fESDpid(0x0),
- fAODpidUtil(0x0)
+ fPIDResponse(0x0)
{
//
// Named Constructor
fPartType[icut]=AliPID::kPion;
fNsigmaLow[icut]=0;
fNsigmaUp[icut]=0;
- fPmin[icut]=0;
- fPmax[icut]=0;
+ fmin[icut]=0;
+ fmax[icut]=0;
fExclude[icut]=kFALSE;
fFunUpperCut[icut]=0x0;
fFunLowerCut[icut]=0x0;
fRequirePIDbit[icut]=0;
+ fActiveCuts[icut]=0;
}
}
//______________________________________________
void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp/*=-99999.*/,
- Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
- UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
+ Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
+ UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
{
//
// Add a pid nsigma cut
- // use response of detector 'det' in the momentum range ('pMin') to ['pMax']
- // use a sigma band betwee 'nSigmaLow' and 'nSigmaUp'
+ // use response of detector 'det' in the range ['min'] to ['max'] for var
+ // use a sigma band between 'nSigmaLow' and 'nSigmaUp'
// if nSigmaUp==-99999. then nSigmaLow will be uesd as a symmetric band +- nSigmaLow
// specify whether to 'exclude' the given band
//
fPartType[fNcuts]=type;
fNsigmaLow[fNcuts]=nSigmaLow;
fNsigmaUp[fNcuts]=nSigmaUp;
- fPmin[fNcuts]=pMin;
- fPmax[fNcuts]=pMax;
+ fmin[fNcuts]=min;
+ fmax[fNcuts]=max;
fExclude[fNcuts]=exclude;
fRequirePIDbit[fNcuts]=pidBitType;
- ++fNcuts;
+ fActiveCuts[fNcuts]=(var==-1 ? AliDielectronVarManager::kP : var);
+
+ AliInfo(Form("Add PID cut %d: sigma [% .1f,% .1f] \t cut [% .1f,% .f] \t var %d->%s \n",
+ fNcuts,nSigmaLow,nSigmaUp,min,max,fActiveCuts[fNcuts],AliDielectronVarManager::GetValueName(fActiveCuts[fNcuts])));
+ ++fNcuts;
+
}
//______________________________________________
void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, TF1 * const funUp,
- Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
- UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
+ Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
+ UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
{
//
// cut using a TF1 as upper cut
return;
}
fFunUpperCut[fNcuts]=funUp;
- AddCut(det,type,nSigmaLow,0.,pMin,pMax,exclude,pidBitType);
+ AddCut(det,type,nSigmaLow,0.,min,max,exclude,pidBitType,var);
}
//______________________________________________
void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, Double_t nSigmaUp,
- Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
- UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
+ Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
+ UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
{
//
// cut using a TF1 as lower cut
return;
}
fFunLowerCut[fNcuts]=funLow;
- AddCut(det,type,0.,nSigmaUp,pMin,pMax,exclude,pidBitType);
+ AddCut(det,type,0.,nSigmaUp,min,max,exclude,pidBitType,var);
}
//______________________________________________
void AliDielectronPID::AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, TF1 * const funUp,
- Double_t pMin/*=0*/, Double_t pMax/*=0*/, Bool_t exclude/*=kFALSE*/,
- UInt_t pidBitType/*=AliDielectronPID::kRequire*/)
+ Double_t min/*=0*/, Double_t max/*=0*/, Bool_t exclude/*=kFALSE*/,
+ UInt_t pidBitType/*=AliDielectronPID::kRequire*/, Int_t var/*=-1*/)
{
//
// cut using a TF1 as lower and upper cut
}
fFunUpperCut[fNcuts]=funUp;
fFunLowerCut[fNcuts]=funLow;
- AddCut(det,type,0.,0.,pMin,pMax,exclude,pidBitType);
+ AddCut(det,type,0.,0.,min,max,exclude,pidBitType,var);
}
//______________________________________________
//loop over all cuts
AliVTrack *part=static_cast<AliVTrack*>(track);
- //TODO: Which momentum to use?
- // Different momenta for different detectors?
- Double_t mom=part->P();
+ AliESDtrack *esdTrack=0x0;
+ Double_t origdEdx=-1;
- Bool_t selected=kFALSE;
- fESDpid=AliDielectronVarManager::GetESDpid();
- fAODpidUtil=AliDielectronVarManager::GetAODpidUtil();
-
- for (UChar_t icut=0; icut<fNcuts; ++icut){
- Double_t pMin=fPmin[icut];
- Double_t pMax=fPmax[icut];
-
- // test momentum range. In case pMin==pMax use all momenta
- if ( (TMath::Abs(pMin-pMax)>1e-20) && (mom<=pMin || mom>pMax) ) continue;
+ // apply ETa correction, remove once this is in the tender
+ if( (part->IsA() == AliESDtrack::Class()) && fgFunEtaCorr ){
+ esdTrack=static_cast<AliESDtrack*>(part);
+ origdEdx=esdTrack->GetTPCsignal();
+ esdTrack->SetTPCsignal(origdEdx/GetEtaCorr(esdTrack),esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
+ }
+
+ //Fill values
+ Double_t values[AliDielectronVarManager::kNMaxValues];
+ AliDielectronVarManager::Fill(track,values);
+ Bool_t selected=kFALSE;
+ fPIDResponse=AliDielectronVarManager::GetPIDResponse();
+ for (UChar_t icut=0; icut<fNcuts; ++icut){
+ Double_t min=fmin[icut];
+ Double_t max=fmax[icut];
+ Double_t val=values[fActiveCuts[icut]];
+
+ // test var range. In case min==max do not cut
+ if ( (TMath::Abs(min-max)>1e-20) && (val<min || val>=max) ) continue;
+
switch (fDetType[icut]){
case kITS:
selected = IsSelectedITS(part,icut);
case kTRD:
selected = IsSelectedTRD(part,icut);
break;
+ case kTRDeleEff:
+ selected = IsSelectedTRDeleEff(part,icut);
+ break;
case kTOF:
selected = IsSelectedTOF(part,icut);
break;
+ case kEMCAL:
+ selected = IsSelectedEMCAL(part,icut);
+ break;
+ }
+ if (!selected) {
+ if (esdTrack) esdTrack->SetTPCsignal(origdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
+
+ return kFALSE;
}
- if (!selected) return kFALSE;
}
+ if (esdTrack) esdTrack->SetTPCsignal(origdEdx,esdTrack->GetTPCsignalSigma(),esdTrack->GetTPCsignalN());
return selected;
}
// ITS part of the PID check
// Don't accept the track if there was no pid bit set
//
- Float_t numberOfSigmas=-1000.;
- if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliESDtrack::kITSpid)) return kFALSE;
- if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kITSpid)) return kTRUE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kITSpid)) return kFALSE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kITSpid)) return kTRUE;
Double_t mom=part->P();
- if (part->IsA()==AliESDtrack::Class()){
- // ESD case in case the PID bit is not set, don't use this track!
- AliESDtrack *track=static_cast<AliESDtrack*>(part);
- numberOfSigmas=fESDpid->NumberOfSigmasITS(track, fPartType[icut]);
- }else if(part->IsA()==AliAODTrack::Class()){
- // AOD case
- // FIXME: Is there a place to check whether the PID is was set in ESD???
- AliAODTrack *track=static_cast<AliAODTrack*>(part);
- numberOfSigmas=fAODpidUtil->NumberOfSigmasITS(track, fPartType[icut]);
- }
+ Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasITS(part, fPartType[icut]);
// test if we are supposed to use a function for the cut
if (fFunUpperCut[icut]) fNsigmaUp[icut] =fFunUpperCut[icut]->Eval(mom);
// TPC part of the PID check
// Don't accept the track if there was no pid bit set
//
- Float_t numberOfSigmas=-1000.;
-
- if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliESDtrack::kTPCpid)) return kFALSE;
- if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kTPCpid)) return kTRUE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTPCpid)) return kFALSE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTPCpid)) return kTRUE;
- Double_t mom=part->P();
+ Double_t mom=part->GetTPCmomentum();
- if (part->IsA()==AliESDtrack::Class()){
- // ESD case in case the PID bit is not set, don't use this track!
- AliESDtrack *track=static_cast<AliESDtrack*>(part);
- const AliExternalTrackParam *in = track->GetInnerParam();
- if (in) mom = in->GetP();
- numberOfSigmas=fESDpid->NumberOfSigmasTPC(track, fPartType[icut]);
- }else if(part->IsA()==AliAODTrack::Class()){
- // AOD case
- // FIXME: Is there a place to check whether the PID is was set in ESD???
- AliAODTrack *track=static_cast<AliAODTrack*>(part);
- const AliAODPid *pidObj = track->GetDetPid();
- if (pidObj) mom = pidObj->GetTPCmomentum();
- numberOfSigmas=fAODpidUtil->NumberOfSigmasTPC(track, fPartType[icut]);
- }
+ Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasTPC(part, fPartType[icut]);
+
if (fPartType[icut]==AliPID::kElectron){
numberOfSigmas-=fgCorr;
}
}
//______________________________________________
-Bool_t AliDielectronPID::IsSelectedTRD(AliVTrack * const /*part*/, Int_t /*icut*/)
+Bool_t AliDielectronPID::IsSelectedTRD(AliVTrack * const part, Int_t icut)
{
//
// TRD part of the pid check
+ // the TRD checks on the probabilities.
+ //
+
+ if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kFALSE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kTRUE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable && (part->GetTRDntrackletsPID()<4)) return kTRUE;
+
+ Double_t p[AliPID::kSPECIES]={0.};
+ fPIDResponse->ComputeTRDProbability(part,AliPID::kSPECIES,p);
+ Float_t particleProb=p[fPartType[icut]];
+
+ Bool_t selected=((particleProb>=fNsigmaLow[icut])&&(particleProb<=fNsigmaUp[icut]))^fExclude[icut];
+ return selected;
+}
+
+//______________________________________________
+Bool_t AliDielectronPID::IsSelectedTRDeleEff(AliVTrack * const part, Int_t icut)
+{
//
- return kFALSE;
+ // TRD part of the pid check using electron efficiency requirement
+ // in this case the upper limit as well as the particle specie is ignored
+ // and the lower limit regarded as the requested electron efficiency
+ //
+
+ if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kFALSE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTRDpid)) return kTRUE;
+
+ Bool_t selected=fPIDResponse->IdentifiedAsElectronTRD(part,fNsigmaLow[icut])^fExclude[icut];
+ return selected;
}
//______________________________________________
// TOF part of the PID check
// Don't accept the track if there was no pid bit set
//
- Float_t numberOfSigmas=-1000.;
- if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliESDtrack::kTOFpid)) return kFALSE;
- if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliESDtrack::kTOFpid)) return kTRUE;
-
- if (part->IsA()==AliESDtrack::Class()){
- // ESD case in case the PID bit is not set, don't use this track!
- AliESDtrack *track=static_cast<AliESDtrack*>(part);
- numberOfSigmas=fESDpid->NumberOfSigmasTOF(track, fPartType[icut], fESDpid->GetTOFResponse().GetTimeZero());
- }else if(part->IsA()==AliAODTrack::Class()){
- // AOD case
- // FIXME: Is there a place to check whether the PID is was set in ESD???
- AliAODTrack *track=static_cast<AliAODTrack*>(part);
- numberOfSigmas=fAODpidUtil->NumberOfSigmasTOF(track, fPartType[icut]);
- }
+ if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!(part->GetStatus()&AliVTrack::kTOFpid)) return kFALSE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!(part->GetStatus()&AliVTrack::kTOFpid)) return kTRUE;
+
+ Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasTOF(part, fPartType[icut]);
Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
return selected;
}
+//______________________________________________
+Bool_t AliDielectronPID::IsSelectedEMCAL(AliVTrack * const part, Int_t icut)
+{
+ //
+ // emcal pid selecttion
+ //
+
+ //TODO: correct way to check for emcal pid?
+ Float_t numberOfSigmas=fPIDResponse->NumberOfSigmasEMCAL(part, fPartType[icut]);
+
+ Bool_t hasPID=numberOfSigmas>-998.;
+
+ if (fRequirePIDbit[icut]==AliDielectronPID::kRequire&&!hasPID) return kFALSE;
+ if (fRequirePIDbit[icut]==AliDielectronPID::kIfAvailable&&!hasPID) return kTRUE;
+
+
+ Bool_t selected=((numberOfSigmas>=fNsigmaLow[icut])&&(numberOfSigmas<=fNsigmaUp[icut]))^fExclude[icut];
+ return selected;
+}
+
//______________________________________________
void AliDielectronPID::SetDefaults(Int_t def){
//
// 2sigma bands TPC:
// - include e 0<p<inf
// - exclude mu,K,pi,p 0<p<2
-
AddCut(kTPC,AliPID::kElectron,2.);
AddCut(kTPC,AliPID::kMuon,-2.,2.,0.,2.,kTRUE);
AddCut(kTPC,AliPID::kPion,-2.,2.,0.,2.,kTRUE);
AddCut(kTPC,AliPID::kPion,-3.,3.,0.,0.,kTRUE);
AddCut(kTPC,AliPID::kProton,-3.,3.,0.,0.,kTRUE);
- } else if (def==3) {
+ } else if (def==3 || def==4) { // def3 and def4 are the same??
// include 2sigma e TPC
// 3sigma bands TOF
// - exclude K 0<p<1
AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
- } else if (def==4) {
- // include 2sigma e TPC
- // 3sigma bands TOF
- // - exclude K 0<p<1
- // - exclude P 0<p<2
- AddCut(kTPC,AliPID::kElectron,2.);
- AddCut(kTOF,AliPID::kKaon,-3.,3.,0.,1.,kTRUE);
- AddCut(kTOF,AliPID::kProton,-6.,6.,0.,1.,kTRUE);
- AddCut(kTOF,AliPID::kProton,-3.,3.,1.,2.,kTRUE);
} else if (def==5) {
AddCut(kTPC,AliPID::kElectron,-0.5,3);
AddCut(kTOF,AliPID::kElectron,-3,3,0,1.5);
// printf("Corr: %f\n",fgCorr);
}
+//______________________________________________
+Double_t AliDielectronPID::GetEtaCorr(AliVTrack *track)
+{
+ //
+ // return eta correction
+ //
+ if (!fgFunEtaCorr) return 1;
+ return fgFunEtaCorr->Eval(track->Eta());
+}
//#############################################################
#include <AliPID.h>
-#include <AliAODTrack.h>
-#include <AliAODPid.h>
-
#include <AliAnalysisCuts.h>
class TF1;
class TList;
class AliVTrack;
class TGraph;
-class AliESDpid;
-class AliAODpidUtil;
+class AliPIDResponse;
+class AliDielectronVarManager;
class AliDielectronPID : public AliAnalysisCuts {
public:
- enum DetType {kITS, kTPC, kTRD, kTOF};
- enum PIDbitTupe {kIgnore=0, kRequire, kIfAvailable};
+ enum DetType {kITS, kTPC, kTRD, kTRDeleEff, kTOF, kEMCAL};
+ enum PIDbitType {kIgnore=0, kRequire, kIfAvailable};
AliDielectronPID();
AliDielectronPID(const char*name, const char* title);
virtual ~AliDielectronPID();
void AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, Double_t nSigmaUp=-99999.,
- Double_t pMin=0, Double_t pMax=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire);
+ Double_t min=0, Double_t max=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire,
+ Int_t var=-1);
void AddCut(DetType det, AliPID::EParticleType type, Double_t nSigmaLow, TF1 * const funUp,
- Double_t pMin=0, Double_t pMax=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire);
+ Double_t min=0, Double_t max=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire,
+ Int_t var=-1);
void AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, Double_t nSigmaUp,
- Double_t pMin=0, Double_t pMax=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire);
+ Double_t min=0, Double_t max=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire,
+ Int_t var=-1);
void AddCut(DetType det, AliPID::EParticleType type, TF1 * const funLow, TF1 * const funUp,
- Double_t pMin=0, Double_t pMax=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire);
+ Double_t min=0, Double_t max=0, Bool_t exclude=kFALSE, UInt_t pidBitType=AliDielectronPID::kRequire,
+ Int_t var=-1);
void SetDefaults(Int_t def);
static void SetCorrVal(Double_t run);
static Double_t GetCorrVal() { return fgCorr; }
static TGraph *GetCorrGraph() { return fgFitCorr; }
-
+
+ static void SetEtaCorrFunction(TF1 *fun) {fgFunEtaCorr=fun;}
+ static TF1* GetEtaCorrFunction() { return fgFunEtaCorr; }
+
+ static Double_t GetEtaCorr(AliVTrack *track);
+
private:
enum {kNmaxPID=10};
-
+
DetType fDetType[kNmaxPID]; //detector type of nsigma cut
AliPID::EParticleType fPartType[kNmaxPID]; //particle type
Float_t fNsigmaLow[kNmaxPID]; //lower nsigma bound
Float_t fNsigmaUp[kNmaxPID]; //upper nsigma bound
- Double_t fPmin[kNmaxPID]; //lower momentum
- Double_t fPmax[kNmaxPID]; //upper momentum
+ Double_t fmin[kNmaxPID]; //lower cut limit
+ Double_t fmax[kNmaxPID]; //upper cut limit
Bool_t fExclude[kNmaxPID]; //use as exclusion band
TF1 *fFunUpperCut[kNmaxPID];//use function as upper cut
TF1 *fFunLowerCut[kNmaxPID];//use function as lower cut
UChar_t fNcuts; //number of cuts
UChar_t fRequirePIDbit[kNmaxPID]; //How to make use of the pid bit (see)
+ UShort_t fActiveCuts[kNmaxPID]; // list of activated cuts
- AliESDpid *fESDpid; //! esd pid object
- AliAODpidUtil *fAODpidUtil; //! AOD pid object
+ AliPIDResponse *fPIDResponse; //! pid response object
static TGraph *fgFitCorr; //spline fit object to correct the nsigma deviation in the TPC electron band
static Double_t fgCorr; //!correction value for current run. Set if fgFitCorr is set and SetCorrVal(run)
// was called
+ static TF1 *fgFunEtaCorr; //function for eta correction of electron sigma
Bool_t IsSelectedITS(AliVTrack * const part, Int_t icut);
Bool_t IsSelectedTPC(AliVTrack * const part, Int_t icut);
Bool_t IsSelectedTRD(AliVTrack * const part, Int_t icut);
+ Bool_t IsSelectedTRDeleEff(AliVTrack * const part, Int_t icut);
Bool_t IsSelectedTOF(AliVTrack * const part, Int_t icut);
+ Bool_t IsSelectedEMCAL(AliVTrack * const part, Int_t icut);
AliDielectronPID(const AliDielectronPID &c);
AliDielectronPID &operator=(const AliDielectronPID &c);
}
}
-//______________________________________________
-Double_t AliDielectronPair::GetLXY(const AliVVertex * const vtx) const
-{
- //
- // Calculate the decay length in XY taking into account the primary vertex position
- //
- if(!vtx) return 0;
- return ( (Xv()-vtx->GetX()) * Px() + (Yv()-vtx->GetY()) * Py() )/Pt() ;
-}
+// //______________________________________________
+// Double_t AliDielectronPair::GetLXY(const AliVVertex * const vtx) const
+// {
+// //
+// // Calculate the decay length in XY taking into account the primary vertex position
+// //
+// if(!vtx) return 0;
+// return ( (Xv()-vtx->GetX()) * Px() + (Yv()-vtx->GetY()) * Py() )/Pt() ;
+// }
-//______________________________________________
-Double_t AliDielectronPair::GetPseudoProperTime(const AliVVertex * const vtx) const
-{
- //
- // Calculate the pseudo proper time
- //
- Double_t lxy=GetLXY(vtx);
- Double_t psProperDecayLength = lxy*(TDatabasePDG::Instance()->GetParticle(443)->Mass())/Pt();
- return psProperDecayLength;
-}
+// //______________________________________________
+// Double_t AliDielectronPair::GetPseudoProperTime(const AliVVertex * const vtx) const
+// {
+// //
+// // Calculate the pseudo proper time
+// //
+// Double_t lxy=GetLXY(vtx);
+// Double_t psProperDecayLength = lxy*(TDatabasePDG::Instance()->GetParticle(443)->Mass())/Pt();
+// return psProperDecayLength;
+// }
// Dummy
Int_t PdgCode() const {return 0;}
//
- Double_t GetLXY(const AliVVertex * const vtx) const;
- Double_t GetPseudoProperTime(const AliVVertex * const vtx) const;
+ // Double_t GetLXY(const AliVVertex * const vtx) const;
+ // Double_t GetPseudoProperTime(const AliVVertex * const vtx) const;
UChar_t GetType() const { return fType; }
void SetProductionVertex(const AliKFParticle &Vtx) { fPair.SetProductionVertex(Vtx); }
//inter leg information
+ Double_t GetKFChi2() const { return fPair.GetChi2(); }
+ Int_t GetKFNdf() const { return fPair.GetNDF(); }
Double_t OpeningAngle() const { return fD1.GetAngle(fD2); }
Double_t DistanceDaughters() const { return fD1.GetDistanceFromParticle(fD2); }
Double_t DistanceDaughtersXY() const { return fD1.GetDistanceFromParticleXY(fD2); }
fHistDataPM(0),
fHistDataPP(0),
fHistDataMM(0),
+ fHistDataME(0),
fValues(6),
fErrors(6),
fIntMin(0),
fHistDataPM(0),
fHistDataPP(0),
fHistDataMM(0),
+ fHistDataME(0),
fValues(6),
fErrors(6),
fIntMin(0),
if (fHistDataPP) delete fHistDataPP;
if (fHistDataPM) delete fHistDataPM;
if (fHistDataMM) delete fHistDataMM;
+ if (fHistDataME) delete fHistDataME;
}
class AliDielectronSignalBase : public TNamed {
public:
enum EBackgroundMethod {
- kFitted = 0,
+ kFittedMC = 0,
+ kFitted,
kLikeSign,
kLikeSignArithm,
kEventMixing,
Double_t GetMassError() const { return fErrors(4);}
Double_t GetMassWidth() const { return fValues(5);}
Double_t GetMassWidthError() const { return fErrors(5);}
-
+
TH1* GetSignalHistogram() const {return fHistSignal;}
TH1* GetBackgroundHistogram() const {return fHistBackground;}
TH1* GetUnlikeSignHistogram() const {return fHistDataPM;}
TH1 *fHistDataPM; // histogram of selected +- pair candidates
TH1 *fHistDataPP; // histogram of selected ++ pair candidates
TH1 *fHistDataMM; // histogram of selected -- pair candidates
+ TH1 *fHistDataME; // histogram of selected +- pair candidates from mixed event
- TVectorD fValues; // values
- TVectorD fErrors; // value errors
+ TVectorD fValues; // values
+ TVectorD fErrors; // value errors
- Double_t fIntMin; // signal extraction range min
- Double_t fIntMax; // signal extraction range max
- Double_t fFitMin; // fit range lowest inv. mass
- Double_t fFitMax; // fit range highest inv. mass
+ Double_t fIntMin; // signal extraction range min
+ Double_t fIntMax; // signal extraction range max
+ Double_t fFitMin; // fit range lowest inv. mass
+ Double_t fFitMax; // fit range highest inv. mass
- Int_t fRebin; // histogram rebin factor
- EBackgroundMethod fMethod; // method for background substraction
- Double_t fScaleMin; // min for scaling of raw and background histogram
- Double_t fScaleMax; // max for scaling of raw and background histogram
- Double_t fScaleFactor; // scale factor of raw to background histogram scaling
+ Int_t fRebin; // histogram rebin factor
+ EBackgroundMethod fMethod; // method for background substraction
+ Double_t fScaleMin; // min for scaling of raw and background histogram
+ Double_t fScaleMax; // max for scaling of raw and background histogram
+ Double_t fScaleFactor; // scale factor of raw to background histogram scaling
- Bool_t fProcessed; // flag
+ Bool_t fProcessed; // flag
- void SetSignificanceAndSOB(); // calculate the significance and S/B
+ void SetSignificanceAndSOB(); // calculate the significance and S/B
TPaveText* DrawStats(Double_t x1=0., Double_t y1=0., Double_t x2=0., Double_t y2=0.);
AliDielectronSignalBase(const AliDielectronSignalBase &c);
fHistBackground->SetBinError(ibin, ebackground);
}
//scale histograms to match integral between fScaleMin and fScaleMax
+ // or if fScaleMax < fScaleMin use fScaleMin as scale factor
if (fScaleMax>fScaleMin) fScaleFactor=ScaleHistograms(fHistDataPM,fHistBackground,fScaleMin,fScaleMax);
+ else if (fScaleMin>0.){
+ fScaleFactor=fScaleMin;
+ fHistBackground->Scale(fScaleFactor);
+ }
//subract background
fHistSignal->Add(fHistBackground,-1);
fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
fHistBackground->FindBin(fIntMax),
fErrors(1));
+ printf("%f %f\n",fValues(0),fValues(1));
// S/B and significance
SetSignificanceAndSOB();
void AliDielectronSignalExt::ProcessEM(TObjArray* const arrhist)
{
//
- // event mixing. not implemented yet.
+ // event mixing
//
- printf("event mixing method is not implemented yet. Like-sign method will be used.\n");
- ProcessLS(arrhist);
+ fHistDataPM = (TH1*)(arrhist->At(0))->Clone("histPMSE"); // +- SE
+ fHistDataME = (TH1*)(arrhist->At(1))->Clone("histPMME"); // +- ME
+ fHistDataPM->Sumw2();
+ fHistDataME->Sumw2();
+ fHistDataPM->SetDirectory(0);
+ fHistDataME->SetDirectory(0);
+
+ // rebin the histograms
+ if (fRebin>1) {
+ fHistDataPM->Rebin(fRebin);
+ fHistDataME->Rebin(fRebin);
+ }
+
+ fHistSignal = new TH1D("HistSignal", "Mixed events background substracted signal",
+ fHistDataPM->GetXaxis()->GetNbins(),
+ fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
+ fHistSignal->SetDirectory(0);
+ fHistBackground = new TH1D("HistBackground", "background contribution from mixed events",
+ fHistDataPM->GetXaxis()->GetNbins(),
+ fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
+ fHistBackground->SetDirectory(0);
+
+ // fill out background and subtracted histogram
+ for(Int_t ibin=1; ibin<=fHistDataPM->GetXaxis()->GetNbins(); ibin++) {
+ Float_t pm = fHistDataPM->GetBinContent(ibin);
+ Float_t epm = fHistDataPM->GetBinError(ibin);
+ Float_t background = fHistDataME->GetBinContent(ibin);
+ Float_t ebackground = fHistDataME->GetBinError(ibin);
+
+ fHistSignal->SetBinContent(ibin, pm);
+ fHistSignal->SetBinError(ibin, epm);
+ fHistBackground->SetBinContent(ibin, background);
+ fHistBackground->SetBinError(ibin, ebackground);
+ }
+
+ if (fScaleMax>fScaleMin) fScaleFactor=ScaleHistograms(fHistDataPM,fHistBackground,fScaleMin,fScaleMax);
+ else if (fScaleMin>0.){
+ fScaleFactor=fScaleMin;
+ fHistBackground->Scale(fScaleFactor);
+ }
+
+ //subract background
+ fHistSignal->Add(fHistBackground,-1);
+
+ // signal
+ fValues(0) = fHistSignal->IntegralAndError(fHistSignal->FindBin(fIntMin),
+ fHistSignal->FindBin(fIntMax), fErrors(0));
+ // background
+ fValues(1) = fHistBackground->IntegralAndError(fHistBackground->FindBin(fIntMin),
+ fHistBackground->FindBin(fIntMax),
+ fErrors(1));
+ // S/B and significance
+ SetSignificanceAndSOB();
+
+ fProcessed = kTRUE;
}
//______________________________________________
}
//scale histograms to match integral between fScaleMin and fScaleMax
+ // or if fScaleMax < fScaleMin use fScaleMin as scale factor
if (fScaleMax>fScaleMin) fScaleFactor=ScaleHistograms(fHistDataPM,fHistBackground,fScaleMin,fScaleMax);
-
+ else if (fScaleMin>0.){
+ fScaleFactor=fScaleMin;
+ fHistBackground->Scale(fScaleFactor);
+ }
+
fHistSignal=(TH1*)fHistDataPM->Clone("histSignal");
fHistSignal->Add(fHistBackground,-1.);
ClassImp(AliDielectronSignalFunc)
+TH1F* AliDielectronSignalFunc::fgHistSimPM=0x0;
+
AliDielectronSignalFunc::AliDielectronSignalFunc() :
AliDielectronSignalBase(),
fFuncSignal(0x0),
fParMass(1),
fParMassWidth(2),
fFitOpt("SMNQE"),
-fUseIntegral(kFALSE)
+fUseIntegral(kFALSE),
+fPolDeg(0),
+fChi2Dof(0.0)
{
//
// Default Constructor
fParMass(1),
fParMassWidth(2),
fFitOpt("SMNQE"),
-fUseIntegral(kFALSE)
+fUseIntegral(kFALSE),
+fPolDeg(0),
+fChi2Dof(0.0)
{
//
// Named Constructor
// Fit the invariant mass histograms and retrieve the signal and background
//
switch(fMethod) {
+ case kFittedMC :
+ ProcessFitIKF(arrhist);
+ break;
+
case kFitted :
ProcessFit(arrhist);
break;
}
}
+//______________________________________________
+void AliDielectronSignalFunc::ProcessFitIKF(TObjArray * const arrhist) {
+ //
+ // Fit the +- invariant mass distribution only
+ //
+ //
+
+ const Double_t bigNumber = 100000.;
+ Double_t chi2ndfm1 = bigNumber;
+ Double_t ratiom1 = bigNumber;
+ Double_t chi2ndf = bigNumber;
+ Int_t nDP =0;
+
+ Int_t maxPolDeg = 8;
+
+ fHistDataPM = (TH1F*)(arrhist->At(1))->Clone("histPM"); // +- SE
+ if(fRebin>1) fHistDataPM->Rebin(fRebin);
+
+ fgHistSimPM = (TH1F*)(arrhist->At(3))->Clone("histPMsim"); // +- mc shape
+ if (!fgHistSimPM) {
+ AliFatal("No mc peak shape found at idx 3.");
+ return;
+ }
+ if(fRebin>1) fgHistSimPM->Rebin(fRebin);
+
+ // try out the polynomial degrees
+ for (Int_t iPD=0; iPD<=maxPolDeg; iPD++) {
+ TH1F *hf1 = (TH1F *) fHistDataPM->Clone(Form("hf1_PD%d",iPD));
+
+ FitOneMinv(hf1, fgHistSimPM, iPD);
+ if (fChi2Dof > 0) chi2ndf = fChi2Dof;
+ AliInfo(Form("nDP: %d, iPD: %d, chi2ndf: %f", nDP, iPD, chi2ndf));
+
+ ratiom1 = TMath::Abs(fChi2Dof - 1);
+ if (chi2ndfm1 > ratiom1) { // search for the closest to 1.
+ chi2ndfm1 = ratiom1;
+ nDP = iPD;
+ }
+ }
+
+
+ // fit again with the best polynomial degree
+ TH1F *h2 = (TH1F *) fHistDataPM->Clone(Form("h2_PD%d",nDP));
+
+ FitOneMinv(h2, fgHistSimPM, nDP);
+ AliInfo(Form("Best Fit: PD %d, chi^2/ndf %.3f, S/B %.3f",nDP,fChi2Dof,fValues(3)));
+
+}
+//______________________________________________
+void AliDielectronSignalFunc::FitOneMinv(TH1F *hMinv, TH1F *hSim, Int_t pod) {
+ //
+ // main function to fit an inv mass spectrum
+ //
+
+ TObjArray *arrResults = new TObjArray;
+ arrResults->SetOwner();
+ arrResults->AddAt(hMinv,0);
+
+ // Degree of polynomial
+ fPolDeg = pod;
+
+ // inclusion and exclusion areas (values)
+ const Double_t kJPMass = 3.096916;
+ // inclusion and exclusion areas (bin numbers)
+ const Int_t binIntLo = hMinv->FindBin(fIntMin);
+ const Int_t binIntHi = hMinv->FindBin(fIntMax);
+ // for error calculation
+ Double_t intAreaEdgeLo = hMinv->GetBinLowEdge(binIntLo);
+ Double_t intAreaEdgeHi = hMinv->GetBinLowEdge(binIntHi)+hMinv->GetBinWidth(binIntHi);
+ Double_t norm = (binIntHi-binIntLo)/(fIntMax - fIntMin);
+
+ TH1F *hBfit = (TH1F *) hMinv->Clone(); // for bg only fit (excluding peak region)
+ TH1F *hSigF = (TH1F *) hMinv->Clone(); // signal with subtracted bg
+ TH1F *hBgrd = (TH1F *) hMinv->Clone(); // bg histogram
+
+ hBfit->Reset();
+ hSigF->Reset();
+ hBgrd->Reset();
+
+ // extract start parameter for the MC signal fit
+ Double_t bgvalAv = (hMinv->Integral(1,hMinv->GetNbinsX()+1) - hMinv->Integral(binIntLo,binIntHi)) / (hMinv->GetNbinsX()+1 - (binIntHi-binIntLo));
+ Double_t pkval = hMinv->GetBinContent(hMinv->FindBin(kJPMass)) - bgvalAv;
+ Double_t heightMC = hSim->GetBinContent(hSim->FindBin(kJPMass));
+ Double_t peakScale = (heightMC > 0. ? pkval/heightMC : 0.0);
+
+ Int_t nBgnd = 2 + fPolDeg; // degree + c1st oefficient + higher coefficients
+ Int_t nMinv = nBgnd + 1; // bgrd + peakscale
+
+ // Create the spectra without peak region
+ for (Int_t iBin = 0; iBin <= hMinv->GetNbinsX(); iBin++) {
+ if ((iBin < binIntLo) || (iBin > binIntHi)) {
+ hBfit->SetBinContent(iBin,hMinv->GetBinContent(iBin));
+ hBfit->SetBinError(iBin,hMinv->GetBinError(iBin));
+ }
+ }
+
+
+ // =======
+ // 1.
+ // =======
+ // Do the fit to the background spectrum
+ TF1 *fBo = new TF1("bgrd_fit",BgndFun,fFitMin,fFitMax,nBgnd);
+ for (Int_t iPar=0; iPar<nBgnd; iPar++) {
+ if (iPar == 0) fBo->FixParameter(0, fPolDeg);
+ if (iPar == 1) fBo->SetParameter(iPar, bgvalAv);
+ if (iPar >= 2) fBo->SetParameter(iPar, 0.);
+ }
+ hBfit->Fit(fBo,"0qR");
+ //hBfit->SetNameTitle("bgrd_fit");
+ arrResults->AddAt(fBo,1);
+
+
+ // =======
+ // 2.
+ // =======
+ // Fit the whole spectrum with peak and background
+ TF1 *fSB = new TF1("bgrd_peak_fit",MinvFun,fFitMin,fFitMax,nMinv);
+ fSB->FixParameter(0, fPolDeg);
+ fSB->SetParameter(1, peakScale);
+ // copy the polynomial parameters
+ for (Int_t iPar=0; iPar<=fPolDeg; iPar++)
+ fSB->SetParameter(2+iPar, fBo->GetParameter(iPar+1));
+ hMinv->Fit(fSB,"0qR");
+ arrResults->AddAt(fSB,2);
+
+
+ // =======
+ // 3.
+ // =======
+ // Create the background function
+ TF1 *fB = new TF1("bgrdOnly_fkt",BgndFun,fFitMin,fFitMax,nBgnd);
+ fB->FixParameter(0,fPolDeg);
+ for (Int_t iDeg=0; iDeg<=fPolDeg; iDeg++) {
+ fB->SetParameter(1+iDeg,fSB->GetParameter(2+iDeg));
+ fB->SetParError(1+iDeg,fSB->GetParError(2+iDeg));
+ }
+ // create background histogram from background function
+ hBgrd->Eval(fB);
+ hBgrd->Fit(fB,"0qR");
+ // calculate the integral and integral error from fit function
+ Double_t intc = fB->Integral(intAreaEdgeLo, intAreaEdgeHi) * norm;
+ Double_t inte = fB->IntegralError(intAreaEdgeLo, intAreaEdgeHi) * norm;
+ arrResults->AddAt(fB,3);
+
+ // Fill the background spectrum erros. Use the error from the fit function for the background fB
+ for (Int_t iBin = 0; iBin <= hBgrd->GetNbinsX(); iBin++) {
+ Double_t x = hBgrd->GetBinCenter(iBin);
+ if ((x >= fFitMin) && (x <= fFitMax)) {
+ Double_t binte = inte / TMath::Sqrt((binIntHi-binIntLo)+1);
+ hBgrd->SetBinError(iBin,binte);
+ }
+ }
+ arrResults->AddAt(hBgrd,4);
+
+ // =======
+ // 4.
+ // =======
+ // Subtract the background
+ hSigF->Add(hMinv,hBgrd,1.0,-1.0);
+ for (Int_t iBin = 0; iBin <= hSigF->GetNbinsX(); iBin++) {
+ Double_t x = hSigF->GetBinCenter(iBin);
+ if ((x < fFitMin) || (x > fFitMax)) {
+ hSigF->SetBinContent(iBin,0.0);
+ hSigF->SetBinError(iBin,0.0);
+ }
+ }
+ hSigF->SetNameTitle("peak_only","");
+ arrResults->AddAt(hSigF,5);
+
+ // =======
+ // 5.
+ // =======
+ // Fit the background-subtracted spectrum
+ TF1 *fS = new TF1("peakOnly_fit",PeakFunCB,fFitMin,fFitMax,5);
+ fS->SetParameters(-.05,1,kJPMass,.003,700);
+ fS->SetParNames("alpha","n","meanx","sigma","N");
+ hSigF->Fit(fS,"0qR");
+ arrResults->AddAt(fS,6);
+
+
+ // connect data members
+ fFuncSignal = (TF1*) arrResults->At(6)->Clone();
+ fFuncBackground = (TF1*) arrResults->At(3)->Clone();
+ fFuncSigBack = (TF1*) arrResults->At(2)->Clone();
+ fHistSignal = (TH1F*)arrResults->At(5)->Clone();
+ fHistBackground = (TH1F*)arrResults->At(4)->Clone();
+
+ // fit results
+ Double_t chi2 = fSB->GetChisquare();
+ Int_t ndf = fSB->GetNDF();
+ fChi2Dof = chi2/ndf;
+
+ // signal + signal error
+ fValues(0) = hSigF->IntegralAndError(binIntLo, binIntHi, fErrors(0));
+ fValues(1) = intc; // background
+ fErrors(1) = inte; // background error
+ // S/B (2) and significance (3)
+ SetSignificanceAndSOB();
+ fValues(4) = fS->GetParameter(2); // mass
+ fErrors(4) = fS->GetParError(2); // mass error
+ fValues(5) = fS->GetParameter(3); // mass wdth
+ fErrors(5) = fS->GetParError(3); // mass wdth error
+
+
+ delete arrResults;
+
+}
+//______________________________________________________________________________
+Double_t AliDielectronSignalFunc::BgndFun(const Double_t *x, const Double_t *par) {
+ // parameters
+ // [0]: degree of polynomial
+ // [1]: constant polynomial coefficient
+ // [2]..: higher polynomial coefficients
+
+ Int_t deg = ((Int_t) par[0]);
+
+ Double_t f = 0.0;
+ Double_t yy = 1.0;
+ Double_t xx = x[0];
+
+ for (Int_t i = 0; i <= deg; i++) {
+ f += par[i+1] * yy;
+ yy *= xx;
+ }
+
+
+ return f;
+}
+//______________________________________________________________________________
+Double_t AliDielectronSignalFunc::PeakFun(const Double_t *x, const Double_t *par) {
+ // Fit MC signal shape
+ // parameters
+ // [0]: scale for simpeak
+
+ Double_t xx = x[0];
+
+ TH1F *hPeak = fgHistSimPM;
+ if (!hPeak) {
+ printf("F-AliDielectronSignalFunc::PeakFun: No histogram for peak fit defined!\n");
+ }
+
+ Int_t idx = hPeak->FindBin(xx);
+ if ((idx <= 1) ||
+ (idx >= hPeak->GetNbinsX())) {
+ return 0.0;
+ }
+
+ return (par[0] * hPeak->GetBinContent(idx));
+
+}
+
+//______________________________________________________________________________
+Double_t AliDielectronSignalFunc::MinvFun(const Double_t *x, const Double_t *par) {
+ // parameters
+ // [0]: degree of polynomial -> [0] for BgndFun
+ // [1]: scale for simpeak -> [0] for PeakFun
+ // [2]: constant polynomial coefficient -> [1] for BgndFun
+ // [3]..: higher polynomial coefficients -> [2].. for BgndFun
+
+ Int_t deg = ((Int_t) par[0]);
+ Double_t parPK[25], parBG[25];
+
+ parBG[0] = par[0]; // degree of polynomial
+
+ parPK[0] = par[1]; // MC minv scale
+ for (Int_t i = 0; i <= deg; i++) parBG[i+1] = par[i+2]; // polynomial coefficients
+
+ Double_t peak = PeakFun(x,parPK);
+ Double_t bgnd = BgndFun(x,parBG);
+ Double_t f = peak + bgnd;
+
+ return f;
+}
+
+//______________________________________________________________________________
+Double_t AliDielectronSignalFunc::PeakFunCB(const Double_t *x, const Double_t *par) {
+ // Crystal Ball function fit
+
+ Double_t alpha = par[0];
+ Double_t n = par[1];
+ Double_t meanx = par[2];
+ Double_t sigma = par[3];
+ Double_t nn = par[4];
+
+ Double_t a = TMath::Power((n/TMath::Abs(alpha)), n) * TMath::Exp(-.5*alpha*alpha);
+ Double_t b = n/TMath::Abs(alpha) - TMath::Abs(alpha);
+
+ Double_t arg = (x[0] - meanx)/sigma;
+ Double_t fitval = 0;
+
+ if (arg > -1.*alpha) {
+ fitval = nn * TMath::Exp(-.5*arg*arg);
+ } else {
+ fitval = nn * a * TMath::Power((b-arg), (-1*n));
+ }
+
+ return fitval;
+}
+
//______________________________________________
void AliDielectronSignalFunc::ProcessFit(TObjArray * const arrhist) {
if(fRebin>1)
fHistDataPM->Rebin(fRebin);
- fHistSignal = new TH1F("HistSignal", "Like-Sign substracted signal",
+ fHistSignal = new TH1F("HistSignal", "Fit substracted signal",
fHistDataPM->GetXaxis()->GetNbins(),
fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
- fHistBackground = new TH1F("HistBackground", "Like-sign contribution",
+ fHistBackground = new TH1F("HistBackground", "Fit contribution",
fHistDataPM->GetXaxis()->GetNbins(),
fHistDataPM->GetXaxis()->GetXmin(), fHistDataPM->GetXaxis()->GetXmax());
} else {
grSig->Draw("f");
}
- if(fMethod==kFitted) grBack->Draw("f");
+ if(fMethod==kFitted || fMethod==kFittedMC) grBack->Draw("f");
fFuncSigBack->Draw("same");
fFuncSigBack->SetLineWidth(2);
if(fMethod==kLikeSign) {
fHistDataMM->Draw("same");
}
- if(fMethod==kFitted)
+ if(fMethod==kFitted || fMethod==kFittedMC)
fFuncBackground->Draw("same");
if (optStat) DrawStats();
signalProcess->Print();
*/
-
#include <TVectorT.h>
#include <TString.h>
#include <TH1F.h>
virtual ~AliDielectronSignalFunc();
virtual void Process(TObjArray * const arrhist);
+ void ProcessFitIKF(TObjArray * const arrhist); // fit the SE +- distribution with mc shape and best chi2/dof
+ void FitOneMinv(TH1F *hMinv, TH1F *hSim, Int_t pod); // fit procedure for one single minv spectrum
+
void ProcessFit(TObjArray * const arrhist); // fit the SE +- distribution
void ProcessLS(TObjArray * const arrhist); // substract the fitted SE like-sign background
void ProcessEM(TObjArray * const arrhist); // substract the fitted SE+ME like-sign background
TF1* GetBackgroundFunction() const { return fFuncBackground; }
TF1* GetCombinedFunction() const { return fFuncSigBack; }
+ Int_t GetPolDeg() const { return fPolDeg; }
+ Double_t GetChi2Dof() const { return fChi2Dof; }
+
virtual void Draw(const Option_t* option = "");
private:
+
+ static Double_t BgndFun(const Double_t *x, const Double_t *par); // polynomial fit function
+ static Double_t PeakFun(const Double_t *x, const Double_t *par); // create peak function from mc shape
+ static Double_t MinvFun(const Double_t *x, const Double_t *par); // combined function of BgndFun + PeakFun
+ static Double_t PeakFunCB(const Double_t *x, const Double_t *par); // crystal ball function for background-subtracted peak fit
+
TF1 *fFuncSignal; // Function for the signal description
TF1 *fFuncBackground; // Function for the background description
TString fFitOpt; // fit option used
Bool_t fUseIntegral; // use the integral of the fitted functions to extract signal and background
+ Int_t fPolDeg; // polynomial degree of the background function
+ Double_t fChi2Dof; // chi2/dof of the fitted inv mass spectra
+ static TH1F* fgHistSimPM; // simulated peak shape
+
ClassDef(AliDielectronSignalFunc,2) // Dielectron SignalFunc
};
fMother2(0),
fGrandMother1(0),
fGrandMother2(0),
+ fLeg1Exclude(kFALSE),
+ fLeg2Exclude(kFALSE),
+ fMother1Exclude(kFALSE),
+ fMother2Exclude(kFALSE),
+ fGrandMother1Exclude(kFALSE),
+ fGrandMother2Exclude(kFALSE),
fLeg1Source(kDontCare),
fLeg2Source(kDontCare),
fMother1Source(kDontCare),
fMother2(0),
fGrandMother1(0),
fGrandMother2(0),
+ fLeg1Exclude(kFALSE),
+ fLeg2Exclude(kFALSE),
+ fMother1Exclude(kFALSE),
+ fMother2Exclude(kFALSE),
+ fGrandMother1Exclude(kFALSE),
+ fGrandMother2Exclude(kFALSE),
fLeg1Source(kDontCare),
fLeg2Source(kDontCare),
fMother1Source(kDontCare),
#include <TNamed.h>
+/*
+ Ionut Cristian Arsene, iarsene@cern.ch
+ */
+
/*
Monte Carlo signal definition:
Leg #1 <-- Mother #1 <-- Grandmother #1
|
Leg #2 <-- Mother #2 <-- Grandmother #2
- All particles can be classified as:
+
+ For every leg, mother or grand-mother, a PDG code and a source can be specified.
+
+ 1.) For the PDG codes, the PYTHIA standard is used.
+ A few non-existent PYTHIA codes are used to select more than one PYTHIA code. All these are described below
+ and implemented in AliDielectronMC::ComparePDG() function:
+ 0 - default, accepts all PYTHIA codes
+ 100 - light unflavoured mesons in the code range 100-199
+ 200 - --"-- 200-299
+ 300 - strange mesons in the code range 300-399
+ 400 - charmed mesons in the code range 400-499
+ 401 - open charm mesons (all D and D* mesons) 400-439
+ 402 - open charm mesons and baryons together 400-439, 4000-4399
+ 403 - all charm hadrons (mesons and baryons) 400-499, 4000-4999
+ 500 - beauty mesons in the code range 500-599
+ 501 - open beauty mesons 500-549
+ 502 - open beauty mesons and baryons 500-549, 5000-5499
+ 503 - all beauty hadrons 500-599, 5000-5999
+ 1000 - light unflavoured baryons in the code range 1000-1999
+ 2000 - --"-- 2000-2999
+ 3000 - strange baryons in the code range 3000-3999
+ 4000 - charmed baryons in the code range 4000-4999
+ 4001 - open charm baryons 4000-4399
+ 5000 - beauty baryons in the code range 5000-5999
+ 5001 - open beauty baryons 5000-5499
+
+ 2.) If the exclusion flags are turned ON then the PDG codes required and the conventional codes described above
+ are used to exclude the selected particles.
+
+ 3.) If the selection of both charges is switched ON then the PDG codes act on both particles and anti-particles.
+
+ 4.) Particles sources implemented:
1. Primary - particle originating in the physics event
- 2. Secondary - particle created during the GEANT propagation due to interaction of primaries with the material
- 3. Direct - particle directly created in the collision (has no mother)
- 4. Secondary - particle which is the product of the decay or reinteraction of another particle
- The 2 legs can originate from the same or different mother particles.
+ 2. FinalState- stable(final state) particles which reach the detector -> according to AliStack::IsPhysicalPrimary()
+ 3. Direct - primary particle which has no mother (e.g. J/psi's added to pythia MC events via generator cocktails,
+ particles generated in a sudden freeze-out in thermal models, initial state particles)
+ 4. Secondary - particle created during the GEANT propagation due to interaction of final state primaries with the material
+
+ 5.) The 2 legs can originate from the same or different mother particles. This can be specified via the SetMotherRelation()
+ method call.
+
+ 6.) The filling of the pure MC step can be switched on using SetFillPureMCStep() method call. This should be used
+ with care since at the pure MC information level there is no cut applied and for abundant particles the combinatorics
+ can be very high.
*/
public:
enum EBranchRelation {kUndefined=0, kSame, kDifferent};
- enum ESource {kDontCare=0, kPrimary, kSecondary, kDirect, kDecayProduct};
+ enum ESource {kDontCare=0, kPrimary, kFinalState, kDirect, kSecondary};
AliDielectronSignalMC();
AliDielectronSignalMC(const Char_t* name, const Char_t* title);
virtual ~AliDielectronSignalMC();
- void SetLegPDGs(Int_t pdg1, Int_t pdg2) {fLeg1 = pdg1; fLeg2 = pdg2;}
- void SetMotherPDGs(Int_t pdg1, Int_t pdg2) {fMother1 = pdg1; fMother2 = pdg2;}
- void SetGrandMotherPDGs(Int_t pdg1, Int_t pdg2) {fGrandMother1 = pdg1; fGrandMother2 = pdg2;}
- void SetLegSources(ESource s1, ESource s2) {fLeg1Source = s1; fLeg2Source = s2;}
- void SetMotherSources(ESource s1, ESource s2) {fMother1Source = s1; fMother2Source = s2;}
- void SetGrandMotherSources(ESource s1, ESource s2) {fGrandMother1Source = s1; fGrandMother2Source = s2;}
- void SetCheckBothChargesLegs(Bool_t flag1, Bool_t flag2) {fCheckBothChargesLeg1 = flag1; fCheckBothChargesLeg2 = flag2;}
- void SetCheckBothChargesMothers(Bool_t flag1, Bool_t flag2) {fCheckBothChargesMother1 = flag1; fCheckBothChargesMother2 = flag2;}
+ void SetLegPDGs(Int_t pdg1, Int_t pdg2, Bool_t exclud