40 const std::string& calibrationPath, std::string&
error) {
42 std::ifstream input{calibrationPath};
44 error =
"cannot open ASCII GoodMag map: " + calibrationPath;
49 unsigned int schemaVersion = 0U;
50 bool schemaVersionSeen =
false;
51 bool payloadVersionSeen =
false;
52 bool etaBinsSeen =
false;
53 bool phiBinsSeen =
false;
54 bool mapRecordsStarted =
false;
56 std::size_t lineNumber = 0U;
57 while (std::getline(input, line)) {
59 if (line.empty() || line[0] ==
'#')
continue;
60 if (hasEmptyCsvField(line)) {
61 error =
"empty CSV field at line " + std::to_string(lineNumber);
65 if (fields.empty())
continue;
66 const std::string& record = fields[0];
67 if (record ==
"META") {
68 if (mapRecordsStarted) {
69 error =
"META row after map records at line " +
70 std::to_string(lineNumber);
73 if (fields.size() != 3U) {
74 error =
"invalid META row at line " + std::to_string(lineNumber);
77 const std::string& key = fields[1];
78 if (key ==
"schemaVersion") {
79 if (schemaVersionSeen ||
80 !parseUnsignedInteger(fields[2], schemaVersion)) {
81 error =
"invalid or duplicate schemaVersion";
84 schemaVersionSeen =
true;
85 }
else if (key ==
"payloadVersion") {
86 if (payloadVersionSeen || fields[2].
empty()) {
87 error =
"invalid or duplicate payloadVersion";
90 map->m_version = fields[2];
91 payloadVersionSeen =
true;
92 }
else if (key ==
"etaBins") {
94 !parseUnsignedInteger(fields[2],
map->m_etaBins)) {
95 error =
"invalid or duplicate etaBins";
99 }
else if (key ==
"phiBinsPerFold") {
101 !parseUnsignedInteger(fields[2],
map->m_phiBinsPerFold)) {
102 error =
"invalid or duplicate phiBinsPerFold";
107 error =
"unknown metadata key at line " +
108 std::to_string(lineNumber) +
": " + key;
114 mapRecordsStarted =
true;
115 if (record !=
"POOR") {
116 error =
"unknown map record at line " + std::to_string(lineNumber) +
120 if (fields.size() != 3U ||
map->m_etaBins == 0U ||
121 map->m_phiBinsPerFold == 0U) {
122 error =
"invalid POOR row at line " + std::to_string(lineNumber);
127 if (!parseInteger(fields[1], etaBin) ||
128 !parseInteger(fields[2], phiFoldBin) || etaBin < 0 ||
129 phiFoldBin < 0 || etaBin >=
static_cast<int>(
map->m_etaBins) ||
130 phiFoldBin >=
static_cast<int>(
map->m_phiBinsPerFold)) {
131 error =
"invalid map bin at line " + std::to_string(lineNumber);
134 if (
map->m_poorBins.empty()) {
135 const std::size_t
count =
static_cast<std::size_t
>(
map->m_etaBins) *
136 map->m_phiBinsPerFold;
137 map->m_poorBins.assign(
count,
false);
139 const std::size_t
index =
static_cast<std::size_t
>(etaBin) *
140 map->m_phiBinsPerFold +
141 static_cast<std::size_t
>(phiFoldBin);
143 error =
"duplicate POOR bin at line " + std::to_string(lineNumber);
147 ++
map->m_poorBinCount;
150 if (!schemaVersionSeen || schemaVersion != 1U || !payloadVersionSeen ||
151 !etaBinsSeen || !phiBinsSeen ||
map->m_etaBins == 0U ||
152 map->m_phiBinsPerFold == 0U) {
153 error =
"incomplete or unsupported ASCII GoodMag metadata";
156 if (
map->m_poorBins.empty()) {
157 const std::size_t
count =
static_cast<std::size_t
>(
map->m_etaBins) *
158 map->m_phiBinsPerFold;
159 map->m_poorBins.assign(
count,
false);