Belle II Software prerelease-10-00-00a
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
32namespace 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 }
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]; // currently unused
138 // float invptTarget = targetvector[1]; // currently unused
139 float thetaTarget = targetvector[2];
140 float zTarget = targetvector[3];
141
142
143 // update 2D track variables
144 m_NeuroTrigger.updateTrack(*m_tracks[itrack]);
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 = {};
154 if (m_neuroParameters.targetZ)
155 targetRaw.push_back(zTarget);
156 if (m_neuroParameters.targetTheta)
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
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],
233 m_neuroParameters.cutSum,
234 m_neuroParameters.relevantCut));
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.
248 m_neuroParameters.relevantCut.lock();
249 m_neuroParameters.cutSum.lock();
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".
253 m_neuroParameters.nInput.lock();
254 m_neuroParameters.nOutput.lock();
255 m_neuroParameters.nMLP.lock();
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 }
265 m_neuroParameters.multiplyHidden.lock();
266
267 if (m_writeconfigFileName == "") {
268 m_neuroParameters.saveconfigtxt(m_configFileName);
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
void setDescription(const std::string &description)
Sets the description of the module.
Definition Module.cc:214
Module()
Constructor.
Definition Module.cc:30
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.
Accessor to arrays stored in the data store.
Definition StoreArray.h:113
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
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.