Belle II Software development
PhysicsObjectsDQMModule.cc
1/**************************************************************************
2 * basf2 (Belle II Analysis Software Framework) *
3 * Author: The Belle II Collaboration *
4 * *
5 * See git log for contributors and copyright holders. *
6 * This file is licensed under LGPL-3.0, see LICENSE.md. *
7 **************************************************************************/
8//+
9// File : PhysicsObjectsDQMModule.cc
10// Description : Module to monitor physics objects on HLT
11//-
12
13#include <dqm/modules/PhysicsObjectsDQM/PhysicsObjectsDQMModule.h>
14#include <analysis/dataobjects/ParticleList.h>
15#include <analysis/variables/EventShapeVariables.h>
16#include <analysis/variables/BelleVariables.h>
17#include <analysis/ContinuumSuppression/FoxWolfram.h>
18#include <analysis/utility/PCmsLabTransform.h>
19#include <mdst/dataobjects/Track.h>
20#include <framework/datastore/StoreArray.h>
21#include <analysis/ClusterUtility/ClusterUtils.h>
22#include <framework/datastore/StoreObjPtr.h>
23#include <framework/gearbox/Const.h>
24#include <mdst/dataobjects/SoftwareTriggerResult.h>
25#include <mdst/dataobjects/TRGSummary.h>
26#include <hlt/softwaretrigger/calculations/utilities.h>
27#include <TDirectory.h>
28#include <map>
29
30using namespace Belle2;
31
32//-----------------------------------------------------------------
33// Register the Module
34//-----------------------------------------------------------------
35REG_MODULE(PhysicsObjectsDQM);
36
37//-----------------------------------------------------------------
38// Implementation
39//-----------------------------------------------------------------
40
42{
43 //Set module properties
44
45 setDescription("Monitor Physics Objects Quality");
47
48 addParam("TriggerIdentifier", m_triggerIdentifier,
49 "Trigger identifier string used to select events for the histograms", std::string("software_trigger_cut&skim&accept_hadron"));
50 addParam("TriggerIdentifierMuMu", m_triggerIdentifierMuMu,
51 "Trigger identifier string used to select events for the mumu histograms",
52 std::string("software_trigger_cut&skim&accept_mumutight"));
53 addParam("TriggerIdentifierBhabha", m_triggerIdentifierBhabha,
54 "Trigger identifier string used to select events for the bhabha histograms",
55 std::string("software_trigger_cut&skim&accept_bhabha_trk_ecl"));
56 addParam("TriggerIdentifierHadronb2", m_triggerIdentifierHadronb2,
57 "Trigger identifier string used to select events for the hadronb2 histograms",
58 std::string("software_trigger_cut&skim&accept_hadronb2"));
59 addParam("TriggerIdentifierHLT", m_triggerIdentifierHLT,
60 "Trigger identifier string used to select events for the HLTprefilter histograms",
61 std::string("software_trigger_cut&filter&total_result"));
62 addParam("PI0PListName", m_pi0PListName, "Name of the pi0 particle list", std::string("pi0:physDQM"));
63 addParam("KS0PListName", m_ks0PListName, "Name of the KS0 particle list", std::string("K_S0:physDQM"));
64 addParam("UpsPListName", m_upsPListName, "Name of the Ups particle list", std::string("Upsilon:physDQM"));
65
66 addParam("UpsBhabhaPListName", m_upsBhabhaPListName, "Name of the Ups bhabha particle list", std::string("Upsilon:ephysDQM"));
67 addParam("UpsHadPListName", m_hadbphysDQM, "Name of the pi hadron particle list", std::string("pi+:hadbphysDQM"));
68}
69
71{
72 TDirectory* oldDir = gDirectory;
73 oldDir->mkdir("PhysicsObjects");
74 oldDir->cd("PhysicsObjects");
75
76 m_h_mKS0 = new TH1F("mKS0", "KS0 Invariant Mass", 20, 0.48, 0.52);
77 m_h_mKS0->SetXTitle("M(K_{S}^{0}) [GeV]");
78
79 m_h_mPI0 = new TH1F("mPI0", "pi0 Invariant Mass", 25, 0.10, 0.15);
80 m_h_mPI0->SetXTitle("M(#pi^{0}) [GeV]");
81
82 m_h_mUPS = new TH1F("mUPS", "Ups Invariant Mass", 500, 9, 12);
83 m_h_mUPS->SetXTitle("M(#mu#mu) [GeV]");
84
85 m_h_R2 = new TH1F("R2", "Event Level R2", 36, 0, 1.2);
86 m_h_R2->SetXTitle("R2");
87
88 m_h_mUPSe = new TH1F("mUPSe", "Ups ee Invariant Mass", 500, 9, 12);
89 m_h_mUPSe->SetXTitle("M(ee) [GeV]");
90
91 m_h_physicsresults = new TH1F("physicsresults", "Event physics results", 10, 0, 10);
92 m_h_physicsresults->SetXTitle("Event physics results");
93 m_h_physicsresults->GetXaxis()->SetBinLabel(2, "Hadron");
94 m_h_physicsresults->GetXaxis()->SetBinLabel(3, "Hadronb2");
95 m_h_physicsresults->GetXaxis()->SetBinLabel(4, "Hadronb2_tight");
96 m_h_physicsresults->GetXaxis()->SetBinLabel(5, "mumu_tight");
97 m_h_physicsresults->GetXaxis()->SetBinLabel(6, "bhabha_trk_ecl");
98
99// Monitoring variables for prefilter
100 m_h_nKshortAllH = new TH1F("hist_nKshortAllH", "hist_nKshortAllH", 50, 0.45, 0.55);
101 m_h_nKshortActiveH = new TH1F("hist_nKshortActiveH", "hist_nKshortActiveH", 50, 0.45, 0.55);
102 m_h_nKshortActiveNotTimeH = new TH1F("hist_nKshortActiveNotTimeH", "hist_nKshortActiveNotTimeH", 50, 0.45, 0.55);
103 m_h_nKshortActiveNotCDCECLH = new TH1F("hist_nKshortActiveNotCDCECLH", "hist_nKshortActiveNotCDCECLH", 50, 0.45, 0.55);
104
105 oldDir->cd();
106}
107
108
110{
111 REG_HISTOGRAM
112
114 result.isOptional();
115 m_l1Trigger.isOptional();
116}
117
118
120{
121 m_h_mKS0->Reset();
122 m_h_mPI0->Reset();
123 m_h_mUPS->Reset();
124 m_h_R2->Reset();
125 m_h_physicsresults->Reset();
126 m_h_nKshortAllH->Reset();
127 m_h_nKshortActiveH->Reset();
130}
131
132
134{
136 if (!result.isValid()) {
137 B2WARNING("SoftwareTriggerResult object not available but needed to select events for the histograms.");
138 return;
139 }
140
141 const std::map<std::string, int>& results = result->getResults();
142
143 //--- HLTPrefilter monitoring ---//
144 // Check if events pass HLT cut //
145 bool HLTAccepted = false;
146 if (results.find(m_triggerIdentifierHLT) == results.end()) {
147 //Cannot find the m_triggerIdentifierHLT
148 B2WARNING("PhysicsObjectsDQM: Can't find trigger identifier: " << m_triggerIdentifierHLT);
149 } else {
150 HLTAccepted = (result->getResult(m_triggerIdentifierHLT) == SoftwareTriggerCutResult::c_accept);
151 if (HLTAccepted != false) {
152
153 //find out if events are in the passive veto (false) or in the active veto window (true)
154 bool inActiveInjectionVeto = false; //events accepted in the passive veto window but not in the active
155 try {
156 if (m_l1Trigger->testInput("passive_veto") == 1 && m_l1Trigger->testInput("cdcecl_veto") == 0)
157 inActiveInjectionVeto = true; //events in active veto
158 } catch (const std::exception&) {}
159
160 if (results.find(m_prefilter_Injection_Strip) != results.end()) {
162 }
163 if (results.find(m_prefilter_CDCECL_Cut) != results.end()) {
164 m_CDCECLCut = (result->getNonPrescaledResult(m_prefilter_CDCECL_Cut) == SoftwareTriggerCutResult::c_accept);
165 }
166
167 // Iterate over Ks particle list //
169
170 if (ks0Particles.isValid() && abs(ks0Particles->getPDGCode()) == Const::Kshort.getPDGCode()) {
171 for (unsigned int i = 0; i < ks0Particles->getListSize(); i++) {
172 const Particle* mergeKsCand = ks0Particles->getParticle(i);
173 const bool isKsCandGood = Variable::goodBelleKshort(mergeKsCand);
174
175 if (isKsCandGood) {
176 m_h_nKshortAllH->Fill(mergeKsCand->getMass()); // Fill all Ks events
177 if (inActiveInjectionVeto) {
178 m_h_nKshortActiveH->Fill(mergeKsCand->getMass()); // Fill Ks events from active veto
179 if (!m_TimingCut)
180 m_h_nKshortActiveNotTimeH->Fill(mergeKsCand->getMass()); // Fill Ks events retained after timing cut of HLTprefilter
181 if (!m_CDCECLCut)
182 m_h_nKshortActiveNotCDCECLH->Fill(mergeKsCand->getMass()); // Fill Ks events retained after CDC-ECL cut of HLTprefilter
183 }
184 }
185 }
186 }
187 }
188 }
189
190 if (results.find(m_triggerIdentifier) == results.end()) {
191 //Cannot find the m_triggerIdentifier, move on to mumu
192 B2WARNING("PhysicsObjectsDQM: Can't find trigger identifier: " << m_triggerIdentifier);
193 } else {
194 const bool accepted = (result->getResult(m_triggerIdentifier) == SoftwareTriggerCutResult::c_accept);
195 if (accepted != false) {
196
197 //Fill entries only when HLT accepted the event
198 if (HLTAccepted)
199 m_h_physicsresults->Fill(1); //hadron events
200
203
204 double R2 = Belle2::Variable::foxWolframR2(nullptr);
205 m_h_R2->Fill(R2);
206
207 if (pi0Particles.isValid() && abs(pi0Particles->getPDGCode()) == Const::pi0.getPDGCode()) {
208 for (unsigned int i = 0; i < pi0Particles->getListSize(); i++) {
209 const Particle* pi0 = pi0Particles->getParticle(i);
210 m_h_mPI0->Fill(pi0->getMass());
211 }
212 }
213 if (ks0Particles.isValid() && abs(ks0Particles->getPDGCode()) == Const::Kshort.getPDGCode()) {
214 for (unsigned int i = 0; i < ks0Particles->getListSize(); i++) {
215 const Particle* ks0 = ks0Particles->getParticle(i);
216 m_h_mKS0->Fill(ks0->getMass());
217 }
218 }
219 }
220 }
221 if (results.find(m_triggerIdentifierMuMu) == results.end()) {
222 //Cannot find the m_triggerIdentifierMuMu, stop now
223 B2WARNING("PhysicsObjectsDQM: Can't find trigger identifier: " << m_triggerIdentifierMuMu);
224 return;
225 } else {
226 const bool accepted = (result->getResult(m_triggerIdentifierMuMu) == SoftwareTriggerCutResult::c_accept);
227 if (accepted != false) {
228 m_h_physicsresults->Fill(4); //mumu events
230 if (UpsParticles.isValid()) {
231 for (unsigned int i = 0; i < UpsParticles->getListSize(); i++) {
232 const Particle* Ups = UpsParticles->getParticle(i);
233 m_h_mUPS->Fill(Ups->getMass());
234 }
235 }
236 }
237 }
238 //bhabha, hadrons
239 if (results.find(m_triggerIdentifierBhabha) == results.end()) {
240 //Cannot find the m_triggerIdentifierBhahba, stop now
241 B2WARNING("PhysicsObjectsDQM: Can't find trigger identifier: " << m_triggerIdentifierBhabha);
242 return;
243 } else {
244 const bool accepted = (result->getResult(m_triggerIdentifierBhabha) == SoftwareTriggerCutResult::c_accept);
245 if (accepted != false) {
246
247 //Fill entries only when HLT accepted the event
248 if (HLTAccepted)
249 m_h_physicsresults->Fill(5); //bhabha events
250
252 if (UpsbhabhaParticles.isValid()) {
253 for (unsigned int i = 0; i < UpsbhabhaParticles->getListSize(); i++) {
254 const Particle* Upse = UpsbhabhaParticles->getParticle(i);
255 m_h_mUPSe->Fill(Upse->getMass());
256 }
257 }
258 }
259 }
260
261 if (results.find(m_triggerIdentifierHadronb2) == results.end()) {
262 //Cannot find the m_triggerIdentifierHadronb2, stop now
263 B2WARNING("PhysicsObjectsDQM: Can't find trigger identifier: " << m_triggerIdentifierHadronb2);
264 return;
265 } else {
266 const bool accepted = (result->getResult(m_triggerIdentifierHadronb2) == SoftwareTriggerCutResult::c_accept);
267 //Fill entries only when HLT accepted the event
268 if (accepted != false && HLTAccepted != false) {
269
270 m_h_physicsresults->Fill(2); //hadronb2 events
271
272 //variables for hadronb2 tight
274 std::vector<ROOT::Math::PxPyPzEVector> m_pionHad;
275 double EsumPiHad = 0.;
276 for (unsigned int i = 0; i < hadpiParticles->getListSize(); i++) {
277 const Particle* parPiHad = hadpiParticles->getParticle(i);
278 ROOT::Math::PxPyPzEVector V4PiHad = PCmsLabTransform::labToCms(parPiHad->get4Vector());
279 m_pionHad.push_back(V4PiHad);
280 EsumPiHad += V4PiHad.E();
281 }
282 //EnECLClustersLE
283 double eneclClusters = 0.;
284 StoreArray<ECLCluster> eclClusters;
285 ClusterUtils Cl;
286 double EsumGamma = 0.;
287 if (eclClusters.isValid()) {
288 for (int ncl = 0; ncl < eclClusters.getEntries(); ncl++) {
289 if (eclClusters[ncl]->hasHypothesis(ECLCluster::EHypothesisBit::c_nPhotons)
290 && eclClusters[ncl]->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons) > 0.1) {
291 eneclClusters += eclClusters[ncl]->getEnergy(ECLCluster::EHypothesisBit::c_nPhotons);
292 if (!eclClusters[ncl]->getRelatedFrom<Track>()) {
293 ROOT::Math::PxPyPzEVector V4Gamma_CMS = PCmsLabTransform::labToCms(Cl.Get4MomentumFromCluster(eclClusters[ncl],
295 EsumGamma += V4Gamma_CMS.E();
296 }
297 }
298 }
299 }
300 double visibleEnergyCMSnorm = (EsumPiHad + EsumGamma) / (Belle2::SoftwareTrigger::BeamEnergyCMS() * 2.0);
301 double EsumCMSnorm = eneclClusters / (Belle2::SoftwareTrigger::BeamEnergyCMS() * 2.0);
302 FoxWolfram fw(m_pionHad);
304 double R2 = fw.getR(2);
305 bool hadronb_tag = visibleEnergyCMSnorm > 0.4 && EsumCMSnorm > 0.2 && R2 < 0.2;
306 if (hadronb_tag) {
307 m_h_physicsresults->Fill(3); //hadronb2 tight events
308 }
309
310 }
311 }
312
313
314
315}
Class to provide momentum-related information from ECLClusters.
const ROOT::Math::PxPyPzEVector Get4MomentumFromCluster(const ECLCluster *cluster, ECLCluster::EHypothesisBit hypo)
Returns four momentum vector.
static const ParticleType pi0
neutral pion particle
Definition Const.h:675
static const ParticleType Kshort
K^0_S particle.
Definition Const.h:678
@ c_nPhotons
CR is split into n photons (N1)
Definition ECLCluster.h:41
Class to calculate the Fox-Wolfram moments up to order 8.
Definition FoxWolfram.h:28
double getR(int i) const
Returns the i-th moment normalized to the 0th-order moment.
Definition FoxWolfram.h:89
void calculateBasicMoments()
Method to perform the calculation of the moments up to order 4, which are the most relevant ones.
Definition FoxWolfram.cc:14
HistoModule()
Constructor.
Definition HistoModule.h:32
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
void setPropertyFlags(unsigned int propertyFlags)
Sets the flags for the module properties.
Definition Module.cc:208
@ c_ParallelProcessingCertified
This module can be run in parallel processing mode safely (All I/O must be done through the data stor...
Definition Module.h:80
static ROOT::Math::PxPyPzMVector labToCms(const ROOT::Math::PxPyPzMVector &vec)
Transforms Lorentz vector into CM System.
Class to store reconstructed particles.
Definition Particle.h:76
ROOT::Math::PxPyPzEVector get4Vector() const
Returns Lorentz vector.
Definition Particle.h:567
double getMass() const
Returns invariant mass (= nominal for FS particles)
Definition Particle.h:527
std::string m_ks0PListName
Name of the KS0 particle list.
void initialize() override
Initializer.
StoreObjPtr< TRGSummary > m_l1Trigger
Objects relevant to HLTprefilter monitoring.
void event() override
This method is called for each event.
std::string m_prefilter_Injection_Strip
HLTPrefilter lines.
std::string m_triggerIdentifier
Trigger identifier string used to select events for the histograms.
bool m_CDCECLCut
Flag for timing cut on injection strip.
TH1F * m_h_nKshortActiveNotCDCECLH
Histogram for Ks events : && active veto && !timing cut.
TH1F * m_h_mUPSe
Ups ee invariant mass.
void beginRun() override
Called when entering a new run.
TH1F * m_h_physicsresults
event physics results
std::string m_upsPListName
Name of the Ups particle list.
std::string m_hadbphysDQM
Name of the pi hadron particle list.
std::string m_upsBhabhaPListName
Name of the Ups bhabha particle list.
std::string m_triggerIdentifierHadronb2
Trigger identifier string used to select events for the hadronb2 histograms.
bool m_TimingCut
CDC-ECL occupancy cut for prefilter.
std::string m_prefilter_CDCECL_Cut
Timing cut for prefilter.
std::string m_triggerIdentifierHLT
Trigger identifier string used to select events for HLTprefilter histograms.
std::string m_triggerIdentifierMuMu
Trigger identifier string used to select events for the mumu histograms.
TH1F * m_h_nKshortActiveH
Histogram for Ks events.
std::string m_pi0PListName
Name of the pi0 particle list.
TH1F * m_h_nKshortActiveNotTimeH
Histogram for Ks events : active veto.
void defineHisto() override
Definition of the histograms.
std::string m_triggerIdentifierBhabha
Trigger identifier string used to select events for the ee histograms.
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
bool isValid() const
Check whether the array was registered.
Definition StoreArray.h:289
int getEntries() const
Get the number of objects in the array.
Definition StoreArray.h:216
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
bool isValid() const
Check whether the object was created.
void addParam(const std::string &name, T &paramVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.
Definition Module.h:559
#define REG_MODULE(moduleName)
Register the given module (without 'Module' suffix) with the framework.
Definition Module.h:649
Abstract base class for different kinds of events.