Belle II Software  release-08-01-10
CDCTriggerNeuroIDHistModule.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 "trg/cdc/modules/neurotrigger/CDCTriggerNeuroIDHistModule.h"
10 #include <framework/datastore/StoreArray.h>
11 #include <mdst/dataobjects/MCParticle.h>
12 #include <tracking/dataobjects/RecoTrack.h>
13 #include <trg/cdc/dataobjects/CDCTriggerSegmentHit.h>
14 #include <trg/cdc/dataobjects/CDCTriggerTrack.h>
15 #include <framework/datastore/StoreObjPtr.h>
16 #include <framework/dataobjects/EventMetaData.h>
17 #include <framework/core/ModuleParam.templateDetails.h>
18 
19 #include <cdc/geometry/CDCGeometryPar.h>
20 #include <framework/gearbox/Unit.h>
21 
22 #include <iostream>
23 #include <fstream>
24 #include <cmath>
25 #include <TFile.h>
26 #include "boost/iostreams/filter/gzip.hpp"
27 #include "boost/iostreams/filtering_streambuf.hpp"
28 #include "boost/iostreams/filtering_stream.hpp"
29 #include "boost/multi_array.hpp"
30 #define BOOST_MULTI_ARRAY_NO_GENERATORS
31 
32 namespace Belle2 {
37  REG_MODULE(CDCTriggerNeuroIDHist);
39  {
41  "description" //TODO
42  );
43  // parameters for saving / loading
44  addParam("hitCollectionName", m_hitCollectionName,
45  "Name of the input StoreArray of CDCTriggerSegmentHits.",
46  std::string(""));
47  addParam("inputCollectionName", m_inputCollectionName,
48  "Name of the StoreArray holding the 2D input tracks.",
49  std::string("TRGCDC2DFinderTracks"));
50  addParam("trainOnRecoTracks", m_trainOnRecoTracks,
51  "If true, use RecoTracks as targets instead of MCParticles.",
52  false);
53  addParam("targetCollectionName", m_targetCollectionName,
54  "Name of the MCParticle/RecoTrack collection used as target values.",
55  std::string("MCParticles"));
56  addParam("writeconfigfile", m_writeconfigFileName,
57  "Name of the config file, where all the parameters and the IDHist configuration is written.",
58  std::string(""));
59  addParam("configfile", m_configFileName,
60  "Name of the config file, where all the parameters and the IDHist configuration is read in from.",
61  std::string(""));
62  addParam("MaxEvents", m_nPrepare,
63  "amount of events used for creating the IDHist. If it is 0, "
64  "all Events are used.",
65  0);
66 
67  }
68 
69 
71  {
77  if (m_configFileName != "") {
80  } else {
81  m_neuroParameters.saveconfigtxt("neuroconfig_example.conf");
82  B2ERROR("Configuration file is missing! Make sure to give the configuration file as a parameter. \
83  An example file neuroconfig_example.conf has been saved.");
84  }
85  m_trainSets_prepare.clear();
87  for (unsigned iMLP = 0; iMLP < m_NeuroTrigger.nSectors(); ++iMLP) {
88  // sectors means experts here; this is the old naming within the neurotrigger
89  // class which originates from times were we had different expert networks for
90  // different geometrical sectors. In future, this might come back because of
91  // the 3DFinder and its rough information about the theta angle of the tracks.
93  // layerid is the layer number where the priority hits are.
94  // for every 1st priority wire there is a corresponding track segment.
95  int layerId = 3;
96  for (int iSL = 0; iSL < 9; ++iSL) {
97 
98  m_trainSets_prepare[iMLP].addCounters(cdc.nWiresInLayer(layerId));
99  // the first superlayer has 2 layers extra compared to the rest
100  layerId += (iSL > 0 ? 6 : 7);
101  }
103  if (m_trainOnRecoTracks) {
105  targets.isRequired(m_targetCollectionName);
106  } else {
108  targets.isRequired(m_targetCollectionName);
109  }
110 
111  m_NeuroTrigger.initializeCollections(m_hitCollectionName);
112 
113 
114 
115 
116  }
117  if (m_NeuroTrigger.nSectors() == 0) {
118  B2ERROR("No networks defined, please make sure to have a proper configuration file! Example file will be created here: ./neurotrigger_default.conf");
119  m_neuroParameters.saveconfigtxt("neurotrigger_default.conf");
120  }
121  }
122 
123 
124 
125  void
127  {
128  StoreObjPtr<EventMetaData> evtmetadata;
129  for (int itrack = 0; itrack < m_tracks.getEntries(); ++itrack) {
130  // get related MCParticle/RecoTrack for target
131  // and retrieve track parameters
132 
133  std::vector<float> targetvector = NeuroTrainer::getTrainTargets(m_trainOnRecoTracks, m_tracks[itrack], m_targetCollectionName);
134  if (targetvector[4] == 0) {
135  continue;
136  } // no valid representation found
137  float phi0Target = targetvector[0];
138  float invptTarget = targetvector[1];
139  float thetaTarget = targetvector[2];
140  float zTarget = targetvector[3];
141 
142 
143  // update 2D track variables
145 
146  // find all matching sectors
147  float phi0 = m_tracks[itrack]->getPhi0();
148  float invpt = m_tracks[itrack]->getKappa(1.5);
149  float theta = atan2(1., m_tracks[itrack]->getCotTheta());
150  std::vector<int> sectors = m_NeuroTrigger.selectMLPsTrain(phi0, invpt, theta);
151  if (sectors.size() == 0) continue;
152  // get target values
153  std::vector<float> targetRaw = {};
155  targetRaw.push_back(zTarget);
157  targetRaw.push_back(thetaTarget);
158  for (unsigned i = 0; i < sectors.size(); ++i) {
159  int isector = sectors[i];
160  std::vector<float> target = m_NeuroTrigger[isector].scaleTarget(targetRaw);
161  // skip out of range targets or rescale them
162  bool outOfRange = false;
163  for (unsigned itarget = 0; itarget < target.size(); ++itarget) {
164  if (fabs(target[itarget]) > 1.) {
165  outOfRange = true;
166  target[itarget] /= fabs(target[itarget]);
167  }
168  }
169  if (!m_neuroParameters.rescaleTarget && outOfRange) continue;
170  if (m_nPrepare == 0 || m_trainSets_prepare[isector].getTrackCounter() < m_nPrepare) {
171  // get relative ids for all hits related to the MCParticle / RecoTrack
172  // and count them to find relevant id range
173  // using only related hits suppresses background EXCEPT for curling tracks
174  if (m_trainOnRecoTracks) {
175  RecoTrack* recoTrack =
176  m_tracks[itrack]->getRelatedTo<RecoTrack>(m_targetCollectionName);
177  for (const CDCTriggerSegmentHit& hit :
178  recoTrack->getRelationsTo<CDCTriggerSegmentHit>(m_hitCollectionName)) {
179  // get relative id
180  double relId = m_NeuroTrigger.getRelId(hit);
181  m_trainSets_prepare[isector].addHit(hit.getISuperLayer(), round(relId));
182  }
183  } else {
184  MCParticle* mcTrack =
185  m_tracks[itrack]->getRelatedTo<MCParticle>(m_targetCollectionName);
186  for (const CDCTriggerSegmentHit& hit :
187  mcTrack->getRelationsTo<CDCTriggerSegmentHit>(m_hitCollectionName)) {
188  // get relative id
189  double relId = m_NeuroTrigger.getRelId(hit);
190  m_trainSets_prepare[isector].addHit(hit.getISuperLayer(), round(relId));
191  }
192  }
193  m_trainSets_prepare[isector].countTrack();
194  }
195  }
196  }
197  bool stop = true;
198  for (unsigned isector = 0; isector < m_trainSets_prepare.size(); ++isector) {
199  if (m_nPrepare == 0 || m_trainSets_prepare[isector].getTrackCounter() < m_nPrepare) {
200  stop = false;
201  break;
202  }
203  }
204  if (stop) {
205  B2INFO("Training sample preparation for NeuroTrigger finished, stopping event loop.");
206  // if required hit number is reached, get relevant ids
207  StoreObjPtr<EventMetaData> eventMetaData;
208  eventMetaData->setEndOfData();
209  }
210  }
211 
212  void
214  {
215 
216  if (m_neuroParameters.IDRanges.size() > 0) {
217  if (m_neuroParameters.IDRanges[0].size() > 0) {
218  if (m_neuroParameters.IDRanges[0][0].isSet()) {
219  // the idranges are already set, print warning:
220  if (!m_neuroParameters.IDRanges[0][0].isLocked()) {
221  B2WARNING("ID ranges are already set in the config file, they will be updated now!");
222  } else {
223  B2ERROR("The ID ranges in the config file are already locked and cannot be updated!");
224  return;
225  }
226  }
227  }
228  }
229  m_neuroParameters.IDRanges.clear();
230  for (unsigned isector = 0; isector < m_trainSets_prepare.size(); ++isector) {
231  CDCTriggerMLPData::HeaderSet hset(isector, NeuroTrainer::getRelevantID(
232  m_trainSets_prepare[isector],
235  std::vector<NNTParam<float>> expertline;
236  expertline.push_back(float(isector));
237  expertline.back().lock();
238  for (auto x : hset.relID) {
239  expertline.push_back(x);
240  expertline.back().lock();
241  }
242  m_neuroParameters.IDRanges.push_back(expertline);
243  B2DEBUG(15, hset);
244  }
245  // lock the variables used in this module, that are not supposed be changed
246  // further down the training chain because of the danger of implications or
247  // wrong assumptions.
250  // the IDRanges are set here; however, they can be altered manually in the
251  // configuration file to achieve potentially better results, eg. widen
252  // the range of the axial phi acceptance. This is why they are not to be "locked".
256  for (auto x : m_neuroParameters.SLpattern) {
257  x.lock();
258  }
259  for (auto x : m_neuroParameters.SLpatternMask) {
260  x.lock();
261  }
262  for (auto x : m_neuroParameters.maxHitsPerSL) {
263  x.lock();
264  }
266 
267  if (m_writeconfigFileName == "") {
269  } else {
271  }
272 
273 
274  // the *rangeTrain variables are used here, but just for obtaining the idranges.
275  // because they only have a very minor effect on those, they are not locked here.
276  //TODO: also write the config file to be directly able to start the training
277  }
278 
280 }
Struct for training data of a single MLP for the neuro trigger.
bool m_trainOnRecoTracks
Switch between MCParticles or RecoTracks as targets.
NeuroTriggerParameters m_neuroParameters
Parameters for the NeuroTrigger.
NeuroTrigger m_NeuroTrigger
Instance of the NeuroTrigger.
std::string m_targetCollectionName
Name of the MCParticles/RecoTracks collection used as target values.
std::string m_inputCollectionName
name of the event time StoreObjPtr
StoreArray< CDCTriggerTrack > m_tracks
List of input tracks.
std::vector< CDCTriggerMLPData > m_trainSets_prepare
dataset for all idhist prepare data
int m_nPrepare
Number of samples to prepare input ranges.
std::string m_writeconfigFileName
name for the output configuration file which holds all the parameters and the idhist tables for each ...
std::string m_configFileName
name for the input configuration file which holds all the parameters and the idhist tables for each e...
Combination of several CDCHits to a track segment hit for the trigger.
The Class for CDC Geometry Parameters.
static CDCGeometryPar & Instance(const CDCGeometry *=nullptr)
Static method to get a reference to the CDCGeometryPar instance.
A Class to store the Monte Carlo particle information.
Definition: MCParticle.h:32
Base class for Modules.
Definition: Module.h:72
void setDescription(const std::string &description)
Sets the description of the module.
Definition: Module.cc:214
void lock()
lock the variable, to make it read only
std::vector< NNTParam< unsigned short > > maxHitsPerSL
Maximum number of hits in a single super layer for all networks.
NNTParam< unsigned > nMLP
Number of networks.
std::vector< NNTParam< unsigned long > > SLpatternMask
Super layer pattern mask for which MLP is trained for all networks.
std::vector< NNTParam< unsigned long > > SLpattern
Super layer pattern for which MLP is trained for all networks.
NNTParam< bool > rescaleTarget
flag to allow for target tracks lying out of the output range to be rescaled during training.
std::vector< std::vector< NNTParam< float > > > IDRanges
relative ID range of the relevant wire IDs of the track segments that are taken into consideration wh...
NNTParam< bool > multiplyHidden
If true, multiply nHidden with number of input nodes.
NNTParam< bool > targetTheta
train theta as output
NNTParam< unsigned > nOutput
number of output nodes
NNTParam< bool > targetZ
train z as output
NNTParam< bool > cutSum
only used in the idhist module.
void loadconfigtxt(const std::string &filename)
load the configuration from a file
void saveconfigtxt(const std::string &filename)
save the configuration to a file
NNTParam< double > relevantCut
only used in the idhist module.
NNTParam< unsigned > nInput
Network parameters.
double getRelId(const CDCTriggerSegmentHit &hit)
Calculate phi position of a hit relative to 2D track (scaled to number of wires).
void initialize(const Parameters &p)
Set parameters and get some network independent parameters.
void updateTrack(const CDCTriggerTrack &track)
Calculate 2D phi position and arclength for the given track and store them.
void initializeCollections(std::string hitCollectionName, std::string eventTimeName, const std::string &et_option)
set the hit collection and event time to required and store the hit collection name
std::vector< int > selectMLPsTrain(float phi0, float invpt, float theta)
Select all matching expert MLPs based on the given track parameters.
unsigned nSectors() const
return number of neural networks
Definition: NeuroTrigger.h:164
This is the Reconstruction Event-Data Model Track.
Definition: RecoTrack.h:79
RelationVector< TO > getRelationsTo(const std::string &name="", const std::string &namedRelation="") const
Get the relations that point from this object to another store array.
bool isRequired(const std::string &name="")
Ensure this array/object has been registered previously.
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
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
virtual void initialize() override
Initialize the module.
virtual void event() override
Called once for each event.
virtual void terminate() override
Do the training for all sectors.
CDCTriggerNeuroIDHistModule()
Constructor, for setting module description and parameters.
Abstract base class for different kinds of events.