mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2025-06-04 03:50:41 +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/RawMasterFile.hpp
|
||||
include/aare/Frame.hpp
|
||||
include/aare/json.hpp
|
||||
include/aare/NDArray.hpp
|
||||
include/aare/NDView.hpp
|
||||
include/aare/NumpyFile.hpp
|
||||
|
@ -23,7 +23,7 @@ class RawFileNameComponents {
|
||||
RawFileNameComponents(const std::filesystem::path &fname);
|
||||
|
||||
/// @brief Get the filename including path of the master file.
|
||||
/// (i.e. what was passed in to the constructor))
|
||||
/// (i.e. what was passed in to the constructor))
|
||||
std::filesystem::path master_fname() const;
|
||||
|
||||
/// @brief Get the filename including path of the data file.
|
||||
@ -31,16 +31,36 @@ class RawFileNameComponents {
|
||||
/// @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;
|
||||
|
||||
|
||||
const std::filesystem::path &base_path() const;
|
||||
const std::string &base_name() const;
|
||||
const std::string &ext() 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 {
|
||||
RawFileNameComponents m_fnc;
|
||||
@ -62,11 +82,13 @@ class RawMasterFile {
|
||||
FrameDiscardPolicy m_frame_discard_policy{};
|
||||
size_t m_frame_padding{};
|
||||
|
||||
//TODO! should these be bool?
|
||||
// TODO! should these be bool?
|
||||
uint8_t m_analog_flag{};
|
||||
uint8_t m_digital_flag{};
|
||||
uint8_t m_transceiver_flag{};
|
||||
|
||||
ScanParameters m_scan_parameters;
|
||||
|
||||
std::optional<size_t> m_analog_samples;
|
||||
std::optional<size_t> m_digital_samples;
|
||||
std::optional<size_t> m_transceiver_samples;
|
||||
@ -78,7 +100,7 @@ class RawMasterFile {
|
||||
|
||||
std::filesystem::path data_fname(size_t mod_id, size_t file_id) const;
|
||||
|
||||
const std::string &version() const; //!< For example "7.2"
|
||||
const std::string &version() const; //!< For example "7.2"
|
||||
const DetectorType &detector_type() const;
|
||||
const TimingMode &timing_mode() const;
|
||||
size_t image_size_in_bytes() const;
|
||||
@ -98,6 +120,9 @@ class RawMasterFile {
|
||||
std::optional<size_t> transceiver_samples() const;
|
||||
std::optional<size_t> number_of_rows() const;
|
||||
std::optional<uint8_t> quad() const;
|
||||
|
||||
ScanParameters scan_parameters() const;
|
||||
|
||||
private:
|
||||
void parse_json(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/CtbRawFile.py
|
||||
aare/transform.py
|
||||
aare/ScanParameters.py
|
||||
)
|
||||
|
||||
# Copy the python files to the build directory
|
||||
|
@ -1,7 +1,7 @@
|
||||
|
||||
from . import _aare
|
||||
import numpy as np
|
||||
|
||||
from .ScanParameters import ScanParameters
|
||||
class CtbRawFile(_aare.CtbRawFile):
|
||||
"""File reader for the CTB raw file format.
|
||||
|
||||
@ -108,7 +108,24 @@ class CtbRawFile(_aare.CtbRawFile):
|
||||
int: Frame position in file.
|
||||
"""
|
||||
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
|
||||
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__()
|
||||
|
||||
|
@ -3,4 +3,5 @@ from . import _aare
|
||||
|
||||
from ._aare import VarClusterFinder, File, RawMasterFile
|
||||
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:
|
||||
#Could be moved to C++ without changing the interface
|
||||
def __init__(self):
|
||||
print('map created')
|
||||
self.pixel_map = _aare.GenerateMoench05PixelMap()
|
||||
|
||||
def __call__(self, data):
|
||||
@ -23,6 +22,7 @@ class Matterhorn02Transform:
|
||||
else:
|
||||
return np.take(data.view(np.uint16), self.pixel_map[0:counters])
|
||||
|
||||
|
||||
#on import generate the pixel maps to avoid doing it every time
|
||||
moench05 = Moench05Transform()
|
||||
matterhorn02 = Matterhorn02Transform()
|
@ -95,11 +95,11 @@ f = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
||||
f.seek(100)
|
||||
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.seek(100)
|
||||
header4, image4 = f.read_frame()
|
||||
# f = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
||||
# f.seek(100)
|
||||
# header4, image4 = f.read_frame()
|
||||
|
||||
# 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 = get_Mh02_frames(fpath.as_posix())
|
||||
# data = get_Mh02_frames(fpath.as_posix())
|
||||
|
||||
# rawi = np.zeros(48*48*4+56, dtype = np.uint16)
|
||||
# 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
|
||||
|
||||
|
||||
f2 = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
||||
header, data = f2.read()
|
||||
plt.plot(data[:,0,20,20])
|
||||
# f2 = aare.CtbRawFile(fpath, transform=transform.matterhorn02)
|
||||
# header, data = f2.read()
|
||||
# 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",
|
||||
&RawMasterFile::max_frames_per_file)
|
||||
.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("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")
|
||||
// .def(py::init<>())
|
||||
// .def_readwrite("frame_number", &ClusterHeader::frame_number)
|
||||
|
@ -1,7 +1,6 @@
|
||||
#include "aare/RawFile.hpp"
|
||||
#include "aare/PixelMap.hpp"
|
||||
#include "aare/defs.hpp"
|
||||
#include "aare/json.hpp"
|
||||
|
||||
#include <fmt/format.h>
|
||||
#include <nlohmann/json.hpp>
|
||||
|
@ -1,5 +1,5 @@
|
||||
#include "aare/RawMasterFile.hpp"
|
||||
|
||||
#include <sstream>
|
||||
namespace aare {
|
||||
|
||||
RawFileNameComponents::RawFileNameComponents(
|
||||
@ -51,6 +51,32 @@ const std::string &RawFileNameComponents::base_name() const {
|
||||
const std::string &RawFileNameComponents::ext() const { return m_ext; }
|
||||
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)
|
||||
: m_fnc(fpath) {
|
||||
if (!std::filesystem::exists(fpath)) {
|
||||
@ -113,6 +139,10 @@ std::optional<size_t> RawMasterFile::transceiver_samples() const {
|
||||
return m_transceiver_samples;
|
||||
}
|
||||
|
||||
ScanParameters RawMasterFile::scan_parameters() const {
|
||||
return m_scan_parameters;
|
||||
}
|
||||
|
||||
void RawMasterFile::parse_json(const std::filesystem::path &fpath) {
|
||||
std::ifstream ifs(fpath);
|
||||
json j;
|
||||
@ -203,6 +233,13 @@ void RawMasterFile::parse_json(const std::filesystem::path &fpath) {
|
||||
// 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
|
||||
// TODO! How does this work with old .raw master files?
|
||||
#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"){
|
||||
auto fpath = test_data_path() / "jungfrau" / "jungfrau_single_master_0.json";
|
||||
REQUIRE(std::filesystem::exists(fpath));
|
||||
|
Loading…
x
Reference in New Issue
Block a user