Skip to content

Commit

Permalink
Fix channel name in test with 'modern' corrected AGIPD data
Browse files Browse the repository at this point in the history
  • Loading branch information
takluyver committed Sep 26, 2024
1 parent 31c28a4 commit fcc832d
Show file tree
Hide file tree
Showing 4 changed files with 30 additions and 28 deletions.
3 changes: 1 addition & 2 deletions extra_data/tests/conftest.py
Original file line number Diff line number Diff line change
Expand Up @@ -161,8 +161,7 @@ def mock_spb_raw_and_proc_run():
@pytest.fixture(scope='session')
def mock_modern_spb_proc_run(format_version):
with TemporaryDirectory() as td:
make_examples.make_modern_spb_proc_run(
td, format_version=format_version)
make_examples.make_modern_spb_proc_run(td)
yield td


Expand Down
8 changes: 4 additions & 4 deletions extra_data/tests/make_examples.py
Original file line number Diff line number Diff line change
Expand Up @@ -346,13 +346,13 @@ def make_reduced_spb_run(dir_path, raw=True, rng=None, format_version='0.5'):
format_version=format_version)


def make_modern_spb_proc_run(dir_path, format_version='0.5'):
def make_modern_spb_proc_run(dir_path, format_version='1.2'):
for modno in range(16):
path = osp.join(dir_path, f'CORR-R0142-AGIPD{modno:0>2}-S00000.h5')
write_file(path, [
AGIPDModule(f'SPB_DET_AGIPD1M-1/CORR/{modno}CH0', raw=False,
frames_per_train=32,
legacy_name=f'SPB_DET_AGIPD1M-1/DET/{modno}CH0')
AGIPDModule(f'SPB_DET_AGIPD1M-1/CORR/{modno}CH0', channel_name='output',
raw=False, frames_per_train=32,
legacy_name=f'SPB_DET_AGIPD1M-1/DET/{modno}CH0')
], ntrains=64, chunksize=32, format_version=format_version)


Expand Down
39 changes: 21 additions & 18 deletions extra_data/tests/mockdata/detectors.py
Original file line number Diff line number Diff line change
Expand Up @@ -19,14 +19,15 @@ class DetectorModule:
]

def __init__(self, device_id, frames_per_train=64, raw=True,
legacy_name=None):
channel_name='xtdf', legacy_name=None):
self.device_id = device_id
self._frames_per_train = frames_per_train
if not raw:
# Raw data has an extra dimension, used in AGIPD to separate data
# and gain. This dimension is removed by the calibration process.
self.image_dims = self.image_dims[1:]
self.raw = raw
self.channel_name = channel_name
self.legacy_name = legacy_name

def write_control(self, f):
Expand Down Expand Up @@ -81,13 +82,13 @@ def write_instrument(self, f):
if ntrains_pad % self.chunksize:
ntrains_pad += + self.chunksize - (ntrains_pad % self.chunksize)

inst_source = f'{self.device_id}:{self.channel_name}'

# INDEX
for part in self.output_parts:
dev_chan = '%s:xtdf/%s' % (self.device_id, part)

