#include <TCanvas.h>
#include <TParticle.h>
#include <TParticlePDG.h>
+#include <TH1F.h>
#include <TChain.h>
#include <TSelector.h>
-
+#include <TFile.h>
#include <AliLog.h>
#include <AliGenEventHeader.h>
#include <AliTracker.h>
#include <AliHeader.h>
-
+#include <AliESDVertex.h>
+#include <AliESD.h>
+#include <AliESDtrack.h>
+#include <AliRunLoader.h>
+#include <AliStack.h>
#include "esdTrackCuts/AliESDtrackCuts.h"
-#include "dNdEtaCorrection.h"
+#include "dNdEta/AlidNdEtaCorrection.h"
+#include "AliPWG0Helper.h"
ClassImp(AlidNdEtaCorrectionSelector)
-AlidNdEtaCorrectionSelector::AlidNdEtaCorrectionSelector(TTree *) :
- AliSelector(),
+AlidNdEtaCorrectionSelector::AlidNdEtaCorrectionSelector() :
+ AliSelectorRL(),
fEsdTrackCuts(0),
fdNdEtaCorrection(0),
- fdNdEtaCorrectionFinal(0)
+ fPIDParticles(0),
+ fPIDTracks(0),
+ fSignMode(0)
{
//
// Constructor. Initialization of pointers
// list is deleted by the TSelector dtor
}
+Bool_t AlidNdEtaCorrectionSelector::SignOK(TParticlePDG* particle)
+{
+ // returns if a particle with this sign should be counted
+ // this is determined by the value of fSignMode, which should have the same sign
+ // as the charge
+ // if fSignMode is 0 all particles are counted
+
+ if (fSignMode == 0)
+ return kTRUE;
+
+ if (!particle)
+ {
+ printf("WARNING: not counting a particle that does not have a pdg particle\n");
+ return kFALSE;
+ }
+
+ Double_t charge = particle->Charge();
+
+ if (fSignMode > 0)
+ if (charge < 0)
+ return kFALSE;
+
+ if (fSignMode < 0)
+ if (charge > 0)
+ return kFALSE;
+
+ return kTRUE;
+}
+
void AlidNdEtaCorrectionSelector::Begin(TTree * tree)
{
// The Begin() function is called at the start of the query.
// When running with PROOF Begin() is only called on the client.
// The tree argument is deprecated (on PROOF 0 is passed).
- AliSelector::Begin(tree);
+ AliSelectorRL::Begin(tree);
+
+ TString option = GetOption();
+ AliInfo(Form("Called with option %s.", option.Data()));
+
+ if (option.Contains("only-positive"))
+ {
+ AliInfo("Processing only positive particles.");
+ fSignMode = 1;
+ }
+ else if (option.Contains("only-negative"))
+ {
+ AliInfo("Processing only negative particles.");
+ fSignMode = -1;
+ }
}
void AlidNdEtaCorrectionSelector::SlaveBegin(TTree * tree)
// When running with PROOF SlaveBegin() is called on each slave server.
// The tree argument is deprecated (on PROOF 0 is passed).
- AliSelector::SlaveBegin(tree);
+ AliSelectorRL::SlaveBegin(tree);
- fdNdEtaCorrection = new dNdEtaCorrection();
+ fdNdEtaCorrection = new AlidNdEtaCorrection("dndeta_correction", "dndeta_correction");
- if (fChain)
- fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (fChain->GetUserInfo()->FindObject("AliESDtrackCuts"));
+ if (fTree)
+ fEsdTrackCuts = dynamic_cast<AliESDtrackCuts*> (fTree->GetUserInfo()->FindObject("AliESDtrackCuts"));
if (!fEsdTrackCuts)
AliDebug(AliLog::kError, "ERROR: Could not read EsdTrackCuts from user info");
-}
-Bool_t AlidNdEtaCorrectionSelector::Notify()
-{
- // The Notify() function is called when a new file is opened. This
- // can be either for a new TTree in a TChain or when when a new TTree
- // is started when using PROOF. Typically here the branch pointers
- // will be retrieved. It is normaly not necessary to make changes
- // to the generated code, but the routine can be extended by the
- // user if needed.
-
- if (AliSelector::Notify() == kFALSE)
- return kFALSE;
+ fPIDParticles = new TH1F("pid_particles", "PID of generated primary particles", 10001, -5000.5, 5000.5);
+ fPIDTracks = new TH1F("pid_tracks", "MC PID of reconstructed tracks", 10001, -5000.5, 5000.5);
- return kTRUE;
+ fClustersITSPos = new TH1F("clusters_its_pos", "clusters_its_pos", 7, -0.5, 6.5);
+ fClustersTPCPos = new TH1F("clusters_tpc_pos", "clusters_tpc_pos", 160, -0.5, 159.5);
+
+ fClustersITSNeg = new TH1F("clusters_its_neg", "clusters_its_neg", 7, -0.5, 6.5);
+ fClustersTPCNeg = new TH1F("clusters_tpc_neg", "clusters_tpc_neg", 160, -0.5, 159.5);
}
Bool_t AlidNdEtaCorrectionSelector::Process(Long64_t entry)
// WARNING when a selector is used with a TChain, you must use
// the pointer to the current TTree to call GetEntry(entry).
// The entry is always the local entry number in the current tree.
- // Assuming that fChain is the pointer to the TChain being processed,
- // use fChain->GetTree()->GetEntry(entry).
+ // Assuming that fTree is the pointer to the TChain being processed,
+ // use fTree->GetTree()->GetEntry(entry).
- if (AliSelector::Process(entry) == kFALSE)
+ if (AliSelectorRL::Process(entry) == kFALSE)
return kFALSE;
// check prerequesites
return kFALSE;
}
+ AliStack* stack = GetStack();
+ if (!stack)
+ {
+ AliDebug(AliLog::kError, "Stack not available");
+ return kFALSE;
+ }
+
if (!fEsdTrackCuts)
{
AliDebug(AliLog::kError, "fESDTrackCuts not available");
return kFALSE;
}
- // ########################################################
- // get the EDS vertex
- const AliESDVertex* vtxESD = fESD->GetVertex();
-
- Bool_t goodEvent = kTRUE;
+ Bool_t vertexReconstructed = AliPWG0Helper::IsVertexReconstructed(fESD);
- // the vertex should be reconstructed
- if (strcmp(vtxESD->GetName(),"default")==0)
- goodEvent = kFALSE;
+ Bool_t eventTriggered = AliPWG0Helper::IsEventTriggered(fESD);
- Double_t vtx_res[3];
- vtx_res[0] = vtxESD->GetXRes();
- vtx_res[1] = vtxESD->GetYRes();
- vtx_res[2] = vtxESD->GetZRes();
-
- // the resolution should be reasonable???
- if (vtx_res[2]==0 || vtx_res[2]>0.1)
- goodEvent = kFALSE;
-
+ fdNdEtaCorrection->IncreaseEventCount();
+ if (eventTriggered)
+ fdNdEtaCorrection->IncreaseTriggeredEventCount();
- // ########################################################
// get the MC vertex
AliGenEventHeader* genHeader = header->GenEventHeader();
TArrayF vtxMC(3);
genHeader->PrimaryVertex(vtxMC);
- // ########################################################
// loop over mc particles
- TTree* particleTree = GetKinematics();
- TParticle* particle = 0;
- particleTree->SetBranchAddress("Particles", &particle);
+ Int_t nPrim = stack->GetNprimary();
- Int_t nPrim = header->GetNprimary();
- Int_t nTotal = header->GetNtrack();
-
- for (Int_t i_mc = nTotal - nPrim; i_mc < nTotal; ++i_mc)
+ for (Int_t iMc = 0; iMc < nPrim; ++iMc)
{
- particleTree->GetEntry(i_mc);
+ AliDebug(AliLog::kDebug+1, Form("MC Loop: Processing particle %d.", iMc));
+
+ TParticle* particle = stack->Particle(iMc);
if (!particle)
+ {
+ AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (mc loop).", iMc));
continue;
+ }
- if (IsPrimaryCharged(particle, nPrim) == kFALSE)
+ if (AliPWG0Helper::IsPrimaryCharged(particle, nPrim) == kFALSE)
+ continue;
+
+ if (SignOK(particle->GetPDG()) == kFALSE)
continue;
Float_t eta = particle->Eta();
-
- fdNdEtaCorrection->FillParticleAllEvents(vtxMC[2], eta);
-
- if (goodEvent)
- fdNdEtaCorrection->FillParticleWhenGoodEvent(vtxMC[2], eta);
-
+ Float_t pt = particle->Pt();
+
+ if (vertexReconstructed)
+ {
+ fdNdEtaCorrection->FillParticle(vtxMC[2], eta, pt);
+ if (pt > 0.1 && pt < 0.2)
+ fPIDParticles->Fill(particle->GetPdgCode());
+ }
+
+ fdNdEtaCorrection->FillParticleAllEvents(eta, pt);
+ if (eventTriggered)
+ fdNdEtaCorrection->FillParticleWhenEventTriggered(eta, pt);
}// end of mc particle
// ########################################################
// loop over esd tracks
Int_t nTracks = fESD->GetNumberOfTracks();
+
+ // count the number of "good" tracks as parameter for vertex reconstruction efficiency
+ Int_t nGoodTracks = 0;
for (Int_t t=0; t<nTracks; t++)
{
+ AliDebug(AliLog::kDebug+1, Form("ESD Loop: Processing track %d.", t));
+
AliESDtrack* esdTrack = fESD->GetTrack(t);
// cut the esd track?
if (!fEsdTrackCuts->AcceptTrack(esdTrack))
continue;
- // using the eta of the mc particle
+ nGoodTracks++;
+
+ // using the properties of the mc particle
Int_t label = TMath::Abs(esdTrack->GetLabel());
if (label == 0)
{
AliDebug(AliLog::kWarning, Form("WARNING: cannot find corresponding mc part for track %d.", t));
continue;
}
- particleTree->GetEntry(nTotal - nPrim + label);
- fdNdEtaCorrection->FillParticleWhenMeasuredTrack(vtxMC[2], particle->Eta());
+ TParticle* particle = stack->Particle(label);
+ if (!particle)
+ {
+ AliDebug(AliLog::kError, Form("UNEXPECTED: particle with label %d not found in stack (track loop).", label));
+ continue;
+ }
+
+ if (SignOK(particle->GetPDG()) == kFALSE)
+ continue;
+ if (vertexReconstructed)
+ {
+ fdNdEtaCorrection->FillParticleWhenMeasuredTrack(vtxMC[2], particle->Eta(), particle->Pt());
+ if (particle->Pt() > 0.1 && particle->Pt() < 0.2)
+ {
+ fPIDTracks->Fill(particle->GetPdgCode());
+ if (particle->GetPDG()->Charge() > 0)
+ {
+ fClustersITSPos->Fill(esdTrack->GetITSclusters(0));
+ fClustersTPCPos->Fill(esdTrack->GetTPCclusters(0));
+ }
+ else
+ {
+ fClustersITSNeg->Fill(esdTrack->GetITSclusters(0));
+ fClustersTPCNeg->Fill(esdTrack->GetTPCclusters(0));
+ }
+ }
+ }
} // end of track loop
+ fdNdEtaCorrection->FillEvent(vtxMC[2], nGoodTracks);
+ if (eventTriggered)
+ {
+ fdNdEtaCorrection->FillEventWithTrigger(vtxMC[2], nGoodTracks);
+ if (vertexReconstructed)
+ fdNdEtaCorrection->FillEventWithTriggerWithReconstructedVertex(vtxMC[2], nGoodTracks);
+ }
+
return kTRUE;
}
// have been processed. When running with PROOF SlaveTerminate() is called
// on each slave server.
- AliSelector::SlaveTerminate();
+ AliSelectorRL::SlaveTerminate();
// Add the histograms to the output on each slave server
if (!fOutput)
// a query. It always runs on the client, it can be used to present
// the results graphically or save the results to file.
- AliSelector::Terminate();
+ AliSelectorRL::Terminate();
- fdNdEtaCorrectionFinal = dynamic_cast<dNdEtaCorrection*> (fOutput->FindObject("dndeta_correction"));
+ fdNdEtaCorrection = dynamic_cast<AlidNdEtaCorrection*> (fOutput->FindObject("dndeta_correction"));
+ if (!fdNdEtaCorrection)
+ {
+ AliDebug(AliLog::kError, "Could not read object from output list");
+ return;
+ }
- fdNdEtaCorrectionFinal->Finish();
+ fdNdEtaCorrection->Finish();
- TFile* fout = new TFile("correction_map.root","RECREATE");
+ TFile* fout = new TFile(Form("correction_map%s.root", GetOption()), "RECREATE");
fEsdTrackCuts->SaveHistograms("esd_track_cuts");
- fdNdEtaCorrectionFinal->SaveHistograms();
+ fdNdEtaCorrection->SaveHistograms();
fout->Write();
fout->Close();
- fdNdEtaCorrectionFinal->DrawHistograms();
+ fdNdEtaCorrection->DrawHistograms();
+
+ new TCanvas("pidcanvas", "pidcanvas", 500, 500);
+
+ fPIDParticles->Draw();
+ fPIDTracks->SetLineColor(2);
+ fPIDTracks->Draw("SAME");
+
+ TDatabasePDG* pdgDB = new TDatabasePDG;
+
+ for (Int_t i=0; i <= fPIDParticles->GetNbinsX()+1; ++i)
+ if (fPIDParticles->GetBinContent(i) > 0)
+ printf("PDG = %d (%s): generated: %d, reconstructed: %d, ratio: %f\n", (Int_t) fPIDParticles->GetBinCenter(i), pdgDB->GetParticle((Int_t) fPIDParticles->GetBinCenter(i))->GetName(), (Int_t) fPIDParticles->GetBinContent(i), (Int_t) fPIDTracks->GetBinContent(i), ((fPIDTracks->GetBinContent(i) > 0) ? fPIDParticles->GetBinContent(i) / fPIDTracks->GetBinContent(i) : -1));
+
+ delete pdgDB;
+ pdgDB = 0;
+
+ TCanvas* canvas = new TCanvas("clusters", "clusters", 1000, 500);
+ canvas->Divide(2, 1);
+
+ canvas->cd(1);
+ fClustersITSPos->Draw();
+ fClustersITSNeg->SetLineColor(kRed);
+ fClustersITSNeg->Draw("SAME");
+
+ canvas->cd(2);
+ fClustersTPCPos->Draw();
+ fClustersTPCNeg->SetLineColor(kRed);
+ fClustersTPCNeg->Draw("SAME");
}