Beispiel #1
0
    def test_transforms_correctly_with_polarization_rotation(self):
        # We test that rotating the lab frame correctly rotates
        # the polarization.
        # If we rotate (x0, y0) -> (y1, -x1), then the polarization
        # in the new coordinates should be
        # E1x = E0y, E1y = -E1x
        scatterer = sphere
        medium_wavevec = 2 * np.pi / wavelen
        medium_index = index
        theory = MieLens()

        krho = np.linspace(0, 100, 11)
        phi_0 = 0 * krho + np.pi / 180.0  # a small component along y
        phi_1 = phi_0 - np.pi / 2
        kz = np.full_like(krho, 20.0)

        pol_0 = xr.DataArray([1.0, 0, 0])
        pos_0 = np.array([krho, phi_0, kz])

        pol_1 = xr.DataArray([0, -1.0, 0])
        pos_1 = np.array([krho, phi_1, kz])

        args = (scatterer, medium_wavevec, medium_index)

        fields_0 = theory._raw_fields(pos_0, *args, pol_0)
        fields_1 = theory._raw_fields(pos_1, *args, pol_1)

        self.assertTrue(np.allclose(fields_1[0],  fields_0[1], **TOLS))
        self.assertTrue(np.allclose(fields_1[1], -fields_0[0], **TOLS))
Beispiel #2
0
 def _get_theory_and_scaling(self, params):
     if self.theory == 'mielens':
         theory = MieLens(lens_angle=params['lens_angle'])  # 0.0015 ms
         scaling = 1.0
     elif self.theory == 'mieonly':
         theory = Mie()
         scaling = params['alpha']
     elif self.theory == 'mielensalpha':
         theory = MieLens(lens_angle=params['lens_angle'])  # 0.0015 ms
         scaling = params['alpha']
     return theory, scaling
Beispiel #3
0
    def test_calculate_scattered_field_lensmie_same_as_mielens(self):
        detector = test_common.xschema_lens
        scatterer = test_common.sphere
        medium_wavevec = 2 * np.pi / test_common.wavelen
        medium_index = test_common.index
        illum_polarization = test_common.xpolarization

        theory_old = MieLens(lens_angle=LENS_ANGLE)
        theory_new = LENSMIE

        fields_old = theory_old.calculate_scattered_field(scatterer, detector)
        fields_new = theory_new.calculate_scattered_field(scatterer, detector)

        assert_allclose(fields_old, fields_new, atol=5e-3)
Beispiel #4
0
    def test_holopy_hologram_equal_to_exact_calculation(self):
        # Checks that phase shifts and wrappers for mielens are correct
        theory_mielens = MieLens()
        illum_wavelength = 0.66  # 660 nm red light
        k = 2 * np.pi / illum_wavelength
        center = (10, 10, 5.)

        kwargs = {'particle_kz': center[2] * k,
                  'index_ratio': 1.2,
                  'size_parameter': 0.5 * k,
                  'lens_angle': theory_mielens.lens_angle}
        detector = detector_grid(10, 2.0)
        x = detector.x.values.reshape(-1, 1) - center[0]
        y = detector.y.values.reshape(1, -1) - center[1]

        rho = np.sqrt(x**2 + y**2)
        phi = np.arctan2(y, x)

        calculator = mielensfunctions.MieLensCalculator(**kwargs)
        scatterer = Sphere(n=kwargs['index_ratio'],
                           r=kwargs['size_parameter'] / k,
                           center=center)

        holo_calculate = calculator.calculate_total_intensity(k * rho, phi)
        holo_holopy = calc_holo(
            detector, scatterer, illum_wavelen=illum_wavelength,
            medium_index=1., illum_polarization=(1, 0), theory=theory_mielens)

        is_ok = np.allclose(holo_calculate, holo_holopy.values.squeeze(),
                            **TOLS)
        self.assertTrue(is_ok)
Beispiel #5
0
def compare_fit_holo(data, fit_scatterer, fit_lens_angle):
    guess_holo = hologram2array(
        calc_holo(data,
                  fit_scatterer,
                  theory=MieLens(lens_angle=fit_lens_angle)))
    data_holo = hologram2array(data)
    compare_imgs(data_holo, guess_holo, ['Data', 'Model'])
