M3badchannels (#526)

* badchannels for m3 and modify for g2 (file from single and multi)

* m3: invert polarity of bit 7 and 11 signals from setmodule, allow commas in bad channel file

* badchannel file can take commas, colons and comments (also taking care of spaces at the end of channel numbers)

* tests 'badchannels' and 'Channel file reading' added, removing duplicates in badchannel list, defining macro for num counters in client side

* fix segfault when list from file is empty, 

* fix tests assertion for ctbconfig (adding message) for c++11

* fixed badchannels in m3server (clocking in trimming) 

* badchannel tests can be run from any folder (finds the file)
This commit is contained in:
Dhanya Thattil
2022-09-01 15:30:04 +02:00
committed by GitHub
parent 02322bb3c2
commit 7de6f157b5
36 changed files with 499 additions and 221 deletions

View File

@ -7,6 +7,7 @@
#include <cstdio>
#include <fstream>
#include <string>
#include <vector>
namespace sls {
@ -48,4 +49,13 @@ int getFileSize(std::ifstream &ifs);
ssize_t getFileSize(FILE *fd, const std::string &prependErrorString);
std::string getFileNameFromFilePath(const std::string &fpath);
/** File can have # for comments.
* Channels can be separated by spaces, commas
* and ranges provided using ':', eg. 23:29
* */
std::vector<int> getChannelsFromFile(const std::string &fname);
std::string getAbsolutePathFromCurrentProcess(const std::string &fname);
} // namespace sls

View File

@ -73,6 +73,8 @@
#define MAX_PATTERN_LEVELS 6
#define M3_MAX_PATTERN_LEVELS 3
#define MAX_NUM_COUNTERS 3
#define DEFAULT_STREAMING_TIMER_IN_MS 500
#define NUM_RX_THREAD_IDS 9

View File

@ -5,10 +5,10 @@
#define APILIB 0x220609
#define APIRECEIVER 0x220609
#define APIGUI 0x220609
#define APIGOTTHARD 0x220816
#define APIEIGER 0x220816
#define APIMYTHEN3 0x220822
#define APICTB 0x220825
#define APIMOENCH 0x220825
#define APIGOTTHARD2 0x220830
#define APIJUNGFRAU 0x220831
#define APICTB 0x220831
#define APIGOTTHARD 0x220831
#define APIJUNGFRAU 0x220831
#define APIMOENCH 0x220831
#define APIMYTHEN3 0x220901
#define APIGOTTHARD2 0x220901

View File

@ -1,15 +1,18 @@
// SPDX-License-Identifier: LGPL-3.0-or-other
// Copyright (C) 2021 Contributors to the SLS Detector Package
#include "sls/file_utils.h"
#include "sls/ToString.h"
#include "sls/logger.h"
#include "sls/sls_detector_exceptions.h"
#include <errno.h>
#include <ios>
#include <iostream>
#include <libgen.h> // dirname
#include <sstream>
#include <sys/stat.h>
#include <sys/types.h>
#include <unistd.h> //readlink
namespace sls {
@ -162,4 +165,99 @@ ssize_t getFileSize(FILE *fd, const std::string &prependErrorString) {
return fileSize;
}
std::vector<int> getChannelsFromFile(const std::string &fname) {
// read bad channels file
std::ifstream input_file(fname);
if (!input_file) {
throw RuntimeError("Could not open bad channels file " + fname +
" for reading");
}
std::vector<int> list;
for (std::string line; std::getline(input_file, line);) {
// ignore comments
if (line.find('#') != std::string::npos) {
line.erase(line.find('#'));
}
// replace comma with space
std::replace_if(
begin(line), end(line), [](char c) { return (c == ','); }, ' ');
// replace x:y with a sequence of x to y
auto result = line.find(':');
while (result != std::string::npos) {
auto start = line.rfind(' ', result);
if (start == std::string::npos) {
start = 0;
} else
++start;
int istart = StringTo<int>(line.substr(start, result - start));
auto stop = line.find(' ', result);
if (stop == std::string::npos) {
stop = line.length();
}
int istop =
StringTo<int>(line.substr(result + 1, stop - result - 1));
std::vector<int> v(istop - istart);
std::generate(v.begin(), v.end(),
[n = istart]() mutable { return n++; });
line.replace(start, stop - start, ToString(v));
LOG(logDEBUG1) << line;
result = line.find(':');
}
// remove punctuations including [ and ]
line.erase(std::remove_if(begin(line), end(line), ispunct), end(line));
LOG(logDEBUG) << "\nline: [" << line << ']';
// split line (delim space) and push to list
std::vector<std::string> vec = split(line, ' ');
for (auto it : vec) {
int ival = 0;
try {
ival = StringTo<int>(it);
} catch (std::exception &e) {
throw RuntimeError("Could not load channels from file. Invalid "
"channel number: " +
it);
}
list.push_back(ival);
}
}
// remove duplicates from list
auto listSize = list.size();
std::sort(list.begin(), list.end());
list.erase(unique(list.begin(), list.end()), list.end());
if (list.size() != listSize) {
LOG(logWARNING) << "Removed duplicates from channel file";
}
LOG(logDEBUG1) << "list:" << ToString(list);
return list;
}
std::string getAbsolutePathFromCurrentProcess(const std::string &fname) {
if (fname[0] == '/') {
return fname;
}
// get path of current binary
char path[MAX_STR_LENGTH];
memset(path, 0, MAX_STR_LENGTH);
ssize_t len = readlink("/proc/self/exe", path, MAX_STR_LENGTH - 1);
if (len < 0) {
throw RuntimeError("Could not get absolute path for " + fname);
}
path[len] = '\0';
// get dir path and attach file name
std::string absPath = (std::string(dirname(path)) + '/' + fname);
return absPath;
}
} // namespace sls

View File

@ -14,7 +14,9 @@ std::vector<std::string> split(const std::string &strToSplit, char delimeter) {
std::string item;
std::vector<std::string> splittedStrings;
while (std::getline(ss, item, delimeter)) {
splittedStrings.push_back(item);
if (item.length() > 0) {
splittedStrings.push_back(item);
}
}
return splittedStrings;
}

View File

@ -15,4 +15,6 @@ target_sources(tests PRIVATE
${CMAKE_CURRENT_SOURCE_DIR}/test-UdpRxSocket.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-logger.cpp
${CMAKE_CURRENT_SOURCE_DIR}/test-ZmqSocket.cpp
)
)
configure_file(${CMAKE_CURRENT_SOURCE_DIR}/test-file_utils-channels.txt ${CMAKE_BINARY_DIR}/bin/test-file_utils-channels.txt COPYONLY)

View File

@ -0,0 +1,5 @@
0
#should remove duplicates
12, 15, 43
40:45 #sequence from 40 to 44
1279

View File

@ -7,6 +7,8 @@
#include <unistd.h>
#include <vector>
#include "tests/globals.h"
namespace sls {
TEST_CASE("Get size of empty file") {
@ -29,4 +31,13 @@ TEST_CASE("Get size of file with data") {
REQUIRE(ifs.tellg() == 0); // getting size resets pos!
}
TEST_CASE("Channel file reading") {
std::string fname =
getAbsolutePathFromCurrentProcess(TEST_FILE_NAME_BAD_CHANNELS);
std::vector<int> list;
REQUIRE_NOTHROW(list = getChannelsFromFile(fname));
std::vector<int> expected = {0, 12, 15, 40, 41, 42, 43, 44, 1279};
REQUIRE(list == expected);
}
} // namespace sls