Belle II Software development
CurlTaggerModule.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#include <analysis/modules/CurlTagger/CurlTaggerModule.h>
10
11#include <framework/datastore/StoreObjPtr.h>
12
13#include <analysis/dataobjects/Particle.h>
14#include <analysis/dataobjects/ParticleList.h>
15
16#include <analysis/variables/TrackVariables.h>
17#include <analysis/variables/Variables.h>
18#include <analysis/variables/MCTruthVariables.h>
19
20#include <vector>
21#include <string>
22
23//Module Includes
24#include <analysis/modules/CurlTagger/Bundle.h>
25#include <analysis/modules/CurlTagger/Selector.h>
26#include <analysis/modules/CurlTagger/SelectorCut.h>
27#include <analysis/modules/CurlTagger/SelectorMVA.h>
28
29using namespace Belle2;
30
31//-----------------------------------------------------------------
32// Register the Module
33//-----------------------------------------------------------------
34REG_MODULE(CurlTagger);
35
36//-----------------------------------------------------------------
37// Implementation
38//-----------------------------------------------------------------
39
41{
42 // Set module properties
44 R"DOC(Curl Tagger is a tool designed to identify and tag extra tracks caused by low pt particles curling around the detector. For further documentation please see 'tagCurlTracks' in modularAnalysis.)DOC");
45
46 // Parameter definitions
47 addParam("particleLists", m_ParticleLists, "input particle lists to check for curls or use for training");
48 addParam("belle", m_BelleFlag, "flag to distinuguish Belle (true) from Belle II (false) data", false);
49 addParam("ptCut", m_PtCut, "Preselection pt cut. Only consider tracks below threshold as candidates for curlers.", 0.5);
50 addParam("selectorType", m_SelectorType,
51 "the name of the selector to use when deciding if two reconstructed particles are the same true particle, available : 'cut', 'mva'",
52 std::string("cut"));
53 addParam("mcTruth", m_McStatsFlag,
54 "additionally bundles the particles using their genParticleIndex and tags them with extraInfo(isTruthCurl) and extraInfo(truthBundleSize).",
55 false);
56 addParam("train", m_TrainFlag, "flag for training the MVA or other methods if needed", false);
57 addParam("usePayloadCut", m_payloadCutFlag, "flag for using the optimised cut value stored in the payload.", true);
58 addParam("responseCut", m_ResponseCut,
59 "minimum allowed selector response for a match. If usePayloadCut is true the value will be overwritten with the cut stored in the payload.",
60 0.5);
61 addParam("trainFilename", m_TrainFileName,
62 "EXPERT: the name of the output root file created when running in training mode.",
63 std::string("CurlTagger_Training.root"));
64}
65
67
69{
70 if (Variable::particlePt(p) > m_PtCut) {return false;}
71 if (!(Variable::trackNCDCHits(p) > 0 || Variable::trackNVXDHits(p) > 0)) {return false;} //should never happen anyway but might as well check
72 if (p -> getCharge() == 0) {return false;}
73 return true;
74}
75
77{
78 //initialise the selection function chosen by user
79 if (m_SelectorType.compare("cut") == 0) {
81 //Only really works for belle data right now
82 if (!m_BelleFlag) {
83 B2WARNING("Curl Tagger 'cut' selector is only calibrated for Belle");
84 }
85
86 } else if (m_SelectorType.compare("mva") == 0) {
88 } else {
89 B2ERROR("Curl Track Tagger - Selector type does not exists.");
90 }
91
92 //initialise the selector if it has an initialize function
93 m_Selector->initialize();
94}
95
97{
98 if (m_payloadCutFlag) {
99 // override the responseCut with the cut stored in the payload
100 m_ResponseCut = m_Selector->getOptimalResponseCut();
101 }
102}
103
105{
106 for (auto& iList : m_ParticleLists) {
107 StoreObjPtr<ParticleList> particleList(iList);
108
109 //check particle List exists and has particles
110 if (!particleList) {
111 B2ERROR("ParticleList " << iList << " not found");
112 continue;
113 }
114 unsigned int particleListSize = particleList -> getListSize();
115 if (particleListSize == 0) {
116 continue;
117 }
118
119 // Classify
120 if (!m_TrainFlag) {
121 std::vector<CurlTagger::Bundle> bundles;
122 std::vector<CurlTagger::Bundle> truthBundles; //only used if mcstatsFlag is true but empty lists are basically free
123
124 for (unsigned int i = 0; i < particleListSize; i++) {
125
126 Particle* iPart = particleList -> getParticle(i);
127 iPart -> addExtraInfo("isCurl", 0);
128 iPart -> addExtraInfo("bundleSize", 0);
129 if (m_McStatsFlag) {
130 iPart -> addExtraInfo("isTruthCurl", 0);
131 iPart -> addExtraInfo("truthBundleSize", 0);
132 }
133 if (!passesPreSelection(iPart)) {continue;}
134
135 bool addedParticleToBundle = false;
136 std::vector<float> bundlesResponse;
137
138 for (CurlTagger::Bundle bundle : bundles) {
139 unsigned int bundleSize = bundle.size();
140 float averageResponse = 0;
141
142 for (unsigned int b = 0; b < bundleSize; b++) {
143 Particle* bPart = bundle.getParticle(b);
144 averageResponse += m_Selector -> getResponse(iPart, bPart);
145 }
146
147 averageResponse /= bundleSize;
148 bundlesResponse.push_back(averageResponse);
149 } //bundles
150
151 if (bundlesResponse.size() > 0) {
152 auto maxElement = std::max_element(bundlesResponse.begin(), bundlesResponse.end());
153 if (*maxElement > m_ResponseCut) {
154 int maxPosition = std::distance(bundlesResponse.begin(), maxElement);
155 bundles[maxPosition].addParticle(iPart);
156 addedParticleToBundle = true;
157 }
158 }
159
160 if (!addedParticleToBundle) {
161 CurlTagger::Bundle tempBundle = CurlTagger::Bundle(false);
162 tempBundle.addParticle(iPart);
163 bundles.push_back(tempBundle);
164 }
165
166 if (m_McStatsFlag) {
167 bool addedParticleToTruthBundle = false;
168 for (auto& truthBundle : truthBundles) {
169 Particle* bPart = truthBundle.getParticle(0);
170 if (Variable::genParticleIndex(iPart) == Variable::genParticleIndex(bPart)) {
171 truthBundle.addParticle(iPart);
172 addedParticleToTruthBundle = true;
173 break;
174 } // same genParticleIndex
175 } //truthBundles
176 if (!addedParticleToTruthBundle) {
177 CurlTagger::Bundle truthTempBundle = CurlTagger::Bundle(true);
178 truthTempBundle.addParticle(iPart);
179 truthBundles.push_back(truthTempBundle);
180 } //create new truth bundle
181 }//MCStatsFlag
182 } // iParticle
183 for (CurlTagger::Bundle bundle : bundles) {
184 bundle.tagCurlInfo();
185 if (m_McStatsFlag) {
186 bundle.tagSizeInfo();
187 }
188 }
189 if (m_McStatsFlag) {
190 for (CurlTagger::Bundle truthBundle : truthBundles) {
191 truthBundle.tagCurlInfo();
192 truthBundle.tagSizeInfo();
193 }
194 }
195 } else {// !TrainFlag
196 for (unsigned int i = 0; i < particleListSize; i++) {
197 Particle* iPart = particleList -> getParticle(i);
198 if (!passesPreSelection(iPart)) {continue;}
199
200 for (unsigned int j = 0; j < particleListSize; j++) {
201 Particle* jPart = particleList -> getParticle(j);
202 if (i == j) {continue;}
203 if (!passesPreSelection(jPart)) {continue;}
204
205 m_Selector->collectTrainingInfo(iPart, jPart);
206 } //jPart
207 } //iPart
208 } // Training events
209 } // particle Lists
210}
211
215
217{
218 m_Selector->finalize();
219 delete m_Selector;
220}
std::vector< std::string > m_ParticleLists
input particle lists
bool passesPreSelection(Particle *particle)
preselects particles that may be curl tracks
virtual void initialize() override
initialise
virtual void event() override
event code - all curl track selection done here
virtual void endRun() override
end run - unused
bool m_payloadCutFlag
flag for overriding the m_responseCut with a value retrieved from the payload
virtual void terminate() override
termination
virtual ~CurlTaggerModule() override
destructor
bool m_TrainFlag
switch between training and classifying
virtual void beginRun() override
begin run - unused
std::string m_SelectorType
name of selector function to use
bool m_McStatsFlag
if true also does some truth based matching and tags the particles with truthCurl info
CurlTaggerModule()
Constructor: Sets the description, the properties and the parameters of the module.
double m_PtCut
preselection pt cut
bool m_BelleFlag
flags if data/mc comes from belle or belle II
std::string m_TrainFileName
expert: output file name of ntuple produced in training mode
CurlTagger::Selector * m_Selector
contains the selector used
double m_ResponseCut
min classifier response to consider a match
class to contain particles identified to come from the same actual/mc particle
Definition Bundle.h:23
void addParticle(Particle *particle)
adds Particle to Bundle
Definition Bundle.cc:34
Simple cut based selector for curl tracks taken from Belle note 1079.
Definition SelectorCut.h:24
MVA based selector for tagging curl tracks in Belle and Belle II.
Definition SelectorMVA.h:34
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
Class to store reconstructed particles.
Definition Particle.h:76
Type-safe access to single objects in the data store.
Definition StoreObjPtr.h:96
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.