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