Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

DEV: created filter objects with attenuation #25

Open
wants to merge 22 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
22 commits
Select commit Hold shift + click to select a range
76f8ca4
DEV: created filter objects with attenuation
brookeferber Jul 14, 2017
3f99215
STY: Changed "filter" and added line at file's end
brookeferber Jul 17, 2017
bf87a08
STY: Removed extra blank line @ end file
brookeferber Jul 17, 2017
5871e33
ENH: Added filter object to attenuate image
brookeferber Jul 17, 2017
474d983
STY: renamed get_attenuation and XRayFilter
brookeferber Jul 17, 2017
b471dda
TST: Added filter test and revised to meet test
brookeferber Jul 17, 2017
8a30964
ENH: Revised to add filters to det factory
brookeferber Jul 17, 2017
ed33c69
ENH: Added testing for filters pertaining to det
brookeferber Jul 17, 2017
f2b544f
TST: Developed filter tests
brookeferber Jul 18, 2017
4dc3391
DEV: Revised det for trigger_read; fixd filter bug
brookeferber Jul 18, 2017
373d44e
BUG: Get attenuation if filter is installed
brookeferber Jul 19, 2017
8369f1b
BUG: Updated image cycles
brookeferber Jul 19, 2017
3288cb5
BUG: if filter_bank never executes
brookeferber Jul 20, 2017
60a79aa
BUG: Fixed filter tests
brookeferber Jul 21, 2017
8f2b446
BUG: Revised shutter assertion
brookeferber Jul 21, 2017
365f441
BUG: Adjusted data used in dets test
brookeferber Jul 21, 2017
2e9e93b
BUG: Switched shutter set position
brookeferber Jul 21, 2017
1a89d76
ENH: Added updated detector tests
brookeferber Jul 21, 2017
48b367c
ENH: add tests file
brookeferber Jul 21, 2017
7e4a2dc
BUG: Adjusted shutter test for cycle inc
brookeferber Jul 25, 2017
0614614
BUG: Updated travis for bluesky
brookeferber Jul 25, 2017
b7cd3fa
STY: Revised code for flake8 errors
brookeferber Jul 25, 2017
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .travis.yml
Original file line number Diff line number Diff line change
Expand Up @@ -53,10 +53,11 @@ before_install:

install:
- export GIT_FULL_HASH=`git rev-parse HEAD`
- conda create -n testenv nose python=$TRAVIS_PYTHON_VERSION pytest coverage pip databroker bluesky flake8 pyFAI mongoquery codecov attrs metadatastore filestore -c conda-forge -c lightsource2-tag -c soft-matter
- conda create -n testenv nose python=$TRAVIS_PYTHON_VERSION pytest coverage pip databroker flake8 pyFAI mongoquery codecov attrs metadatastore filestore -c conda-forge -c lightsource2-tag -c soft-matter
- source activate testenv
- 'pip install https://github.com/NSLS-II/portable-mds/zipball/master#egg=portable_mds'
- 'pip install https://github.com/NSLS-II/portable-fs/zipball/master#egg=portable_fs'
- 'pip install https://github.com/NSLS-II/bluesky/zipball/master#egg=bluesky'
- python setup.py install
# Need to clean the python build directory (and other cruft) or pytest is
# going to find the build directory and get confused why there are two sets
Expand Down
70 changes: 26 additions & 44 deletions xpdsim/dets.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,6 @@
from cycler import cycler
from pims import ImageSequence
from pkg_resources import resource_filename as rs_fn
from bluesky.utils import new_uid

DATA_DIR = rs_fn('xpdsim', 'data/')

