Skip to content

Instantly share code, notes, and snippets.

@tacaswell
Created August 7, 2018 14:20
Show Gist options
  • Save tacaswell/41b63823158e81f589f1d84cd09f3b2f to your computer and use it in GitHub Desktop.
Save tacaswell/41b63823158e81f589f1d84cd09f3b2f to your computer and use it in GitHub Desktop.
class FileStoreSquashing(FileStorePluginBase):
'''Write out 'squashed' files
.. note::
See :class:`FileStoreBase` for the rest of the required parametrs
This mixin will also configure the ``cam`` and ``proc`` plugins
on the parent.
This is useful to work around the dynamic range of detectors
and minimizing disk spaced used by synthetically increasing
the exposure time of the saved images.
Parameters
----------
images_per_set_name, number_of_sets_name : str, optional
The names of the signals on the parent to get the
images_pre_set and number_of_sets from.
The total number of frames extracted from the camera will be
:math:`number\_of\_sets * images\_per\_set` and result in
``number_of_sets`` tiff files each of which is the average of
``images_per_set`` frames from the detector.
Defaults to ``'images_per_set'`` and ``'number_of_sets'``
cam_name : str, optional
The name of the :class:`~ophyd.areadetector.cam.CamBase`
instance on the parent.
Defaults to ``'cam'``
proc_name : str, optional
The name of the
:class:`~ophyd.areadetector.plugins.ProcessPlugin` instance on
the parent.
Defaults to ``'proc1'``
Notes
-----
This class in cooperative and expected to particpate in multiple
inheritance, all ``*args`` and extra ``**kwargs`` are passed up the
MRO chain.
'''
def __init__(self, *args,
images_per_set_name='images_per_set',
number_of_sets_name="number_of_sets",
cam_name='cam', proc_name='proc1',
**kwargs):
super().__init__(*args, **kwargs)
# this is lifted from the FilestoreHDF5 plugin
self.filestore_spec = 'AD_HDF5' # spec name stored in resource doc
self.stage_sigs.update([('file_template', '%s%s_%6.6d.h5'),
('file_write_mode', 'Stream'),
('capture', 1)
])
# this is state we need to keep track of for the squashing
self._ips_name = images_per_set_name
self._num_sets_name = number_of_sets_name
# this is needed set the pipeline up correctly
self._cam_name = cam_name
self._proc_name = proc_name
cam = getattr(self.parent, self._cam_name)
proc = getattr(self.parent, self._proc_name)
# this sets up the AD processing pipeline to be what we want
self.stage_sigs.update([
# make proc listen to the camera
(proc.nd_array_port, cam.port_name.get()),
# configure the processing plugin to be what we want it to be
(proc.reset_filter, 1),
(proc.enable_filter, 1),
(proc.filter_type, 'Average'),
(proc.auto_reset_filter, 1),
(proc.filter_callbacks, 1),
# make the hdf5 plugin listen to the process plugin
('nd_array_port', proc.port_name.get())
])
def get_frames_per_point(self):
return getattr(self.parent, self._num_sets_name).get()
def stage(self):
cam = getattr(self.parent, self._cam_name)
proc = getattr(self.parent, self._proc_name)
images_per_set = getattr(self.parent, self._ips_name).get()
num_sets = getattr(self.parent, self._num_sets_name).get()
self.stage_sigs.update([(proc.num_filter, images_per_set),
(cam.num_images, images_per_set * num_sets)])
super().stage()
# this is needed due to confused internal names! this is the
# read path and used as such in _generate_resource
self._fn = self._fp
# build the resource kwargs dictionary
resource_kwargs = {'frame_per_point': self.get_frames_per_point()}
self._generate_resource(resource_kwargs)
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment