outline python class a bit
This commit is contained in:
+3
-1
@@ -47,8 +47,10 @@ add_library(jungfraucalibration STATIC ${SourceFiles} ${PUBLICHEADERS})
|
||||
target_include_directories(
|
||||
jungfraucalibration PUBLIC "$<BUILD_INTERFACE:${CMAKE_CURRENT_SOURCE_DIR}/include>")
|
||||
|
||||
target_link_libraries(jungfraucalibration PRIVATE aare_core) # TODO: should it be public?
|
||||
target_link_libraries(jungfraucalibration PUBLIC aare_core) # TODO: should it be public?
|
||||
|
||||
# TODO: add other compile options?
|
||||
target_compile_features(jungfraucalibration PRIVATE cxx_std_17)
|
||||
|
||||
#add_subdirectory(examples)
|
||||
|
||||
|
||||
@@ -1,14 +1,14 @@
|
||||
|
||||
#include "aare/JungfrauDataFile.hpp"
|
||||
#include "aare/utils/SparseMask.hpp"
|
||||
#include "aare/NDArray.hpp"
|
||||
|
||||
using namespace aare;
|
||||
|
||||
namespace jungfraucalibration
|
||||
{
|
||||
|
||||
SparseMask CreateBadChannelPixelMask(JungfrauDataFile &pedestal_file, const size_t num_pedestals_g0, const size_t num_pedestals_g1, const size_t num_pedestals_g2);
|
||||
NDArray<bool, 2> CreateBadChannelPixelMask(JungfrauDataFile &pedestal_file, const size_t num_pedestals_g0, const size_t num_pedestals_g1, const size_t num_pedestals_g2);
|
||||
|
||||
SparseMask CreateBadChannelPixelMask(JungfrauDataFile &pedestals_g0_file, const JungfrauDataFile &pedestals_g1_file, const JungfrauDataFile &pedestal_g2_file);
|
||||
NDArray<bool, 2> CreateBadChannelPixelMask(JungfrauDataFile &pedestals_g0_file, const JungfrauDataFile &pedestals_g1_file, const JungfrauDataFile &pedestal_g2_file);
|
||||
|
||||
} // namespace jungfraucalibration
|
||||
@@ -1,108 +1,77 @@
|
||||
from pathlib import Path
|
||||
import JungfrauCalibrationParameters
|
||||
from aare import JungfrauDataFile
|
||||
from helpers import get_first_file
|
||||
import numpy as np
|
||||
|
||||
class JungfrauCalibrationParameters:
|
||||
"""
|
||||
A class to hold calibration parameters for the Jungfrau detector.
|
||||
"""
|
||||
from aare.calibration import get_gain
|
||||
|
||||
@property
|
||||
def pedestal_file_dir(self) -> Path:
|
||||
return self._pedestal_file_dir
|
||||
|
||||
@pedestal_file_dir.setter
|
||||
def pedestal_file_dir(self, filepath : Path):
|
||||
if not filepath.exists():
|
||||
raise ValueError(f"Pedestal file directory {filepath} does not exist.")
|
||||
self._pedestal_file_dir = filepath
|
||||
class JungfrauCalibration:
|
||||
|
||||
@property
|
||||
def pedestal_g0_file_prefix(self) -> str:
|
||||
return self._pedestal_g0_file_prefix
|
||||
def __init__(self, calibration_params: JungfrauCalibrationParameters):
|
||||
self.calibration_params = calibration_params
|
||||
self.bad_channel_mask : np.ndarray
|
||||
self.histogram : np.ndarray
|
||||
|
||||
@pedestal_g0_file_prefix.setter
|
||||
def pedestal_g0_file_prefix(self, file_prefix : str):
|
||||
self._pedestal_g0_file_prefix = file_prefix
|
||||
|
||||
# TODO: add deprecated decorator
|
||||
@property
|
||||
def pedestal_file_prefix(self) -> str:
|
||||
return self._pedestal_file_prefix
|
||||
@pedestal_file_prefix.setter
|
||||
def pedestal_file_prefix(self, file_prefix : str):
|
||||
self._pedestal_file_prefix = file_prefix
|
||||
|
||||
@property
|
||||
def num_pedestals_g0(self) -> int:
|
||||
return self._num_pedestals_g0
|
||||
|
||||
@num_pedestals_g0.setter
|
||||
def num_pedestals_g0(self, num_pedestals : int):
|
||||
self._num_pedestals_g0 = num_pedestals
|
||||
# TODO: maybe pass num pedestals, pedestal file instead of calibration params?
|
||||
def calculate_bad_pixels_mask(self) -> np.ndarray:
|
||||
"""
|
||||
Calculate the bad pixels mask for the Jungfrau detector.
|
||||
|
||||
@property
|
||||
def num_pedestals_g1(self) -> int:
|
||||
return self._num_pedestals_g1
|
||||
|
||||
@num_pedestals_g1.setter
|
||||
def num_pedestals_g1(self, num_pedestals : int):
|
||||
self._num_pedestals_g1 = num_pedestals
|
||||
Returns:
|
||||
np.ndarray: A boolean array where True indicates a bad pixel.
|
||||
"""
|
||||
if(self.calibration_params.num_pedestals_g0 is not None and self.calibration_params.num_pedestals_g1 is not None and self.calibration_params.num_pedestals_g2 is not None):
|
||||
|
||||
jungfrau_file = JungfrauDataFile(get_first_file(self.calibration_params.pedestal_file_dir, self.calibration_params.pedestal_file_prefix))
|
||||
|
||||
@property
|
||||
def num_pedestals_g2(self) -> int:
|
||||
return self._num_pedestals_g2
|
||||
|
||||
@num_pedestals_g2.setter
|
||||
def num_pedestals_g2(self, num_pedestals : int):
|
||||
self._num_pedestals_g2 = num_pedestals
|
||||
g0_pedestal_frames = jungfrau_file.read_n(self.calibration_params.num_pedestals_g0) # TODO: option to only read gain? - mmh reading things twice from filesystem also bad
|
||||
g1_pedestal_frames = jungfrau_file.read_n(self.calibration_params.num_pedestals_g1)
|
||||
|
||||
@property
|
||||
def raw_file_dir(self) -> Path:
|
||||
return self._raw_file_dir
|
||||
|
||||
@raw_file_dir.setter
|
||||
def raw_file_dir(self, filepath : Path):
|
||||
if not filepath.exists():
|
||||
raise ValueError(f"Raw file directory {filepath} does not exist.")
|
||||
self._raw_file_dir = filepath
|
||||
g2_pedestal_frames = jungfrau_file.read_n(self.calibration_params.num_pedestals_g2)
|
||||
|
||||
@property
|
||||
def raw_file_prefix(self) -> str:
|
||||
return self._raw_file_prefix
|
||||
|
||||
@raw_file_prefix.setter
|
||||
def raw_file_prefix(self, file_prefix : str):
|
||||
self._raw_file_prefix = file_prefix
|
||||
# get gain from each pixel - update mask
|
||||
max_frames = max(self.calibration_params.num_pedestals_g0, self.calibration_params.num_pedestals_g1, self.calibration_params.num_pedestals_g2)
|
||||
|
||||
bad_channel_mask = np.zeros((jungfrau_file.rows(), jungfrau_file.cols()), dtype=bool) # bad channels pixel mask
|
||||
|
||||
# TODO add a read_config method
|
||||
|
||||
|
||||
def calculate_bad_pixels_mask(calibration_params: JungfrauCalibrationParameters):
|
||||
"""
|
||||
Calculate the bad pixels mask for the Jungfrau detector.
|
||||
|
||||
Returns:
|
||||
np.ndarray: A boolean array where True indicates a bad pixel.
|
||||
"""
|
||||
|
||||
if(calibration_params.num_pedestals_g0 is not None and calibration_params.num_pedestals_g1 is not None and calibration_params.num_pedestals_g2 is not None):
|
||||
# TODO loop to etensive
|
||||
|
||||
return bad_channel_mask
|
||||
|
||||
jungfrau_file = JungfrauDataFile(get_first_file(calibration_params.pedestal_file_dir, calibration_params.pedestal_file_prefix))
|
||||
|
||||
g0_pedestal_frames = jungfrau_file.read_n(calibration_params.num_pedestals_g0) # TODO: option to only read gain? - mmh reading things twice from filesystem also bad
|
||||
def calculate_histogram(self):
|
||||
"""
|
||||
Calculate the histogram of each pixel.
|
||||
|
||||
g1_pedestal_frames = jungfrau_file.read_n(calibration_params.num_pedestals_g1)
|
||||
Returns:
|
||||
np.ndarray: The histogram for each pixel value
|
||||
"""
|
||||
|
||||
g2_pedestal_frames = jungfrau_file.read_n(calibration_params.num_pedestals_g2)
|
||||
|
||||
def fit_function(self):
|
||||
"""
|
||||
Fit a Gaussian to the histogram of each pixel.
|
||||
|
||||
Returns:
|
||||
np.ndarray: The fitted Gaussian parameters for each pixel.
|
||||
"""
|
||||
|
||||
def calibrate_G0(self):
|
||||
"""
|
||||
Calibrate the G0 gain of the Jungfrau detector.
|
||||
|
||||
# Placeholder for actual implementation
|
||||
# This function should analyze the detector data and identify bad pixels
|
||||
pass
|
||||
Returns:
|
||||
np.ndarray: The calibrated G0 gain values for each pixel.
|
||||
"""
|
||||
|
||||
self.calculate_bad_pixels_mask()
|
||||
self.calculate_histogram()
|
||||
self.fit_function()
|
||||
|
||||
## additional plot methods for visualizing the histogram and fitted Gaussian parameters can be added here - depens how fast not neccessary to compute on the fly
|
||||
|
||||
def main():
|
||||
calibration_params = JungfrauCalibrationParameters()
|
||||
@@ -114,6 +83,9 @@ def main():
|
||||
calibration_params.num_pedestals_g0 = 1000
|
||||
calibration_params.num_pedestals_g1 = 1000
|
||||
calibration_params.num_pedestals_g2 = 1000
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,77 @@
|
||||
from pathlib import Path
|
||||
|
||||
class JungfrauCalibrationParameters:
|
||||
"""
|
||||
A class to hold calibration parameters for the Jungfrau detector.
|
||||
"""
|
||||
|
||||
@property
|
||||
def pedestal_file_dir(self) -> Path:
|
||||
return self._pedestal_file_dir
|
||||
|
||||
@pedestal_file_dir.setter
|
||||
def pedestal_file_dir(self, filepath : Path):
|
||||
if not filepath.exists():
|
||||
raise ValueError(f"Pedestal file directory {filepath} does not exist.")
|
||||
self._pedestal_file_dir = filepath
|
||||
|
||||
@property
|
||||
def pedestal_g0_file_prefix(self) -> str:
|
||||
return self._pedestal_g0_file_prefix
|
||||
|
||||
@pedestal_g0_file_prefix.setter
|
||||
def pedestal_g0_file_prefix(self, file_prefix : str):
|
||||
self._pedestal_g0_file_prefix = file_prefix
|
||||
|
||||
# TODO: add deprecated decorator
|
||||
@property
|
||||
def pedestal_file_prefix(self) -> str:
|
||||
return self._pedestal_file_prefix
|
||||
@pedestal_file_prefix.setter
|
||||
def pedestal_file_prefix(self, file_prefix : str):
|
||||
self._pedestal_file_prefix = file_prefix
|
||||
|
||||
@property
|
||||
def num_pedestals_g0(self) -> int:
|
||||
return self._num_pedestals_g0
|
||||
|
||||
@num_pedestals_g0.setter
|
||||
def num_pedestals_g0(self, num_pedestals : int):
|
||||
self._num_pedestals_g0 = num_pedestals
|
||||
|
||||
@property
|
||||
def num_pedestals_g1(self) -> int:
|
||||
return self._num_pedestals_g1
|
||||
|
||||
@num_pedestals_g1.setter
|
||||
def num_pedestals_g1(self, num_pedestals : int):
|
||||
self._num_pedestals_g1 = num_pedestals
|
||||
|
||||
@property
|
||||
def num_pedestals_g2(self) -> int:
|
||||
return self._num_pedestals_g2
|
||||
|
||||
@num_pedestals_g2.setter
|
||||
def num_pedestals_g2(self, num_pedestals : int):
|
||||
self._num_pedestals_g2 = num_pedestals
|
||||
|
||||
@property
|
||||
def raw_file_dir(self) -> Path:
|
||||
return self._raw_file_dir
|
||||
|
||||
@raw_file_dir.setter
|
||||
def raw_file_dir(self, filepath : Path):
|
||||
if not filepath.exists():
|
||||
raise ValueError(f"Raw file directory {filepath} does not exist.")
|
||||
self._raw_file_dir = filepath
|
||||
|
||||
@property
|
||||
def raw_file_prefix(self) -> str:
|
||||
return self._raw_file_prefix
|
||||
|
||||
@raw_file_prefix.setter
|
||||
def raw_file_prefix(self, file_prefix : str):
|
||||
self._raw_file_prefix = file_prefix
|
||||
|
||||
|
||||
# TODO add a read_config method
|
||||
+8
-9
@@ -7,7 +7,7 @@ using namespace aare;
|
||||
namespace jungfraucalibration
|
||||
{
|
||||
|
||||
SparseMask CreateBadChannelPixelMask(JungfrauDataFile &pedestal_file, const size_t num_pedestals_g0, const size_t num_pedestals_g1, const size_t num_pedestals_g2)
|
||||
NDArray<bool, 2> CreateBadChannelPixelMask(JungfrauDataFile &pedestal_file, const size_t num_pedestals_g0, const size_t num_pedestals_g1, const size_t num_pedestals_g2)
|
||||
{
|
||||
auto pedestals_g0 = pedestal_file.read_n(num_pedestals_g0);
|
||||
auto pedestals_g1 = pedestal_file.read_n(num_pedestals_g1);
|
||||
@@ -17,30 +17,29 @@ namespace jungfraucalibration
|
||||
const size_t cols = pedestal_file.cols();
|
||||
|
||||
// get gain from each pixel - update mask
|
||||
SparseMask bad_channel_mask(STORAGEFORMAT::ROWMAJOR, rows, cols); // bad channels pixel mask
|
||||
NDArray<bool, 2> bad_channel_mask({static_cast<ssize_t>(rows), static_cast<ssize_t>(cols)}, false); // bad channels pixel mask
|
||||
|
||||
size_t max_frames = std::max({num_pedestals_g0, num_pedestals_g1, num_pedestals_g2});
|
||||
|
||||
// TODO is this more efficient e.g. all three frames fit into cache instead of doing one file at the time?
|
||||
for (size_t frame_idx = 0; frame_idx < max_frames; ++frame_idx)
|
||||
{
|
||||
|
||||
for (size_t row = 0; row < rows; ++row)
|
||||
{
|
||||
for (size_t col = 0; col < cols; ++col)
|
||||
{
|
||||
// TODO: nicer to access element from frame directly instead of view()? What is the type?
|
||||
if (frame_idx < num_pedestals_g0 && get_gain(pedestals_g0[frame_idx].view<uint32_t>()(row, col)) != 0)
|
||||
if (frame_idx < num_pedestals_g0 && get_gain(pedestals_g0[frame_idx].view<uint16_t>()(row, col)) != 0)
|
||||
{
|
||||
bad_channel_mask.insert(row, col);
|
||||
bad_channel_mask(row, col) = true;
|
||||
}
|
||||
if (frame_idx < num_pedestals_g1 && get_gain(pedestals_g1[frame_idx].view<uint32_t>()(row, col)) != 1)
|
||||
if (frame_idx < num_pedestals_g1 && get_gain(pedestals_g1[frame_idx].view<uint16_t>()(row, col)) != 1)
|
||||
{
|
||||
bad_channel_mask.insert(row, col);
|
||||
bad_channel_mask(row, col) = true;
|
||||
}
|
||||
if (frame_idx < num_pedestals_g2 && get_gain(pedestals_g2[frame_idx].view<uint32_t>()(row, col)) != 2)
|
||||
if (frame_idx < num_pedestals_g2 && get_gain(pedestals_g2[frame_idx].view<uint16_t>()(row, col)) != 2)
|
||||
{
|
||||
bad_channel_mask.insert(row, col);
|
||||
bad_channel_mask(row, col) = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user