Skip to content

Commit 385aec0

Browse files
committed
PWGEM/PhotonMeson: add a task to check MC V0s
1 parent 09fddeb commit 385aec0

2 files changed

Lines changed: 160 additions & 0 deletions

File tree

PWGEM/PhotonMeson/TableProducer/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -53,3 +53,8 @@ o2physics_add_dpl_workflow(produce-meson-calo
5353
SOURCES produceMesonCalo.cxx
5454
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
5555
COMPONENT_NAME Analysis)
56+
57+
o2physics_add_dpl_workflow(check-v0-mc
58+
SOURCES checkV0MC.cxx
59+
PUBLIC_LINK_LIBRARIES O2::Framework O2::DCAFitter O2Physics::AnalysisCore
60+
COMPONENT_NAME Analysis)
Lines changed: 155 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,155 @@
1+
// Copyright 2019-2020 CERN and copyright holders of ALICE O2.
2+
// See https://alice-o2.web.cern.ch/copyright for details of the copyright holders.
3+
// All rights not expressly granted are reserved.
4+
//
5+
// This software is distributed under the terms of the GNU General Public
6+
// License v3 (GPL Version 3), copied verbatim in the file "COPYING".
7+
//
8+
// In applying this license CERN does not waive the privileges and immunities
9+
// granted to it by virtue of its status as an Intergovernmental Organization
10+
// or submit itself to any jurisdiction.
11+
12+
/// \brief check MC true V0s
13+
/// \author daiki.sekihata@cern.ch
14+
15+
#include <TMath.h>
16+
#include <TVector2.h>
17+
#include "Framework/runDataProcessing.h"
18+
#include "Framework/AnalysisTask.h"
19+
#include "Framework/AnalysisDataModel.h"
20+
#include "Common/Core/trackUtilities.h"
21+
#include "PWGEM/PhotonMeson/DataModel/gammaTables.h"
22+
#include "PWGEM/PhotonMeson/Utils/PCMUtilities.h"
23+
#include "PWGEM/PhotonMeson/Utils/MCUtilities.h"
24+
25+
using namespace o2;
26+
using namespace o2::soa;
27+
using namespace o2::framework;
28+
using namespace o2::framework::expressions;
29+
30+
using MyTracks = soa::Join<aod::TracksIU, aod::TracksExtra, aod::TracksDCA, aod::TracksCovIU>;
31+
using MyTracksMC = soa::Join<MyTracks, aod::McTrackLabels>;
32+
33+
struct checkV0MC {
34+
35+
Configurable<float> maxX{"maxX", 83.1, "maximum X (starting point of track X)"};
36+
Configurable<float> maxY{"maxY", 20.0, "maximum X (starting point of track X)"};
37+
Configurable<float> minpt{"minpt", 0.01, "min pt for track"};
38+
Configurable<float> maxeta{"maxeta", 0.9, "eta acceptance"};
39+
Configurable<float> dcamin{"dcamin", 0.1, "dcamin"};
40+
Configurable<float> dcamax{"dcamax", 1e+10, "dcamax"};
41+
42+
HistogramRegistry fRegistry{
43+
"fRegistry",
44+
{
45+
{"hDiffCollId", "difference in collision id between ele/pos", {HistType::kTH1F, {{101, -50.5f, +50.5f}}}},
46+
{"hOrphanTrack", "Number of orphan track from true photon conversions", {HistType::kTH1F, {{1, 0.5f, +1.5f}}}},
47+
{"hV0PhotonCorrX", "V0 photon track iu X correlation;track iu X for ele;track iu X for pos", {HistType::kTH2F, {{100, 0, +100}, {100, 0, +100}}}},
48+
{"hV0PhotonCorrY", "V0 photon track iu Y correlation;track iu Y for ele;track iu Y diff", {HistType::kTH2F, {{200, -100, +100}, {400, -20, +20}}}},
49+
{"hV0PhotonCorrZ", "V0 photon track iu Z correlation;track iu Z for ele;track iu Z diff", {HistType::kTH2F, {{200, -100, +100}, {400, -20, +20}}}},
50+
{"hV0PhotonCorrYvsX", "V0 photon track iu Y correlation;track iu Y for ele;track iu Y diff", {HistType::kTH2F, {{100, 0, +100}, {400, -20, +20}}}},
51+
{"hV0PhotonCorrZvsX", "V0 photon track iu Z correlation;track iu Z for ele;track iu Z diff", {HistType::kTH2F, {{100, 0, +100}, {400, -20, +20}}}},
52+
},
53+
};
54+
55+
template <typename TTrack>
56+
bool isSelected(TTrack const& track)
57+
{
58+
if (track.pt() < minpt || abs(track.eta()) > maxeta) {
59+
return false;
60+
}
61+
if (abs(track.dcaXY()) < dcamin || dcamax < abs(track.dcaXY())) {
62+
return false;
63+
}
64+
if (!track.hasITS() && !track.hasTPC()) {
65+
return false;
66+
}
67+
68+
if (track.hasTPC()) {
69+
if (track.tpcSignal() < 40.f || 110.f < track.tpcSignal()) {
70+
return false;
71+
}
72+
}
73+
return true;
74+
}
75+
76+
Filter trackFilter = o2::aod::track::x < maxX && nabs(o2::aod::track::y) < maxY && o2::aod::track::pt > minpt&& nabs(o2::aod::track::eta) < maxeta&& dcamin < nabs(o2::aod::track::dcaXY) && nabs(o2::aod::track::dcaXY) < dcamax;
77+
using MyFilteredTracksMC = soa::Filtered<MyTracksMC>;
78+
Partition<MyFilteredTracksMC> posTracks = o2::aod::track::signed1Pt > 0.f;
79+
Partition<MyFilteredTracksMC> negTracks = o2::aod::track::signed1Pt < 0.f;
80+
Partition<MyFilteredTracksMC> orphan_posTracks = o2::aod::track::signed1Pt > 0.f && o2::aod::track::collisionId < 0;
81+
Partition<MyFilteredTracksMC> orphan_negTracks = o2::aod::track::signed1Pt < 0.f && o2::aod::track::collisionId < 0;
82+
83+
int ndf = 0;
84+
85+
using MyCollisions = soa::Join<aod::McCollisionLabels, aod::Collisions>;
86+
void processMC(MyCollisions const& collisions, aod::McCollisions const&, aod::BCsWithTimestamps const& bcs, MyFilteredTracksMC const& tracks, aod::McParticles const& mcTracks)
87+
{
88+
LOGF(info, "n pos tracks = %d , n neg tracks = %d", posTracks.size(), negTracks.size());
89+
ndf++;
90+
if (ndf > 3) { // 3 DFs are enough.
91+
return;
92+
}
93+
94+
for (auto& [ele, pos] : combinations(CombinationsFullIndexPolicy(negTracks, posTracks))) {
95+
if (!ele.has_mcParticle() || !pos.has_mcParticle()) {
96+
continue;
97+
}
98+
99+
if (!isSelected(ele) || !isSelected(pos)) {
100+
continue;
101+
}
102+
103+
auto elemc = ele.template mcParticle_as<aod::McParticles>();
104+
auto posmc = pos.template mcParticle_as<aod::McParticles>();
105+
106+
int photonid = FindCommonMotherFrom2Prongs(posmc, elemc, -11, 11, 22, mcTracks);
107+
if (photonid < 0) { // check swap, true electron is reconstructed as positron and vice versa.
108+
photonid = FindCommonMotherFrom2Prongs(posmc, elemc, 11, -11, 22, mcTracks);
109+
}
110+
if (photonid < 0) {
111+
continue;
112+
}
113+
// At this point, there are only true photon conversions.
114+
auto photonmc = mcTracks.iteratorAt(photonid);
115+
if (!IsPhysicalPrimary(photonmc.mcCollision(), photonmc, mcTracks)) {
116+
continue;
117+
}
118+
119+
bool has_coll_ele = ele.has_collision();
120+
bool has_coll_pos = pos.has_collision();
121+
122+
if (!has_coll_ele) {
123+
fRegistry.fill(HIST("hOrphanTrack"), 1);
124+
}
125+
if (!has_coll_pos) {
126+
fRegistry.fill(HIST("hOrphanTrack"), 1);
127+
}
128+
129+
if (!has_coll_ele || !has_coll_pos) {
130+
continue;
131+
}
132+
133+
auto collision_ele = ele.collision();
134+
auto collision_pos = pos.collision();
135+
int diff = collision_ele.globalIndex() - collision_pos.globalIndex();
136+
fRegistry.fill(HIST("hDiffCollId"), diff);
137+
138+
fRegistry.fill(HIST("hV0PhotonCorrX"), ele.x(), pos.x());
139+
fRegistry.fill(HIST("hV0PhotonCorrY"), ele.y(), pos.y() - ele.y());
140+
fRegistry.fill(HIST("hV0PhotonCorrZ"), ele.z(), pos.z() - ele.z());
141+
fRegistry.fill(HIST("hV0PhotonCorrYvsX"), ele.x(), pos.y() - ele.y());
142+
fRegistry.fill(HIST("hV0PhotonCorrZvsX"), ele.x(), pos.z() - ele.z());
143+
144+
} // end of pairing loop
145+
}
146+
PROCESS_SWITCH(checkV0MC, processMC, "process mc truth info", true);
147+
148+
void processDummy(soa::Join<aod::McCollisionLabels, aod::Collisions> const& collisions) {}
149+
PROCESS_SWITCH(checkV0MC, processDummy, "process dummy", false);
150+
};
151+
152+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
153+
{
154+
return WorkflowSpec{adaptAnalysisTask<checkV0MC>(cfgc, TaskName{"check-v0-mc"})};
155+
}

0 commit comments

Comments
 (0)