Expand Down Expand Up @@ -61,12 +60,13 @@ class SimulatedPE1C(be.ReaderWithFileStore):
"""

def __init__(self, name, read_fields, fs, shutter=None,
dark_fields=None, **kwargs):
dark_fields=None, filter_bank=None, **kwargs):
self.images_per_set = PutGet()
self.number_of_sets = PutGet()
self.cam = SimulatedCam()
self.shutter = shutter
self._staged = False
self.filter_bank = filter_bank
super().__init__(name, read_fields, fs=fs, **kwargs)
self.ready = True # work around a hack in Reader
if dark_fields:
Expand All @@ -75,39 +75,18 @@ def __init__(self, name, read_fields, fs, shutter=None,
else:
self._dark_fields = None

def trigger(self):
def trigger_read(self):
rv = super().trigger_read()
if self.shutter and self._dark_fields and \
self.shutter.read()['rad']['value'] == 0:
read_v = {field: {'value': func(), 'timestamp': ttime.time()}
for field, func in self._dark_fields.items()
if field in self.read_attrs}
self._result.clear()
for idx, (name, reading) in enumerate(read_v.items()):
# Save the actual reading['value'] to disk and create a record
# in FileStore.
np.save('{}_{}.npy'.format(self._path_stem, idx),
reading['value'])
datum_id = new_uid()
self.fs.insert_datum(self._resource_id, datum_id,
dict(index=idx))
# And now change the reading in place, replacing the value with
# a reference to FileStore.
reading['value'] = datum_id
self._result[name] = reading

delay_time = self.exposure_time
if delay_time:
if self.loop.is_running():
st = be.SimpleStatus()
self.loop.call_later(delay_time, st._finished)
return st
else:
ttime.sleep(delay_time)

return be.NullStatus()

else:
return super().trigger()
self.shutter.read()['rad']['value'] == 0:
rv = {field: {'value': func(), 'timestamp': ttime.time()}
for field, func in self._dark_fields.items()
if field in self.read_attrs}
read_v = dict(rv)
read_v['pe1_image']['value'] = read_v['pe1_image']['value'].copy()
if self.filter_bank:
read_v['pe1_image']['value'] *= self.filter_bank.get_attenuation()
return read_v


def build_image_cycle(path):
Expand All @@ -124,7 +103,10 @@ def build_image_cycle(path):
Cycler:
The iterable like object to cycle through the images
"""
imgs = ImageSequence(os.path.join(path, '*.tif*'))
if isinstance(path, str):
imgs = ImageSequence(os.path.join(path, '*.tif*'), dtype=np.float64)
else:
imgs = [np.ones(path)]
return cycler(pe1_image=[i for i in imgs])


Expand All @@ -133,7 +115,7 @@ def build_image_cycle(path):
chess_path = os.path.join(DATA_DIR, 'chess/')


