8#include <trg/cdc/NeuroTriggerParameters.h>
12#include "boost/iostreams/filter/gzip.hpp"
13#include "boost/iostreams/filtering_streambuf.hpp"
14#include "boost/iostreams/filtering_stream.hpp"
15#include "boost/multi_array.hpp"
18#include <framework/core/Module.h>
23NeuroTriggerParameters::NeuroTriggerParameters(std::string& filename)
33 std::ifstream confile;
35 confile.open(filename, std::ifstream::in);
38 B2ERROR(
"Configuration file " + filename +
" could not be loaded! Make sure to give the configuration file as a parameter. \
39 An example file neuroconfig_example.conf has been saved.");
44 if (!confile.is_open()) {
46 B2ERROR(
"Configuration file " + filename +
" could not be loaded! Make sure to give the configuration file as a parameter. \
47 An example file neuroconfig_example.conf has been saved.");
50 while (std::getline(confile, line_all)) {
52 std::size_t hashtag = line_all.find(
'#');
53 std::string line = line_all.substr(0, hashtag);
57 if (line.length() < 3) {
62 if (line.find(
'=') == std::string::npos) {
65 line.erase(std::remove(line.begin(), line.end(),
' '), line.end());
66 par = line.substr(0, line.find(
'='));
68 l = line.substr(line.find(
"=") + 1, 1);
73 key = (locked) ? line.substr((line.find(
'=') + 2), line.length() - line.find(
'=') - 2) : line.substr((line.find(
'=') + 1),
74 line.length() - line.find(
'=') - 1);
75 if (par ==
"nInput") {
78 }
else if (par ==
"nOutput") {
81 }
else if (par ==
"relevantCut") {
84 }
else if (par ==
"nMLP") {
85 nMLP = std::stoul(key);
87 }
else if (par ==
"targetZ") {
90 }
else if (par ==
"targetTheta") {
93 }
else if (par ==
"multiplyHidden") {
96 }
else if (par ==
"rescaleTarget") {
99 }
else if (par ==
"cutSum") {
102 }
else if (par ==
"tMax") {
103 tMax = std::stoul(key);
105 }
else if (par ==
"ETOption") {
108 }
else if (par ==
"IDRanges") {
109 IDRanges = read2dArray<float>(key, locked);
110 }
else if (par ==
"phiRangeUse") {
112 }
else if (par ==
"thetaRangeUse") {
114 }
else if (par ==
"invptRangeUse") {
116 }
else if (par ==
"phiRangeTrain") {
118 }
else if (par ==
"thetaRangeTrain") {
120 }
else if (par ==
"invptRangeTrain") {
122 }
else if (par ==
"nHidden") {
123 nHidden = read2dArray<float>(key, locked);
124 }
else if (par ==
"maxHitsPerSL") {
125 maxHitsPerSL = read1dArray<unsigned short>(key, locked);
126 }
else if (par ==
"outputScale") {
128 }
else if (par ==
"SLpattern") {
129 SLpattern = read1dArray<unsigned long>(key, locked);
130 }
else if (par ==
"SLpatternMask") {
132 }
else if (par ==
"precision") {
133 precision = read1dArray<unsigned>(key, locked);
141 if (vec.size() < 1) {
return false;}
142 else if (vec[0].size() < 1) {
return false;}
143 else {
return vec[0][0].isSet();}
150 if (vec.size() < 1) {
return false;}
151 else {
return vec[0].isSet();}
158 std::ofstream savestream;
159 savestream.open(filename);
160 savestream <<
"########################################################" << std::endl;
161 savestream <<
"### Neurotrigger configuration file created by basf2 ###" << std::endl;
162 savestream <<
"########################################################" << std::endl << std::endl;
163 savestream <<
"# '=' means the parameter is set and can be changed," << std::endl;
164 savestream <<
"# '==' means the parameter is locked and should not be changed." << std::endl << std::endl;
166 savestream <<
"# number of input nodes " << std::endl;
169 savestream << std::endl;
170 }
else {savestream <<
"nInput = 27" << std::endl;}
171 savestream <<
"# number of output nodes " << std::endl;
174 savestream << std::endl;
175 }
else {savestream <<
"nOutput = 2" << std::endl;}
176 savestream <<
"# If true, relevantCut is applied to the sum over hit counters, " << std::endl;
177 savestream <<
"# otherwise directly on the hit counters." << std::endl;
180 savestream << std::endl;
181 }
else {savestream <<
"cutSum = 0" << std::endl;}
182 savestream <<
"# only used in the idhist module. it defines the how much of the idrange is cut off after making the histogram " <<
186 savestream << std::endl;
187 }
else {savestream <<
"relevantCut = 0.02" << std::endl;}
188 savestream <<
"# flag to allow for target tracks lying out of the output range to be rescaled during training. " << std::endl;
191 savestream << std::endl;
192 }
else {savestream <<
"rescaleTarget = 0" << std::endl;}
193 savestream <<
"# Number of networks. For network specific parameters you can give " << std::endl;
194 savestream <<
"# either a list with values for each network, or a single value that will be used" << std::endl;
195 savestream <<
"# for all. The ranges are also valid if nPhi * nPt * nTheta * nPattern = nMLPs. " << std::endl;
197 savestream <<
"nMLP " << (
nMLP.
isLocked() ?
"== " :
"= ") <<
nMLP << std::endl;
198 savestream << std::endl;
199 }
else {savestream <<
"nMLP = 5" << std::endl;}
200 savestream <<
"# train z as output " << std::endl;
203 savestream << std::endl;
204 }
else {savestream <<
"targetZ = 1" << std::endl;}
205 savestream <<
"# train theta as output " << std::endl;
208 savestream << std::endl;
209 }
else {savestream <<
"targetTheta = 1" << std::endl;}
210 savestream <<
"# If true, multiply nHidden with number of input nodes. " << std::endl;
213 savestream << std::endl;
214 }
else {savestream <<
"multiplyHidden = 0" << std::endl;}
215 savestream <<
"# Maximal drift time, identical for all networks. " << std::endl;
217 savestream <<
"tMax " << (
tMax.
isLocked() ?
"== " :
"= ") <<
tMax << std::endl;
218 savestream << std::endl;
219 }
else {savestream <<
"tMax = 256" << std::endl;}
220 savestream <<
"# Determine, how the event time should be obtained. The options are:" << std::endl;
221 for (
unsigned i = 0; i < 11; i++) {
222 savestream <<
"# " << i <<
": " << to_strTiming(i) << std::endl;
226 savestream << std::endl;
227 }
else {savestream <<
"ETOption = 7" << std::endl;}
228 savestream <<
"# Phi region for which MLP is used in degree for all networks. " << std::endl;
230 savestream << print2dArray<float>(
"phiRangeUse",
phiRangeUse);
231 savestream << std::endl;
232 }
else {savestream <<
"phiRangeUse = [[0, 360]]" << std::endl;}
233 savestream <<
"# relative ID range of the relevant wire IDs of the track segments " << std::endl;
234 savestream <<
"# that are taken into consideration when determining the best fitting track segments. " << std::endl;
236 savestream << print2dArray<float>(
"IDRanges",
IDRanges);
237 savestream << std::endl;
239 savestream <<
"IDRanges = [[0,-1.5,1.5,-7.5,-0.5,-1.5,1.5,0.5,7.5,-1.5,1.5,-8.5,0.5,-2.5,1.5,-0.5,10.5,-3.5,2.5],";
240 savestream <<
"[1,-1.5,1.5,-7.5,-0.5,-1.5,1.5,0.5,7.5,-1.5,1.5,-8.5,0.5,-2.5,1.5,-0.5,10.5,-3.5,2.5],";
241 savestream <<
"[2,-1.5,1.5,-7.5,-0.5,-1.5,1.5,0.5,7.5,-1.5,1.5,-8.5,0.5,-2.5,1.5,-0.5,10.5,-3.5,2.5],";
242 savestream <<
"[3,-1.5,1.5,-7.5,-0.5,-1.5,1.5,0.5,7.5,-1.5,1.5,-8.5,0.5,-2.5,1.5,-0.5,10.5,-3.5,2.5],";
243 savestream <<
"[4,-1.5,1.5,-7.5,-0.5,-1.5,1.5,0.5,7.5,-1.5,1.5,-8.5,0.5,-2.5,1.5,-0.5,10.5,-3.5,2.5]]";
244 savestream << std::endl;
246 savestream <<
"# Theta region for which MLP is used in degree for all networks. " << std::endl;
248 savestream << print2dArray<float>(
"thetaRangeUse",
thetaRangeUse);
249 savestream << std::endl;
250 }
else {savestream <<
"thetaRangeUse = [[10, 170]]" << std::endl;}
251 savestream <<
"# Charge / Pt region for which MLP is used in 1/GeV for all networks. " << std::endl;
253 savestream << print2dArray<float>(
"invptRangeUse",
invptRangeUse);
254 savestream << std::endl;
255 }
else {savestream <<
"invptRangeUse = [[-5, 5]]" << std::endl;}
256 savestream <<
"# Phi region for which MLP is trained in degree for all networks. " << std::endl;
257 savestream <<
"# Can be larger than use range to avoid edge effects. " << std::endl;
259 savestream << print2dArray<float>(
"phiRangeTrain",
phiRangeTrain);
260 savestream << std::endl;
261 }
else {savestream <<
"phiRangeTrain = [[0, 360]]" << std::endl;}
262 savestream <<
"# Theta region for which MLP is trained in degree for all networks. " << std::endl;
263 savestream <<
"# Can be larger than use range to avoid edge effects. " << std::endl;
266 savestream << std::endl;
267 }
else {savestream <<
"thetaRangeTrain = [[10, 170]]" << std::endl;}
268 savestream <<
"# charge/Pt region for which MLP is trained in degree for all networks. " << std::endl;
269 savestream <<
"# Can be larger than use range to avoid edge effects. " << std::endl;
272 savestream << std::endl;
273 }
else {savestream <<
"invptRangeTrain = [[-5, 5]]" << std::endl;}
274 savestream <<
"# Number of nodes in each hidden layer for all networks" << std::endl;
275 savestream <<
"# or factor to multiply with number of inputs." << std::endl;
276 savestream <<
"# The number of layers is derived from the shape." << std::endl;
278 savestream << print2dArray<float>(
"nHidden",
nHidden);
279 savestream << std::endl;
280 }
else {savestream <<
"nHidden = [[81]]" << std::endl;}
281 savestream <<
"# Maximum number of hits in a single super layer for all networks. " << std::endl;
283 savestream << print1dArray<unsigned short>(
"maxHitsPerSL",
maxHitsPerSL);
284 savestream << std::endl;
285 }
else {savestream <<
"maxHitsPerSL = [1]" << std::endl;}
286 savestream <<
"# Output scale for all networks. " << std::endl;
288 savestream << print2dArray<float>(
"outputScale",
outputScale);
289 savestream << std::endl;
290 }
else {savestream <<
"outputScale = [[-100, 100, 10, 170]]" << std::endl;}
291 savestream <<
"# Super layer pattern for which MLP is trained for all networks." << std::endl;
292 savestream <<
"# Binary pattern of 9 * maxHitsPerSL bits (on/off for each hit)." << std::endl;
293 savestream <<
"# 0 in bit <i>: hits from super layer <i> are not used." << std::endl;
294 savestream <<
"# 1 in bit <i>: hits from super layer <i> are used." << std::endl;
295 savestream <<
"# SLpattern = 0: use any hits present, don't check the pattern. " << std::endl;
297 savestream << print1dArray<unsigned long>(
"SLpattern",
SLpattern);
298 savestream << std::endl;
299 }
else {savestream <<
"SLpattern = [511, 383, 479, 503, 509]" << std::endl;}
300 savestream <<
"# Super layer pattern mask for which MLP is trained for all networks." << std::endl;
301 savestream <<
"# Binary pattern of 9 * maxHitsPerSL bits (on/off for each hit)." << std::endl;
302 savestream <<
"# 0 in bit <i>: super layer <i> may or may not have a hit." << std::endl;
303 savestream <<
"# 1 in bit <i>: super layer <i>" << std::endl;
304 savestream <<
"# - must have a hit if SLpattern bit <i> = 1" << std::endl;
305 savestream <<
"# - must not have a hit if SLpattenr bit <i> = 0 " << std::endl;
307 savestream << print1dArray<unsigned long>(
"SLpatternMask",
SLpatternMask);
308 savestream << std::endl;
309 }
else {savestream <<
"SLpatternMask = [170]" << std::endl;}
310 savestream <<
"# precision used for the hardware simulation " << std::endl;
312 savestream << print1dArray<unsigned>(
"precision",
precision);
313 savestream << std::endl;
314 }
else {savestream <<
"precision = [12, 8, 8, 12, 10, 10]" << std::endl;}
322 std::stringstream savestream;
323 savestream << name <<
" " << (vecvec[0][0].isLocked() ?
"== " :
"= ") <<
"[";
324 bool outcomma =
false;
325 for (
auto x : vecvec) {
326 if (outcomma) {savestream <<
",";}
329 bool incomma =
false;
331 if (incomma) {savestream <<
",";}
337 savestream <<
"]" << std::endl;
338 return savestream.str();
344 std::stringstream savestream;
345 savestream << name <<
" " << (vecvec[0].isLocked() ?
"== " :
"= ") <<
"[";
346 bool incomma =
false;
347 for (
auto y : vecvec) {
348 if (incomma) {savestream <<
",";}
352 savestream <<
"]" << std::endl;
353 return savestream.str();
358 std::vector<std::vector<NNTParam<X>>> retarr;
359 std::string key = keyx;
361 key = key.substr(key.find(
"[") + 1, std::string::npos);
362 for (std::size_t ipos = 0; ipos != std::string::npos; ipos = key.find(
"[", ipos + 1)) {
363 std::string pairstr = key.substr(ipos + 1, key.find(
"]", ipos + 1) - ipos - 1);
364 std::vector<NNTParam<X>> newpair;
366 for (jpos = 0; jpos != std::string::npos; jpos = pairstr.find(
",", jpos)) {
367 if (!(jpos == 0)) {jpos++;}
368 newpair.push_back(
NNTParam<X>(std::stof(pairstr.substr(jpos, pairstr.find(
",") - jpos))));
369 if (locked) {newpair.back().lock();}
371 retarr.push_back(newpair);
379 std::string key = keyx;
381 std::string pairstr = key.substr(1, key.find(
"]", 1) - 1);
382 std::vector<NNTParam<X>> newpair;
384 for (jpos = 0; jpos != std::string::npos; jpos = pairstr.find(
",", jpos)) {
385 if (!(jpos == 0)) {jpos++;}
386 newpair.push_back(
NNTParam<X>(std::stof(pairstr.substr(jpos, pairstr.find(
",") - jpos))));
387 if (locked) {newpair.back().lock();}
Class to represent a complete set to describe a Neurotrigger.
bool isLocked() const
check, if variable was already locked and is read only now
bool isSet() const
check, if variable was already initialized
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.
std::vector< std::vector< NNTParam< float > > > invptRangeUse
Charge / Pt region for which MLP is used in 1/GeV for all networks.
std::vector< std::vector< NNTParam< float > > > thetaRangeUse
Theta region for which MLP is used in degree 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< std::vector< NNTParam< float > > > nHidden
Number of nodes in each hidden layer for all networks or factor to multiply with number of inputs.
std::vector< std::vector< NNTParam< float > > > thetaRangeTrain
Theta region for which MLP is trained in degree for all networks.
bool checkarr(std::vector< std::vector< NNTParam< X > > > vec)
check, if a vector is already set.
NNTParam< unsigned > tMax
Maximal drift time, identical for all networks.
std::vector< NNTParam< X > > read1dArray(std::string keyx, bool locked)
fill the array from a given string that looks like: [1,2,3]
std::vector< NNTParam< unsigned long > > SLpattern
Super layer pattern for which MLP is trained for all networks.
std::string print2dArray(const std::string &name, std::vector< std::vector< NNTParam< X > > > vecvec)
this is a class for piping the output of a 2d array to a string with brackets
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
std::vector< std::vector< NNTParam< float > > > phiRangeUse
Phi region for which MLP is used in degree for all networks.
NNTParam< unsigned > ETOption
Determine, how the event time should be obtained.
NNTParam< bool > targetZ
train z as output
NNTParam< bool > cutSum
only used in the idhist module.
std::vector< std::vector< NNTParam< X > > > read2dArray(std::string keyx, bool locked)
fill the array from a given string that looks like: [[1,2],[3, 4]]
std::vector< std::vector< NNTParam< float > > > invptRangeTrain
Charge / Pt region for which MLP is trained in 1/GeV for all networks.
std::vector< std::vector< NNTParam< float > > > phiRangeTrain
Phi region for which MLP is trained in degree for all networks.
void loadconfigtxt(const std::string &filename)
load the configuration from a file
void saveconfigtxt(const std::string &filename)
save the configuration to a file
std::string print1dArray(const std::string &name, std::vector< NNTParam< X > > vecvec)
this is a class for piping the output of a 1d array to a string with brackets
NNTParam< double > relevantCut
only used in the idhist module.
NNTParam< unsigned > nInput
Network parameters.
std::vector< NNTParam< unsigned > > precision
precision used for the hardware simulation
std::vector< std::vector< NNTParam< float > > > outputScale
Output scale for all networks.
Abstract base class for different kinds of events.