Belle II Software development
trg-cdc-deadch-writedb.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/**************************************************************************
10 * Automated CDCTRG dead-channel payload writer (reads JSON config).
11 * Usage (inside basf2 build, after scons):
12 * trg-cdc-deadch-writedb cdcdead_config.json
13 **************************************************************************/
14
15#include <framework/database/DBImportObjPtr.h>
16#include <framework/database/DBObjPtr.h>
17#include <framework/database/DBStore.h>
18#include <framework/datastore/StoreObjPtr.h>
19#include <framework/datastore/DataStore.h>
20#include <framework/dataobjects/EventMetaData.h>
21#include <framework/logging/LogSystem.h>
22#include <trg/cdc/dbobjects/CDCTriggerDeadch.h>
23
24#include <algorithm>
25#include <cctype>
26#include <fstream>
27#include <iostream>
28#include <sstream>
29#include <string>
30#include <vector>
31
32using namespace Belle2;
33
34#define ONLINE 0
35//#define ONLINE 1
36
38 int run[4];
39 std::vector<int> mgr;
40};
41
42bool get_wire_mgr(int mask_sl[], int mask_layer[], int mask_ch[], int mgr)
43{
44 int mgr_sl = mgr / 1000;
45 int mgr_i = (mgr - mgr_sl * 1000) / 10;
46 int mgr_u = mgr % 10;
47 //MGR0 0-4 :L3-7 lch0-159
48 //MGR1 0-4 :L8-12 lch0-159
49 //MGR2 0-5 :L14-18 lch0-191
50 //MGR3 0-6 :L20-24 lch0-223
51 //MGR4 0-7 :L26-30 lch0-255
52 //MGR5 0-8 :L32-36 lch0-287
53 //MGR6 0-9 :L38-42 lch0-319
54 //MGR7 0-10:L44-48 lch0-351
55 //MGR8 0-11:L50-54 lch0-383
56 //160*8 + 160*6 + 192*6 + 224*6 + 256*6 + 288*6 + 320*6 + 352*6 + 384*6 = 14336 = nSenseWires
57
58 for (int i = 0; i < 32; i++) {
59 mask_sl[i] = mgr_sl;
60 mask_ch[i] = mgr_i * 32 + i;
61 mask_layer[i] = 0;
62 if (mgr_u == 1) mask_layer[i] += 3;
63 if (mgr_sl == 0) mask_layer[i] += 2;
64 }
65 for (int i = 0; i < 32; i++) {
66 mask_sl[i + 32] = mgr_sl;
67 mask_ch[i + 32] = mgr_i * 32 + i;
68 mask_layer[i + 32] = 1;
69 if (mgr_u == 1) mask_layer[i + 32] += 3;
70 if (mgr_sl == 0) mask_layer[i + 32] += 2;
71 }
72 for (int i = 0; i < 32; i++) {
73 mask_sl[i + 64] = mgr_sl;
74 mask_ch[i + 64] = mgr_i * 32 + i;
75 mask_layer[i + 64] = 2;
76 if (mgr_u == 1) mask_layer[i + 64] += 3;
77 if (mgr_sl == 0) mask_layer[i + 64] += 2;
78 }
79 return true;
80}
81
82static std::string trim(const std::string& s)
83{
84 size_t b = 0;
85 while (b < s.size() && std::isspace(static_cast<unsigned char>(s[b]))) b++;
86 size_t e = s.size();
87 while (e > b && std::isspace(static_cast<unsigned char>(s[e - 1]))) e--;
88 return s.substr(b, e - b);
89}
90
91static std::vector<int> parseIntList(const std::string& line)
92{
93 std::vector<int> out;
94 size_t lb = line.find('[');
95 size_t rb = line.find(']');
96 if (lb == std::string::npos || rb == std::string::npos || rb <= lb) return out;
97 std::string inner = line.substr(lb + 1, rb - lb - 1);
98 std::stringstream ss(inner);
99 std::string tok;
100 while (std::getline(ss, tok, ',')) {
101 tok = trim(tok);
102 if (!tok.empty()) out.push_back(std::stoi(tok));
103 }
104 return out;
105}
106
107static bool loadConfigs(const std::string& path, std::vector<DeadchConfig>& configs)
108{
109 std::ifstream ifs(path);
110 if (!ifs) {
111 std::cerr << "Cannot open config file: " << path << std::endl;
112 return false;
113 }
114
115 std::string line;
116 bool inConfigs = false;
117 DeadchConfig current{};
118 bool haveCurrent = false;
119
120 while (std::getline(ifs, line)) {
121 line = trim(line);
122 if (line.find("\"configs\"") != std::string::npos) {
123 inConfigs = true;
124 continue;
125 }
126 if (!inConfigs) continue;
127
128 if (line.find('}') != std::string::npos && haveCurrent) {
129 configs.push_back(current);
130 current = DeadchConfig{};
131 haveCurrent = false;
132 }
133 if (line.find("\"run\"") != std::string::npos) {
134 std::vector<int> run = parseIntList(line);
135 if (run.size() != 4) {
136 std::cerr << "Bad run array (need 4 values): " << line << std::endl;
137 return false;
138 }
139 for (int i = 0; i < 4; i++) current.run[i] = run[i];
140 haveCurrent = true;
141 }
142 if (line.find("\"mgr\"") != std::string::npos) {
143 current.mgr = parseIntList(line);
144 }
145 }
146
147 if (haveCurrent) configs.push_back(current);
148
149 if (configs.empty()) {
150 std::cerr << "No configs found in " << path << std::endl;
151 return false;
152 }
153 return true;
154}
155
156void setdeadchFromConfigs(const std::vector<DeadchConfig>& configs)
157{
158 const static int MAX_N_LAYERS = 8;
159 const int N_config = configs.size();
160
161 auto badch_map = new bool[N_config][9][8][384]; //sl layer ch
162 for (int i = 0; i < N_config; i++) {
163 for (unsigned int j = 0; j < c_nSuperLayers; j++) {
164 for (unsigned int k = 0; k < MAX_N_LAYERS; k++) {
165 for (unsigned int l = 0; l < c_maxNDriftCells; l++) {
166 badch_map[i][j][k][l] = true;
167 }
168 }
169 }
170 }
171
172 // mask L54 for all runs
173 for (int i = 0; i < N_config; i++) {
174 for (unsigned int j = 8; j < 9; j++) {
175 for (unsigned int k = 4; k < 5; k++) {
176 for (unsigned int l = 0; l < c_maxNDriftCells; l++) {
177 badch_map[i][j][k][l] = false;
178 }
179 }
180 }
181 }
182
183 // mask merger (ONLINE==0 only; ONLINE==1 uses config 0 with L54 mask only, no merger)
184 if (ONLINE == 0) {
185 for (int i = 0; i < N_config; i++) {
186 for (unsigned int j = 0; j < configs[i].mgr.size(); j++) {
187 int mgr_sl[96];
188 int mgr_layer[96];
189 int mgr_ch[96];
190 get_wire_mgr(mgr_sl, mgr_layer, mgr_ch, configs[i].mgr[j]);
191 for (int k = 0; k < 96; k++) {
192 badch_map[i][mgr_sl[k]][mgr_layer[k]][mgr_ch[k]] = false;
193 }
194 }
195 }
196 }
197
199 db_dead.construct();
200
201 if (ONLINE == 0) {
202 for (int i = 0; i < N_config; i++) {
203 const int* r = configs[i].run;
204 std::cout << "import config " << i << " iov=(" << r[0] << "," << r[1]
205 << "," << r[2] << "," << r[3] << ") n_mgr=" << configs[i].mgr.size() << std::endl;
206 IntervalOfValidity iov(r[0], r[1], r[2], r[3]);
207 for (unsigned int j = 0; j < c_nSuperLayers; j++) {
208 for (unsigned int k = 0; k < MAX_N_LAYERS; k++) {
209 for (unsigned int l = 0; l < c_maxNDriftCells; l++) {
210 db_dead->setdeadch(j, k, l, badch_map[i][j][k][l]);
211 }
212 }
213 }
214 db_dead.import(iov);
215 }
216 } else if (ONLINE == 1) {
217 for (int i = 0; i < 1; i++) { //no merger dead channel for run-independent MC. L54 is masked.
218 IntervalOfValidity iov(0, 0, -1, -1);
219 for (unsigned int j = 0; j < c_nSuperLayers; j++) {
220 for (unsigned int k = 0; k < MAX_N_LAYERS; k++) {
221 for (unsigned int l = 0; l < c_maxNDriftCells; l++) {
222 db_dead->setdeadch(j, k, l, badch_map[i][j][k][l]);
223 }
224 }
225 }
226 db_dead.import(iov);
227 }
228 }
229
230 delete[] badch_map;
231}
232
233int main(int argc, char* argv[])
234{
235 std::string configPath = "cdcdead_config.json";
236 if (argc >= 2) configPath = argv[1];
237
238 std::vector<DeadchConfig> configs;
239 if (!loadConfigs(configPath, configs)) return 1;
240
241 std::cout << "Loaded " << configs.size() << " config(s) from " << configPath << std::endl;
242 setdeadchFromConfigs(configs);
243 std::cout << "Done. localdb written in current working directory." << std::endl;
244 return 0;
245}
bool import(const IntervalOfValidity &iov)
Import the object to database.
Class for importing a single object to the database.
void construct(Args &&... params)
Construct an object of type T in this DBImportObjPtr using the provided constructor arguments.
A class that describes the interval of experiments/runs for which an object in the database is valid.
Abstract base class for different kinds of events.