ATLAS Offline Software
Loading...
Searching...
No Matches
EtaCMA.cxx
Go to the documentation of this file.
1/*
2 Copyright (C) 2002-2025 CERN for the benefit of the ATLAS collaboration
3*/
4
5#include "GaudiKernel/MsgStream.h"
7
11
12#include <cstdio>
13#include <cstdlib>
14#include <fstream>
15
16using namespace RPC_CondCabling;
17
30
40
41EtaCMA::~EtaCMA() = default;
42
44 if (this != &cma) {
49 m_inversion = cma.inversion();
51 }
52 return *this;
53}
54
56 if (pivot_station()) // Check and connect strips with Pivot matrix channels
57 {
58 for (int i = pivot_start_ch(); i <= pivot_stop_ch(); ++i) {
59 int strip_number = (m_active_pivot_chs) ? 1 : pivot_start_st();
60 RPClink::iterator found = m_pivot_RPCs.find(i);
61 if (found == m_pivot_RPCs.end()) continue;
62 RPCchamber* rpc = (*found).second;
63 int final_strip = rpc->eta_strips();
64 if (i == pivot_stop_ch()) final_strip = pivot_stop_st();
65 do {
67 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EtaCMA") << noMoreChannels("Pivot");
68 return false;
69 }
70
71 int st_effective = strip_number - 1;
72 if (!i && side == Negative) st_effective = abs(st_effective - final_strip) - 1;
73
74 if (rpc->ijk_etaReadout() == 1) {
75 m_pivot[0][0][m_active_pivot_chs] = i * 100 + st_effective;
76 m_pivot[0][1][m_active_pivot_chs] = 10000 + i * 100 + st_effective;
77 } else {
78 m_pivot[0][1][m_active_pivot_chs] = i * 100 + st_effective;
79 m_pivot[0][0][m_active_pivot_chs] = 10000 + i * 100 + st_effective;
80 }
81 rpc->add_eta_channel(st_effective);
83 } while (++strip_number <= final_strip);
84 }
85 // Set first and last connectors code
86 int code = pivot_station() * 100000 + 2 * 100000000;
87 m_first_pivot_code = code + m_pivot[0][0][0];
89 }
90 if (lowPt_station() && lowPt_number_co() != -1) {
91 for (int i = lowPt_start_ch(); i <= lowPt_stop_ch(); ++i) {
92 int strip_number = (m_active_lowPt_chs) ? 1 : lowPt_start_st();
93 RPClink::iterator found = m_lowPt_RPCs.find(i);
94 if (found == m_lowPt_RPCs.end()) continue;
95 RPCchamber* rpc = (*found).second;
96 int final_strip = rpc->eta_strips();
97 if (i == lowPt_stop_ch()) final_strip = lowPt_stop_st();
98 do {
100 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EtaCMA") << noMoreChannels("Low Pt");
101 return false;
102 }
103
104 int st_effective = strip_number - 1;
105 if (!i && side == Negative) st_effective = abs(st_effective - final_strip) - 1;
106
107 if (rpc->ijk_etaReadout() == 1) {
108 m_lowPt[0][0][m_active_lowPt_chs] = i * 100 + st_effective;
109 m_lowPt[0][1][m_active_lowPt_chs] = 10000 + i * 100 + st_effective;
110 } else {
111 m_lowPt[0][1][m_active_lowPt_chs] = i * 100 + st_effective;
112 m_lowPt[0][0][m_active_lowPt_chs] = 10000 + i * 100 + st_effective;
113 }
114 rpc->add_eta_channel(st_effective);
116 } while (++strip_number <= final_strip);
117 }
118 // Set first and last connectors code
119 int code = lowPt_station() * 100000 + 2 * 100000000;
120 m_first_lowPt_code = code + m_lowPt[0][0][0];
121 m_last_lowPt_code = code + m_lowPt[0][0][m_active_lowPt_chs - 1];
122 }
123 if (highPt_station() && highPt_number_co() != -1) {
124 for (int i = highPt_start_ch(); i <= highPt_stop_ch(); ++i) {
125 int strip_number = (m_active_highPt_chs) ? 1 : highPt_start_st();
126 RPClink::iterator found = m_highPt_RPCs.find(i);
127 if (found == m_highPt_RPCs.end()){
128 continue;
129 }
130 RPCchamber* rpc = (*found).second;
131 int final_strip = rpc->eta_strips();
132 if (i == highPt_stop_ch()) final_strip = highPt_stop_st();
133 do {
135 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EtaCMA") << noMoreChannels("High Pt");
136 return false;
137 }
138
139 int st_effective = strip_number - 1;
140 if (!i && side == Negative) st_effective = abs(st_effective - final_strip) - 1;
141
142 if (rpc->ijk_etaReadout() == 1) {
143 m_highPt[0][0][m_active_highPt_chs] = i * 100 + st_effective;
144 m_highPt[0][1][m_active_highPt_chs] = 10000 + i * 100 + st_effective;
145 } else {
146 m_highPt[0][1][m_active_highPt_chs] = i * 100 + st_effective;
147 m_highPt[0][0][m_active_highPt_chs] = 10000 + i * 100 + st_effective;
148 }
149 rpc->add_eta_channel(st_effective);
151 } while (++strip_number <= final_strip);
152 }
153 // Set first and last connectors code
154 int code = highPt_station() * 100000 + 2 * 100000000;
155 m_first_highPt_code = code + m_highPt[0][0][0];
157 }
158 return true;
159}
160
162 if (pivot_station()) // Check and connect Pivot chambers
163 {
164 for (int i = pivot_start_ch(); i <= pivot_stop_ch(); ++i) {
165 RPCchamber* rpc = setup.find_chamber(pivot_station(), i);
166 if (rpc) {
167 rpc->add_cma(this);
168 m_pivot_RPCs.insert(RPClink::value_type(i, rpc));
169 } else {
170 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EtaCMA") << no_connection_error("RPC - pivot", i);
171 return false;
172 }
173 }
174 }
175
176 if (lowPt_station() && lowPt_number_co() != -1) { // Check and connect Low Pt chambers
178 ++m_lowPt_start_st; // RPC strips starts from 1!
179 for (int i = m_lowPt_start_ch; i <= m_lowPt_stop_ch; ++i) {
180 RPCchamber* rpc = setup.find_chamber(lowPt_station(), i);
181 if (rpc) {
182 rpc->add_cma(this);
183 m_lowPt_RPCs.insert(RPClink::value_type(i, rpc));
184 } else {
185 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EtaCMA") << no_connection_error("RPC - low Pt", i);
186 return false;
187 }
189 }
190 } else {
192 return false;
193 }
194 }
195
196 if (highPt_station() && highPt_number_co() != -1) { // Check and connect High Pt chambers
198 ++m_highPt_start_st; // RPC strips starts from 1!
199 for (int i = m_highPt_start_ch; i <= m_highPt_stop_ch; ++i) {
200 RPCchamber* rpc = setup.find_chamber(highPt_station(), i);
201 if (rpc) {
202 rpc->add_cma(this);
203 m_highPt_RPCs.insert(RPClink::value_type(i, rpc));
204 } else {
205 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EtaCMA") << no_connection_error("RPC - high Pt", i);
206 return false;
207 }
209 }
210 } else {
212 return false;
213 }
214 }
215 return true;
216}
217
219 int l;
220 if (stat == lowPt_station()) {
221 bool result = setup.local_conn_add(Eta, stat, lowPt_start_co(), l, m_lowPt_start_ch, m_lowPt_start_st) &&
222 setup.local_conn_add(Eta, stat, lowPt_stop_co(), l, m_lowPt_stop_ch, m_lowPt_stop_st);
223 if ((!m_lowPt_start_ch || !m_lowPt_stop_ch) && setup.side() == NoHalf) {
224 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EvenPhiCMA") << "Sector Type must belong "
225 "to a specific side when RPC chamber is in between eta 0";
226 return false;
227 }
228 return result;
229 } else if (stat == highPt_station()) {
230 bool result = setup.local_conn_add(Eta, stat, highPt_start_co(), l, m_highPt_start_ch, m_highPt_start_st) &&
231 setup.local_conn_add(Eta, stat, highPt_stop_co(), l, m_highPt_stop_ch, m_highPt_stop_st);
232 if ((!m_highPt_start_ch || !m_highPt_stop_ch) && setup.side() == NoHalf) {
233 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EvenPhiCMA") << "Sector Type must belong "
234 "to a specific side when RPC chamber is in between eta 0";
235 return false;
236 }
237 return result;
238
239 } else {
240 REPORT_MESSAGE_WITH_CONTEXT(MSG::ERROR, "EvenPhiCMA") << "Station n. " << stat
241 << " don't give input to CMA confirm planes!";
242 return false;
243 }
244}
245
246bool EtaCMA::setup(SectorLogicSetup& setup, MsgStream& log) {
247 // Connect the CMA with RPC chambers
248 if (!connect(setup)) return false;
249
250 // Check boundary of CMA channels
251 EtaCMA* prev = setup.previousCMA(*this);
252 if (prev && pivot_station()) {
253 if (pivot_start_ch() == prev->pivot_stop_ch()) {
254 if (!(pivot_start_st() == prev->pivot_stop_st() + 1)) {
255 log << MSG::ERROR << two_obj_error_message("strips mismatch", prev) << endmsg;
256 return false;
257 }
258 } else if (!(pivot_start_ch() == prev->pivot_stop_ch() + 1)) {
259 log << MSG::ERROR << two_obj_error_message("chambers mismatch", prev) << endmsg;
260 return false;
261 } else {
263 log << MSG::ERROR << two_obj_error_message("boundary mismatch", prev) << endmsg;
264 return false;
265 }
266 }
267 }
268
269 // Build the cabling map
270 if (!cable_CMA_channels(setup.side())) return false;
271
272 // invert the strip cabling if needed
273 if (!doInversion(setup)) return false;
274
275 // only 1 repository allowed so far
276 std::string LVL1_configuration_repository;
277 LVL1_configuration_repository = "ATLAS.data";
278
279 // Read the program file if exist
280 SectorLogicSetup::SECTORlist sectors = setup.sectors();
281 SectorLogicSetup::SECTORlist::const_iterator it = sectors.begin();
282
283 char s_tag[4];
284 sprintf(s_tag, "s%02d", *it);
285
286 char t_tag[3];
287 sprintf(t_tag, "t%1d", id().PAD_index());
288
289 char c_tag[4] = {'_', 'c', '2', '\0'};
290 if (id().Ixx_index() == 1) c_tag[2] = '3';
291
292 std::ifstream CMAprogLow;
293 std::istringstream CMAprogLow_COOL;
294 char name[200];
295
296 // LB retrieve pointer to the map of the trigger roads
297 const std::map<std::string, std::string>* p_trigroads = setup.GetPtoTrigRoads();
298
299 // Read trigger configurations from files
300
301 if (p_trigroads == nullptr) {
302 while (!CMAprogLow.is_open() && it != sectors.end()) {
303 std::ostringstream namestr;
304
305 std::string dir;
306 dir = setup.online_database();
307 namestr << dir << "/" << s_tag << "_" << t_tag << "_pl" << c_tag << ".txt" << std::ends; // M.C. search for local files
308
309 namestr.str().copy(name, namestr.str().length(), 0);
310 name[namestr.str().length()] = 0;
311 if (log.level() <= MSG::DEBUG) {
312 log << "filename for the trigger roads " << name << endmsg;
313 }
314
315 CMAprogLow.open(name);
316 ++it;
317 namestr.clear();
318 }
319 }
320 // Trigger configuration loaded from COOL
321 else {
322 while (CMAprogLow_COOL.str().empty() && it != sectors.end()) {
323 std::ostringstream namestr;
324 namestr << s_tag << "_" << t_tag << "_pl" << c_tag << ".txt" << std::ends;
325 namestr.str().copy(name, namestr.str().length(), 0);
326 name[namestr.str().length()] = 0;
327 std::map<std::string, std::string>::const_iterator itc;
328 itc = p_trigroads->find(name);
329 if (itc != p_trigroads->end()) {
330 CMAprogLow_COOL.str(itc->second.c_str());
331
332 if (log.level() <= MSG::VERBOSE) {
333 log << MSG::VERBOSE << "EtaCMA low: key " << name << "found in the Trigger Road Map --> OK"
334 << ", EtaCMA low: key " << itc->second.c_str()
335 << ", Etacma:CMAPROGLOW " << CMAprogLow_COOL.str()
336 << endmsg;
337 }
338 }
339 ++it;
340 namestr.clear();
341 }
342 }
343 if (CMAprogLow.is_open()) {
344 std::unique_ptr<CMAprogram> program = std::make_unique<CMAprogram>(CMAprogLow, true);
345 if (program->check()) {
346 m_lowPt_program = std::move(program);
347 if (setup.cosmic()) {
348 m_lowPt_program->open_threshold(0);
349 m_lowPt_program->open_threshold(1);
350 }
351 for (unsigned int i = 0; i < 3; ++i) {
352 if (!m_lowPt_program->hasProgrammed(i)) {
353 if (log.level() <= MSG::DEBUG) {
354 log << MSG::DEBUG << s_tag << ": " << id() << ": low-pt: has threshold " << i
355 << " not programmed." << endmsg;
356 }
357 }
358 }
359 }
360 CMAprogLow.close();
361 if (log.level() <= MSG::DEBUG) {
362 log << MSG::DEBUG << "EtaCMA::setup low_pt program has been read ---- " << endmsg;
363 }
364 } else if (!CMAprogLow_COOL.str().empty()) {
365 std::unique_ptr<CMAprogram> program = std::make_unique<CMAprogram>(CMAprogLow_COOL, true);
366 if (program->check()) {
367 m_lowPt_program = std::move(program);
368 if (setup.cosmic()) {
369 m_lowPt_program->open_threshold(0);
370 m_lowPt_program->open_threshold(1);
371 }
372 for (unsigned int i = 0; i < 3; ++i) {
373 if (!m_lowPt_program->hasProgrammed(i)) {
374 if (log.level() <= MSG::DEBUG) {
375 log << MSG::DEBUG << s_tag << ": " << id() << ": low-pt: has threshold " << i
376 << " not programmed." << endmsg;
377 }
378 }
379 }
380 }
381 CMAprogLow_COOL.str("");
382 } else {
383 if (log.level() <= MSG::DEBUG) {
384 log << MSG::DEBUG << name << " not found! Putting a dummy configuration" << endmsg;
385 }
386 m_lowPt_program = std::make_unique<CMAprogram>();
387 m_lowPt_program->open_threshold(0);
388 }
389
390 it = sectors.begin();
391 std::ifstream CMAprogHigh;
392 std::istringstream CMAprogHigh_COOL;
393
394 if (p_trigroads == nullptr) {
395 while (!CMAprogHigh.is_open() && it != sectors.end()) {
396 std::ostringstream namestr;
397 std::string dir;
398 dir = setup.online_database();
399 namestr << dir << "/" << s_tag << "_" << t_tag << "_ph" << c_tag << ".txt" << std::ends;
400
401 namestr.str().copy(name, namestr.str().length(), 0);
402 name[namestr.str().length()] = 0;
403 if (log.level() <= MSG::DEBUG) {
404 log << MSG::DEBUG << "filename for the trigger roads " << name << endmsg;
405 }
406 CMAprogHigh.open(name);
407 ++it;
408 namestr.clear();
409 }
410 }
411 // Trigger configuration loaded from COOL
412 else {
413 while (CMAprogHigh_COOL.str().empty() && it != sectors.end()) {
414 std::ostringstream namestr;
415 namestr << s_tag << "_" << t_tag << "_ph" << c_tag << ".txt" << std::ends;
416 namestr.str().copy(name, namestr.str().length(), 0);
417 name[namestr.str().length()] = 0;
418 std::map<std::string, std::string>::const_iterator itc;
419 itc = p_trigroads->find(name);
420 if (itc != p_trigroads->end()) {
421 if (log.level() <= MSG::VERBOSE) {
422 log << MSG::VERBOSE << "EtaCMA high: key " << name << "found in the Trigger Road Map --> OK"
423 << ", EtaCMA high: key " << itc->second.c_str() << endmsg;
424 }
425 CMAprogHigh_COOL.str(itc->second.c_str());
426 if (log.level() <= MSG::VERBOSE) {
427 log << MSG::VERBOSE << "EtaCMA:CMAPROGHIGH " << CMAprogHigh_COOL.str() << endmsg;
428 }
429 }
430 ++it;
431 namestr.clear();
432 }
433 }
434
435 if (CMAprogHigh.is_open()) {
436 std::unique_ptr<CMAprogram> program = std::make_unique<CMAprogram>(CMAprogHigh, true);
437 if (program->check()) {
438 m_highPt_program = std::move(program);
439 if (setup.cosmic()) {
440 m_highPt_program->open_threshold(0);
441 m_highPt_program->open_threshold(1);
442 }
443 for (unsigned int i = 0; i < 3; ++i) {
444 if (!m_highPt_program->hasProgrammed(i)) {
445 if (log.level() <= MSG::DEBUG) {
446 log << MSG::DEBUG << s_tag << ": " << id() << ": high-pt: has threshold " << i
447 << " not programmed." << endmsg;
448 }
449 }
450 }
451 }
452 CMAprogHigh.close();
453 if (log.level() <= MSG::DEBUG) {
454 log << MSG::DEBUG << "EtaCMA::setup high_pt program has been read ---- " << endmsg;
455 }
456 } else if (!CMAprogHigh_COOL.str().empty()) {
457 std::unique_ptr<CMAprogram> program = std::make_unique<CMAprogram>(CMAprogHigh_COOL, true);
458 if (program->check()) {
459 m_highPt_program = std::move(program);
460 if (setup.cosmic()) {
461 m_highPt_program->open_threshold(0);
462 m_highPt_program->open_threshold(1);
463 }
464 for (unsigned int i = 0; i < 3; ++i) {
465 if (!m_highPt_program->hasProgrammed(i)) {
466 if (log.level() <= MSG::DEBUG) {
467 log << MSG::DEBUG << s_tag << ": " << id() << ": high-pt: has threshold " << i
468 << " not programmed." << endmsg;
469 }
470 }
471 }
472 }
473 CMAprogHigh_COOL.str("");
474 } else {
475 if (log.level() <= MSG::DEBUG) {
476 log << MSG::DEBUG << " not found! Putting a dummy configuration" << endmsg;
477 }
478 m_highPt_program = std::make_unique<CMAprogram>();
479 m_highPt_program->open_threshold(0);
480 }
481
482 return true;
483}
484
486 SectorLogicSetup::SECTORlist Sectors = setup.sectors();
487 SectorLogicSetup::SECTORlist::const_iterator it = Sectors.begin();
488 int sector = *it;
489
490 RPClink::const_iterator rpc;
491 if (lowPt_station() && lowPt_number_co() != -1) {
492 rpc = m_lowPt_RPCs.begin();
493 if ((*rpc).second->inversion(sector)) {
494 m_inversion = true;
497 int tmp = m_first_lowPt_code;
499 m_last_lowPt_code = tmp;
500 }
501 }
502
503 if (pivot_station()) {
504 rpc = m_pivot_RPCs.begin();
505 if ((*rpc).second->inversion(sector)) {
506 m_inversion = true;
509 int tmp = m_first_pivot_code;
511 m_last_pivot_code = tmp;
512 }
513 }
514
515 if (highPt_station() && highPt_number_co() != -1) {
516 rpc = m_highPt_RPCs.begin();
517 if ((*rpc).second->inversion(sector)) {
518 m_inversion = true;
521 int tmp = m_first_highPt_code;
523 m_last_highPt_code = tmp;
524 }
525 }
526
527 if (m_inversion) m_id->inversion();
528
529 return true;
530}
531
533 RPClink::const_iterator found = m_pivot_RPCs.find(pivot_stop_ch());
534 if (found == m_pivot_RPCs.end()) return false;
535 return (*found).second->eta_strips() == pivot_stop_st();
536}
537
539 return pivot_start_st() == 1;
540}
#define endmsg
@ LowPt
@ HighPt
@ Pivot
@ Inversion
Helpers for checking error return status codes and reporting errors.
#define REPORT_MESSAGE_WITH_CONTEXT(LVL, CONTEXT_NAME)
Report a message, with an explicitly specified context name.
HalfType
Definition RPCdef.h:9
@ NoHalf
Definition RPCdef.h:9
@ Negative
Definition RPCdef.h:9
const std::string & name() const
Definition BaseObject.h:23
int highPt_number_co() const
unsigned int last_lowPt_channel() const
int pivot_stop_st() const
int pivot_stop_ch() const
unsigned int first_lowPt_channel() const
int highPt_stop_st() const
CMAconfiguration m_conf_type
int pivot_station() const
static constexpr int confirm_channels
int(* m_lowPt)[2][confirm_channels]
int lowPt_start_co() const
bool correct(L1RPCcabCorrection type, CMAinput it, unsigned int layer, unsigned short int Ch1, unsigned short int Ch2, short int num) const
int(* m_pivot)[2][pivot_channels]
CMAparameters & operator=(const CMAparameters &)
int pivot_start_st() const
int highPt_start_st() const
unsigned int m_last_pivot_code
unsigned int m_last_lowPt_code
int highPt_stop_co() const
int lowPt_stop_st() const
const CMAidentity & id() const
int lowPt_start_st() const
int lowPt_number_co() const
unsigned int m_first_pivot_code
std::string two_obj_error_message(const std::string &, CMAparameters *)
int lowPt_stop_ch() const
int highPt_station() const
std::string noMoreChannels(const std::string &stat)
int lowPt_station() const
void create_highPt_map(int)
unsigned int m_first_highPt_code
std::unique_ptr< CMAprogram > m_lowPt_program
std::unique_ptr< CMAidentity > m_id
int highPt_stop_ch() const
int highPt_start_ch() const
unsigned int m_last_highPt_code
int lowPt_start_ch() const
void create_pivot_map(int)
void create_lowPt_map(int)
std::unique_ptr< CMAprogram > m_highPt_program
unsigned int m_first_lowPt_code
unsigned int first_highPt_channel() const
int highPt_start_co() const
int lowPt_stop_co() const
unsigned int last_pivot_channel() const
CMAparameters(const parseParams &parse)
std::string no_confirm_error(int)
int(* m_highPt)[2][confirm_channels]
int pivot_start_ch() const
static constexpr int pivot_channels
unsigned int first_pivot_channel() const
unsigned int last_highPt_channel() const
std::string no_connection_error(const std::string &, int) const
bool cable_CMA_channels(HalfType)
Definition EtaCMA.cxx:55
const RPClink & pivot_RPCs(void) const
Definition EtaCMA.h:44
EtaCMA(const parseParams &parse)
Definition EtaCMA.cxx:18
bool doInversion(SectorLogicSetup &)
Definition EtaCMA.cxx:485
EtaCMA & operator=(const EtaCMA &)
Definition EtaCMA.cxx:43
bool begin_at_RPC_Z_boundary(void) const
Definition EtaCMA.cxx:538
bool end_at_RPC_Z_boundary(void) const
Definition EtaCMA.cxx:532
bool inversion(void) const
Definition EtaCMA.h:48
const RPClink & lowPt_RPCs(void) const
Definition EtaCMA.h:45
const RPClink & highPt_RPCs(void) const
Definition EtaCMA.h:46
bool connect(SectorLogicSetup &)
Definition EtaCMA.cxx:161
bool got_confirm_cabling(SectorLogicSetup &, int)
Definition EtaCMA.cxx:218
bool setup(SectorLogicSetup &, MsgStream &)
Definition EtaCMA.cxx:246
void add_cma(const EtaCMA *)
std::map< std::string, std::string > parse(const std::string &list)