Beispiel #6
0
    def _forward(self, pars, detector):
        """
        Compute a forward model (the hologram)

        Parameters
        -----------
        pars: list
            Values for each parameter used to compute the hologram. Ordering
            is given by self._parameters
        detector: xarray
            dimensions of the resulting hologram. Metadata taken from
            detector if not given explicitly when instantiating self.
        """
        alpha = read_map(self._maps['model'], pars)['alpha']
        optics_kwargs = self._find_optics(pars, detector)
        scatterer = self._scatterer_from_parameters(pars)
        theory_kwargs = read_map(self._maps['theory'], pars)
        # FIXME would be nice to have access to the interpolator kwargs
        theory = MieLens(**theory_kwargs)
        try:
            return calc_holo(detector,
                             scatterer,
                             theory=theory,
                             scaling=alpha,
                             **optics_kwargs)
        except InvalidScatterer:
            return -np.inf
Beispiel #7
0
 def test_raises_error_if_multiple_z_values(self):
     theory = MieLens()
     np.random.seed(10)
     positions = np.random.randn(3, 10)  # the zs will differ by chance
     self.assertRaises(
         ValueError, theory._raw_fields, positions, sphere, 1.0, 1.33,
         xschema.illum_polarization)
Beispiel #8
0
def calculate_models(data, fits):
    fitholos = [
        calc_holo(datum,
                  fit.scatterer,
                  theory=MieLens(lens_angle=fit.parameters['lens_angle']))
        if fit is not None else 0 * datum + 1
        for datum, fit in zip(data, fits)
    ]
    return fitholos
 def calc_model(cls, data, params, theory_type='mielens'):
     scatterer = cls._make_scatterer(params)
     if theory_type == 'mielens':
         theory = MieLens(lens_angle=params['lens_angle'])
         scaling = 1.0
     else:
         theory = Mie()
         scaling = params['alpha']
     model = calc_holo(data, scatterer, theory=theory, scaling=scaling)
     return model
Beispiel #10
0
    def test_raw_fields_similar_mielens_ypolarization(self):
        detector = SMALL_DETECTOR
        scatterer = test_common.sphere
        medium_wavevec = 2 * np.pi / test_common.wavelen
        medium_index = test_common.index
        illum_polarization = xr.DataArray([0, 1.0, 0])

        theory_old = MieLens(lens_angle=LENS_ANGLE)
        pos_old = theory_old._transform_to_desired_coordinates(
            detector, scatterer.center, wavevec=medium_wavevec)

        theory_new = LENSMIE
        pos_new = theory_new._transform_to_desired_coordinates(
            detector, scatterer.center, wavevec=medium_wavevec)

        args = (scatterer, medium_wavevec, medium_index, illum_polarization)
        f0x, f0y, f0z = theory_old._raw_fields(pos_old, *args)
        fx, fy, fz = theory_new._raw_fields(pos_new, *args)
        assert_allclose(f0x, fx, atol=2e-3)
        assert_allclose(f0y, fy, atol=2e-3)
        assert_allclose(f0z, fz, atol=2e-3)
Beispiel #11
0
 def test_can_calculate_for_positive_and_negative_z(self):
     theory = MieLens()
     ka = 5.0
     radius = ka * wavelen * 0.5 / np.pi
     sphere_index = 1.59
     is_ok = []
     for kz in [-50., 0., 50.]:
         center = (0, 0, kz * wavelen * 0.5 / np.pi)
         this_sphere = Sphere(n=sphere_index, r=radius, center=center)
         holo = calc_holo(xschema, this_sphere, index, wavelen,
                          xpolarization, theory=theory)
         is_ok.append(holo.data.ptp() > 0)
     self.assertTrue(all(is_ok))
Beispiel #12
0
    def evaluate_model(self, params):
        scatterer = self.make_scatterer(params)
        if self.theory == 'mieonly':
            theory = Mie()
        else:
            theory = MieLens(lens_angle=params['lens_angle'])
        if self.theory == 'mielens':
            scaling = 1.0
        else:
            scaling = params['alpha']

        model = calc_holo(self.data, scatterer, theory=theory, scaling=scaling)
        return model
Beispiel #13
0
    def test_mielens_multiple_returns_nonzero(self):
        scatterers = [
            Sphere(n=1.59, r=5e-7, center=(1e-6, -1e-6, 10e-6)),
            Sphere(n=1.59, r=1e-6, center=[8e-6, 5e-6, 5e-6]),
            Sphere(n=1.59 + 0.0001j, r=5e-7, center=[5e-6, 10e-6, 3e-6]),
            ]
        sphere_collection = Spheres(scatterers=scatterers)
        theory = MieLens()

        schema = yschema
        holo = calc_holo(schema, sphere_collection, index, wavelen,
                         theory=theory)
        self.assertTrue(holo is not None)
        self.assertTrue(holo.values.std() > 0)
