def test_calc_holo_with_twocolor_index(self): indices = OrderedDict([('red',1.5),('green',2)]) radius = 0.5 center = (1, 1, 1) illum_wavelen = OrderedDict([('red', 0.66), ('green', 0.52)]) sphere_red = Sphere(n=indices['red'], r=radius, center=center) sphere_green = Sphere(n=indices['green'], r=radius, center=center) sphere_both = Sphere(n=indices, r=radius, center=center) schema_single_color = update_metadata( detector_grid(shape=2, spacing=1), illum_polarization=(0,1), medium_index=1.3) schema_two_colors = update_metadata( detector_grid( shape=2,spacing=1,extra_dims={'illumination':['red','green']}), illum_polarization=(0,1), medium_index=1.3) red_hologram = calc_holo( schema_single_color, sphere_red, illum_wavelen=illum_wavelen['red']) green_hologram = calc_holo( schema_single_color, sphere_green, illum_wavelen=illum_wavelen['green']) both_hologram = calc_holo( schema_two_colors,sphere_both, illum_wavelen=illum_wavelen) joined = np.concatenate([ np.array([red_hologram.values]), np.array([green_hologram.values])]) assert_equal(both_hologram.values, joined)
def test_preserves_metadata_keys(self): data1 = update_metadata(make_data(seed=1), **METADATA_VALUES) data2 = update_metadata(make_data(seed=2), **METADATA_VALUES) data = [data1, data2] concatenated = clean_concat(data, 'point') for key in METADATA_VALUES.keys(): self.assertIn(key, concatenated.attrs) self.assertTrue(hasattr(concatenated, key))
def test_preserves_metadata_values(self): data1 = update_metadata(make_data(seed=1), **METADATA_VALUES) data2 = update_metadata(make_data(seed=2), **METADATA_VALUES) data = [data1, data2] concatenated = clean_concat(data, 'point') for key, value in METADATA_VALUES.items(): if key != 'illum_polarization': self.assertEqual(getattr(concatenated, key), value) polarization_ok = np.all(concatenated.illum_polarization[:2] == METADATA_VALUES['illum_polarization']) self.assertTrue(polarization_ok)
def test_does_update_medium_index(self): detector = detector_grid(3, 0.1) np.random.seed(10) medium_index = 1 + np.random.rand() updated_detector = update_metadata(detector, medium_index=medium_index) self.assertEqual(updated_detector.medium_index, medium_index)
def bg_correct(raw, bg, df=None): """Correct for noisy images by dividing by a background. The calculation used is (raw-df)/(bg-df). Parameters ---------- raw : xarray.DataArray Image to be background divided. bg : xarray.DataArray background image recorded with the same optical setup. df : xarray.DataArray dark field image recorded without illumination. Returns ------- corrected_image : xarray.DataArray A copy of the background divided input image with None values of noise_sd updated to match bg. """ if df is None: df = raw.copy() df[:] = 0 if not (raw.shape == bg.shape == df.shape and list(get_spacing(raw)) == list(get_spacing(bg)) == list(get_spacing(df))): raise BadImage( "raw and background images must have the same shape and spacing") holo = (raw - df) / zero_filter(bg - df) holo = copy_metadata(raw, holo) if hasattr(holo, 'noise_sd') and hasattr( bg, 'noise_sd') and holo.noise_sd is None: holo = update_metadata(holo, noise_sd=bg.noise_sd) return holo
def test_calc_field(): s = Sphere(n=1.59, r=.5, center=(0, 0, 1)) t = update_metadata(detector_grid(shape=(2, 2), spacing=.1), illum_wavelen=0.66, medium_index=1.33, illum_polarization=(1, 0)) thry = Mie(False) f = calc_field(t, s, 1.33, .66, (1, 0), theory=thry) assert_obj_close(t.attrs, f.attrs) gold = xr.DataArray(np.array([[[ -3.95866810e-01 + 2.47924378e+00j, 0.00000000e+00 + 0.00000000e+00j, 0.00000000e+00 - 0.00000000e+00j ], [ -4.91260953e-01 + 2.32779296e+00j, 9.21716363e-20 - 5.72226912e-19j, 2.99878926e-18 - 1.41959276e-17j ]], [[ -4.89755627e-01 + 2.31844748e+00j, 0.00000000e+00 + 0.00000000e+00j, 4.89755627e-02 - 2.31844748e-01j ], [ -5.71886751e-01 + 2.17145168e+00j, 1.72579090e-03 - 8.72241140e-03j, 5.70160960e-02 - 2.16272927e-01j ]]]), dims=['x', 'y', 'vector'], coords={ 'x': t.x, 'y': t.y, 'vector': ['x', 'y', 'z'] }) assert abs((f - gold).max()) < 5e-9
def calc_model(self, params, metadata): sphere = self.create_sphere_from(params) # 0.036 ms theory, scaling = self._get_theory_and_scaling(params) if 'illum_wavelen' in params: wavelength = float(params['illum_wavelen']) metadata = update_metadata(metadata, illum_wavelen=wavelength) return calc_holo(metadata, sphere, theory=theory, scaling=scaling)
def test_does_update_illum_wavelength(self): detector = detector_grid(3, 0.1) np.random.seed(11) illum_wavelen = np.random.rand() updated_detector = update_metadata(detector, illum_wavelen=illum_wavelen) self.assertEqual(updated_detector.illum_wavelen, illum_wavelen)
def prep_schema(detector, medium_index, illum_wavelen, illum_polarization): detector = update_metadata( detector, medium_index, illum_wavelen, illum_polarization) if detector.illum_wavelen is None: raise MissingParameter("wavelength") if detector.medium_index is None: raise MissingParameter("medium refractive index") if illum_polarization is not False and detector.illum_polarization is None: raise MissingParameter("polarization") illum_wavelen = ensure_array(detector.illum_wavelen) illum_polarization = detector.illum_polarization if len(illum_wavelen) > 1 or ensure_array(illum_polarization).ndim == 2: # multiple illuminations to calculate if illumination in illum_polarization.dims: if isinstance(illum_wavelen, xr.DataArray): pass else: if len(illum_wavelen) == 1: illum_wavelen = illum_wavelen.repeat( len(illum_polarization.illumination)) illum_wavelen = xr.DataArray( illum_wavelen, dims=illumination, coords={illumination: illum_polarization.illumination}) else: # need to interpret illumination from detector.illum_wavelen if not isinstance(illum_wavelen, xr.DataArray): illum_wavelen = xr.DataArray( illum_wavelen, dims=illumination, coords={illumination: illum_wavelen}) illum_polarization = xr.broadcast( illum_polarization, illum_wavelen, exclude=[vector])[0] if illumination in detector.dims: detector = detector.sel( illumination=detector.illumination[0], drop=True) detector = update_metadata( detector, illum_wavelen=illum_wavelen, illum_polarization=illum_polarization) return detector
def test_does_update_illum_polarization(self): detector = detector_grid(3, 0.1) np.random.seed(12) illum_polarization = np.random.randn(2) illum_polarization /= np.linalg.norm(illum_polarization) updated_detector = update_metadata( detector, illum_polarization=illum_polarization) is_ok = np.all(updated_detector.illum_polarization.values[:2] == illum_polarization) self.assertTrue(is_ok)
def test_j0_roots(): # Checks for misbehavior when j_0(x) = 0 eps = 1e-12 d = detector_grid(shape=8, spacing=1) d = update_metadata(d,illum_wavelen=1, medium_index=1, illum_polarization=(1,0)) s_exact = Sphere(r=1,n=1.1,center=(4,4,5)) # causes kr = 0 near center s_close = Sphere(r=1,n=1.1,center=(4,4,5-eps)) h_exact = calc_field(d,s_exact) h_close = calc_field(d,s_close) np.testing.assert_allclose(h_exact, h_close)
def _calculate_multiple_color_scattered_field(self, scatterer, schema): field = [] for illum in schema.illum_wavelen.illumination.values: this_schema = update_metadata( schema, illum_wavelen=ensure_array( schema.illum_wavelen.sel(illumination=illum).values)[0], illum_polarization=ensure_array( schema.illum_polarization.sel(illumination=illum).values)) this_field = self._calculate_single_color_scattered_field( scatterer.select({illumination: illum}), this_schema) field.append(this_field) field = clean_concat(field, dim=schema.illum_wavelen.illumination) return field
def load_average(filepath, refimg=None, spacing=None, medium_index=None, illum_wavelen=None, illum_polarization=None, normals=None, noise_sd=None, channel=None, image_glob='*.tif'): """ Average a set of images (usually as a background) Parameters ---------- filepath : string or list(string) Directory or list of filenames or filepaths. If filename is a directory, it will average all images matching image_glob. refimg : xarray.DataArray reference image to provide spacing and metadata for the new image. spacing : float Spacing between pixels in the images. Used preferentially over refimg value if both are provided. medium_index : float Refractive index of the medium in the images. Used preferentially over refimg value if both are provided. illum_wavelen : float Wavelength of illumination in the images. Used preferentially over refimg value if both are provided. illum_polarization : list-like Polarization of illumination in the images. Used preferentially over refimg value if both are provided. image_glob : string Glob used to select images (if images is a directory) Returns ------- averaged_image : xarray.DataArray Image which is an average of images noise_sd attribute contains average pixel stdev normalized by total image intensity """ if normals is not None: raise ValueError(NORMALS_DEPRECATION_MESSAGE) if isinstance(filepath, str): if os.path.isdir(filepath): filepath = glob.glob(os.path.join(filepath, image_glob)) else: #only a single image filepath = [filepath] if len(filepath) < 1: raise LoadError(filepath, "No images found") # read spacing from refimg if none provided if spacing is None: spacing = get_spacing(refimg) # read colour channels from refimg channel_dict = {'0': 'red', '1': 'green', '2': 'blue'} if channel is None and refimg is not None and illumination in refimg.dims: channel = [ i for i, col in enumerate(['red', 'green', 'blue']) if col in refimg[illumination].values ] if np.isscalar(spacing): spacing = np.repeat(spacing, 2) # calculate the average accumulator = Accumulator() for path in filepath: accumulator.push(load_image(path, spacing, channel=channel)) mean_image = accumulator.mean() # calculate average noise from image if noise_sd is None and len(filepath) > 1: if channel: noise_sd = xr.DataArray(accumulator.cv(), [[channel_dict[str(ch)] for ch in channel]], ['illumination']) else: noise_sd = ensure_array(accumulator.cv()) # crop according to refimg dimensions if refimg is not None: def extent(i): name = ['x', 'y'][i] return np.around(refimg[name].values / spacing[i]).astype('int') mean_image = mean_image.isel(x=extent(0), y=extent(1)) mean_image['x'] = refimg.x mean_image['y'] = refimg.y # copy metadata from refimg if refimg is not None: mean_image = copy_metadata(refimg, mean_image, do_coords=False) # overwrite metadata from refimg with provided values return update_metadata(mean_image, medium_index, illum_wavelen, illum_polarization, normals, noise_sd)
def convert_holopy(self, data): x = data.copy() if x.noise_sd is None: x = update_metadata(x, noise_sd=self.estimate_noise_from(data)) y = torch.tensor(data.values.squeeze(), dtype=torch.float32) return {'x': x, 'y': y}
def test_does_update_noise_sd(self): detector = detector_grid(3, 0.1) np.random.seed(13) noise_sd = np.random.rand() updated_detector = update_metadata(detector, noise_sd=noise_sd) self.assertEqual(updated_detector.noise_sd, noise_sd)
import unittest import warnings import xarray as xr import numpy as np from nose.plugins.attrib import attr from holopy.inference.prior import Uniform from holopy.inference.result import UncertainValue, FitResult, SamplingResult from holopy.inference import AlphaModel, CmaStrategy, EmceeStrategy from holopy.scattering import Sphere from holopy.scattering.errors import MissingParameter from holopy.core.metadata import detector_grid, update_metadata from holopy.core.tests.common import assert_read_matches_write DATA = update_metadata(detector_grid(shape=10, spacing=2), 1.33, 0.660, (0, 1)) par_s = Sphere(n=Uniform(1.5, 1.65), r=Uniform(0.5, 0.7), center=[10, 10, 10]) MODEL = AlphaModel(par_s, alpha=Uniform(0.6, 0.9, guess=0.8)) INTERVALS = [ UncertainValue(1.6, 0.1, name='n'), UncertainValue(0.6, 0.1, name='r'), UncertainValue(0.7, 0.1, name='alpha') ] def generate_fit_result(): return FitResult(DATA, MODEL, CmaStrategy(), 10, {'intervals': INTERVALS}) def generate_sampling_result(): samples = np.array([[[1, 2], [11, 12], [3, 3]], [[0, 3], [1, 3], [5, 6]]])
def make_metadata(): detector = detector_grid(7, 0.1, name='metadata') return update_metadata(detector, **METADATA_VALUES)