9#include "GaudiKernel/EventContext.h"
19 ISvcLocator* pSvcLocator)
30 return StatusCode::SUCCESS;
37 if (
m_done.load(std::memory_order_acquire)) {
38 return StatusCode::SUCCESS;
41 bool expected =
false;
42 if (!
m_done.compare_exchange_strong(expected,
true, std::memory_order_acq_rel)) {
43 return StatusCode::SUCCESS;
51 return StatusCode::FAILURE;
53 output <<
"DetectorResourceID,True DetectorResourceID,FELIX Card Name,Uplink Pin,DMA buffer,SourceID\n";
55 std::vector<int> dma_buffer_vec =
DmaBuffer();
57 for (
size_t i = 0; i <
m_rows.size(); ++i) {
59 const auto w_and_fe_id =
waferId(row);
60 const Identifier&
id = std::get<0>(w_and_fe_id);
61 const int fe = std::get<1>(w_and_fe_id);
62 std::bitset<32>
onlineId = std::get<2>(w_and_fe_id);
63 const std::string waferId_str =
id.get_identifier32().getString();
69 std::bitset<32> sID =
sourceID(
parseSPChain(row.spChain), row.md, row.fe, row.flx_card_device, dma_buffer_vec[i]);
71 std::string
x = waferId_str.substr(0, waferId_str.length() - 2 );
79 bitcheck(b, 2, 25,
"DetResID: Wafer ID");
81 std::bitset<32> febits = std::bitset<32>(fe);
83 bitcheck(febits, 0, 1,
"DetResID: Front-End ID");
88 output << waferId_str <<
"\t"
90 << b.to_string() <<
"\t"
91 << febits.to_string() <<
"\t"
96 << std::hex<<
onlineId.to_ulong() <<
"\t";
99 std::stringstream
res;
100 res << std::hex << std::uppercase << b.to_ulong();
103 output << std::hex << (b|
onlineId).to_ulong() <<
","
105 << row.flx_card_device <<
","
107 << dma_buffer_vec[i] <<
","
108 << sID.to_ulong() <<
"\n";
118 return StatusCode::SUCCESS;
123 if (resolvedCsv.empty()) {
125 return StatusCode::FAILURE;
127 std::ifstream input(resolvedCsv);
130 return StatusCode::FAILURE;
133 if (resolvedFelixCsv.empty()) {
135 return StatusCode::FAILURE;
137 std::ifstream inputFelix(resolvedFelixCsv);
138 if (!inputFelix.good()) {
139 ATH_MSG_FATAL(
"Could not open FELIX CSV file: " << resolvedFelixCsv);
140 return StatusCode::FAILURE;
148 bool firstLine =
true;
149 while (std::getline(input, line)) {
158 const std::vector<std::string> fields =
splitCsvLine(line);
159 if (fields.size() < 5) {
165 row.spChain =
trim(fields[0]);
166 row.md =
trim(fields[1]);
167 row.fe = std::stoi(
trim(fields[2]));
168 row.flx_card_device =
trim(fields[3]);
169 row.fiber =
static_cast<unsigned int>(std::stoul(
trim(fields[4])));
171 m_rows.push_back(std::move(row));
174 ATH_MSG_INFO(
"Loaded " <<
m_rows.size() <<
" Front-End Chips CSV rows from " << resolvedCsv);
184 while (std::getline(inputFelix, line)) {
192 const std::vector<std::string> fields =
splitCsvLine(line);
193 if (fields.size() < 3) {
199 row.host =
trim(fields[0]);
200 row.card1 = (
unsigned int) std::stoi(
trim(fields[1]));
201 row.card2 = (
unsigned int) std::stoi(
trim(fields[2]));
206 return StatusCode::SUCCESS;
211 <<
", module " << row.md <<
", FE " << row.fe);
214 std::vector<std::string> spChain_cur =
parseSPChain(row.spChain);
220 int fe_n =
feID(spChain_cur, row.fe );
221 std::bitset<32> online_id =
onlineId(spChain_cur, row.md, row.fe);
227 const auto begin = input.find_first_not_of(
" \t\r\n");
228 if (begin == std::string::npos) {
232 const auto end = input.find_last_not_of(
" \t\r\n");
233 return input.substr(begin, end - begin + 1);
237 std::vector<std::string> fields;
238 std::stringstream
ss(line);
241 while (std::getline(
ss, field,
',')) {
242 fields.push_back(field);
248 std::vector<std::string> elements;
249 std::stringstream
ss(spChain);
252 while (std::getline(
ss, element,
'-')) {
253 elements.push_back(element);
262 if (spchain[1] ==
"IS" &&
263 (spchain[2] ==
"L0" || spchain[2] ==
"L1") &&
264 spchain.at(3)[0] !=
'R') {
267 else if (spchain[1] ==
"OB" &&
268 (spchain[2] ==
"L2" || spchain[2] ==
"L3" ||
269 spchain[2] ==
"L4") &&
270 (spchain.at(3)[0] ==
'B')) {
275 std::string sideAC = spchain[4];
276 if(sideAC !=
"A" && sideAC !=
"C"){
279 int side = (sideAC ==
"A")? 1 : -1;
287 return spchain.at(2)[1] -
'0';
290 if (spchain[2] ==
"L01" &&
291 (spchain.at(5) ==
"SP1" || spchain.at(5) ==
"SP3")) {
292 ATH_MSG_DEBUG(
"added layer 0 barrel vertical combined ring: SP chain "
293 << spchain[1]<< spchain[2]<< spchain[3]<< spchain[4]<< spchain[5]);
296 else if (spchain[2] ==
"L01" &&
297 (spchain.at(5) ==
"SP2" || spchain.at(5) ==
"SP4")) {
300 else if(spchain[1] ==
"OB" && (spchain[2] ==
"L2" ||
301 spchain[2] ==
"L3" ||
302 spchain[2] ==
"L4") ){
303 return (2* ((spchain.at(2))[1] -
'0') - 1);
305 else if(spchain[1] ==
"IS" && spchain[2] ==
"L05"){
308 else if(spchain[1] ==
"IS" && spchain[2] ==
"L1"){
311 else if(spchain[1] ==
"EC"){
312 return 2* (spchain.at(2)[1]-
'0');
327 std::string phi_str = (spchain.at(3)).substr(1,2);
328 if(ld == 0 || ld ==1 ){
329 return std::stoi(phi_str) - 1;
332 int phi = std::stoi(phi_str) - 1 ;
333 phi = (mod[2] ==
'T') ? 2*
phi + 1 : 2*
phi;
339 std::string sp_str(1, (spchain.at(5)[2]));
341 ATH_MSG_DEBUG(
"return phi = " << 6 * (stoi(mod) - 1 ) + 2 * (fe - 1));
342 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1);
344 else if(sp_str ==
"3"){
345 ATH_MSG_DEBUG(
"return phi = " << 6 * (stoi(mod) - 1 ) + 2 * (fe - 1) + 1);
346 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1) + 1;
353 else if (spchain[2] ==
"L01" &&
354 (spchain.at(5) ==
"SP2" || spchain.at(5) ==
"SP4")) {
356 std::string sp_str(1, spchain.at(5)[2]);
358 return 2 * (stoi(mod) - 1 ) ;
360 else if(sp_str ==
"4"){
361 return 2 * (stoi(mod) - 1 ) + 1;
369 else if(ld == 3 || ld == 5 || ld ==7){
370 std::string phi_str = mod.substr(2,2);
371 int phi = std::stoi(phi_str)-1;
375 return 6 * (stoi(mod) - 1 ) + 2 * (fe - 1);
378 std::string sp_str(1, spchain.at(5)[2]);
380 return 2 * (stoi(mod) - 1 ) ;
382 else if(sp_str ==
"2"){
383 return 2 * (stoi(mod) - 1 ) + 1;
386 else if(ld == 4 || ld == 6 || ld ==8){
387 std::string phi_str = mod.substr(2,2);
388 int phi = std::stoi(phi_str) - 1;
403 int side = (spchain[4] ==
"A") ? 1 : -1;
407 return side * (3 * (std::stoi(mod) -1) + fe );
410 return side * std::stoi(mod);
413 std::string eta_str(1, mod[4]);
414 int eta = std::stoi(eta_str);
424 if(spchain[2] ==
"L01"){
425 std::string eta_str = (spchain.at(3)).substr(1,2);
426 return std::stoi(eta_str)-1;
428 else if(ld == 3 || ld == 5 || ld ==7){
429 std::string eta_str = (spchain.at(3)).substr(1,2);
430 return std::stoi(eta_str) - 1 ;
433 std::string eta_str = (spchain.at(3)).substr(1,2);
434 return std::stoi(eta_str) - 1;
437 std::string eta_str = (spchain.at(3)).substr(1,2);
438 return std::stoi(eta_str) + 14 ;
440 else if(ld == 4 || ld == 6 || ld ==8){
441 std::string eta_str = (spchain.at(3)).substr(1,2);
442 return std::stoi(eta_str) - 1 ;
456 if(ld ==0 || (ld == 1 && std::abs(b_ec) == 2 ) ){
468 std::bitset<32> febits(0);
470 int fe_id =
feID(spchain, fe);
476 if(ld == 1 || ld ==2 ){
478 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
481 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
484 if(ld == 3 || ld == 4 ){
485 febits = legacy ? std::bitset<32>(0xF0000000) : std::bitset<32>(0x30000000) ;
491 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
494 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
497 if(ld == 5 || ld ==7){
498 febits = legacy ? std::bitset<32>(0xF0000000) : std::bitset<32>(0x30000000) ;
500 if(ld == 4 && etamod < 5){
502 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
505 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
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 == 8 && etamod < 7){
517 febits = legacy ? std::bitset<32>(0xF0000000) : std::bitset<32>(0x30000000) ;
519 if(ld == 8 && etamod >= 7){
521 febits = legacy ? std::bitset<32>(0x30000000) : std::bitset<32>(0x10000000) ;
524 febits = legacy ? std::bitset<32>(0xC0000000) : std::bitset<32>(0x20000000) ;
529 febits |= std::bitset<32>(
"00001100000000000000000000000000");
531 bitcheck(febits, 26, 29,
"DetResID: Online ID");
538 std::vector<int> dmaNumbers;
539 dmaNumbers.reserve(
m_rows.size());
542 while (i <
m_rows.size()) {
543 const std::string& card =
m_rows[i].flx_card_device;
545 unsigned int minFiber = std::numeric_limits<unsigned int>::max();
546 for (; j <
m_rows.size() ; ++j) {
547 if(
m_rows[j].flx_card_device != card){
551 minFiber =
m_rows[j].fiber;
555 if (minFiber == std::numeric_limits<unsigned int>::max()) {
557 for (
size_t k = i; k < j; ++k){
558 dmaNumbers.push_back(9);
565 for (
size_t k = i; k < j; ++k) {
567 if (
m_rows[k].fiber >= minFiber) {
568 const int offset =
static_cast<int>(
m_rows[k].fiber) -
static_cast<int>(minFiber);
572 if(b_ec == 0 && ld ==0){
584 << card <<
" ; nDMAs =" << dma <<
", line " << k );
587 dmaNumbers.push_back(std::move(dma));
595std::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 {
602 std::bitset<32> b(0);
603 std::bitset<32> subdet =
subDetID(b_ec, ld, etamod);
606 bitcheck(subdet, 16, 23,
"SourceID : SubDetectorID " );
609 auto hostIndex =
flxHost((
unsigned int) std::stoi(flx_card_device[0]));
610 std::bitset<32> flx_host = std::bitset<32>(hostIndex.first);
612 bitcheck(flx_host, 8, 15,
"SourceID : FELIX host " );
614 std::bitset<32> flxCard = std::bitset<32>(hostIndex.second);
616 bitcheck(flxCard, 5, 5,
"SourceID : FELIX card " );
618 std::bitset<32> flxDev = std::bitset<32>(std::stoi(flx_card_device[1]) - 1 );
620 bitcheck(flxDev, 4, 4,
"SourceID : card device " );
622 std::bitset<32> dma_b = std::bitset<32>(dma);
624 bitcheck(dma_b, 0, 1,
"SourceID : DMA buffer index " );
626 b = subdet | flx_host | flxCard | flxDev | dma_b;
633 std::vector<std::string> fields;
634 std::stringstream
ss(s);
637 while (std::getline(
ss, field,
'.')) {
638 fields.push_back(field);
640 if (fields.size() !=2){
643 if (fields[1] !=
"1" && fields[1] !=
"2" ){
651 if(barrel_endcap == 0){
654 return std::bitset<32>(0x90);
657 return std::bitset<32>(0x91);
662 return std::bitset<32>(0x92);
665 return std::bitset<32>(0x93);
669 else if(barrel_endcap == 2){
671 return std::bitset<32>(0x90);
674 return std::bitset<32>(0x92);
677 return std::bitset<32>(0x94);
680 return std::bitset<32>(0x96);
683 ATH_MSG_ERROR(
"Wrong barrel_endcap / layer_disk / eta_mod values ");
685 return std::bitset<32>(0);
688 else if(barrel_endcap == -2){
690 return std::bitset<32>(0x91);
693 return std::bitset<32>(0x93);
696 return std::bitset<32>(0x95);
699 return std::bitset<32>(0x97);
702 ATH_MSG_ERROR(
"Wrong barrel_endcap / layer_disk / eta_mod values ");
704 return std::bitset<32>(0);
708 ATH_MSG_ERROR(
"Wrong barrel_endcap value: " << barrel_endcap);
710 return std::bitset<32>(0);
718 std::ifstream fcheck(s);
719 if (!fcheck.good()) {
721 return StatusCode::FAILURE;
727 bool firstLine =
true;
728 std::vector < OutputCsvRow > rowVec;
729 while (std::getline(fcheck, line)) {
737 const std::vector<std::string> fields =
splitCsvLine(line);
738 if (fields.size() < 6) {
744 const auto parseHex = [](
const std::string& value) ->
unsigned int {
745 std::istringstream iss(value);
747 unsigned int parsed = 0;
752 row.detResId = std::bitset<32>(parseHex(fields[0]));
753 row.tdetResId = std::bitset<32>(parseHex(fields[1]));
754 row.card_dev = fields[2];
755 row.fiber = parseHex(fields[3]);
756 row.dma = std::stoi(fields[4]);
757 row.sourceId = std::bitset<32>(parseHex(fields[5]));
758 rowVec.push_back(std::move(row));
764 std::vector<std::string > cards;
765 while (i < rowVec.size()) {
766 const std::string& card = rowVec[i].card_dev;
767 if(std::find(cards.begin(), cards.end(), card) != cards.end()) {
770 cards.push_back(card);
773 std::map < int, float> fiber_links_map ;
774 std::map < int, int> fiber_dma_map ;
775 int dma_nfiber[4] = {};
778 for (; j < rowVec.size() ; ++j) {
779 if(rowVec[j].card_dev != card){
783 fiber_dma_map[rowVec[j].fiber] = rowVec[j].dma ;
785 if(rowVec[j].fiber > 12){
786 ATH_MSG_WARNING(
"Sanity check of file " << s <<
" : Bad number of fibers, line: " << j );
790 if( (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0xf0000000) ){
791 fiber_links_map[rowVec[j].fiber] += 0.25;
793 else if( (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0xc0000000) ||
794 (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0x30000000)) {
795 fiber_links_map[rowVec[j].fiber] += 0.5;
797 else if( (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0x00000000)) {
798 fiber_links_map[rowVec[j].fiber] += 1;
801 ATH_MSG_WARNING(
"Sanity check of file " << s <<
" : Bad Chip ID value in DetResID, line: " << j );
805 if( (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0x30000000) ){
806 fiber_links_map[rowVec[j].fiber] += 0.25;
808 else if( (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0x20000000) ||
809 (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0x10000000)) {
810 fiber_links_map[rowVec[j].fiber] += 0.5;
812 else if( (rowVec[j].detResId & std::bitset<32>(0xf0000000)) == std::bitset<32>(0x00000000)) {
813 fiber_links_map[rowVec[j].fiber] += 1;
816 ATH_MSG_WARNING(
"Sanity check of file " << s <<
" : Bad Chip ID value in DetResID, line: " << j );
822 for (
const auto & p : fiber_links_map ) {
823 if(ceilf(p.second) != p.second){
825 << card <<
" ; Fiber " << p.first <<
"N links = " << p.second );
828 ATH_MSG_WARNING(
"More than 6 physical lpGBT links, file " << s <<
" : Card.device = "
829 << card <<
" ; Fiber " << p.first <<
" ; N links = " << p.second );
834 for (
const auto & p : fiber_dma_map ) {
837 ATH_MSG_WARNING(
"DMA buffer index higher than 3, file " << s <<
" : Card.device = "
838 << card <<
" ; DMA " << p.second <<
" ; fiber = " << p.first );
841 dma_nfiber[p.second] ++;
843 for (std::size_t g = 0; g < std::size(dma_nfiber); ++g) {
844 if(dma_nfiber[g] > 3){
845 ATH_MSG_WARNING(
"More than 3 fibers, file " << s <<
" : Card.device = "
846 << card <<
" ; DMA " << g <<
" ; N fibers = " << dma_nfiber[g] );
853 return StatusCode::SUCCESS;
862 uint32_t
x =
static_cast<uint32_t
> (b.to_ulong());
864 uint32_t lsb_used = std::countr_zero(
x);
865 uint32_t msb_used = std::bit_width(
x) - 1;
867 if( (msb_used > msb_lim) || (lsb_used < lsb_lim) ){
868 ATH_MSG_WARNING(
"Bits used for this ID (" << s <<
") are not correctly set");
869 ATH_MSG_WARNING(
" MSB used = " << msb_used <<
" MSB allowed = " << msb_lim);
870 ATH_MSG_WARNING(
" LSB used = " << lsb_used <<
" LSB allowed = " << lsb_lim);
880 return (p.card1 == card);
884 return (p.card2 == card);
892 std::size_t pos = s.rfind(
'-');
893 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);
896 ATH_MSG_WARNING(
"Couldn't find a host for card number " << card <<
", returning (0, 0)");
897 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_WARNING(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
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
const StatusCode sanityCheck(const std::string &s, bool legacy=false) 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)