i_first = f.create_dataset('INDEX/%s/first' % dev_chan,
i_first = f.create_dataset(f'INDEX/{inst_source}/{part}/first',
(self.ntrains,), 'u8', maxshape=(None,))
i_count = f.create_dataset('INDEX/%s/count' % dev_chan,
i_count = f.create_dataset(f'INDEX/{inst_source}/{part}/count',
(self.ntrains,), 'u8', maxshape=(None,))
if part == 'image':
# First first is always 0
Expand All @@ -108,63 +109,65 @@ def write_instrument(self, f):
if self.raw:
# Raw data have an extra dimension (length 1) and an unlimited max
# for the first dimension.
ds = f.create_dataset('INSTRUMENT/%s:xtdf/image/trainId' % self.device_id,
ds = f.create_dataset(f'INSTRUMENT/{inst_source}/image/trainId',
(nframes, 1), 'u8', maxshape=(None, 1))
ds[:, 0] = tid_index

pid = f.create_dataset('INSTRUMENT/%s:xtdf/image/pulseId' % self.device_id,
pid = f.create_dataset(f'INSTRUMENT/{inst_source}/image/pulseId',
(nframes, 1), 'u8', maxshape=(None, 1))
pid[:, 0] = pid_index

cid = f.create_dataset('INSTRUMENT/%s:xtdf/image/cellId' % self.device_id,
cid = f.create_dataset(f'INSTRUMENT/{inst_source}/image/cellId',
(nframes, 1), 'u2', maxshape=(None, 1))
cid[:, 0] = pid_index # Cell IDs mirror pulse IDs for now
else:
# Corrected data drops the extra dimension, and maxshape==shape.
f.create_dataset(
'INSTRUMENT/%s:xtdf/image/trainId' % self.device_id,
f'INSTRUMENT/{inst_source}/image/trainId',
(nframes,), 'u8', chunks=True, data=tid_index
)

f.create_dataset(
'INSTRUMENT/%s:xtdf/image/pulseId' % self.device_id,
f'INSTRUMENT/{inst_source}/image/pulseId',
(nframes,), 'u8', chunks=True, data=pid_index
)

f.create_dataset( # Cell IDs mirror pulse IDs for now
'INSTRUMENT/%s:xtdf/image/cellId' % self.device_id,
f'INSTRUMENT/{inst_source}/image/cellId',
(nframes,), 'u2', chunks=True, data=pid_index
)

max_len = None if self.raw else nframes
for (key, datatype, dims) in self.image_keys:
f.create_dataset('INSTRUMENT/%s:xtdf/image/%s' % (self.device_id, key),
f.create_dataset(f'INSTRUMENT/{inst_source}/image/{key}',
(nframes,) + dims, datatype, maxshape=((max_len,) + dims))


# INSTRUMENT (other parts)
for part in ['detector', 'header', 'trailer']:
ds = f.create_dataset('INSTRUMENT/%s:xtdf/%s/trainId' % (self.device_id, part),
ds = f.create_dataset(f'INSTRUMENT/{inst_source}/{part}/trainId',
(ntrains_pad,), 'u8', maxshape=(None,))
ds[:self.ntrains] = trainids

for (key, datatype, dims) in self.other_keys:
f.create_dataset('INSTRUMENT/%s:xtdf/%s' % (self.device_id, key),
f.create_dataset(f'INSTRUMENT/{inst_source}/{key}',
(ntrains_pad,) + dims, datatype, maxshape=((None,) + dims))

if self.legacy_name is not None:
# The legacy source name for corrected data is the same as for
# raw data, which for these detectors always has the xtdf channel.
f[f'INDEX/{self.legacy_name}:xtdf'] = h5py.SoftLink(
f'/INDEX/{self.device_id}:xtdf')
f'/INDEX/{inst_source}')
f[f'INSTRUMENT/{self.legacy_name}:xtdf'] = h5py.SoftLink(
f'/INSTRUMENT/{self.device_id}:xtdf')
f'/INSTRUMENT/{inst_source}')

def datasource_ids(self):
for part in self.output_parts:
yield 'INSTRUMENT/%s:xtdf/%s' % (self.device_id, part)
yield f'INSTRUMENT/{self.device_id}:{self.channel_name}/{part}'

if self.legacy_name is not None:
for part in self.output_parts:
yield 'INSTRUMENT/%s:xtdf/%s' % (self.legacy_name, part)
yield f'INSTRUMENT/{self.legacy_name}:xtdf/{part}'


class AGIPDModule(DetectorModule):
Expand Down
8 changes: 4 additions & 4 deletions extra_data/tests/test_reader_mockdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -1153,9 +1153,9 @@ def test_run_metadata_no_trains(mock_scs_run):
def test_proc_legacy_sources(mock_modern_spb_proc_run):
run = RunDirectory(mock_modern_spb_proc_run)

src_pattern = 'SPB_DET_AGIPD1M-1/{}/{}CH0:xtdf'
corr_sources = {src_pattern.format('CORR', i) for i in range(16)}
det_sources = {src_pattern.format('DET', i) for i in range(16)}
src_pattern = 'SPB_DET_AGIPD1M-1/{}/{}CH0:{}'
corr_sources = {src_pattern.format('CORR', i, 'output') for i in range(16)}
det_sources = {src_pattern.format('DET', i, 'xtdf') for i in range(16)}

# Should contain both canonical and legacy names.
assert run.all_sources == corr_sources | det_sources
Expand All @@ -1169,7 +1169,7 @@ def test_proc_legacy_sources(mock_modern_spb_proc_run):
assert run.legacy_sources == dict(zip(
sorted(det_sources), sorted(corr_sources)))

det_mod0 = src_pattern.format('DET', 0)
det_mod0 = src_pattern.format('DET', 0, 'xtdf')

# Classic APIs continue to work as normal, but raise warnings
# whenever data is accessed through creation of SourceData object.
Expand Down

0 comments on commit fcc832d

Please sign in to comment.