forked from AliceO2Group/O2Physics
-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PWGEM/PhotonMeson: add a task for chic1
- Loading branch information
Showing
3 changed files
with
338 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,328 @@ | ||
// Copyright 2019-2020 CERN and copyright holders of ALICE O2. | ||
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders. | ||
// All rights not expressly granted are reserved. | ||
// | ||
// This software is distributed under the terms of the GNU General Public | ||
// License v3 (GPL Version 3), copied verbatim in the file "COPYING". | ||
// | ||
// In applying this license CERN does not waive the privileges and immunities | ||
// granted to it by virtue of its status as an Intergovernmental Organization | ||
// or submit itself to any jurisdiction. | ||
// | ||
// ======================== | ||
// | ||
// This code runs loop over photons and ee for chic1->J/psi + gamma | ||
// Please write to: [email protected], [email protected] | ||
|
||
#include <cstring> | ||
#include <iterator> | ||
|
||
#include "TString.h" | ||
#include "Math/Vector4D.h" | ||
#include "Framework/runDataProcessing.h" | ||
#include "Framework/AnalysisTask.h" | ||
#include "Framework/AnalysisDataModel.h" | ||
#include "Framework/ASoAHelpers.h" | ||
#include "Common/Core/RecoDecay.h" | ||
#include "PWGEM/PhotonMeson/Utils/PairUtilities.h" | ||
#include "PWGEM/PhotonMeson/DataModel/gammaTables.h" | ||
#include "PWGEM/PhotonMeson/Core/V0PhotonCut.h" | ||
#include "PWGEM/PhotonMeson/Core/DalitzEECut.h" | ||
#include "PWGEM/PhotonMeson/Core/CutsLibrary.h" | ||
#include "PWGEM/PhotonMeson/Core/HistogramsLibrary.h" | ||
|
||
using namespace o2; | ||
using namespace o2::aod; | ||
using namespace o2::framework; | ||
using namespace o2::framework::expressions; | ||
using namespace o2::soa; | ||
using namespace o2::aod::photonpair; | ||
using namespace o2::aod::pwgem::photon; | ||
|
||
using MyCollisions = soa::Join<aod::EMReducedEvents, aod::EMReducedEventsMult, aod::EMReducedEventsCent, aod::EMReducedEventsNgPCM, aod::EMReducedEventsNee>; | ||
using MyCollision = MyCollisions::iterator; | ||
|
||
using MyV0Photons = soa::Join<aod::V0PhotonsKF, aod::V0KFEMReducedEventIds>; | ||
using MyV0Photon = MyV0Photons::iterator; | ||
|
||
using MyDalitzEEs = soa::Join<aod::DalitzEEs, aod::DalitzEEEMReducedEventIds>; | ||
using MyDalitzEE = MyDalitzEEs::iterator; | ||
|
||
using MyPrimaryElectrons = soa::Join<aod::EMPrimaryElectrons, aod::EMPrimaryElectronEMReducedEventIds, aod::EMPrimaryElectronsPrefilterBit>; | ||
using MyPrimaryElectron = MyPrimaryElectrons::iterator; | ||
|
||
struct Chic1ToJpsiGamma { | ||
|
||
Configurable<int> cfgCentEstimator{"cfgCentEstimator", 2, "FT0M:0, FT0A:1, FT0C:2"}; | ||
Configurable<float> cfgCentMin{"cfgCentMin", 0, "min. centrality"}; | ||
Configurable<float> cfgCentMax{"cfgCentMax", 999, "max. centrality"}; | ||
|
||
Configurable<float> maxY{"maxY", 0.9, "maximum rapidity for reconstructed particles"}; | ||
Configurable<std::string> fConfigPCMCuts{"cfgPCMCuts", "qc,nocut", "Comma separated list of V0 photon cuts"}; | ||
Configurable<std::string> fConfigDalitzEECuts{"cfgDalitzEECuts", "mee2000_4000_minpt1000_maxeta09_tpconly", "Comma separated list of ee cuts"}; | ||
|
||
Configurable<std::string> fConfigEMEventCut{"cfgEMEventCut", "minbias", "em event cut"}; // only 1 event cut per wagon | ||
EMEventCut fEMEventCut; | ||
static constexpr std::string_view event_types[2] = {"before", "after"}; | ||
|
||
OutputObj<THashList> fOutputEvent{"Event"}; | ||
OutputObj<THashList> fOutputPair{"Pair"}; // 2-photon pair | ||
THashList* fMainList = new THashList(); | ||
|
||
std::vector<V0PhotonCut> fPCMCuts; | ||
std::vector<DalitzEECut> fDalitzEECuts; | ||
|
||
std::vector<std::string> fPairNames; | ||
void init(InitContext& context) | ||
{ | ||
if (context.mOptions.get<bool>("processPCMDalitzEE")) { | ||
fPairNames.push_back("PCMDalitzEE"); | ||
} | ||
|
||
DefinePCMCuts(); | ||
DefineDalitzEECuts(); | ||
addhistograms(); | ||
TString ev_cut_name = fConfigEMEventCut.value; | ||
fEMEventCut = *eventcuts::GetCut(ev_cut_name.Data()); | ||
|
||
fOutputEvent.setObject(reinterpret_cast<THashList*>(fMainList->FindObject("Event"))); | ||
fOutputPair.setObject(reinterpret_cast<THashList*>(fMainList->FindObject("Pair"))); | ||
} | ||
|
||
template <typename TCuts1, typename TCuts2> | ||
void add_pair_histograms(THashList* list_pair, const std::string pairname, TCuts1 const& cuts1, TCuts2 const& cuts2) | ||
{ | ||
for (auto& cut1 : cuts1) { | ||
for (auto& cut2 : cuts2) { | ||
std::string cutname1 = cut1.GetName(); | ||
std::string cutname2 = cut2.GetName(); | ||
|
||
THashList* list_pair_subsys = reinterpret_cast<THashList*>(list_pair->FindObject(pairname.data())); | ||
std::string photon_cut_name = cutname1 + "_" + cutname2; | ||
THashList* list_pair_subsys_photoncut = reinterpret_cast<THashList*>(o2::aod::pwgem::photon::histogram::AddHistClass(list_pair_subsys, photon_cut_name.data())); | ||
o2::aod::pwgem::photon::histogram::DefineHistograms(list_pair_subsys_photoncut, "chic1_to_jpsi_gamma"); | ||
} // end of cut2 loop | ||
} // end of cut1 loop | ||
} | ||
|
||
static constexpr std::string_view pairnames[9] = {"PCMPCM", "PHOSPHOS", "EMCEMC", "PCMPHOS", "PCMEMC", "PCMDalitzEE", "PCMDalitzMuMu", "PHOSEMC", "DalitzEEDalitzEE"}; | ||
void addhistograms() | ||
{ | ||
fMainList->SetOwner(true); | ||
fMainList->SetName("fMainList"); | ||
|
||
// create sub lists first. | ||
o2::aod::pwgem::photon::histogram::AddHistClass(fMainList, "Event"); | ||
THashList* list_ev = reinterpret_cast<THashList*>(fMainList->FindObject("Event")); | ||
|
||
o2::aod::pwgem::photon::histogram::AddHistClass(fMainList, "Pair"); | ||
THashList* list_pair = reinterpret_cast<THashList*>(fMainList->FindObject("Pair")); | ||
|
||
for (auto& pairname : fPairNames) { | ||
LOGF(info, "Enabled pairs = %s", pairname.data()); | ||
|
||
THashList* list_ev_pair = reinterpret_cast<THashList*>(o2::aod::pwgem::photon::histogram::AddHistClass(list_ev, pairname.data())); | ||
for (const auto& evtype : event_types) { | ||
THashList* list_ev_type = reinterpret_cast<THashList*>(o2::aod::pwgem::photon::histogram::AddHistClass(list_ev_pair, evtype.data())); | ||
o2::aod::pwgem::photon::histogram::DefineHistograms(list_ev_type, "Event", evtype.data()); | ||
} | ||
|
||
o2::aod::pwgem::photon::histogram::AddHistClass(list_pair, pairname.data()); | ||
if (pairname == "PCMDalitzEE") { | ||
add_pair_histograms(list_pair, pairname, fPCMCuts, fDalitzEECuts); | ||
} | ||
|
||
} // end of pair name loop | ||
} | ||
|
||
void DefinePCMCuts() | ||
{ | ||
TString cutNamesStr = fConfigPCMCuts.value; | ||
if (!cutNamesStr.IsNull()) { | ||
std::unique_ptr<TObjArray> objArray(cutNamesStr.Tokenize(",")); | ||
for (int icut = 0; icut < objArray->GetEntries(); ++icut) { | ||
const char* cutname = objArray->At(icut)->GetName(); | ||
LOGF(info, "add cut : %s", cutname); | ||
fPCMCuts.push_back(*pcmcuts::GetCut(cutname)); | ||
} | ||
} | ||
LOGF(info, "Number of PCM cuts = %d", fPCMCuts.size()); | ||
} | ||
|
||
void DefineDalitzEECuts() | ||
{ | ||
TString cutNamesStr = fConfigDalitzEECuts.value; | ||
if (!cutNamesStr.IsNull()) { | ||
std::unique_ptr<TObjArray> objArray(cutNamesStr.Tokenize(",")); | ||
for (int icut = 0; icut < objArray->GetEntries(); ++icut) { | ||
const char* cutname = objArray->At(icut)->GetName(); | ||
LOGF(info, "add cut : %s", cutname); | ||
fDalitzEECuts.push_back(*dalitzeecuts::GetCut(cutname)); | ||
} | ||
} | ||
LOGF(info, "Number of DalitzEE cuts = %d", fDalitzEECuts.size()); | ||
} | ||
|
||
template <PairType pairtype, typename TG1, typename TG2, typename TCut1, typename TCut2> | ||
bool IsSelectedPair(TG1 const& g1, TG2 const& g2, TCut1 const& cut1, TCut2 const& cut2) | ||
{ | ||
bool is_selected_pair = false; | ||
if constexpr (pairtype == PairType::kPCMDalitzEE) { | ||
is_selected_pair = o2::aod::photonpair::IsSelectedPair<aod::V0Legs, MyPrimaryElectrons>(g1, g2, cut1, cut2); | ||
} else { | ||
is_selected_pair = true; | ||
} | ||
return is_selected_pair; | ||
} | ||
|
||
template <PairType pairtype, typename TEvents, typename TPhotons1, typename TPhotons2, typename TPreslice1, typename TPreslice2, typename TCuts1, typename TCuts2, typename TLegs, typename TEMPrimaryElectrons> | ||
void SameEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons) | ||
{ | ||
THashList* list_ev_pair_before = static_cast<THashList*>(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject(event_types[0].data())); | ||
THashList* list_ev_pair_after = static_cast<THashList*>(fMainList->FindObject("Event")->FindObject(pairnames[pairtype].data())->FindObject(event_types[1].data())); | ||
THashList* list_pair_ss = static_cast<THashList*>(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); | ||
|
||
for (auto& collision : collisions) { | ||
|
||
const float centralities[3] = {collision.centFT0M(), collision.centFT0A(), collision.centFT0C()}; | ||
if (centralities[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities[cfgCentEstimator]) { | ||
continue; | ||
} | ||
|
||
o2::aod::pwgem::photon::histogram::FillHistClass<EMHistType::kEvent>(list_ev_pair_before, "", collision); | ||
if (!fEMEventCut.IsSelected(collision)) { | ||
continue; | ||
} | ||
o2::aod::pwgem::photon::histogram::FillHistClass<EMHistType::kEvent>(list_ev_pair_after, "", collision); | ||
reinterpret_cast<TH1F*>(list_ev_pair_before->FindObject("hCollisionCounter"))->Fill("accepted", 1.f); | ||
reinterpret_cast<TH1F*>(list_ev_pair_after->FindObject("hCollisionCounter"))->Fill("accepted", 1.f); | ||
|
||
auto photons1_coll = photons1.sliceBy(perCollision1, collision.globalIndex()); | ||
auto photons2_coll = photons2.sliceBy(perCollision2, collision.globalIndex()); | ||
|
||
for (auto& cut1 : cuts1) { | ||
for (auto& cut2 : cuts2) { | ||
for (auto& [g1, g2] : combinations(CombinationsFullIndexPolicy(photons1_coll, photons2_coll))) { | ||
if (!IsSelectedPair<pairtype>(g1, g2, cut1, cut2)) { | ||
continue; | ||
} | ||
auto pos_sv = g1.template posTrack_as<aod::V0Legs>(); | ||
auto ele_sv = g1.template negTrack_as<aod::V0Legs>(); | ||
auto pos_pv = g2.template posTrack_as<MyPrimaryElectrons>(); | ||
auto ele_pv = g2.template negTrack_as<MyPrimaryElectrons>(); | ||
if (pos_sv.trackId() == pos_pv.trackId() || ele_sv.trackId() == ele_pv.trackId()) { | ||
continue; | ||
} | ||
|
||
ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // pcm | ||
ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); // j/psi->ee | ||
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; | ||
if (abs(v12.Rapidity()) > maxY) { | ||
continue; | ||
} | ||
float delta_m = v12.M() - g2.mass(); | ||
reinterpret_cast<TH2F*>(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject("hDeltaM_Mee_Same"))->Fill(delta_m, g2.mass()); | ||
} // end of combination | ||
} // end of cut2 loop | ||
} // end of cut1 loop | ||
} // end of collision loop | ||
} | ||
|
||
Configurable<int> ndepth{"ndepth", 10, "depth for event mixing"}; | ||
ConfigurableAxis ConfVtxBins{"ConfVtxBins", {VARIABLE_WIDTH, -10.0f, -8.f, -6.f, -4.f, -2.f, 0.f, 2.f, 4.f, 6.f, 8.f, 10.f}, "Mixing bins - z-vertex"}; | ||
ConfigurableAxis ConfCentBins{"ConfCentBins", {VARIABLE_WIDTH, 0.0f, 5.0f, 10.0f, 20.0f, 30.0f, 40.0f, 50.0f, 60.0f, 70.0f, 80.0f, 90.0f, 100.0f, 999.f}, "Mixing bins - centrality"}; | ||
using BinningType_M = ColumnBinningPolicy<aod::collision::PosZ, aod::cent::CentFT0M>; | ||
using BinningType_A = ColumnBinningPolicy<aod::collision::PosZ, aod::cent::CentFT0A>; | ||
using BinningType_C = ColumnBinningPolicy<aod::collision::PosZ, aod::cent::CentFT0C>; | ||
BinningType_M colBinning_M{{ConfVtxBins, ConfCentBins}, true}; | ||
BinningType_A colBinning_A{{ConfVtxBins, ConfCentBins}, true}; | ||
BinningType_C colBinning_C{{ConfVtxBins, ConfCentBins}, true}; | ||
|
||
template <PairType pairtype, typename TEvents, typename TPhotons1, typename TPhotons2, typename TPreslice1, typename TPreslice2, typename TCuts1, typename TCuts2, typename TLegs, typename TEMPrimaryElectrons, typename TMixedBinning> | ||
void MixedEventPairing(TEvents const& collisions, TPhotons1 const& photons1, TPhotons2 const& photons2, TPreslice1 const& perCollision1, TPreslice2 const& perCollision2, TCuts1 const& cuts1, TCuts2 const& cuts2, TLegs const& legs, TEMPrimaryElectrons const& emprimaryelectrons, TMixedBinning const& colBinning) | ||
{ | ||
THashList* list_pair_ss = static_cast<THashList*>(fMainList->FindObject("Pair")->FindObject(pairnames[pairtype].data())); | ||
|
||
for (auto& [collision1, collision2] : soa::selfCombinations(colBinning, ndepth, -1, collisions, collisions)) { // internally, CombinationsStrictlyUpperIndexPolicy(collisions, collisions) is called. | ||
|
||
const float centralities1[3] = {collision1.centFT0M(), collision1.centFT0A(), collision1.centFT0C()}; | ||
const float centralities2[3] = {collision2.centFT0M(), collision2.centFT0A(), collision2.centFT0C()}; | ||
|
||
if (centralities1[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities1[cfgCentEstimator]) { | ||
continue; | ||
} | ||
if (centralities2[cfgCentEstimator] < cfgCentMin || cfgCentMax < centralities2[cfgCentEstimator]) { | ||
continue; | ||
} | ||
if (!fEMEventCut.IsSelected(collision1) || !fEMEventCut.IsSelected(collision2)) { | ||
continue; | ||
} | ||
|
||
auto photons_coll1 = photons1.sliceBy(perCollision1, collision1.globalIndex()); | ||
auto photons_coll2 = photons2.sliceBy(perCollision2, collision2.globalIndex()); | ||
|
||
for (auto& cut1 : cuts1) { | ||
for (auto& cut2 : cuts2) { | ||
for (auto& [g1, g2] : combinations(soa::CombinationsFullIndexPolicy(photons_coll1, photons_coll2))) { | ||
|
||
if (!IsSelectedPair<pairtype>(g1, g2, cut1, cut2)) { | ||
continue; | ||
} | ||
|
||
auto pos_sv = g1.template posTrack_as<aod::V0Legs>(); | ||
auto ele_sv = g1.template negTrack_as<aod::V0Legs>(); | ||
auto pos_pv = g2.template posTrack_as<MyPrimaryElectrons>(); | ||
auto ele_pv = g2.template negTrack_as<MyPrimaryElectrons>(); | ||
if (pos_sv.trackId() == pos_pv.trackId() || ele_sv.trackId() == ele_pv.trackId()) { | ||
continue; | ||
} | ||
ROOT::Math::PtEtaPhiMVector v1(g1.pt(), g1.eta(), g1.phi(), 0.); // pcm | ||
ROOT::Math::PtEtaPhiMVector v2(g2.pt(), g2.eta(), g2.phi(), g2.mass()); // j/psi->ee | ||
ROOT::Math::PtEtaPhiMVector v12 = v1 + v2; | ||
if (abs(v12.Rapidity()) > maxY) { | ||
continue; | ||
} | ||
float delta_m = v12.M() - g2.mass(); | ||
reinterpret_cast<TH2F*>(list_pair_ss->FindObject(Form("%s_%s", cut1.GetName(), cut2.GetName()))->FindObject("hDeltaM_Mee_Mixed"))->Fill(delta_m, g2.mass()); | ||
|
||
} // end of different photon combinations | ||
} // end of cut2 loop | ||
} // end of cut1 loop | ||
} // end of different collision combinations | ||
} | ||
|
||
Partition<MyCollisions> grouped_collisions = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); // this goes to same event. | ||
Filter collisionFilter_common = nabs(o2::aod::collision::posZ) < 10.f && o2::aod::collision::numContrib > (uint16_t)0 && o2::aod::evsel::sel8 == true; | ||
Filter collisionFilter_centrality = (cfgCentMin < o2::aod::cent::centFT0M && o2::aod::cent::centFT0M < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0A && o2::aod::cent::centFT0A < cfgCentMax) || (cfgCentMin < o2::aod::cent::centFT0C && o2::aod::cent::centFT0C < cfgCentMax); | ||
Filter collisionFilter_subsys = (o2::aod::emreducedevent::ngpcm >= 1); | ||
using MyFilteredCollisions = soa::Filtered<MyCollisions>; | ||
|
||
Filter DalitzEEFilter = o2::aod::dalitzee::sign == 0; // analyze only uls. adding LS bkg is a good idea, too. | ||
using MyFilteredDalitzEEs = soa::Filtered<MyDalitzEEs>; | ||
|
||
Preslice<MyV0Photons> perCollision_pcm = aod::v0photonkf::emreducedeventId; | ||
Preslice<MyDalitzEEs> perCollision_dalitz = aod::dalitzee::emreducedeventId; | ||
|
||
void processPCMDalitzEE(MyCollisions const& collisions, MyFilteredCollisions const& filtered_collisions, MyV0Photons const& v0photons, aod::V0Legs const& legs, MyFilteredDalitzEEs const& dielectrons, MyPrimaryElectrons const& emprimaryelectrons) | ||
{ | ||
SameEventPairing<PairType::kPCMDalitzEE>(grouped_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, legs, emprimaryelectrons); | ||
if (cfgCentEstimator == 0) { | ||
MixedEventPairing<PairType::kPCMDalitzEE>(filtered_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, legs, emprimaryelectrons, colBinning_M); | ||
} else if (cfgCentEstimator == 1) { | ||
MixedEventPairing<PairType::kPCMDalitzEE>(filtered_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, legs, emprimaryelectrons, colBinning_A); | ||
} else if (cfgCentEstimator == 2) { | ||
MixedEventPairing<PairType::kPCMDalitzEE>(filtered_collisions, v0photons, dielectrons, perCollision_pcm, perCollision_dalitz, fPCMCuts, fDalitzEECuts, legs, emprimaryelectrons, colBinning_C); | ||
} | ||
} | ||
|
||
void processDummy(MyCollisions const& collisions) {} | ||
|
||
PROCESS_SWITCH(Chic1ToJpsiGamma, processPCMDalitzEE, "pairing PCM-EE", false); | ||
PROCESS_SWITCH(Chic1ToJpsiGamma, processDummy, "Dummy function", true); | ||
}; | ||
|
||
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc) | ||
{ | ||
return WorkflowSpec{ | ||
adaptAnalysisTask<Chic1ToJpsiGamma>(cfgc, TaskName{"chic1-to-jpsigamma"})}; | ||
} |