Skip to content

Commit 397e0fc

Browse files
authored
[PWGEM/Dilepton] add a simple task to check PV in MC (#17381)
1 parent 3890d19 commit 397e0fc

2 files changed

Lines changed: 210 additions & 0 deletions

File tree

PWGEM/Dilepton/Tasks/CMakeLists.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -170,6 +170,11 @@ o2physics_add_dpl_workflow(study-dcafitter
170170
PUBLIC_LINK_LIBRARIES O2::Framework O2::DetectorsVertexing O2::DCAFitter O2Physics::AnalysisCore
171171
COMPONENT_NAME Analysis)
172172

173+
o2physics_add_dpl_workflow(test-pv
174+
SOURCES testPV.cxx
175+
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore
176+
COMPONENT_NAME Analysis)
177+
173178
o2physics_add_dpl_workflow(evaluate-acceptance
174179
SOURCES evaluateAcceptance.cxx
175180
PUBLIC_LINK_LIBRARIES O2::Framework O2Physics::AnalysisCore

PWGEM/Dilepton/Tasks/testPV.cxx

Lines changed: 205 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,205 @@
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+
/// \file testPV.cxx
13+
/// \brief a task to check PV quality in MC
14+
/// \author daiki.sekihata@cern.ch
15+
16+
#include "Common/CCDB/EventSelectionParams.h"
17+
#include "Common/DataModel/EventSelection.h"
18+
19+
#include <Framework/AnalysisDataModel.h>
20+
#include <Framework/AnalysisHelpers.h>
21+
#include <Framework/AnalysisTask.h>
22+
#include <Framework/Configurable.h>
23+
#include <Framework/HistogramRegistry.h>
24+
#include <Framework/HistogramSpec.h>
25+
#include <Framework/InitContext.h>
26+
#include <Framework/runDataProcessing.h>
27+
28+
#include <string>
29+
30+
using namespace o2;
31+
using namespace o2::soa;
32+
using namespace o2::framework;
33+
using namespace o2::framework::expressions;
34+
using namespace o2::constants::physics;
35+
36+
struct testPV {
37+
38+
// Configurables
39+
// Configurable<std::string> ccdburl{"ccdb-url", "http://alice-ccdb.cern.ch", "url of the ccdb repository"};
40+
41+
struct : ConfigurableGroup {
42+
std::string prefix = "eventCut";
43+
Configurable<int> cfgEventGeneratorId{"cfgEventGeneratorId", -1, "event generator index. e.g. select gap/signal events"};
44+
Configurable<float> cfgZvtxMin{"cfgZvtxMin", -10.f, "min. Zvtx"};
45+
Configurable<float> cfgZvtxMax{"cfgZvtxMax", 10.f, "max. Zvtx"};
46+
Configurable<bool> cfgRequireFT0AND{"cfgRequireFT0AND", true, "require FT0AND"};
47+
Configurable<bool> cfgRequireNoTFB{"cfgRequireNoTFB", true, "require No time frame border"};
48+
Configurable<bool> cfgRequireNoITSROFB{"cfgRequireNoITSROFB", false, "require no ITS readout frame border"};
49+
Configurable<bool> cfgRequireNoSameBunchPileup{"cfgRequireNoSameBunchPileup", false, "require no same bunch pileup in event cut"};
50+
Configurable<bool> cfgRequireGoodZvtxFT0vsPV{"cfgRequireGoodZvtxFT0vsPV", false, "require good Zvtx between FT0 vs. PV in event cut"};
51+
Configurable<bool> cfgRequireVertexITSTPC{"cfgRequireVertexITSTPC", false, "require Vertex ITSTPC in event cut"}; // ITS-TPC matched track contributes PV.
52+
Configurable<bool> cfgRequireVertexTOFmatched{"cfgRequireVertexTOFmatched", false, "require Vertex TOFmatched in event cut"}; // ITS-TPC-TOF matched track contributes PV.
53+
// for RCT
54+
o2::framework::Configurable<bool> cfgRequireGoodRCT{"cfgRequireGoodRCT", true, "require good detector flag in run condtion table"};
55+
o2::framework::Configurable<std::string> cfgRCTLabel{"cfgRCTLabel", "CBT", "select 1 [CBT, CBT_hadronPID, CBT_muon_glo] see O2Physics/Common/CCDB/RCTSelectionFlags.h"};
56+
o2::framework::Configurable<bool> cfgCheckZDC{"cfgCheckZDC", false, "set ZDC flag for AA"};
57+
o2::framework::Configurable<bool> cfgTreatLimitedAcceptanceAsBad{"cfgTreatLimitedAcceptanceAsBad", false, "reject all events where the detectors relevant for the specified Runlist are flagged as LimitedAcceptance"};
58+
} eventCut;
59+
60+
HistogramRegistry fRegistry{"fRegistry"};
61+
62+
void init(o2::framework::InitContext&)
63+
{
64+
// ccdb->setURL(ccdburl);
65+
// ccdb->setCaching(true);
66+
// ccdb->setLocalObjectValidityChecking();
67+
// ccdb->setFatalWhenNull(false);
68+
69+
mRunNumber = 0;
70+
71+
addHistograms();
72+
}
73+
74+
int mRunNumber{0};
75+
// Service<o2::ccdb::BasicCCDBManager> ccdb;
76+
77+
template <typename TBC>
78+
void initCCDB(TBC const& bc)
79+
{
80+
if (mRunNumber == bc.runNumber()) {
81+
return;
82+
}
83+
84+
mRunNumber = bc.runNumber();
85+
}
86+
87+
void addHistograms()
88+
{
89+
auto hCollisionCounter = fRegistry.add<TH1>("hCollisionCounter", "collision counter", kTH1D, {{2, 0.5f, 2.5f}}, false);
90+
hCollisionCounter->GetXaxis()->SetBinLabel(1, "all");
91+
hCollisionCounter->GetXaxis()->SetBinLabel(2, "accepted");
92+
93+
fRegistry.add("Vertex/hZvtx", "vertex z; Z_{vtx} (cm)", kTH1F, {{100, -50, +50}}, false);
94+
fRegistry.add("Vertex/hNContrib", "Number of PV contributors;N_{contrib}", kTH1F, {{101, -0.5, 100.5}}, false);
95+
fRegistry.add("Vertex/hChi2", "vertex chi2;#chi^{2}/N_{contrib}", kTH1F, {{100, 0, 10}}, false);
96+
fRegistry.add("Vertex/hChi2vsNContrib", "vertex #chi^{2}/N_{contrib} vs. N_{contrib};N_{contrib};#chi^{2}/N_{contrib}", kTH2F, {{101, -0.5, 100.5}, {100, 0, 10}}, false);
97+
98+
fRegistry.add("Vertex/hSigmaX", "vertex #sigma_{X} vs. N_{contrib};N_{contrib};#sigma_{X} (#mum)", kTH2F, {{101, -0.5, 100.5}, {1000, 0, 100}}, false);
99+
fRegistry.add("Vertex/hSigmaY", "vertex #sigma_{Y} vs. N_{contrib};N_{contrib};#sigma_{Y} (#mum)", kTH2F, {{101, -0.5, 100.5}, {1000, 0, 100}}, false);
100+
fRegistry.add("Vertex/hSigmaZ", "vertex #sigma_{Z} vs. N_{contrib};N_{contrib};#sigma_{Z} (#mum)", kTH2F, {{101, -0.5, 100.5}, {1000, 0, 100}}, false);
101+
102+
fRegistry.add("Vertex/hDeltaX", "vertex #DeltaX vs. N_{contrib};N_{contrib};#DeltaX = (X_{rec} #minus X_{gen})/#sigma_{X}", kTH2F, {{101, -0.5, 100.5}, {200, -10, 10}}, false);
103+
fRegistry.add("Vertex/hDeltaY", "vertex #DeltaY vs. N_{contrib};N_{contrib};#DeltaY = (Y_{rec} #minus Y_{gen})/#sigma_{Y}", kTH2F, {{101, -0.5, 100.5}, {200, -10, 10}}, false);
104+
fRegistry.add("Vertex/hDeltaZ", "vertex #DeltaZ vs. N_{contrib};N_{contrib};#DeltaZ = (Z_{rec} #minus Z_{gen})/#sigma_{Z}", kTH2F, {{101, -0.5, 100.5}, {200, -10, 10}}, false);
105+
106+
fRegistry.add("Vertex/hCollisionTime", "vertex time;N_{contrib};collision time (ns)", kTH2F, {{101, -0.5, 100.5}, {500, -25, 25}}, false);
107+
fRegistry.add("Vertex/hCollisionTimeRes", "vertex time resolution;N_{contrib};collision time resolution (ns)", kTH2F, {{101, -0.5, 100.5}, {250, 0, 25}}, false);
108+
}
109+
110+
template <typename TCollision>
111+
bool isSelectedCollision(TCollision const& collision)
112+
{
113+
if (!(eventCut.cfgZvtxMin < collision.posZ() && collision.posZ() < eventCut.cfgZvtxMax)) {
114+
return false;
115+
}
116+
if (eventCut.cfgRequireFT0AND && !collision.selection_bit(o2::aod::evsel::kIsTriggerTVX)) {
117+
return false;
118+
}
119+
if (eventCut.cfgRequireNoTFB && !collision.selection_bit(o2::aod::evsel::kNoTimeFrameBorder)) {
120+
return false;
121+
}
122+
if (eventCut.cfgRequireNoITSROFB && !collision.selection_bit(o2::aod::evsel::kNoITSROFrameBorder)) {
123+
return false;
124+
}
125+
if (eventCut.cfgRequireNoSameBunchPileup && !collision.selection_bit(o2::aod::evsel::kNoSameBunchPileup)) {
126+
return false;
127+
}
128+
if (eventCut.cfgRequireGoodZvtxFT0vsPV && !collision.selection_bit(o2::aod::evsel::kIsGoodZvtxFT0vsPV)) {
129+
return false;
130+
}
131+
if (eventCut.cfgRequireVertexITSTPC && !collision.selection_bit(o2::aod::evsel::kIsVertexITSTPC)) {
132+
return false;
133+
}
134+
if (eventCut.cfgRequireVertexTOFmatched && !collision.selection_bit(o2::aod::evsel::kIsVertexTOFmatched)) {
135+
return false;
136+
}
137+
return true;
138+
}
139+
140+
template <typename TCollision, typename TMCCollision>
141+
void fillVertexHistograms(TCollision const& collision, TMCCollision const& mcCollision)
142+
{
143+
fRegistry.fill(HIST("Vertex/hZvtx"), collision.posZ());
144+
fRegistry.fill(HIST("Vertex/hNContrib"), collision.numContrib());
145+
fRegistry.fill(HIST("Vertex/hChi2"), collision.chi2() / collision.numContrib());
146+
fRegistry.fill(HIST("Vertex/hChi2vsNContrib"), collision.numContrib(), collision.chi2() / collision.numContrib());
147+
148+
fRegistry.fill(HIST("Vertex/hSigmaX"), collision.numContrib(), std::sqrt(collision.covXX()) * 1e+4); // convert cm to um
149+
fRegistry.fill(HIST("Vertex/hSigmaY"), collision.numContrib(), std::sqrt(collision.covYY()) * 1e+4); // convert cm to um
150+
fRegistry.fill(HIST("Vertex/hSigmaZ"), collision.numContrib(), std::sqrt(collision.covZZ()) * 1e+4); // convert cm to um
151+
152+
fRegistry.fill(HIST("Vertex/hDeltaX"), collision.numContrib(), (collision.posX() - mcCollision.posX()) / std::sqrt(collision.covXX()));
153+
fRegistry.fill(HIST("Vertex/hDeltaY"), collision.numContrib(), (collision.posY() - mcCollision.posY()) / std::sqrt(collision.covYY()));
154+
fRegistry.fill(HIST("Vertex/hDeltaZ"), collision.numContrib(), (collision.posZ() - mcCollision.posZ()) / std::sqrt(collision.covZZ()));
155+
156+
fRegistry.fill(HIST("Vertex/hCollisionTime"), collision.numContrib(), collision.collisionTime());
157+
fRegistry.fill(HIST("Vertex/hCollisionTimeRes"), collision.numContrib(), collision.collisionTimeRes());
158+
}
159+
160+
template <typename TBCs, typename TCollisions, typename TMCCollisions, typename TMCParticles>
161+
void run(TBCs const&, TCollisions const& collisions, TMCCollisions const&, TMCParticles const&)
162+
{
163+
for (const auto& collision : collisions) {
164+
if (!collision.has_mcCollision()) {
165+
continue;
166+
}
167+
auto bc = collision.template bc_as<TBCs>();
168+
initCCDB(bc);
169+
170+
auto mcCollision = collision.template mcCollision_as<aod::McCollisions>();
171+
if (eventCut.cfgEventGeneratorId > -1 && mcCollision.getSubGeneratorId() != eventCut.cfgEventGeneratorId) {
172+
continue;
173+
}
174+
175+
fRegistry.fill(HIST("hCollisionCounter"), 1);
176+
177+
if (!isSelectedCollision(collision)) {
178+
continue;
179+
}
180+
fRegistry.fill(HIST("hCollisionCounter"), 2);
181+
182+
fillVertexHistograms(collision, mcCollision);
183+
184+
} // end of collision loop
185+
}
186+
187+
using MyCollisions = soa::Join<aod::Collisions, aod::EvSels, aod::McCollisionLabels>;
188+
using MyBCs = soa::Join<aod::BCsWithTimestamps, aod::BcSels>;
189+
190+
Filter collisionFilter_evsel = eventCut.cfgZvtxMin < o2::aod::collision::posZ && o2::aod::collision::posZ < eventCut.cfgZvtxMax;
191+
using FilteredMyCollisions = soa::Filtered<MyCollisions>;
192+
193+
void processMC(FilteredMyCollisions const& collisions, MyBCs const& bcs, aod::McCollisions const& mcCollisions, aod::McParticles const& mcParticles)
194+
{
195+
run(bcs, collisions, mcCollisions, mcParticles);
196+
}
197+
PROCESS_SWITCH(testPV, processMC, "processMC", true);
198+
199+
void processDummy(MyCollisions const&) {}
200+
PROCESS_SWITCH(testPV, processDummy, "processDummy", false);
201+
};
202+
WorkflowSpec defineDataProcessing(ConfigContext const& cfgc)
203+
{
204+
return WorkflowSpec{adaptAnalysisTask<testPV>(cfgc, TaskName{"test-pv"})};
205+
}

0 commit comments

Comments
 (0)