def setUp(self): ins = Instrument(magnification=.048, wavelength=.447, n_m=1.335) p1 = Sphere(r_p=[150, 150, 200], a_p=1., n_p=1.45) p2 = Sphere(r_p=[75, 75, 150], a_p=1.25, n_p=1.61) coords = coordinates((201, 201)) self.model = GeneralizedLorenzMie(coords, [p1, p2], ins) self.fast_model = FastGeneralizedLorenzMie(coords, [p1, p2], ins) self.cuda_model = CudaGeneralizedLorenzMie(coords, [p1, p2], ins)
def feature_extent(sphere, config, nfringes=20): '''Radius of holographic feature in pixels''' s = Sphere() s.a_p = sphere.a_p s.n_p = sphere.n_p s.z_p = sphere.z_p h = LMHologram(coordinates=np.arange(300)) h.instrument.properties = config['instrument'] h.particle = sphere # roughly estimate radii of zero crossings b = h.hologram() - 1. ndx = np.where(np.diff(np.sign(b)))[0] + 1 return float(ndx[nfringes])
def make_sample(config): '''Returns an array of Sphere objects''' particle = config['particle'] nrange = particle['nspheres'] mpp = config['instrument']['magnification'] if nrange[0] == nrange[1]: nspheres = nrange[0] else: nspheres = np.random.randint(nrange[0], nrange[1]) sample = [] for n in range(nspheres): np.random.seed() sphere = Sphere() for prop in ('a_p', 'n_p', 'k_p', 'z_p'): setattr(sphere, prop, make_value(particle[prop])) ##Making sure separation between particles is large enough## close = True aval = sphere.a_p zval = sphere.z_p while close: close = False xval = make_value(particle['x_p']) yval = make_value(particle['y_p']) for s in sample: xs, ys, zs = s.x_p, s.y_p, s.z_p atest = s.a_p dist = np.sqrt((xs - xval)**2 + (ys - yval)**2 + (zs - zval)**2) threshold = (atest + aval) / mpp if dist < threshold: close = True setattr(sphere, 'x_p', xval) setattr(sphere, 'y_p', yval) sample.append(sphere) return sample
def __init__(self, a_p=None, n_p=None, r_p=None, particle=None, **kwargs): ''' Parameters ---------- a_p : float or numpy.ndarray, optional Starting radius of sphere. Alternatively, can be an array of radii of concentric shells within the sphere n_p : complex or numpy.ndarray, optional Starting refractive index of sphere. Alternatively, can be an array of refractive indexes of the shells. r_p : numpy.ndarray or list, optional coordinates of sphere center: (x_p, y_p, z_p) ''' super(LorenzMie, self).__init__(**kwargs) self.particle = Sphere() if a_p is not None: self.particle.a_p = a_p if n_p is not None: self.particle.n_p = n_p if r_p is not None: self.particle.r_p = r_p
def make_sample(config): '''Returns an array of Sphere objects''' particle = config['particle'] nrange = particle['nspheres'] nspheres = np.random.randint(nrange[0], nrange[1]) sample = [] for n in range(nspheres): sphere = Sphere() for prop in ('a_p', 'n_p', 'k_p', 'x_p', 'y_p', 'z_p'): setattr(sphere, prop, make_value(particle[prop])) sample.append(sphere) return sample
def setUp(self): self.particle = Sphere() self.fast_particle = FastSphere() self.particle.r_p = (100, 200, 300) self.fast_particle.r_p = (100, 200, 300)
class TestSphere(unittest.TestCase): def setUp(self): self.particle = Sphere() self.fast_particle = FastSphere() self.particle.r_p = (100, 200, 300) self.fast_particle.r_p = (100, 200, 300) def test_set_ap(self): value = 1. self.particle.a_p = value self.assertEqual(value, self.particle.a_p) value = [1., 1.5] self.particle.a_p = value self.assertSequenceEqual(value, self.particle.a_p.tolist()) def test_set_np(self): value = 1.5 self.particle.n_p = value self.assertEqual(value, self.particle.n_p) value = [1.5, 1.51] self.particle.n_p = value self.assertSequenceEqual(value, self.particle.n_p.tolist()) def test_fast(self): self.particle.a_p = 1. self.particle.n_p = 1.45 self.fast_particle.a_p = 1. self.fast_particle.n_p = 1.45 n_m = 1.34 wavelength = 0.447 ab = self.particle.ab(n_m, wavelength) fast_ab = self.fast_particle.ab(n_m, wavelength) self.assertTrue(np.allclose(ab[0:20, :], fast_ab[0:20, :])) def test_coefficients(self): self.particle.a_p = 1. self.particle.n_p = 1.45 n_m = 1.34 wavelength = 0.447 ab = self.particle.ab(n_m, wavelength) # supposed ground truth from IDL implementation gt = np.array( [[0.j, 0.j], [0.99922907 - 0.027754991j, 0.99913551 - 0.029389456j], [0.99798931 - 0.044795570j, 0.99922896 - 0.027756943j], [0.99912817 - 0.029513850j, 0.99536713 - 0.067907302j], [0.99113427 - 0.093739712j, 0.99898631 - 0.031822280j], [0.99745408 - 0.050392869j, 0.98372746 - 0.12652173j], [0.97954507 - 0.14155044j, 0.99484334 - 0.071624499j], [0.98344449 - 0.12759869j, 0.97377732 - 0.15979691j], [0.97295236 - 0.16222228j, 0.96333549 - 0.18793674j], [0.94122462 - 0.23520381j, 0.97203532 - 0.16487164j], [0.93923397 - 0.23890065j, 0.90827363 - 0.28863930j], [0.90681965 - 0.29068501j, 0.89369866 - 0.30822291j], [0.85285635 - 0.35424906j, 0.90527481 - 0.29283498j], [0.80640888 - 0.39511213j, 0.79527030 - 0.40350397j], [0.74158827 - 0.43776147j, 0.67754233 - 0.46741707j], [0.67568826 - 0.46811712j, 0.68941667 - 0.46273246j], [0.58974388 - 0.49188010j, 0.67362393 - 0.46888669j], [0.39208775 - 0.48821609j, 0.44840396 - 0.49733072j], [0.13651257 - 0.34333204j, 0.11909958 - 0.32390565j], [0.023845866 - 0.15256881j, 0.014321099 - 0.11881079j], [0.0027834357 - 0.052684800j, 0.0012329865 - 0.035092254j], [0.00025087072 - 0.015836912j, 8.5639136e-05 - 0.0092537453j], [1.7963837e-05 - 0.0042383386j, 4.8214299e-06 - 0.0021957702j], [1.0259636e-06 - 0.0010128981j, 2.1937314e-07 - 0.00046837281j], [4.6954175e-08 - 0.00021668912j, 8.0932302e-09 - 8.9962382e-05j], [1.7358544e-09 - 4.1663586e-05j, 2.4393269e-10 - 1.5618345e-05j], [5.2348010e-11 - 7.2351925e-06j, 6.0618245e-12 - 2.4620773e-06j], [1.3008375e-12 - 1.1405426e-06j, 1.2536060e-13 - 3.5406299e-07j], [2.6896048e-14 - 1.6400015e-07j, 2.1766243e-15 - 4.6654306e-08j], [4.6687756e-16 - 2.1607350e-08j, 3.1991070e-17 - 5.6560648e-09j], [6.8604036e-18 - 2.6192371e-09j, 4.0101716e-19 - 6.3325905e-10j], [8.5980970e-20 - 2.9322501e-10j, 4.3169528e-21 - 6.5703417e-11j], [9.2545268e-22 - 3.0421149e-11j, 4.0162615e-23 - 6.3372936e-12j], [8.6092607e-24 - 2.9340497e-12j, 3.2488696e-25 - 5.6988406e-13j], [6.9664134e-26 - 2.6383515e-13j, 2.3050348e-27 - 4.7906383e-14j], [4.9651027e-28 - 2.2178247e-14j, 1.5031287e-29 - 3.7739203e-15j], [3.4175377e-30 - 1.7471016e-15j, 1.3633875e-31 - 2.7923729e-16j], [4.3729724e-32 - 1.2926869e-16j, 4.4429448e-33 - 1.9447037e-17j], [1.9627507e-33 - 9.0026403e-18j, 2.6860514e-34 - 1.2772834e-18j], [1.2393948e-34 - 5.9129145e-19j, 1.6573650e-35 - 7.9263326e-20j], [7.6708376e-36 - 3.6693179e-20j, 9.7307317e-37 - 4.6553744e-21j], [4.5045616e-37 - 2.1550971e-21j, 5.4177177e-38 - 2.5919978e-22j], [2.5080037e-38 - 1.1999046e-22j, 2.8639380e-39 - 1.3701950e-23j], [1.3258143e-39 - 6.3430989e-24j, 1.4400608e-40 - 6.8896892e-25j], [6.6679424e-41 - 3.1901465e-25j, 6.9378818e-42 - 3.3192937e-26j], [3.2184201e-42 - 1.5397901e-26j, 3.4506417e-43 - 1.6508920e-27j], [1.5867090e-43 - 7.5912988e-28j, 2.7763127e-44 - 1.3282725e-28j]]) self.assertTrue(np.allclose(ab[0:20, :], gt[0:20, :]))
if __name__ == '__main__': from pylorenzmie.theory.Instrument import Instrument from pylorenzmie.theory.Sphere import Sphere import matplotlib.pyplot as plt # Create coordinate grid for image x = np.arange(0, 201) y = np.arange(0, 201) xv, yv = np.meshgrid(x, y) xv = xv.flatten() yv = yv.flatten() zv = np.zeros_like(xv) coordinates = np.stack((xv, yv, zv)) # Place a sphere in the field of view, above the focal plane particle = Sphere() particle.r_p = [125, 75, 100] particle.a_p = 0.5 particle.n_p = 1.45 # Form image with default instrument instrument = Instrument() instrument.magnification = 0.135 instrument.wavelength = 0.447 instrument.n_m = 1.335 k = instrument.wavenumber() # Use Generalized Lorenz-Mie theory to compute field kernel = CudaGeneralizedLorenzMie(coordinates=coordinates, particle=particle, instrument=instrument) field = kernel.field() # Compute hologram from field and show it