def det_factory(name, fs, path, shutter=None, **kwargs):
def det_factory(name, fs, path, shutter=None, filter_bank=None, **kwargs):
"""Build a detector using real images

Parameters
Expand All @@ -157,6 +139,8 @@ def det_factory(name, fs, path, shutter=None, **kwargs):
def nexter():
return next(gen)['pe1_image']

kwargs['read_fields'] = {'pe1_image': lambda: nexter()}

if shutter:
stream_piece = next(gen)
sample_img = stream_piece['pe1_image']
Expand All @@ -165,12 +149,10 @@ def nexter():
def dark_nexter():
return np.zeros(sample_img.shape)

return SimulatedPE1C(name,
{'pe1_image': lambda: nexter()}, fs=fs,
shutter=shutter,
dark_fields={'pe1_image': lambda: dark_nexter()},
**kwargs)
kwargs.update(shutter=shutter,
dark_fields={'pe1_image': lambda: dark_nexter()})

if filter_bank:
kwargs.update(filter_bank=filter_bank)

return SimulatedPE1C(name,
{'pe1_image': lambda: nexter()}, fs=fs,
**kwargs)
return SimulatedPE1C(name, fs=fs, **kwargs)
37 changes: 37 additions & 0 deletions xpdsim/filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,37 @@
import bluesky.examples as be


class FilterBank():
def __init__(self, attenuations=None):
if attenuations is None:
attenuations = {'filter1': .5, 'filter2': .5, 'filter3': .5,
'filter4': .5}
self.filter_list = []
for k, v in attenuations.items():
f = XRayFilter(k, {'rad': lambda x: x}, {'x': 0}, v)
self.filter_list.append(f)
setattr(self, k, f)

def get_attenuation(self):
totalAttenuation = 1
for i in self.filter_list:
totalAttenuation *= i.get_XRayFilter_attenuation()
return totalAttenuation


class XRayFilter(be.Mover):
def __init__(self, name, fields, initial_set, attenuation, **kwargs):
self.attenuation = attenuation
super().__init__(name, fields, initial_set, **kwargs)

def get_XRayFilter_attenuation(self):
position_info = self.read()
position_info_subdict = position_info.get('rad')
position_info_sub_subdict = position_info_subdict.get('value')
if (position_info_sub_subdict == 0):
return 1
else:
return self.attenuation


XRayFilterBankExample = FilterBank()
Binary file added xpdsim/tests/.test_dets.py.swp
Binary file not shown.
72 changes: 63 additions & 9 deletions xpdsim/tests/test_dets.py
Original file line number Diff line number Diff line change
@@ -1,29 +1,36 @@
from ..dets import det_factory, build_image_cycle, nsls_ii_path, chess_path
from ..dets import (det_factory, build_image_cycle, # chess_path
)
from bluesky.plans import Count, abs_set
from bluesky.tests.utils import setup_test_run_engine
from numpy.testing import assert_array_equal
import pytest
from ..movers import shctl1
import numpy as np
import bluesky.examples as be
from ..filter import XRayFilterBankExample

test_params = [('nslsii', nsls_ii_path), ('chess', chess_path)]
# Note the missing Chess data, there seems to be a de-syncing of the det and
# cycle which causes the tests to not pass, FIXME
# test_params = [('nslsii', nsls_ii_path), ('chess', chess_path)]
test_params = [('10x10', (10, 10))]


@pytest.mark.parametrize(('name', 'fp'), test_params)
def test_dets(db, tmp_dir, name, fp):
det = det_factory(name, db.fs, fp, save_path=tmp_dir)
RE = setup_test_run_engine()
RE.subscribe('all', db.mds.insert)
scan = Count([det], )
uid = RE(scan)
db.fs.register_handler('RWFS_NPY', be.ReaderWithFSHandler)
cycle2 = build_image_cycle(fp)
cg = cycle2()
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
assert_array_equal(d['data']['pe1_image'], next(cg)['pe1_image'])
assert uid is not None
for i in range(5):
scan = Count([det], )
uid = RE(scan)
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
img = next(cg)['pe1_image']
assert_array_equal(d['data']['pe1_image'], img)
assert uid is not None


@pytest.mark.parametrize(('name', 'fp'), test_params)
Expand All @@ -41,13 +48,60 @@ def test_dets_shutter(db, tmp_dir, name, fp):
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
assert_array_equal(d['data']['pe1_image'],
np.zeros(next(cg)['pe1_image'].shape))
np.zeros(d['data']['pe1_image'].shape))
assert uid is not None

# With the shutter up
RE(abs_set(shctl1, 1, wait=True))
uid = RE(scan)
next(cg)
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
assert_array_equal(d['data']['pe1_image'], next(cg)['pe1_image'])
assert uid is not None


@pytest.mark.parametrize(('name', 'fp'), test_params)
def test_dets_XRayFilter(db, tmp_dir, name, fp):
det = det_factory(name, db.fs, fp, save_path=tmp_dir,
filter_bank=XRayFilterBankExample)
RE = setup_test_run_engine()
RE.subscribe('all', db.mds.insert)
scan = Count([det], )
db.fs.register_handler('RWFS_NPY', be.ReaderWithFSHandler)
cycle2 = build_image_cycle(fp)
cg = cycle2()
# No filters
for f in XRayFilterBankExample.filter_list:
RE(abs_set(f, 0, wait=True))
uid = RE(scan)
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
assert_array_equal(d['data']['pe1_image'], next(cg)['pe1_image'])
assert uid is not None

# Each filter
for f in XRayFilterBankExample.filter_list:
RE(abs_set(f, 0, wait=True))
count = 0
for f in XRayFilterBankExample.filter_list:
count += 1
RE(abs_set(f, 1, wait=True))
uid = RE(scan)
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
assert_array_equal((d['data']['pe1_image']),
next(cg)['pe1_image'] *
f.get_XRayFilter_attenuation())
assert uid is not None
RE(abs_set(f, 0, wait=True))

# All filters
for f in XRayFilterBankExample.filter_list:
RE(abs_set(f, 1, wait=True))
uid = RE(scan)
for n, d in db.restream(db[-1], fill=True):
if n == 'event':
assert_array_equal(d['data']['pe1_image'], (next(cg)['pe1_image'])
* XRayFilterBankExample.get_attenuation())
assert uid is not None
7 changes: 7 additions & 0 deletions xpdsim/tests/test_filter.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
from ..filter import XRayFilter


def test_filter():
f = XRayFilter('filter1', {'rad': lambda x: x}, {'x': 0}, 0.5)

assert f.attenuation == .5