Beispiel #14
0
def calculate_central_lobe_at(zs):
    illum_wavelength = 0.66  # 660 nm red light
    k = 2 * np.pi / illum_wavelength
    detector = detector_grid(4, 2.0)

    central_lobes = []
    for z in zs:
        center = (0, 0, z)
        scatterer = Sphere(n=1.59, r=0.5, center=center)
        holo = calc_holo(
            detector, scatterer, illum_wavelen=illum_wavelength,
            medium_index=1.33, illum_polarization=(1, 0), theory=MieLens())
        central_lobe = holo.values.squeeze()[0, 0]
        central_lobes.append(central_lobe)
    return np.array(central_lobes)
Beispiel #15
0
    def test_mielens_x_polarization_differs_from_y(self):
        # test holograms for orthogonal polarizations; make sure they're
        # not the same, nor too different from one another.
        theory = MieLens()
        holo_x = calc_holo(xschema, sphere, index, wavelen,
                           illum_polarization=xpolarization, theory=theory)
        holo_y = calc_holo(yschema, sphere, index, wavelen,
                           illum_polarization=ypolarization, theory=theory)

        # the two arrays should not be equal
        self.assertFalse(np.allclose(holo_x, holo_y, **SOFTTOLS))

        # but their max and min values should be very close
        # (really exact because we lose no symmetry from the grid)
        self.assertTrue(np.isclose(holo_x.max(), holo_y.max(), **MEDTOLS))
        self.assertTrue(np.isclose(holo_x.min(), holo_y.min(), **MEDTOLS))
Beispiel #16
0
    def forward(self, pars, detector):
        """
        Compute a forward model (the hologram)

        Parameters
        -----------
        pars: dict(string, float)
            Dictionary containing values for each parameter used to compute
            the hologram. Possible parameters are given by self.parameters.
        detector: xarray
            dimensions of the resulting hologram. Metadata taken from
            detector if not given explicitly when instantiating self.
        """
        optics_kwargs, scatterer = self._optics_scatterer(pars, detector)
        # We need the lens parameter(s) for the theory:
        theory_kwargs = {name: self._get_parameter(name, pars, detector)
                         for name in self.theory_params}
        # FIXME would be nice to have access to the interpolator kwargs
        theory = MieLens(**theory_kwargs)
        try:
            return calc_holo(detector, scatterer, theory=theory,
                             scaling=1.0, **optics_kwargs)
        except InvalidScatterer:
            return -np.inf
Beispiel #17
0
def make_stack_figures(data, fits, n=None, r=None, z_positions=None):
    scatterers = [fit.scatterer for fit in fits]
    z = [fit.scatterer.center[2]
         for fit in fits] if z_positions is None else z_positions
    for scatterer, z_pos in zip(scatterers, z):
        scatterer.n = n if n is not None else scatterer.n
        scatterer.r = r if r is not None else scatterer.r
        scatterer.center[
            2] = z_pos if z_positions is not None else scatterer.center[2]

    model_holos = [
        calc_holo(dt, scatterer, theory=MieLens(lens_angle=1.0))
        for dt, scatterer in zip(data, scatterers)
    ]

    data_stack_xz = np.vstack([dt.values.squeeze()[50, :] for dt in data])
    data_stack_yz = np.vstack([dt.values.squeeze()[:, 50] for dt in data])

    model_stack_xz = np.vstack(
        [holo.values.squeeze()[50, :] for holo in model_holos])
    model_stack_yz = np.vstack(
        [holo.values.squeeze()[:, 50] for holo in model_holos])

    return data_stack_xz, data_stack_yz, model_stack_xz, model_stack_yz
Beispiel #18
0
    def test_mielens_is_close_to_mieonly(self):
        """Tests that a mielens hologram is similar to a mie-only hologram."""
        theory_mielens = MieLens()
        theory_mieonly = Mie()

        holo_mielens = calc_holo(
            xschema, sphere, index, wavelen, xpolarization,
            theory=theory_mielens)
        holo_mieonly = calc_holo(
            xschema, sphere, index, wavelen, xpolarization,
            scaling=1.0, theory=theory_mieonly)

        # the two arrays should not be equal
        self.assertFalse(np.allclose(holo_mielens, holo_mieonly, **TOLS))

        # but their max and min values should be close:
        ptp_close_ish = np.isclose(
            holo_mielens.values.ptp(), holo_mieonly.values.ptp(), atol=0.1)
        # and their median should be close:
        median_close_ish = np.isclose(
            np.median(holo_mielens), np.median(holo_mieonly), atol=0.1)

        self.assertTrue(ptp_close_ish)
        self.assertTrue(median_close_ish)
Beispiel #19
0
 def test_does_not_crash(self):
     theory = MieLens()
     holo = calc_holo(xschema, sphere, index, wavelen, xpolarization,
                      theory=theory)
     self.assertTrue(holo is not None)