Motivation
The motivation of this implementation is to have the possibility of using
AliCFContainer with Real Data analysis.
Pros
It would make easier to understand the influence of different variables cuts in the Lc Yield. In pPb analysis, studies using
THnSparse made by Audrey seem to make this possibility quite feasible concerning CPU and memory usage.
Working with different cuts in one single analysis reduces
GRID overall time and proc consumptions.
Cons
The
AliCFContainer is not allowed in the Lego trains, expect with the option kCheetah of the Monte Carlo
AliCFContainer
that exists in the
AliVertexingHF code.
The usage of
AliCFContainer with no proper bin selection or without a pre-selection of candidates makes the outputs huge when merging (use with care!).
Code implementations
Add Variable
Three
AddVar functions were introduced. They are able to deal with symmetric bins, by adding binMin and binMax, or with
asymmetric bins by adding an array Double_t.
TVectorD was introduced in order to save information in a TObjarray format.
The variables are simply added in the
AddtaskLambdac. It is not necessary to provide the total number of bins.
if(storeCFContainer){
TString name="fCFLambadc";
TString title="CFofLambdac";
Double_t vLcPt[16]={0.,2.,4.,7.,8.,9.,10.,11.,12.,15.,16.,18.,20.,25.,50.,100.};
Double_t vCosP[19]={0.,0.2,0.4,0.5,.7,.75,.8,.85,.9,.91,.92,.93,.94,.95,.96,.97,.98,.99,1.};
Double_t VtrackPt[34]={0.,0.3,0.4,0.5,0.6,0.7,0.8,0.9,1.,1.1,1.2,1.3,1.4,
1.5,1.6,1.7,1.8,1.9,2.,2.1,2.2.,2.3,2.4,2.5,2.6,2.7,2.8,2.9,3.0,3.5,4.0,5.0,7.0,10.};
//Any order should be fine.
//Code protection limits the number of variables up to the maximum available
//it is not recommended to add two or more variables of the same type, since there is a unique name correspondence
//So far, one can actually do it (for instance, to try different sets of binning), but do not try afterwards to get the variable by name C->GetVar(string)
Double_t range=0.13;
Double_t Upmasslimit = 2.286+range;
Double_t Lowmasslimit = 2.286-range;
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kCosP,18,vCosP);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kDecayL,50,0.,0.1);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kDCAMax,50,0,0.02);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kSigmaV,50,0.,0.05);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kDistMinToPrim,100,0.,.1);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kPtProton,33,VtrackPt);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kPtKaon,33,VtrackPt);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kPtPion,33,VtrackPt);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kd0Proton,50,0.,0.1);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kd0Kaon,50,0.,0.1);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kd0Pion,50,0.,0.1);
// lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kd0square,100,0,0.01);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kSelection,4,0.,4.);
// lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kSelectionPID,4,0.,4.);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kLcPt,15,vLcPt);
lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kInvMass,100,Lowmasslimit,Upmasslimit);
// lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kIsInjected,7,-3.,4.);
// lambdacTask->AddCFVar(AliAnalysisTaskSELambdacUp::kIsLc,7,-3.,4.);
}
.h
// MARCEL:Setters for CF Container
void AddCFVar(const int i,const int nbins,const Double_t binMin,const Double_t binMax);
void AddCFVar(const int i,const int nbins,const Double_t *binMin);
void AddCFVar(const int i,TVectorD *binMin);
TVectorD* MakeVectorBin(const int nbins,const Double_t binMin,const Double_t binMax) const;
.cxx
TVectorD* AliAnalysisTaskSELambdac::MakeVectorBin(const int nbins,const Double_t binMin,const Double_t binMax) const{
TVectorD *vectorbin=new TVectorD(nbins+1);
Double_t xmin=binMin;
Double_t xmax=binMax;
Int_t Nbins=nbins;
Double_t binWidth=(-xmin+xmax)/Nbins;
for (Int_t i=0;i<nbins+1;i++)
(*vectorbin)[i]=xmin+binWidth*(Double_t)i;
return vectorbin;
}
void AliAnalysisTaskSELambdac::AddCFVar(const int itype,const int nbins,const Double_t binMin,const Double_t binMax){
TVectorD *vector=0x0;
vector=MakeVectorBin(nbins,binMin,binMax);
AddCFVar(itype,vector);
}
void AliAnalysisTaskSELambdac::AddCFVar(const int itype,const int nbins,const Double_t *bin){
TVectorD *vector = new TVectorD(nbins+1);
for(int i=0;i<nbins+1;i++) (*vector)[i]=bin[i];
AddCFVar(itype,vector);
}
void AliAnalysisTaskSELambdac::AddCFVar(const int itype,TVectorD *bin){
if (!fVarArrayCF){
fVarArrayCF=new TObjArray();
fVarArrayCF->SetOwner();
}
if (!fVarTypes){
fVarTypes=new TArrayI(kNMaxCF);
}
if(fNVar>=kNMaxCF){
AliError("fNVarCF == Nmax Variables, not adding anymore\n");
return;
}
fVarArrayCF->Add(bin);
fVarTypes->AddAt(itype,fNVar);
fNVarCF++;
}
Variable types
The types of variable added follow a function enum introduced in the .h file. It was also introduced a proper name to each variable.
.h
enum VarTypes{
kCosP=0,
kDecayL,
kDCAMax,
kSigmaV,
kDistMinToPrim,
kPtProton,
kPtKaon,
kPtPion,
kLcPt,
kd0Proton,
kd0Kaon,
kd0Pion,
kd0square,
kSelection,
kSelectionPID,
kInvMass,
kIsInjected,
kIsLc,
kIsLcfromLb,
kNMaxCF
};
static const char* fgkVarNames[kNMaxCF];
.cxx
const char* AliAnalysisTaskSELambdac::fgkVarNames[AliAnalysisTaskSELambdac::kNMaxCF]= {"fCosP","fDecayL","fDCAMax","fSigmaV","fDistMintoPrim","fPtProton","fPtKaon","fPtPion","fLcPt","fd0Proton","fd0Kaon","fd0Pion","fd0square","fSelection","fSelectionPID","fInvMass","fIsInjected","fIsLc"};
Creating the Container
The Container is completely defined in the :CreatOutputs part of the task. It makes use of fNVar, fVarArray and fVartypes, in order to correctly define the Container.
A histogram for event counting was introduced. The reason was that the Container is written in a separate file. It seems to be important to have event counting for
checking purpose.
if(fFillCFContainer) {
fHistNEventsCF = new TH1F("fHistNEventsCF", "Number of processed events; ; Events",3,-1.5,1.5);
fHistNEventsCF->Sumw2();
fHistNEventsCF->SetMinimum(0);
Int_t nSelStep = 1;
const int nVar = fNVarCF;
if(fNVarCF<1){
AliError("NVarCF should be >=1 !");
return;
}
TString name="fCFLambadc"; //! maybe named on Addtask?
TString title="CFofLambdac";//!
Int_t nbins[nVar];
if(!fVarArrayCF){
AliError("VarArrayCF not available !");
return;
}
for (Int_t i=0;i<nVar;i++) {
Int_t nBins=(static_cast<TVectorD*>(fVarArrayCF->At(i)))->GetNoElements()-1;
nbins[i]=nBins;
if(nbins[i]==0){
AliError("\n Nbins cannot be zero !");
return;
}
}
fCFLambdac = new AliCFContainer(name,title,nSelStep,nVar,nbins);
for(int i=0;i<nVar;i++) {
int itype=GetVarType(i);
fCFLambdac->SetBinLimits(i,GetVarBin(i));
TString xname = GetCFVarName(itype);
fCFLambdac->SetVarTitle(i,xname);
}
fListCF = new TList();
fListCF->SetOwner();
fListCF->SetName("ListCF");
fListCF->Add(fHistNEventsCF);
fListCF->Add(fCFLambdac);
PostData(9,fListCF);
}
Filling the Container
The variables filled in the container follow the sequence defined by their types. In ::Exec() of .cxx
Bool_t isLc,isLcromLb and isInjected were not described here. They were used for the Upgrade task tests. One needs to think how to use them(or whether they are important)
Double_t tmp[kNMaxCF]; //All the variables to be filled
Double_t buffer[GetNVar()]; //Variables chosen to be in CF
if (fFillCFContainer&&passProdCuts>0) {
//--------------------------AUDREY : fix here the variables----------------
//AliAODTrack *track0=(AliAODTrack*)part->GetDaughter(0);
//AliAODTrack *track1=(AliAODTrack*)part->GetDaughter(1);
//AliAODTrack *track2=(AliAODTrack*)part->GetDaughter(2);
// Marcel Question AliAODTrack::Pt vs part->PtProng
//tmp[4] = TMath::Max(part->GetDist12toPrim(),part->GetDist23toPrim());
// Need to check carefully... Min instead of Max?
// tmp[9]= cuts->IsSelected(part,AliRDHFCuts::kCandidate,aod);
Double_t dcas[3]={0};
part->GetDCAs(dcas);
tmp[0]=part->CosPointingAngle();
tmp[1]=part->DecayLength();
tmp[2]=TMath::Max(dcas[0],TMath::Max(dcas[1],dcas[2]));
tmp[3]=TMath::Min(part->GetDist12toPrim(),part->GetDist23toPrim());
tmp[4]=part->GetSigmaVert();
tmp[8]=part->Pt();
if(passProdCuts==1||passProdCuts==3){
tmp[5] = part->PtProng(0);
tmp[6] = part->PtProng(1);
tmp[7] = part->PtProng(2);
tmp[9] = TMath::Abs(part->Getd0Prong(0));
tmp[10] = TMath::Abs(part->Getd0Prong(1));
tmp[11] = TMath::Abs(part->Getd0Prong(2));
}
else{
tmp[5] = part->PtProng(2);
tmp[6] = part->PtProng(1);
tmp[7] = part->PtProng(0);
tmp[9] = TMath::Abs(part->Getd0Prong(2));
tmp[10] = TMath::Abs(part->Getd0Prong(1));
tmp[11] = TMath::Abs(part->Getd0Prong(0));
}
tmp[12]=part->Prodd0d0();
tmp[13]=passProdCuts;
tmp[14]=passPIDCuts;
if(invMasspiKp>0.) tmp[15]=invMasspiKp;
if(invMasspKpi>0.) tmp[15]=invMasspKpi;
tmp[16]=IsInjected;
tmp[17]=IsLc;
tmp[18]=IsLcfromLb;
//Fills the CF according to the types defined in the AddTask
for(int i=0;i<GetNVar();i++) { buffer[i] = tmp[GetVarType(i)]; }
fCFLambdac->Fill(buffer,0);
}