48 "The NeuroTrigger module of the GRL.\n"
49 "Takes CDC track and ECL cluster to prepare input data\n"
50 "for the training of a neural network.\n"
51 "Networks are trained after the event loop and saved."
56 "Name of the StoreArray holding the information of tracks and clusters from cdc ecl klm.",
57 string(
"TRGGRLObjects"));
59 "Name of the root file saving the output histogram.",
62 "Save the output histogram to root file.",
65 "Number of expert MLPs.", 1u);
67 "Number of expert CDC MLPs.", 0u);
69 "Number of expert ECL MLPs.", 1u);
71 "#cdc track of expert MLPs.", {0});
73 "#ecl cluster of expert MLPs.", {24});
75 "Number of nodes in each hidden layer for all networks "
76 "or factor to multiply with number of inputs (1 list or nMLP lists). "
77 "The number of layers is derived from the shape.",
79 addParam(
"multiplyHidden", m_parameters.multiplyHidden,
80 "If true, multiply nHidden with number of input nodes.",
false);
81 addParam(
"outputScale", m_parameters.outputScale,
82 "Output scale for all networks (1 value list or nMLP value lists). "
83 "Output[i] of the MLP is scaled from [-1, 1] "
84 "to [outputScale[2*i], outputScale[2*i+1]]. "
85 "(units: z[cm] / theta[degree])",
86 {{ -1., 1., -1., 1., -1., 1., -1., 1., -1., 1., -1., 1., -1., 1., -1., 1., -1., 1., -1., 1.}});
87 addParam(
"csvThetaPhiFile", m_csvThetaPhiFile,
88 "CSV file for theta/phi correction per tcid.",
91 addParam(
"TRGECLClusters", m_TrgECLClusterName,
92 "Name of the StoreArray holding the information of trigger ecl clusters ",
93 string(
"TRGECLClusters"));
94 addParam(
"MVACut", m_nn_thres,
95 "Cut values applied to the 10 MLP outputs", {
96 0, 0, 0, 0, 0, 0, 0, 0, 0, 0
98 addParam(
"useDB", m_useDB,
99 "Flag to use database to set config",
true);
112 if (csvPath.empty()) {
113 B2ERROR(
"Cannot find tcid_correct_theta_phi.csv");
117 std::ifstream infile(csvPath);
118 if (!infile.is_open()) {
119 B2ERROR((
"Failed to open " + csvPath).c_str());
124 bool isFirstLine =
true;
125 while (std::getline(infile, line)) {
131 std::stringstream ss(line);
132 std::string tc_str, theta_str, phi_str;
133 std::getline(ss, tc_str,
',');
134 std::getline(ss, theta_str,
',');
135 std::getline(ss, phi_str,
',');
137 if (tc_str.empty() || theta_str.empty() || phi_str.empty())
continue;
139 int tc = std::stoi(tc_str);
140 if (tc == 0)
continue;
141 double theta = std::stod(theta_str) * TMath::RadToDeg();
142 double phi = std::stod(phi_str) * TMath::RadToDeg();
144 thetaMap[tc] = theta;
155 for (
int tc = 1; tc <= 576; ++tc) {
156 if (thetaMap.count(tc)) {
167 B2INFO(
"Loaded TC geometry (theta/phi) from tcid_correct_theta_phi.csv");
168 B2INFO(Form(
"Example: TC 1 => theta = %.3f deg, phi = %.3f deg",
TCThetaLab.at(0),
TCPhiLab.at(0)));
180 B2FATAL(
"No database for TRG GRL config. exp " << evtMetaData->getExperiment() <<
" run "
181 << evtMetaData->getRun());
226 <<
" total_bit_bias=" <<
m_db_trggrlconfig->get_ecltaunn_total_bit_bias().size());
231 for (
unsigned int isector = 0; isector <
m_parameters.nMLP; isector++) {
234 B2ERROR(
"weight of GRL ecltaunn could not be loaded correctly.");
241 for (
unsigned int isector = 0; isector <
m_parameters.nMLP; isector++) {
242 h_target.push_back(
new TH1D((
"h_target_" + to_string(isector)).c_str(),
243 (
"h_target_" + to_string(isector)).c_str(), 100, -40.0, 40.0));
261 std::vector<std::tuple<float, float, float, float, int>> eclClusters;
262 eclClusters.reserve(necl);
264 for (
int ic = 0; ic < necl; ic++) {
265 auto* eclCluster = eclTrgClusterArray[ic];
266 int TC = eclCluster->getMaxTCId();
269 float energy = eclTrgClusterArray[ic]->getEnergyDep() * 1000.0;
270 float time = eclCluster->getTimeAve();
272 float phi =
TCPhiLab.at(TC - 1) + 180;
273 float thetaComp = theta;
275 eclClusters.emplace_back(energy, thetaComp, phi, time, TC);
280 std::sort(eclClusters.begin(), eclClusters.end(),
281 [](
const std::tuple<float, float, float, float, int>& a,
282 const std::tuple<float, float, float, float, int>& b) {
283 return std::get<0>(a) > std::get<0>(b);
286 std::vector<float> MLPinput(24, 0.0f);
287 for (
size_t i = 0; i < eclClusters.size() && i < 6; i++) {
288 float energy, theta, phi, time;
290 std::tie(energy, theta, phi, time, TC) = eclClusters.at(i);
291 MLPinput.at(i) = energy;
292 MLPinput.at(i + 6) = theta;
293 MLPinput.at(i + 12) = phi;
294 MLPinput.at(i + 18) = time;
298 float LSB_ADC = 1 / 5.25;
299 float LSB_angle = 1 / 1.40625;
300 std::for_each(MLPinput.begin() + 0, MLPinput.begin() + 6, [LSB_ADC](
float & x) { x = std::ceil(x * LSB_ADC); });
301 std::for_each(MLPinput.begin() + 6, MLPinput.begin() + 12, [LSB_angle](
float & x) { x = std::ceil(x * LSB_angle); });
302 std::for_each(MLPinput.begin() + 12, MLPinput.begin() + 18, [LSB_angle](
float & x) { x = std::ceil(x * LSB_angle); });
305 std::vector<float> outputs =
m_GRLNeuro.runMLP(0, MLPinput);
307 for (
int i = 0; i < 10; i++) {
308 h_target.at(0)->Fill(outputs.at(i));
312 for (
int i = 0; i < 10 && i < (int)
m_nn_thres.size(); i++) {
318 trgInfo->setTauNN(tauNN);
void addParam(const std::string &name, T ¶mVariable, const std::string &description, const T &defaultValue)
Adds a new parameter to the module.