diff --git a/MANIFEST.in b/MANIFEST.in old mode 100644 new mode 100755 index 523902ae46b58a1345f8fb9541aa9d2c4c3b5f0b..273f97285be35932338beea1a8b651dc7a238e12 --- a/MANIFEST.in +++ b/MANIFEST.in @@ -1,2 +1,6 @@ -global-include *.pyx -global-include *.c \ No newline at end of file +graft tests +graft pyrost/config +graft pyrost/bin +exclude dev.pyx +global-exclude *.py[cod] +global-exclude *.so \ No newline at end of file diff --git a/dev.ipynb b/dev.ipynb index 825fd1531afef0ad3d3ef0a533e0f8848484c817..58de49180e67cdb8134d664585acc6a4667bad98 100755 --- a/dev.ipynb +++ b/dev.ipynb @@ -8,7 +8,7 @@ { "data": { "text/plain": [ - "(None, <pyximport.pyximport.PyxImporter at 0x7f9d187e8590>)" + "(None, <pyximport.pyximport.PyxImporter at 0x7fa6306d8bd0>)" ] }, "execution_count": 1, @@ -217,7 +217,7 @@ }, { "cell_type": "code", - "execution_count": 6, + "execution_count": 5, "metadata": {}, "outputs": [], "source": [ @@ -229,73 +229,36 @@ }, { "cell_type": "code", - "execution_count": 8, + "execution_count": 9, "metadata": {}, "outputs": [ { "name": "stdout", "output_type": "stream", "text": [ - "2020-11-27 17:58:02,589 - STSim - INFO - Initializing\n", - "2020-11-27 17:58:02,591 - STSim - INFO - Current parameters\n", - "2020-11-27 17:58:02,591 - STSim - INFO - Initializing coordinate arrays at the sample's plane\n", - "2020-11-27 17:58:02,592 - STSim - INFO - Number of points in x axis: 1287\n", - "2020-11-27 17:58:02,593 - STSim - INFO - Number of points in y axis: 1810\n", - "2020-11-27 17:58:02,594 - STSim - INFO - Generating wavefields at the sample's plane\n", - "2020-11-27 17:58:02,599 - STSim - INFO - The wavefields have been generated\n", - "2020-11-27 17:58:02,601 - STSim - INFO - Generating barcode's transmission coefficients\n", - "2020-11-27 17:58:02,603 - STSim - INFO - The coefficients have been generated\n", - "2020-11-27 17:58:02,604 - STSim - INFO - Generating wavefields at the detector's plane\n", - "2020-11-27 17:58:02,830 - STSim - INFO - The wavefields have been generated\n", - "2020-11-27 17:58:02,831 - STSim - INFO - Making ptychograph...\n", - "2020-11-27 17:58:02,832 - STSim - INFO - Source blur size: 100.000000 um\n", - "2020-11-27 17:58:02,835 - STSim - INFO - The ptychograph is generated, data shape: (10, 1, 2000)\n", - "2020-11-27 17:58:02,836 - STSim - INFO - Saving data in the directory: results/test_sim\n", - "2020-11-27 17:58:02,837 - STSim - INFO - Making ini files...\n", - "2020-11-27 17:58:02,854 - STSim - INFO - results/test_sim/update_pixel_map.ini saved\n", - "2020-11-27 17:58:02,856 - STSim - INFO - results/test_sim/zernike.ini saved\n", - "2020-11-27 17:58:02,858 - STSim - INFO - results/test_sim/calculate_phase.ini saved\n", - "2020-11-27 17:58:02,859 - STSim - INFO - results/test_sim/make_reference.ini saved\n", - "2020-11-27 17:58:02,861 - STSim - INFO - results/test_sim/calc_error.ini saved\n", - "2020-11-27 17:58:02,863 - STSim - INFO - results/test_sim/speckle_gui.ini saved\n", - "2020-11-27 17:58:02,865 - STSim - INFO - results/test_sim/generate_pixel_map.ini saved\n", - "2020-11-27 17:58:02,867 - STSim - INFO - results/test_sim/update_translations.ini saved\n", - "2020-11-27 17:58:02,869 - STSim - INFO - results/test_sim/parameters.ini saved\n", - "2020-11-27 17:58:02,871 - STSim - INFO - results/test_sim/protocol.ini saved\n", - "2020-11-27 17:58:02,872 - STSim - INFO - Making a cxi file...\n", - "2020-11-27 17:58:02,873 - STSim - INFO - Using the following cxi protocol:\n", - "2020-11-27 17:58:02,874 - STSim - INFO - basis_vectors [float]: '/entry_1/instrument_1/detector_1/basis_vectors' \n", - "2020-11-27 17:58:02,875 - STSim - INFO - data [float]: '/entry_1/data_1/data' \n", - "2020-11-27 17:58:02,876 - STSim - INFO - defocus [float]: '/speckle_tracking/defocus' \n", - "2020-11-27 17:58:02,878 - STSim - INFO - defocus_fs [float]: '/speckle_tracking/dfs' \n", - "2020-11-27 17:58:02,879 - STSim - INFO - defocus_ss [float]: '/speckle_tracking/dss' \n", - "2020-11-27 17:58:02,880 - STSim - INFO - distance [float]: '/entry_1/instrument_1/detector_1/distance' \n", - "2020-11-27 17:58:02,881 - STSim - INFO - energy [float]: '/entry_1/instrument_1/source_1/energy' \n", - "2020-11-27 17:58:02,882 - STSim - INFO - good_frames [int]: '/frame_selector/good_frames' \n", - "2020-11-27 17:58:02,883 - STSim - INFO - m0 [int]: '/speckle_tracking/m0' \n", - "2020-11-27 17:58:02,884 - STSim - INFO - mask [bool]: '/speckle_tracking/mask' \n", - "2020-11-27 17:58:02,885 - STSim - INFO - n0 [int]: '/speckle_tracking/n0' \n", - "2020-11-27 17:58:02,887 - STSim - INFO - phase [float]: '/speckle_tracking/phase' \n", - "2020-11-27 17:58:02,888 - STSim - INFO - pixel_map [float]: '/speckle_tracking/pixel_map' \n", - "2020-11-27 17:58:02,889 - STSim - INFO - pixel_abberations [float]: '/speckle_tracking/pixel_abberations' \n", - "2020-11-27 17:58:02,890 - STSim - INFO - pixel_translations [float]: '/speckle_tracking/pixel_translations' \n", - "2020-11-27 17:58:02,891 - STSim - INFO - reference_image [float]: '/speckle_tracking/reference_image' \n", - "2020-11-27 17:58:02,892 - STSim - INFO - roi [int]: '/speckle_tracking/roi' \n", - "2020-11-27 17:58:02,893 - STSim - INFO - translations [float]: '/entry_1/sample_1/geometry/translations' \n", - "2020-11-27 17:58:02,895 - STSim - INFO - wavelength [float]: '/entry_1/instrument_1/source_1/wavelength' \n", - "2020-11-27 17:58:02,896 - STSim - INFO - whitefield [float]: '/speckle_tracking/whitefield' \n", - "2020-11-27 17:58:02,897 - STSim - INFO - x_pixel_size [float]: '/entry_1/instrument_1/detector_1/x_pixel_size' \n", - "2020-11-27 17:58:02,898 - STSim - INFO - y_pixel_size [float]: '/entry_1/instrument_1/detector_1/y_pixel_size' \n", - "2020-11-27 17:58:02,918 - STSim - INFO - results/test_sim/data.cxi saved\n" + "2020-11-29 13:02:50,237 - STSim - INFO - Initializing\n", + "2020-11-29 13:02:50,237 - STSim - INFO - Current parameters\n", + "2020-11-29 13:02:50,238 - STSim - INFO - Initializing coordinate arrays at the sample's plane\n", + "2020-11-29 13:02:50,238 - STSim - INFO - Number of points in x axis: 1287\n", + "2020-11-29 13:02:50,239 - STSim - INFO - Number of points in y axis: 1810\n", + "2020-11-29 13:02:50,241 - STSim - INFO - Generating wavefields at the sample's plane\n", + "2020-11-29 13:02:50,248 - STSim - INFO - The wavefields have been generated\n", + "2020-11-29 13:02:50,249 - STSim - INFO - Generating barcode's transmission coefficients\n", + "2020-11-29 13:02:50,252 - STSim - INFO - The coefficients have been generated\n", + "2020-11-29 13:02:50,252 - STSim - INFO - Generating wavefields at the detector's plane\n", + "2020-11-29 13:02:50,454 - STSim - INFO - The wavefields have been generated\n", + "2020-11-29 13:02:50,455 - STSim - INFO - Making ptychograph...\n", + "2020-11-29 13:02:50,456 - STSim - INFO - Source blur size: 100.000000 um\n", + "2020-11-29 13:02:50,459 - STSim - INFO - The ptychograph is generated, data shape: (10, 1, 2000)\n" ] } ], "source": [ "st_params = st_sim.parameters(**params)\n", - "st_conv = st_sim.STConverter()\n", + "st_conv = st_sim.converter()\n", "with st_sim.STSim(st_params) as sim_obj:\n", " data = sim_obj.ptychograph()\n", - " st_conv.save_sim(data, sim_obj, 'results/test_sim')" + " st_data = st_conv.export_data(data, st_params)" ] }, { diff --git a/docs/conf.py b/docs/conf.py index 7b5a172374835e89e5de2c06673f59a3530ada52..786ec05d72bc032d7f39978906ab07f7ec4f5f4a 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -22,7 +22,7 @@ copyright = '2020, Nikolay Ivanov' author = 'Nikolay Ivanov' # The full version, including alpha/beta/rc tags -release = '0.1.2' +release = '0.1.3' # -- General configuration --------------------------------------------------- diff --git a/pyrost/data_processing.py b/pyrost/data_processing.py index 7a8a5307d96a01a21b806872966b4073a751f6a8..e9921a1b62e1b74b1774d9e845b1a6d88bf009ed 100755 --- a/pyrost/data_processing.py +++ b/pyrost/data_processing.py @@ -693,7 +693,8 @@ class SpeckleTracking(DataContainer): return {'pixel_map': pixel_map} def iter_update(self, sw_fs, sw_ss=0, ls_pm=3., ls_ri=10., - n_iter=5, f_tol=3e-3, verbose=True, method='search'): + n_iter=5, f_tol=3e-3, verbose=True, method='search', + return_errors=True): """Perform iterative Robust Speckle Tracking update. `ls_ri` and `ls_pm` define high frequency cut-off to supress the noise. Iterative update terminates when the difference between total @@ -723,6 +724,8 @@ class SpeckleTracking(DataContainer): * 'newton' : Iterative Newton's method based on finite difference gradient approximation. * 'search' : Grid search along the search window. + return_errors : bool, optional + Return errors array if True. Returns ------- @@ -730,7 +733,8 @@ class SpeckleTracking(DataContainer): A new :class:`SpeckleTracking` object with the updated `pixel_map` and `reference_image`. list - List of total MSE values for each iteration. + List of total MSE values for each iteration. Only if + `return_errors` is True. """ obj = self.update_reference(ls_ri=ls_ri, sw_ss=sw_ss, sw_fs=sw_fs) errors = [obj.total_mse(ls_ri=ls_ri)] @@ -759,7 +763,10 @@ class SpeckleTracking(DataContainer): print('Iteration No. {:d}: Total MSE = {:.3f}'.format(it, errors[-1])) if errors[-2] - errors[-1] <= f_tol: break - return obj, errors + if return_errors: + return obj, errors + else: + return obj def total_mse(self, ls_ri=3.): """Return average mean-squared-error (MSE) per pixel. diff --git a/pyrost/simulation/__init__.py b/pyrost/simulation/__init__.py index 52326949c39d0be0f3cf642aa51961c5bfa36eb9..ee6275bccc096b7fc6ede7a9023b242058b28207 100755 --- a/pyrost/simulation/__init__.py +++ b/pyrost/simulation/__init__.py @@ -3,4 +3,4 @@ Speckle Tracking scans. Wavefront propagation is based on the Fresnel diffraction theory. """ from .st_sim_param import STParams, parameters -from .st_sim import STSim, STConverter \ No newline at end of file +from .st_sim import STSim, STConverter, converter diff --git a/pyrost/simulation/st_sim.py b/pyrost/simulation/st_sim.py index 4ed04495557565d38c9ee1165e6a434cc64213c7..3cd9b9f5a6613aff6d7668fce2738b9103b687ac 100755 --- a/pyrost/simulation/st_sim.py +++ b/pyrost/simulation/st_sim.py @@ -118,14 +118,18 @@ class STSim: def __init__(self, st_params, bsteps=None): self.parameters = st_params - self.__dict__.update(**self.parameters.export_dict()) self._init_logging() self._init_coord() self._init_lens() self._init_barcode(bsteps) self._init_detector() + def __getattr__(self, attr): + if attr in self.parameters: + return self.parameters.__getattr__(attr) + def _init_logging(self): + os.makedirs(self.log_dir, exist_ok=True) self.logger = logging.getLogger(self.__class__.__name__) self.logger.level = logging.INFO filename = os.path.join(self.log_dir, datetime.datetime.now().strftime('%d-%m-%Y_%H-%M-%S.log')) @@ -508,6 +512,28 @@ class STConverter: if logger: logger.info("{:s} saved".format(os.path.join(dir_path, 'data.cxi'))) +def converter(coord_ratio=1e-6, float_precision='float64'): + """Return the default simulation converter. + + Parameters + ---------- + coord_ratio : float, optional + Coordinates ratio between the simulated and saved data. + float_precision: {'float32', 'float64'}, optional + Floating point precision. + + Returns + ------- + STConverter + Default simulation data converter. + + See Also + -------- + STConverter : Full converter class description. + """ + return STConverter(protocol=cxi_protocol(float_precision), + coord_ratio=coord_ratio) + def main(): """Main fuction to run Speckle Tracking simulation and save the results to a CXI file. """ diff --git a/pyrost/simulation/st_sim_param.py b/pyrost/simulation/st_sim_param.py index c6e0e3623ae3d9c8956bec68095d34669cb06b7d..590a2db87bc3b888bc514578eaa61752b4241949 100755 --- a/pyrost/simulation/st_sim_param.py +++ b/pyrost/simulation/st_sim_param.py @@ -126,6 +126,12 @@ class STParams(INIParser): super(STParams, self).__init__(**kwargs) self.__dict__['_lookup'] = self.lookup_dict() + def __iter__(self): + return self._lookup.__iter__() + + def __contains__(self, attr): + return attr in self._lookup + def __getattr__(self, attr): if attr in self._lookup: return self.__dict__[self._lookup[attr]][attr] diff --git a/pytest.ini b/pytest.ini index b30dddcd92a195a3dde59278db4f7f16d82c230a..6e7ae8f6073cc6bdfd5a6073298ccba274d18590 100644 --- a/pytest.ini +++ b/pytest.ini @@ -1,4 +1,5 @@ [pytest] markers = st_sim: test Speckle Tracking simulation package - rst: rest Robust Speckle Tracking package \ No newline at end of file + rst: test Robust Speckle Tracking package + standalone: standalone test \ No newline at end of file diff --git a/setup.py b/setup.py old mode 100644 new mode 100755 index c8bcbf8cde004404ede7f38e3d5106c408bb0e10..c4a850a8a034992851946031fb1208e2eb84db9f --- a/setup.py +++ b/setup.py @@ -42,7 +42,7 @@ with open('README.md', 'r') as readme: long_description = readme.read() setup(name='pyrost', - version='0.1.2', + version='0.1.3', author='Nikolay Ivanov', author_email="nikolay.ivanov@desy.de", long_description=long_description, diff --git a/test_pyrost.py b/tests/test_pyrost.py similarity index 80% rename from test_pyrost.py rename to tests/test_pyrost.py index 32e46351b890028cf3db01a5cd6e79e928265841..0ed993abca8b7a37caaab6287caa27e38b0ecaa1 100755 --- a/test_pyrost.py +++ b/tests/test_pyrost.py @@ -45,10 +45,17 @@ def exp_data_2d(request): @pytest.fixture(params=['float32', 'float64']) def loader(request): """ - Return a default cxi protocol + Return the default loader. """ return rst.loader(request.param) +@pytest.fixture(params=['float32', 'float64']) +def converter(request): + """ + Return the default loader. + """ + return st_sim.converter(float_precision=request.param) + @pytest.fixture(scope='function') def ini_path(): """Return a path to the experimental speckle tracking data. @@ -68,8 +75,8 @@ def test_st_params(st_params, ini_path): @pytest.mark.st_sim def test_st_sim(st_params): - sim = st_sim.STSim(st_params) - ptych = sim.ptychograph() + with st_sim.STSim(st_params) as sim_obj: + ptych = sim_obj.ptychograph() assert len(ptych.shape) == 3 assert ptych.shape[0] == st_params.n_frames @@ -95,6 +102,7 @@ def test_iter_update(sim_data, loader): data_path = os.path.join(sim_data, 'data.cxi') assert os.path.isfile(data_path) st_data = loader.load(data_path, roi=(0, 1, 400, 1450)) + assert st_data.data.dtype == loader.protocol.known_types['float'] st_obj = st_data.get_st() pixel_map0 = st_obj.pixel_map.copy() st_obj.iter_update(sw_ss=0, sw_fs=150, ls_pm=2.5, ls_ri=15, @@ -108,3 +116,15 @@ def test_data_process_routines(exp_data_2d, loader): data = loader.load(**exp_data_2d) data = data.make_mask(method='eiger-bad') assert (data.get('whitefield') <= 65535).all() + +@pytest.mark.standalone +def test_full(st_params, converter): + with st_sim.STSim(st_params) as sim_obj: + ptych = sim_obj.ptychograph() + data = converter.export_data(ptych, st_params) + assert data.data.dtype == converter.protocol.known_types['float'] + st_obj = data.get_st() + st_res = st_obj.iter_update(sw_fs=20, ls_pm=3, ls_ri=5, + verbose=True, n_iter=10, return_errors=False) + assert (st_obj.pixel_map != st_res.pixel_map).any() + assert st_res.pixel_map.dtype == converter.protocol.known_types['float'] \ No newline at end of file