14#include "GaudiKernel/EventContext.h"
24 ISvcLocator* pSvcLocator)
35 return StatusCode::SUCCESS;
42 if (
m_done.load(std::memory_order_acquire)) {
43 return StatusCode::SUCCESS;
46 bool expected =
false;
47 if (!
m_done.compare_exchange_strong(expected,
true, std::memory_order_acq_rel)) {
48 return StatusCode::SUCCESS;
56 return StatusCode::FAILURE;
58 output <<
"DetectorResourceID,TrueDetectorResourceID,FELIX Card Name,Uplink Pin,DMA buffer,SourceID\n";
60 std::vector<int> dma_buffer_vec =
DmaBuffer();
62 for (
size_t i = 0; i <
m_rows.size(); ++i) {
64 const auto w_and_fe_id =
waferId(row);
65 const Identifier&
id = std::get<0>(w_and_fe_id);
66 const int fe = std::get<1>(w_and_fe_id);
69 std::bitset<32>
onlineId = std::bitset<32>(
"00001000000000000000000000000000");
70 const std::string waferId_str =
id.get_identifier32().getString();
76 std::bitset<32> sID =
sourceID(
parseSPChain(row.spChain), row.md, row.fe, row.flx_card_device, dma_buffer_vec[i]);
78 std::string
x = waferId_str.substr(0, waferId_str.length() - 2 );
85 bitcheck(b, 0, 23,
"DetResID: Wafer ID");
87 std::bitset<32> febits = std::bitset<32>(fe);
91 bitcheck(febits, 30, 31,
"DetResID: Chip ID");
96 output << waferId_str <<
"\t"
98 << b.to_string() <<
"\t"
99 << febits.to_string() <<
"\t"
100 << std::dec << bec <<
"\t"
104 << std::hex<<
onlineId.to_ulong() <<
"\t";
107 std::stringstream
res;
108 res << std::hex << std::uppercase << b.to_ulong();
111 output << std::hex << (b|
onlineId).to_ulong() <<
","
113 << row.flx_card_device <<
","
115 << dma_buffer_vec[i] <<
","
116 << sID.to_ulong() <<
"\n";
126 return StatusCode::SUCCESS;
131 if (resolvedCsv.empty()) {
133 return StatusCode::FAILURE;
135 std::ifstream input(resolvedCsv);
138 return StatusCode::FAILURE;
141 if (resolvedFelixCsv.empty()) {
143 return StatusCode::FAILURE;
145 std::ifstream inputFelix(resolvedFelixCsv);
146 if (!inputFelix.good()) {
147 ATH_MSG_FATAL(
"Could not open FELIX CSV file: " << resolvedFelixCsv);
148 return StatusCode::FAILURE;
156 bool firstLine =
true;
157 while (std::getline(input, line)) {
166 const std::vector<std::string> fields =
splitCsvLine(line);
167 if (fields.size() < 5) {
173 row.spChain =
trim(fields[0]);
174 row.md =
trim(fields[1]);
175 row.fe = std::stoi(
trim(fields[2]));
176 row.flx_card_device =
trim(fields[3]);
177 row.fiber =
static_cast<unsigned int>(std::stoul(
trim(fields[4])));
179 m_rows.push_back(std::move(row));
182 ATH_MSG_INFO(
"Loaded " <<
m_rows.size() <<
" Front-End Chips CSV rows from " << resolvedCsv);
192 while (std::getline(inputFelix, line)) {
200 const std::vector<std::string> fields =
splitCsvLine(line);
201 if (fields.size() < 3) {
207 row.host =
trim(fields[0]);
208 row.card1 = (
unsigned int) std::stoi(
trim(fields[1]));
209 row.card2 = (
unsigned int) std::stoi(
trim(fields[2]));
214 return StatusCode::SUCCESS;
219 <<
", module " << row.md <<
", FE " << row.fe);
222 std::vector<std::string> spChain_cur =
parseSPChain(row.spChain);
228 int fe_n =
feID(spChain_cur, row.fe );
229 std::bitset<32> online_id =
onlineId(spChain_cur, row.md, row.fe);
235 const auto begin = input.find_first_not_of(
" \t\r\n");
236 if (begin == std::string::npos) {
240 const auto end = input.find_last_not_of(
" \t\r\n");
241 return input.substr(begin, end - begin + 1);
245 std::vector<std::string> fields;
246 std::stringstream
ss(line);
249 while (std::getline(
ss, field,
',')) {
250 fields.push_back(field);
256 std::vector<std::string> elements;
257 std::stringstream
ss(spChain);
260 while (std::getline(
ss, element,
'-')) {
261 elements.push_back(element);
270 if (spchain[1] ==
"IS" &&
271 (spchain[2] ==
"L0" || spchain[2] ==
"L1") &&
272 spchain.at(3)[0] !=
'R') {
275 else if (spchain[1] ==
"OB" &&
276 (spchain[2] ==
"L2" || spchain[2] ==
"L3" ||
277 spchain[2] ==
"L4") &&
278 (spchain.at(3)[0] ==
'B')) {
283 std::string sideAC = spchain[4];
284 if(sideAC !=
"A" && sideAC !=
"C"){
287 int side = (sideAC ==
"A")? 1 : -1;
295 return spchain.at(2)[1] -
'0';
298 if (spchain[2] ==
"L01" &&
299 (spchain.at(5) ==
"SP1" || spchain.at(5) ==
"SP3")) {
300 ATH_MSG_DEBUG(
"added layer 0 barrel vertical combined ring: SP chain "
301 << spchain[1]<< spchain[2]<< spchain[3]<< spchain[4]<< spchain[5]);
304 else if (spchain[2] ==
"L01" &&
305 (spchain.at(5) ==
"SP2" || spchain.at(5) ==
"SP4")) {
308 else if(spchain[1] ==
"OB" && (spchain[2] ==
"L2" ||
309 spchain[2] ==
"L3" ||
310 spchain[2] ==
"L4") ){
311 return (2* ((spchain.at(2))[1] -
'0') - 1);
313 else if(spchain[1] ==
"IS" && spchain[2] ==
"L05"){
316 else if(spchain[1] ==
"IS" && spchain[2] ==
"L1"){
319 else if(spchain[1] ==
"EC"){
320 return 2* (spchain.at(2)[1]-
'0');
335 std::string phi_str = (spchain.at(3)).substr(1,2);
336 if(ld == 0 || ld ==1 ){
337 return std::stoi(phi_str) - 1;
340 int phi = std::stoi(phi_str) - 1 ;
341 phi = (mod[2] ==
'T') ? 2*
phi + 1 : 2*
phi;
347 std::string sp_str(1, (spchain.at(5)[2]));
349 ATH_MSG_DEBUG(
"return phi = " << 6 * (stoi(mod) - 1 ) + 2 * (fe - 1));
350 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1);
352 else if(sp_str ==
"3"){
353 ATH_MSG_DEBUG(
"return phi = " << 6 * (stoi(mod) - 1 ) + 2 * (fe - 1) + 1);
354 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1) + 1;
361 else if (spchain[2] ==
"L01" &&
362 (spchain.at(5) ==
"SP2" || spchain.at(5) ==
"SP4")) {
364 std::string sp_str(1, spchain.at(5)[2]);
366 return 2 * (stoi(mod) - 1 ) ;
368 else if(sp_str ==
"4"){
369 return 2 * (stoi(mod) - 1 ) + 1;
377 else if(ld == 3 || ld == 5 || ld ==7){
378 std::string phi_str = mod.substr(2,2);
379 int phi = std::stoi(phi_str)-1;
383 std::string sp_str(1, spchain.at(5)[2]);
385 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1) ;
387 else if(sp_str ==
"2"){
388 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1) + 1;
396 std::string sp_str(1, spchain.at(5)[2]);
398 return 2 * (stoi(mod) - 1 ) ;
400 else if(sp_str ==
"2"){
401 return 2 * (stoi(mod) - 1 ) + 1;
404 else if(ld == 4 || ld == 6 || ld ==8){
405 std::string phi_str = mod.substr(2,2);
406 int phi = std::stoi(phi_str) - 1;
421 int side = (spchain[4] ==
"A") ? 1 : -1;
425 return side * (3 * (std::stoi(mod) -1) + fe );
428 return side * std::stoi(mod);
431 std::string eta_str(1, mod[4]);
432 int eta = std::stoi(eta_str);
442 if(spchain[2] ==
"L01"){
443 std::string eta_str = (spchain.at(3)).substr(1,2);
444 return std::stoi(eta_str)-1;
446 else if(ld == 3 || ld == 5 || ld ==7){
447 std::string eta_str = (spchain.at(3)).substr(1,2);
448 return std::stoi(eta_str) - 1 ;
451 std::string eta_str = (spchain.at(3)).substr(1,2);
452 return std::stoi(eta_str) - 1;
455 std::string eta_str = (spchain.at(3)).substr(1,2);
456 return std::stoi(eta_str) + 14 ;
458 else if(ld == 4 || ld == 6 || ld ==8){
459 std::string eta_str = (spchain.at(3)).substr(1,2);
460 return std::stoi(eta_str) - 1 ;
474 if(ld ==0 || (ld == 1 && std::abs(b_ec) == 2 ) ){
487 std::bitset<32> febits(0);
489 int fe_id =
feID(spchain, fe);
495 if(ld == 1 || ld ==2 ){
497 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
500 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
503 if(ld == 3 || ld == 4 ){
504 febits = legacy ? std::bitset<32>(0xF0000000) : std::bitset<32>(0x30000000) ;
510 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
513 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
516 if(ld == 5 || ld ==7){
517 febits = legacy ? std::bitset<32>(0xF0000000) : std::bitset<32>(0x30000000) ;
519 if(ld == 4 && etamod < 5){
521 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
524 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
529 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
532 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
535 if(ld == 8 && etamod < 7){
536 febits = legacy ? std::bitset<32>(0xF0000000) : std::bitset<32>(0x30000000) ;
538 if(ld == 8 && etamod >= 7){
540 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
543 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
548 febits |= std::bitset<32>(
"00000010000000000000000000000000");
554 std::vector<int> dmaNumbers;
555 dmaNumbers.reserve(
m_rows.size());
558 while (i <
m_rows.size()) {
559 const std::string& card =
m_rows[i].flx_card_device;
561 unsigned int minFiber = std::numeric_limits<unsigned int>::max();
562 for (; j <
m_rows.size() ; ++j) {
563 if(
m_rows[j].flx_card_device != card){
567 minFiber =
m_rows[j].fiber;
571 if (minFiber == std::numeric_limits<unsigned int>::max()) {
573 for (
size_t k = i; k < j; ++k){
574 dmaNumbers.push_back(9);
581 for (
size_t k = i; k < j; ++k) {
583 if (
m_rows[k].fiber >= minFiber) {
584 const int offset =
static_cast<int>(
m_rows[k].fiber) -
static_cast<int>(minFiber);
588 if(b_ec == 0 && ld ==0){
600 << card <<
" ; nDMAs =" << dma <<
", line " << k );
603 dmaNumbers.push_back(std::move(dma));
611std::bitset<32>
ITkPixelCsvWaferIdAlg::sourceID(
const std::vector<std::string>& spchain,
const std::string& mod,
int fe,
const std::string& flx,
const unsigned int dma)
const {
618 std::bitset<32> b(0);
619 std::bitset<32> subdet =
subDetID(b_ec, ld, etamod);
622 bitcheck(subdet, 16, 23,
"SourceID : SubDetectorID " );
625 auto hostIndex =
flxHost((
unsigned int) std::stoi(flx_card_device[0]));
626 std::bitset<32> flx_host = std::bitset<32>(hostIndex.first);
628 bitcheck(flx_host, 8, 15,
"SourceID : FELIX host " );
630 std::bitset<32> flxCard = std::bitset<32>(hostIndex.second);
632 bitcheck(flxCard, 5, 5,
"SourceID : FELIX card " );
634 std::bitset<32> flxDev = std::bitset<32>(std::stoi(flx_card_device[1]) - 1 );
636 bitcheck(flxDev, 4, 4,
"SourceID : card device " );
638 std::bitset<32> dma_b = std::bitset<32>(dma);
640 bitcheck(dma_b, 0, 1,
"SourceID : DMA buffer index " );
642 b = subdet | flx_host | flxCard | flxDev | dma_b;
649 std::vector<std::string> fields;
650 std::stringstream
ss(s);
653 while (std::getline(
ss, field,
'.')) {
654 fields.push_back(field);
656 if (fields.size() !=2){
659 if (fields[1] !=
"1" && fields[1] !=
"2" ){
667 if(barrel_endcap == 0){
670 return std::bitset<32>(0xa1);
673 return std::bitset<32>(0xa2);
678 return std::bitset<32>(0xa3);
681 return std::bitset<32>(0xa4);
685 else if(barrel_endcap == 2){
687 return std::bitset<32>(0xa1);
690 return std::bitset<32>(0xa3);
693 return std::bitset<32>(0xa5);
696 return std::bitset<32>(0xa7);
699 ATH_MSG_ERROR(
"Wrong barrel_endcap / layer_disk / eta_mod values ");
701 return std::bitset<32>(0);
704 else if(barrel_endcap == -2){
706 return std::bitset<32>(0xa2);
709 return std::bitset<32>(0xa4);
712 return std::bitset<32>(0xa6);
715 return std::bitset<32>(0xa8);
718 ATH_MSG_ERROR(
"Wrong barrel_endcap / layer_disk / eta_mod values ");
720 return std::bitset<32>(0);
724 ATH_MSG_ERROR(
"Wrong barrel_endcap value: " << barrel_endcap);
726 return std::bitset<32>(0);
738 std::ifstream fcheck(s);
739 if (!fcheck.good()) {
741 return StatusCode::FAILURE;
747 bool firstLine =
true;
748 std::vector < OutputCsvRow > rowVec;
749 while (std::getline(fcheck, line)) {
757 const std::vector<std::string> fields =
splitCsvLine(line);
758 if (fields.size() < 6) {
764 const auto parseHex = [](
const std::string& value) ->
unsigned int {
765 std::istringstream iss(value);
767 unsigned int parsed = 0;
772 row.detResId = std::bitset<32>(parseHex(fields[0]));
773 row.tdetResId = std::bitset<32>(parseHex(fields[1]));
774 row.card_dev = fields[2];
775 row.fiber = parseHex(fields[3]);
776 row.dma = std::stoi(fields[4]);
777 row.sourceId = std::bitset<32>(parseHex(fields[5]));
778 rowVec.push_back(std::move(row));
784 std::vector<std::string > cards;
785 while (i < rowVec.size()) {
786 const std::string& card = rowVec[i].card_dev;
787 if(std::find(cards.begin(), cards.end(), card) != cards.end()) {
790 cards.push_back(card);
793 std::map < int, float> fiber_links_map ;
794 std::map < int, int> fiber_dma_map ;
795 int dma_nfiber[4] = {};
798 for (; j < rowVec.size() ; ++j) {
799 if(rowVec[j].card_dev != card){
803 fiber_dma_map[rowVec[j].fiber] = rowVec[j].dma ;
805 if(rowVec[j].fiber > 12){
806 ATH_MSG_WARNING(
"Sanity check of file " << s <<
" : Bad number of fibers, line: " << j );
845 for (
const auto & p : fiber_links_map ) {
846 if(ceilf(p.second) != p.second){
848 << card <<
" ; Fiber " << p.first <<
"N links = " << p.second );
851 ATH_MSG_WARNING(
"More than 6 physical lpGBT links, file " << s <<
" : Card.device = "
852 << card <<
" ; Fiber " << p.first <<
" ; N links = " << p.second );
857 for (
const auto & p : fiber_dma_map ) {
860 ATH_MSG_WARNING(
"DMA buffer index higher than 3, file " << s <<
" : Card.device = "
861 << card <<
" ; DMA " << p.second <<
" ; fiber = " << p.first );
864 dma_nfiber[p.second] ++;
866 for (std::size_t g = 0; g < std::size(dma_nfiber); ++g) {
867 if(dma_nfiber[g] > 3){
868 ATH_MSG_WARNING(
"More than 3 fibers, file " << s <<
" : Card.device = "
869 << card <<
" ; DMA " << g <<
" ; N fibers = " << dma_nfiber[g] );
876 return StatusCode::SUCCESS;
885 uint32_t
x =
static_cast<uint32_t
> (b.to_ulong());
887 uint32_t lsb_used = std::countr_zero(
x);
888 uint32_t msb_used = std::bit_width(
x) - 1;
890 if( (msb_used > msb_lim) || (lsb_used < lsb_lim) ){
891 ATH_MSG_WARNING(
"Bits used for this ID (" << s <<
") are not correctly set");
892 ATH_MSG_WARNING(
" MSB used = " << msb_used <<
" MSB allowed = " << msb_lim);
893 ATH_MSG_WARNING(
" LSB used = " << lsb_used <<
" LSB allowed = " << lsb_lim);
903 return (p.card1 == card);
907 return (p.card2 == card);
915 std::size_t pos = s.rfind(
'-');
916 return (pos == std::string::npos) ? std::pair <unsigned int, unsigned int>(0,0) : std::pair <unsigned int, unsigned int>(std::stoi(s.substr(pos + 1)), Ncard);
919 ATH_MSG_WARNING(
"Couldn't find a host for card number " << card <<
", returning (0, 0)");
920 return std::pair <unsigned int, unsigned int>(0, 0);
Scalar eta() const
pseudorapidity method
Scalar phi() const
phi method
#define ATH_CHECK
Evaluate an expression and check for errors.
#define ATH_MSG_DEBUG(x,...)
#define ATH_MSG_ERROR(x,...)
#define ATH_MSG_WARNING(x,...)
#define ATH_MSG_INFO(x,...)
#define ATH_MSG_FATAL(x,...)
std::pair< std::vector< unsigned int >, bool > res
This is an Identifier helper class for the Pixel subdetector.
const ServiceHandle< StoreGateSvc > & detStore() const
bool msgLvl(const MSG::Level lvl) const
An algorithm that can be simultaneously executed in multiple threads.
virtual StatusCode initialize() override
virtual StatusCode execute(const EventContext &ctx) const override
static std::string trim(const std::string &input)
std::vector< std::string > splitFLX_card_device(const std::string &s) const
std::atomic< bool > m_done
static std::vector< std::string > splitCsvLine(const std::string &line)
const PixelID * m_pixIdHelper
void bitcheck(std::bitset< 32 > b, uint32_t lsb_lim, uint32_t msb_lim, std::string_view s="") const
std::vector< int > DmaBuffer() const
std::pair< unsigned int, unsigned int > flxHost(unsigned int card) const
Gaudi::Property< std::string > m_FelixCardFile
const StatusCode sanityCheck(std::string s, bool legacy=false) const
std::vector< CsvRow > m_rows
int phi_module(const std::vector< std::string > &spchain, const std::string &mod, int fe) const
Gaudi::Property< std::string > m_outputFile
static std::vector< std::string > parseSPChain(const std::string &spChain)
int feID(const std::vector< std::string > &spchain, int fe) const
Gaudi::Property< std::string > m_csvFile
std::bitset< 32 > onlineId(const std::vector< std::string > &spchain, const std::string &mod, int fe, bool legacy=false) const
std::vector< FelixCsvRow > m_felix_rows
int barrel_ec(const std::vector< std::string > &spchain) const
std::tuple< Identifier, int, std::bitset< 32 > > waferId(const CsvRow &row) const
std::bitset< 32 > subDetID(int barrel_endcap, int layer_disk, int eta) const
std::bitset< 32 > sourceID(const std::vector< std::string > &spchain, const std::string &mod, int fe, const std::string &flx, const unsigned int dma) const
int eta_module(const std::vector< std::string > &spchain, const std::string &mod, int fe) const
ITkPixelCsvWaferIdAlg(const std::string &name, ISvcLocator *pSvcLocator)
int layer_disk(const std::vector< std::string > &spchain) const
static std::string find_file(const std::string &logical_file_name, const std::string &search_path)