mirror of
https://github.com/slsdetectorgroup/aare.git
synced 2026-07-03 15:24:30 +02:00
Dev/matterhorn decoder (#324)
- reshape image directly in decoder such that first dimension is num counters - take into account chip artefact in decoder. --------- Co-authored-by: Erik Fröjdh <erik.frojdh@psi.ch>
This commit is contained in:
@@ -81,6 +81,10 @@ class Matterhorn10Transform:
|
||||
A matterhorn chip has 256 columns and 256 rows.
|
||||
A matterhornchip with dynamic range 16 and 2 counters thus requires
|
||||
256*256*16*2/(2*64) = 1024 transceiver samples. (Per default 2 channels are enabled per transceiver sample, each channel storing 64 bits)
|
||||
|
||||
.. note::
|
||||
Due to an artefact in the chip, the transformation only fully supports 2 or 4 counters. Also if you enable 2 counters you can only select counter 1 and 2 or 0, 3 to get reasonable results.
|
||||
Otherwise only the first half of the image is correct.
|
||||
"""
|
||||
def __init__(self, dynamic_range : int, num_counters : int):
|
||||
self.pixel_map = _aare.GenerateMatterhorn10PixelMap(dynamic_range, num_counters)
|
||||
@@ -105,7 +109,7 @@ class Matterhorn10Transform:
|
||||
checks if data is compatible for transformation
|
||||
|
||||
:param data: data to be transformed, expected to be a 1D numpy array of uint8
|
||||
:type data: np.ndarray
|
||||
:type data: np.ndarray(n_counters, n_rows, n_cols)
|
||||
:raises ValueError: if not compatible
|
||||
"""
|
||||
expected_size = (Matterhorn10.nRows*Matterhorn10.nCols*self.num_counters*self.dynamic_range)//8 # read_frame returns data in uint8_t
|
||||
@@ -118,11 +122,11 @@ class Matterhorn10Transform:
|
||||
def __call__(self, data):
|
||||
self.data_compatibility(data)
|
||||
if self.dynamic_range == 16:
|
||||
return np.take(data.view(np.uint16), self.pixel_map)
|
||||
return np.take(data.view(np.uint16), self.pixel_map).reshape(self.num_counters, Matterhorn10.nRows, Matterhorn10.nCols)
|
||||
elif self.dynamic_range == 8:
|
||||
return np.take(data.view(np.uint8), self.pixel_map)
|
||||
return np.take(data.view(np.uint8), self.pixel_map).reshape(self.num_counters, Matterhorn10.nRows, Matterhorn10.nCols)
|
||||
else: #dynamic range 4
|
||||
return np.take(_aare.expand4to8bit(data.view(np.uint8)), self.pixel_map)
|
||||
return np.take(_aare.expand4to8bit(data.view(np.uint8)), self.pixel_map).reshape(self.num_counters, Matterhorn10.nRows, Matterhorn10.nCols)
|
||||
|
||||
class Mythen302Transform:
|
||||
"""
|
||||
|
||||
@@ -8,10 +8,10 @@ def test_matterhorn10_16bit(test_data_path):
|
||||
with CtbRawFile(test_data_path / "raw/Matterhorn10/16bit_master_0.json", transform = transform.Matterhorn10Transform(dynamic_range=16, num_counters=1)) as f:
|
||||
headers, frames = f.read_frame()
|
||||
|
||||
assert frames.shape == (256, 256)
|
||||
assert frames.shape == (1, 256, 256)
|
||||
assert frames.dtype == np.uint16
|
||||
|
||||
expected_data = np.tile(np.arange(255, -1, -1,dtype=np.uint16), (256, 1)) # TODO: endianess issue ?
|
||||
expected_data = np.tile(np.arange(255, -1, -1,dtype=np.uint16), (1, 256, 1)) # TODO: endianess issue ?
|
||||
|
||||
assert np.all(frames == expected_data)
|
||||
|
||||
@@ -22,24 +22,23 @@ def test_matterhorn10_8bit(test_data_path):
|
||||
with CtbRawFile(test_data_path / "raw/Matterhorn10/8bit_master_1.json", transform = transform.Matterhorn10Transform(dynamic_range=8, num_counters=1)) as f:
|
||||
headers, frames = f.read_frame()
|
||||
|
||||
assert frames.shape == (256, 256)
|
||||
assert frames.shape == (1, 256, 256)
|
||||
assert frames.dtype == np.uint8
|
||||
|
||||
expected_data = np.tile(np.arange(255, -1, -1,dtype=np.uint8), (256, 1)) # TODO: endianess issue ?
|
||||
expected_data = np.tile(np.arange(255, -1, -1,dtype=np.uint8), (1, 256, 1)) # TODO: endianess issue ?
|
||||
|
||||
assert np.all(frames == expected_data)
|
||||
|
||||
|
||||
@pytest.mark.withdata
|
||||
def test_matterhorn10_4bit(test_data_path):
|
||||
""" Matterhorn10Transform 1 counter 4 bit dynamic range """
|
||||
with CtbRawFile(test_data_path / "raw/Matterhorn10/newnewrun_4bit_1counter_master_0.json", transform = transform.Matterhorn10Transform(dynamic_range=4, num_counters=1)) as f:
|
||||
headers, frames = f.read_frame()
|
||||
|
||||
assert frames.shape == (256, 256)
|
||||
assert frames.shape == (1, 256, 256)
|
||||
assert frames.dtype == np.uint8
|
||||
|
||||
expected_data = np.tile(np.tile(np.arange(15, -1, -1, dtype=np.uint8), 16), (256, 1)) # TODO: endianess issue ?
|
||||
expected_data = np.tile(np.tile(np.arange(15, -1, -1, dtype=np.uint8), 16), (1, 256, 1)) # TODO: endianess issue ?
|
||||
|
||||
assert np.all(frames == expected_data)
|
||||
|
||||
@@ -50,9 +49,9 @@ def test_matterhorn10_16bit_4counters(test_data_path):
|
||||
with CtbRawFile(test_data_path / "raw/Matterhorn10/4counter_16bit_master_4.json", transform = transform.Matterhorn10Transform(dynamic_range=16, num_counters=4)) as f:
|
||||
headers, frames = f.read_frame()
|
||||
|
||||
assert frames.shape == (4*256, 256)
|
||||
assert frames.shape == (4, 256, 256)
|
||||
assert frames.dtype == np.uint16
|
||||
|
||||
expected_data = np.tile(np.arange(255, -1, -1,dtype=np.uint16), (4*256, 1)) # TODO: endianess issue ?
|
||||
expected_data = np.tile(np.arange(255, -1, -1,dtype=np.uint16), (4, 256, 1)) # TODO: endianess issue ?
|
||||
|
||||
assert np.all(frames == expected_data)
|
||||
|
||||
Reference in New Issue
Block a user