Belle II Software  release-08-01-10
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/ParticleList.h>
14 
15 #include <analysis/variables/TrackVariables.h>
16 #include <analysis/variables/Variables.h>
17 #include <analysis/variables/MCTruthVariables.h>
18 
19 #include <vector>
20 #include <string>
21 
22 //Module Includes
23 #include <analysis/modules/CurlTagger/Bundle.h>
24 #include <analysis/modules/CurlTagger/SelectorCut.h>
25 #include <analysis/modules/CurlTagger/SelectorMVA.h>
26 
27 using namespace Belle2;
28 
29 //-----------------------------------------------------------------
30 // Register the Module
31 //-----------------------------------------------------------------
32 REG_MODULE(CurlTagger);
33 
34 //-----------------------------------------------------------------
35 // Implementation
36 //-----------------------------------------------------------------
37 
39 {
40  // Set module properties
42  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");
43 
44  // Parameter definitions
45  addParam("particleLists", m_ParticleLists, "input particle lists to check for curls or use for training");
46  addParam("belle", m_BelleFlag, "flag to distinuguish Belle (true) from Belle II (false) data", false);
47  addParam("ptCut", m_PtCut, "Preselection pt cut. Only consider tracks below threshold as candidates for curlers.", 0.5);
48  addParam("selectorType", m_SelectorType,
49  "the name of the selector to use when deciding if two reconstructed particles are the same true particle, available : 'cut', 'mva'",
50  std::string("cut"));
51  addParam("mcTruth", m_McStatsFlag,
52  "additionally bundles the particles using their genParticleIndex and tags them with extraInfo(isTruthCurl) and extraInfo(truthBundleSize).",
53  false);
54  addParam("train", m_TrainFlag, "flag for training the MVA or other methods if needed", false);
55  addParam("usePayloadCut", m_payloadCutFlag, "flag for using the optimised cut value stored in the payload.", true);
56  addParam("responseCut", m_ResponseCut,
57  "minimum allowed selector response for a match. If usePayloadCut is true the value will be overwritten with the cut stored in the payload.",
58  0.5);
59  addParam("trainFilename", m_TrainFileName,
60  "EXPERT: the name of the output root file created when running in training mode.",
61  std::string("CurlTagger_Training.root"));
62 }
63 
65 
67 {
68  if (Variable::particlePt(p) > m_PtCut) {return false;}
69  if (!(Variable::trackNCDCHits(p) > 0 || Variable::trackNVXDHits(p) > 0)) {return false;} //should never happen anyway but might as well check
70  if (p -> getCharge() == 0) {return false;}
71  return true;
72 }
73 
75 {
76  //initialise the selection function chosen by user
77  if (m_SelectorType.compare("cut") == 0) {
79  //Only really works for belle data right now
80  if (!m_BelleFlag) {
81  B2WARNING("Curl Tagger 'cut' selector is only calibrated for Belle");
82  }
83 
84  } else if (m_SelectorType.compare("mva") == 0) {
86  } else {
87  B2ERROR("Curl Track Tagger - Selector type does not exists.");
88  }
89 
90  //initialise the selector if it has an initialize function
92 }
93 
95 {
96  if (m_payloadCutFlag) {
97  // override the responseCut with the cut stored in the payload
99  }
100 }
101 
103 {
104  for (auto& iList : m_ParticleLists) {
105  StoreObjPtr<ParticleList> particleList(iList);
106 
107  //check particle List exists and has particles
108  if (!particleList) {
109  B2ERROR("ParticleList " << iList << " not found");
110  continue;
111  }
112  unsigned int particleListSize = particleList -> getListSize();
113  if (particleListSize == 0) {
114  continue;
115  }
116 
117  // Classify
118  if (!m_TrainFlag) {
119  std::vector<CurlTagger::Bundle> bundles;
120  std::vector<CurlTagger::Bundle> truthBundles; //only used if mcstatsFlag is true but empty lists are basically free
121 
122  for (unsigned int i = 0; i < particleListSize; i++) {
123 
124  Particle* iPart = particleList -> getParticle(i);
125  iPart -> addExtraInfo("isCurl", 0);
126  iPart -> addExtraInfo("bundleSize", 0);
127  if (m_McStatsFlag) {
128  iPart -> addExtraInfo("isTruthCurl", 0);
129  iPart -> addExtraInfo("truthBundleSize", 0);
130  }
131  if (!passesPreSelection(iPart)) {continue;}
132 
133  bool addedParticleToBundle = false;
134  std::vector<float> bundlesResponse;
135 
136  for (CurlTagger::Bundle bundle : bundles) {
137  unsigned int bundleSize = bundle.size();
138  float averageResponse = 0;
139 
140  for (unsigned int b = 0; b < bundleSize; b++) {
141  Particle* bPart = bundle.getParticle(b);
142  averageResponse += m_Selector -> getResponse(iPart, bPart);
143  }
144 
145  averageResponse /= bundleSize;
146  bundlesResponse.push_back(averageResponse);
147  } //bundles
148 
149  if (bundlesResponse.size() > 0) {
150  auto maxElement = std::max_element(bundlesResponse.begin(), bundlesResponse.end());
151  if (*maxElement > m_ResponseCut) {
152  int maxPosition = std::distance(std::begin(bundlesResponse), maxElement);
153  bundles[maxPosition].addParticle(iPart);
154  addedParticleToBundle = true;
155  }
156  }
157 
158  if (!addedParticleToBundle) {
159  CurlTagger::Bundle tempBundle = CurlTagger::Bundle(false);
160  tempBundle.addParticle(iPart);
161  bundles.push_back(tempBundle);
162  }
163 
164  if (m_McStatsFlag) {
165  bool addedParticleToTruthBundle = false;
166  for (auto& truthBundle : truthBundles) {
167  Particle* bPart = truthBundle.getParticle(0);
168  if (Variable::genParticleIndex(iPart) == Variable::genParticleIndex(bPart)) {
169  truthBundle.addParticle(iPart);
170  addedParticleToTruthBundle = true;
171  break;
172  } // same genParticleIndex
173  } //truthBundles
174  if (!addedParticleToTruthBundle) {
175  CurlTagger::Bundle truthTempBundle = CurlTagger::Bundle(true);
176  truthTempBundle.addParticle(iPart);
177  truthBundles.push_back(truthTempBundle);
178  } //create new truth bundle
179  }//MCStatsFlag
180  } // iParticle
181  for (CurlTagger::Bundle bundle : bundles) {
182  bundle.tagCurlInfo();
183  if (m_McStatsFlag) {
184  bundle.tagSizeInfo();
185  }
186  }
187  if (m_McStatsFlag) {
188  for (CurlTagger::Bundle truthBundle : truthBundles) {
189  truthBundle.tagCurlInfo();
190  truthBundle.tagSizeInfo();
191  }
192  }
193  } else {// !TrainFlag
194  for (unsigned int i = 0; i < particleListSize; i++) {
195  Particle* iPart = particleList -> getParticle(i);
196  if (!passesPreSelection(iPart)) {continue;}
197 
198  for (unsigned int j = 0; j < particleListSize; j++) {
199  Particle* jPart = particleList -> getParticle(j);
200  if (i == j) {continue;}
201  if (!passesPreSelection(jPart)) {continue;}
202 
203  m_Selector->collectTrainingInfo(iPart, jPart);
204  } //jPart
205  } //iPart
206  } // Training events
207  } // particle Lists
208 }
209 
211 {
212 }
213 
215 {
216  m_Selector->finalize();
217  delete m_Selector;
218 }
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:25
void addParticle(Particle *particle)
adds Particle to Bundle
Definition: Bundle.cc:33
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
virtual void finalize()
finalise selector if needed
Definition: Selector.h:46
virtual void initialize()
initialise selector if needed
Definition: Selector.h:43
virtual void collectTrainingInfo(Particle *, Particle *)
collect information for training for mva or other selectors
Definition: Selector.h:49
virtual float getOptimalResponseCut()
returns optimal cut to use with selector
Definition: Selector.h:40
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
Class to store reconstructed particles.
Definition: Particle.h:75
Type-safe access to single objects in the data store.
Definition: StoreObjPtr.h:96
REG_MODULE(arichBtest)
Register the Module.
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:560
Abstract base class for different kinds of events.