mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-07 05:10:39 +02:00
added simple decoding of scan parameters
This commit is contained in:
parent
b2e5c71f9c
commit
9c220bff51
@ -244,7 +244,6 @@ set(PUBLICHEADERS
|
|||||||
include/aare/FileInterface.hpp
|
include/aare/FileInterface.hpp
|
||||||
include/aare/RawMasterFile.hpp
|
include/aare/RawMasterFile.hpp
|
||||||
include/aare/Frame.hpp
|
include/aare/Frame.hpp
|
||||||
include/aare/json.hpp
|
|
||||||
include/aare/NDArray.hpp
|
include/aare/NDArray.hpp
|
||||||
include/aare/NDView.hpp
|
include/aare/NDView.hpp
|
||||||
include/aare/NumpyFile.hpp
|
include/aare/NumpyFile.hpp
|
||||||
|
@ -31,16 +31,36 @@ class RawFileNameComponents {
|
|||||||
/// @param file_id file id run_d0_f[file_id]_0
|
/// @param file_id file id run_d0_f[file_id]_0
|
||||||
std::filesystem::path data_fname(size_t mod_id, size_t file_id) const;
|
std::filesystem::path data_fname(size_t mod_id, size_t file_id) const;
|
||||||
|
|
||||||
|
|
||||||
const std::filesystem::path &base_path() const;
|
const std::filesystem::path &base_path() const;
|
||||||
const std::string &base_name() const;
|
const std::string &base_name() const;
|
||||||
const std::string &ext() const;
|
const std::string &ext() const;
|
||||||
int file_index() const;
|
int file_index() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
class ScanParameters {
|
||||||
|
bool m_enabled = false;
|
||||||
|
std::string m_dac;
|
||||||
|
int m_start = 0;
|
||||||
|
int m_stop = 0;
|
||||||
|
int m_step = 0;
|
||||||
|
//TODO! add settleTime, requires string to time conversion
|
||||||
|
|
||||||
|
public:
|
||||||
|
ScanParameters(const std::string &par);
|
||||||
|
ScanParameters() = default;
|
||||||
|
ScanParameters(const ScanParameters &) = default;
|
||||||
|
ScanParameters &operator=(const ScanParameters &) = default;
|
||||||
|
ScanParameters(ScanParameters &&) = default;
|
||||||
|
int start() const;
|
||||||
|
int stop() const;
|
||||||
|
int step() const;
|
||||||
|
const std::string &dac() const;
|
||||||
|
bool enabled() const;
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Class for parsing a master file either in our .json format or the old .raw format
|
* @brief Class for parsing a master file either in our .json format or the old
|
||||||
|
* .raw format
|
||||||
*/
|
*/
|
||||||
class RawMasterFile {
|
class RawMasterFile {
|
||||||
RawFileNameComponents m_fnc;
|
RawFileNameComponents m_fnc;
|
||||||
@ -67,6 +87,8 @@ class RawMasterFile {
|
|||||||
uint8_t m_digital_flag{};
|
uint8_t m_digital_flag{};
|
||||||
uint8_t m_transceiver_flag{};
|
uint8_t m_transceiver_flag{};
|
||||||
|
|
||||||
|
ScanParameters m_scan_parameters;
|
||||||
|
|
||||||
std::optional<size_t> m_analog_samples;
|
std::optional<size_t> m_analog_samples;
|
||||||
std::optional<size_t> m_digital_samples;
|
std::optional<size_t> m_digital_samples;
|
||||||
std::optional<size_t> m_transceiver_samples;
|
std::optional<size_t> m_transceiver_samples;
|
||||||
@ -98,6 +120,9 @@ class RawMasterFile {
|
|||||||
std::optional<size_t> transceiver_samples() const;
|
std::optional<size_t> transceiver_samples() const;
|
||||||
std::optional<size_t> number_of_rows() const;
|
std::optional<size_t> number_of_rows() const;
|
||||||
std::optional<uint8_t> quad() const;
|
std::optional<uint8_t> quad() const;
|
||||||
|
|
||||||
|
ScanParameters scan_parameters() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void parse_json(const std::filesystem::path &fpath);
|
void parse_json(const std::filesystem::path &fpath);
|
||||||
void parse_raw(const std::filesystem::path &fpath);
|
void parse_raw(const std::filesystem::path &fpath);
|
||||||
|
@ -1,68 +0,0 @@
|
|||||||
#pragma once
|
|
||||||
#include <array>
|
|
||||||
#include <map>
|
|
||||||
#include <string>
|
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
// helper functions to write json
|
|
||||||
// append to string for better performance (not tested)
|
|
||||||
|
|
||||||
namespace aare {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* @brief write a digit to a string
|
|
||||||
* takes key and value and outputs->"key": value,
|
|
||||||
* @tparam T type of value (int, uint32_t, ...)
|
|
||||||
* @param s string to append to
|
|
||||||
* @param key key to write
|
|
||||||
* @param value value to write
|
|
||||||
* @return void
|
|
||||||
* @note
|
|
||||||
* - can't use concepts here because we are using c++17
|
|
||||||
*/
|
|
||||||
template <typename T> inline void write_digit(std::string &s, const std::string &key, const T &value) {
|
|
||||||
s += "\"";
|
|
||||||
s += key;
|
|
||||||
s += "\": ";
|
|
||||||
s += std::to_string(value);
|
|
||||||
s += ", ";
|
|
||||||
}
|
|
||||||
inline void write_str(std::string &s, const std::string &key, const std::string &value) {
|
|
||||||
s += "\"";
|
|
||||||
s += key;
|
|
||||||
s += "\": \"";
|
|
||||||
s += value;
|
|
||||||
s += "\", ";
|
|
||||||
}
|
|
||||||
inline void write_map(std::string &s, const std::string &key, const std::map<std::string, std::string> &value) {
|
|
||||||
s += "\"";
|
|
||||||
s += key;
|
|
||||||
s += "\": {";
|
|
||||||
for (const auto &kv : value) {
|
|
||||||
write_str(s, kv.first, kv.second);
|
|
||||||
}
|
|
||||||
// remove last comma or trailing spaces
|
|
||||||
for (size_t i = s.size() - 1; i > 0; i--) {
|
|
||||||
if ((s[i] == ',') || (s[i] == ' ')) {
|
|
||||||
s.pop_back();
|
|
||||||
} else
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
s += "}, ";
|
|
||||||
}
|
|
||||||
|
|
||||||
template <typename T, int N> void write_array(std::string &s, const std::string &key, const std::array<T, N> &value) {
|
|
||||||
s += "\"";
|
|
||||||
s += key;
|
|
||||||
s += "\": [";
|
|
||||||
|
|
||||||
for (size_t i = 0; i < N - 1; i++) {
|
|
||||||
s += std::to_string(value[i]);
|
|
||||||
s += ", ";
|
|
||||||
}
|
|
||||||
s += std::to_string(value[N - 1]);
|
|
||||||
|
|
||||||
s += "], ";
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace aare
|
|
@ -29,6 +29,7 @@ set( PYTHON_FILES
|
|||||||
aare/__init__.py
|
aare/__init__.py
|
||||||
aare/CtbRawFile.py
|
aare/CtbRawFile.py
|
||||||
aare/transform.py
|
aare/transform.py
|
||||||
|
aare/ScanParameters.py
|
||||||
)
|
)
|
||||||
|
|
||||||
# Copy the python files to the build directory
|
# Copy the python files to the build directory
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
|
|
||||||
from . import _aare
|
from . import _aare
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
from .ScanParameters import ScanParameters
|
||||||
class CtbRawFile(_aare.CtbRawFile):
|
class CtbRawFile(_aare.CtbRawFile):
|
||||||
"""File reader for the CTB raw file format.
|
"""File reader for the CTB raw file format.
|
||||||
|
|
||||||
@ -109,6 +109,23 @@ class CtbRawFile(_aare.CtbRawFile):
|
|||||||
"""
|
"""
|
||||||
return super().tell()
|
return super().tell()
|
||||||
|
|
||||||
|
@property
|
||||||
|
def scan_parameters(self):
|
||||||
|
"""Return the scan parameters.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
ScanParameters: Scan parameters.
|
||||||
|
"""
|
||||||
|
return ScanParameters(self.master.scan_parameters)
|
||||||
|
|
||||||
|
@property
|
||||||
|
def master(self):
|
||||||
|
"""Return the master file.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
RawMasterFile: Master file.
|
||||||
|
"""
|
||||||
|
return super().master()
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def image_size_in_bytes(self) -> int:
|
def image_size_in_bytes(self) -> int:
|
||||||
|
16
python/aare/ScanParameters.py
Normal file
16
python/aare/ScanParameters.py
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
from . import _aare
|
||||||
|
|
||||||
|
class ScanParameters(_aare.ScanParameters):
|
||||||
|
def __init__(self, s):
|
||||||
|
super().__init__(s)
|
||||||
|
|
||||||
|
def __iter__(self):
|
||||||
|
return [getattr(self, a) for a in ['start', 'stop', 'step']].__iter__()
|
||||||
|
|
||||||
|
def __str__(self):
|
||||||
|
return f'ScanParameters({self.dac}: {self.start}, {self.stop}, {self.step})'
|
||||||
|
|
||||||
|
def __repr__(self):
|
||||||
|
return self.__str__()
|
||||||
|
|
||||||
|
|
@ -4,3 +4,4 @@ from . import _aare
|
|||||||
from ._aare import VarClusterFinder, File, RawMasterFile
|
from ._aare import VarClusterFinder, File, RawMasterFile
|
||||||
from ._aare import Pedestal, ClusterFinder
|
from ._aare import Pedestal, ClusterFinder
|
||||||
from .CtbRawFile import CtbRawFile
|
from .CtbRawFile import CtbRawFile
|
||||||
|
from .ScanParameters import ScanParameters
|
@ -5,7 +5,6 @@ from . import _aare
|
|||||||
class Moench05Transform:
|
class Moench05Transform:
|
||||||
#Could be moved to C++ without changing the interface
|
#Could be moved to C++ without changing the interface
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
print('map created')
|
|
||||||
self.pixel_map = _aare.GenerateMoench05PixelMap()
|
self.pixel_map = _aare.GenerateMoench05PixelMap()
|
||||||
|
|
||||||
def __call__(self, data):
|
def __call__(self, data):
|
||||||
@ -23,6 +22,7 @@ class Matterhorn02Transform:
|
|||||||
else:
|
else:
|
||||||
return np.take(data.view(np.uint16), self.pixel_map[0:counters])
|
return np.take(data.view(np.uint16), self.pixel_map[0:counters])
|
||||||
|
|
||||||
|
|
||||||
#on import generate the pixel maps to avoid doing it every time
|
#on import generate the pixel maps to avoid doing it every time
|
||||||
moench05 = Moench05Transform()
|
moench05 = Moench05Transform()
|
||||||
matterhorn02 = Matterhorn02Transform()
|
matterhorn02 = Matterhorn02Transform()
|
@ -95,11 +95,11 @@ f = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
|||||||
f.seek(100)
|
f.seek(100)
|
||||||
header1, image1 = f.read_frame()
|
header1, image1 = f.read_frame()
|
||||||
|
|
||||||
fpath = Path(base / 'scan_all15keV_vrf500_vrsh700_th0_master_0.json')
|
# fpath = Path(base / 'scan_all15keV_vrf500_vrsh700_th0_master_0.json')
|
||||||
|
|
||||||
f = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
# f = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
||||||
f.seek(100)
|
# f.seek(100)
|
||||||
header4, image4 = f.read_frame()
|
# header4, image4 = f.read_frame()
|
||||||
|
|
||||||
# n_counters = image.shape[1] / 48**2 / 2
|
# n_counters = image.shape[1] / 48**2 / 2
|
||||||
|
|
||||||
@ -112,7 +112,7 @@ header4, image4 = f.read_frame()
|
|||||||
|
|
||||||
|
|
||||||
#Data come in "blocks" of 4 pixels/receiver
|
#Data come in "blocks" of 4 pixels/receiver
|
||||||
data = get_Mh02_frames(fpath.as_posix())
|
# data = get_Mh02_frames(fpath.as_posix())
|
||||||
|
|
||||||
# rawi = np.zeros(48*48*4+56, dtype = np.uint16)
|
# rawi = np.zeros(48*48*4+56, dtype = np.uint16)
|
||||||
# for i,v in enumerate(rawi[56:]):
|
# for i,v in enumerate(rawi[56:]):
|
||||||
@ -130,7 +130,7 @@ data = get_Mh02_frames(fpath.as_posix())
|
|||||||
# pm[counter, row, col] = row*48 + col+counter*48*48
|
# pm[counter, row, col] = row*48 + col+counter*48*48
|
||||||
|
|
||||||
|
|
||||||
f2 = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
# f2 = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
||||||
header, data = f2.read()
|
# header, data = f2.read()
|
||||||
plt.plot(data[:,0,20,20])
|
# plt.plot(data[:,0,20,20])
|
||||||
|
|
||||||
|
@ -166,11 +166,29 @@ void define_file_io_bindings(py::module &m) {
|
|||||||
.def_property_readonly("max_frames_per_file",
|
.def_property_readonly("max_frames_per_file",
|
||||||
&RawMasterFile::max_frames_per_file)
|
&RawMasterFile::max_frames_per_file)
|
||||||
.def_property_readonly("bitdepth", &RawMasterFile::bitdepth)
|
.def_property_readonly("bitdepth", &RawMasterFile::bitdepth)
|
||||||
|
.def_property_readonly("frame_padding", &RawMasterFile::frame_padding)
|
||||||
|
.def_property_readonly("frame_discard_policy",
|
||||||
|
&RawMasterFile::frame_discard_policy)
|
||||||
|
.def_property_readonly("total_frames_expected", &RawMasterFile::total_frames_expected)
|
||||||
|
.def_property_readonly("geometry", &RawMasterFile::geometry)
|
||||||
.def_property_readonly("analog_samples", &RawMasterFile::analog_samples)
|
.def_property_readonly("analog_samples", &RawMasterFile::analog_samples)
|
||||||
.def_property_readonly("digital_samples",
|
.def_property_readonly("digital_samples",
|
||||||
&RawMasterFile::digital_samples)
|
&RawMasterFile::digital_samples)
|
||||||
.def_property_readonly("transceiver_samples", &RawMasterFile::transceiver_samples);
|
.def_property_readonly("transceiver_samples", &RawMasterFile::transceiver_samples)
|
||||||
|
.def_property_readonly("number_of_rows", &RawMasterFile::number_of_rows)
|
||||||
|
.def_property_readonly("quad", &RawMasterFile::quad)
|
||||||
|
.def_property_readonly("scan_parameters", &RawMasterFile::scan_parameters);
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
py::class_<ScanParameters>(m, "ScanParameters")
|
||||||
|
.def(py::init<const std::string &>())
|
||||||
|
.def(py::init<const ScanParameters&>())
|
||||||
|
.def_property_readonly("enabled", &ScanParameters::enabled)
|
||||||
|
.def_property_readonly("dac", &ScanParameters::dac)
|
||||||
|
.def_property_readonly("start", &ScanParameters::start)
|
||||||
|
.def_property_readonly("stop", &ScanParameters::stop)
|
||||||
|
.def_property_readonly("step", &ScanParameters::step);
|
||||||
// py::class_<ClusterHeader>(m, "ClusterHeader")
|
// py::class_<ClusterHeader>(m, "ClusterHeader")
|
||||||
// .def(py::init<>())
|
// .def(py::init<>())
|
||||||
// .def_readwrite("frame_number", &ClusterHeader::frame_number)
|
// .def_readwrite("frame_number", &ClusterHeader::frame_number)
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
#include "aare/RawFile.hpp"
|
#include "aare/RawFile.hpp"
|
||||||
#include "aare/PixelMap.hpp"
|
#include "aare/PixelMap.hpp"
|
||||||
#include "aare/defs.hpp"
|
#include "aare/defs.hpp"
|
||||||
#include "aare/json.hpp"
|
|
||||||
|
|
||||||
#include <fmt/format.h>
|
#include <fmt/format.h>
|
||||||
#include <nlohmann/json.hpp>
|
#include <nlohmann/json.hpp>
|
||||||
|
@ -1,5 +1,5 @@
|
|||||||
#include "aare/RawMasterFile.hpp"
|
#include "aare/RawMasterFile.hpp"
|
||||||
|
#include <sstream>
|
||||||
namespace aare {
|
namespace aare {
|
||||||
|
|
||||||
RawFileNameComponents::RawFileNameComponents(
|
RawFileNameComponents::RawFileNameComponents(
|
||||||
@ -51,6 +51,32 @@ const std::string &RawFileNameComponents::base_name() const {
|
|||||||
const std::string &RawFileNameComponents::ext() const { return m_ext; }
|
const std::string &RawFileNameComponents::ext() const { return m_ext; }
|
||||||
int RawFileNameComponents::file_index() const { return m_file_index; }
|
int RawFileNameComponents::file_index() const { return m_file_index; }
|
||||||
|
|
||||||
|
// "[enabled\ndac dac 4\nstart 500\nstop 2200\nstep 5\nsettleTime 100us\n]"
|
||||||
|
ScanParameters::ScanParameters(const std::string& par){
|
||||||
|
std::istringstream iss(par.substr(1, par.size()-2));
|
||||||
|
std::string line;
|
||||||
|
while(std::getline(iss, line)){
|
||||||
|
if(line == "enabled"){
|
||||||
|
m_enabled = true;
|
||||||
|
}else if(line.find("dac") != std::string::npos){
|
||||||
|
m_dac = line.substr(4);
|
||||||
|
}else if(line.find("start") != std::string::npos){
|
||||||
|
m_start = std::stoi(line.substr(6));
|
||||||
|
}else if(line.find("stop") != std::string::npos){
|
||||||
|
m_stop = std::stoi(line.substr(5));
|
||||||
|
}else if(line.find("step") != std::string::npos){
|
||||||
|
m_step = std::stoi(line.substr(5));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int ScanParameters::start() const { return m_start; }
|
||||||
|
int ScanParameters::stop() const { return m_stop; }
|
||||||
|
int ScanParameters::step() const { return m_step; }
|
||||||
|
const std::string &ScanParameters::dac() const { return m_dac; }
|
||||||
|
bool ScanParameters::enabled() const { return m_enabled; }
|
||||||
|
|
||||||
|
|
||||||
RawMasterFile::RawMasterFile(const std::filesystem::path &fpath)
|
RawMasterFile::RawMasterFile(const std::filesystem::path &fpath)
|
||||||
: m_fnc(fpath) {
|
: m_fnc(fpath) {
|
||||||
if (!std::filesystem::exists(fpath)) {
|
if (!std::filesystem::exists(fpath)) {
|
||||||
@ -113,6 +139,10 @@ std::optional<size_t> RawMasterFile::transceiver_samples() const {
|
|||||||
return m_transceiver_samples;
|
return m_transceiver_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ScanParameters RawMasterFile::scan_parameters() const {
|
||||||
|
return m_scan_parameters;
|
||||||
|
}
|
||||||
|
|
||||||
void RawMasterFile::parse_json(const std::filesystem::path &fpath) {
|
void RawMasterFile::parse_json(const std::filesystem::path &fpath) {
|
||||||
std::ifstream ifs(fpath);
|
std::ifstream ifs(fpath);
|
||||||
json j;
|
json j;
|
||||||
@ -203,6 +233,13 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) {
|
|||||||
// keep the optional empty
|
// keep the optional empty
|
||||||
}
|
}
|
||||||
|
|
||||||
|
try{
|
||||||
|
std::string scan_parameters = j.at("Scan Parameters");
|
||||||
|
m_scan_parameters = ScanParameters(scan_parameters);
|
||||||
|
}catch (const json::out_of_range &e) {
|
||||||
|
// not a scan
|
||||||
|
}
|
||||||
|
|
||||||
// Update detector type for Moench
|
// Update detector type for Moench
|
||||||
// TODO! How does this work with old .raw master files?
|
// TODO! How does this work with old .raw master files?
|
||||||
#ifdef AARE_VERBOSE
|
#ifdef AARE_VERBOSE
|
||||||
|
@ -38,6 +38,26 @@ TEST_CASE("Master file name does not fit pattern"){
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
TEST_CASE("Parse scan parameters"){
|
||||||
|
ScanParameters s("[enabled\ndac dac 4\nstart 500\nstop 2200\nstep 5\nsettleTime 100us\n]");
|
||||||
|
REQUIRE(s.enabled());
|
||||||
|
REQUIRE(s.dac() == "dac 4");
|
||||||
|
REQUIRE(s.start() == 500);
|
||||||
|
REQUIRE(s.stop() == 2200);
|
||||||
|
REQUIRE(s.step() == 5);
|
||||||
|
}
|
||||||
|
|
||||||
|
TEST_CASE("A disabled scan"){
|
||||||
|
ScanParameters s("[disabled]");
|
||||||
|
REQUIRE_FALSE(s.enabled());
|
||||||
|
REQUIRE(s.dac() == "");
|
||||||
|
REQUIRE(s.start() == 0);
|
||||||
|
REQUIRE(s.stop() == 0);
|
||||||
|
REQUIRE(s.step() == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
TEST_CASE("Parse a master file in .json format"){
|
TEST_CASE("Parse a master file in .json format"){
|
||||||
auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json";
|
auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json";
|
||||||
REQUIRE(std::filesystem::exists(fpath));
|
REQUIRE(std::filesystem::exists(fpath));
|
||||||
|
Loading…
x
Reference in New Issue
Block a user