Пример #1
0
def curve_phantom(curve, direction, kappa,
                  px=(20,20,20), vox_dim=(100,100,100), cyl_rad=0.2, max_l=6,
                  dtype=np.float32):

    # Setup grid
    xyz = np.array(np.meshgrid(
        np.linspace(-(px[0]/2)*vox_dim[0], (px[0]/2)*vox_dim[0], px[0]),
        np.linspace(-(px[1]/2)*vox_dim[1], (px[1]/2)*vox_dim[1], px[1]),
        np.linspace(-(px[2]/2)*vox_dim[2], (px[2]/2)*vox_dim[2], px[2])))
    xyz = np.moveaxis(xyz, [0, 1], [-1, 1])

    # Calculate directions and kappas
    diff = xyz[:,:,:,None,:] - curve
    dist = np.linalg.norm(diff, axis=-1)
    min_dist = np.min(dist, axis=-1) # min dist between grid points and curve
    t_index = np.argmin(dist, axis=-1)
    min_dir = direction[t_index] # directions for closest point on curve
    min_k = kappa[t_index] # kappas
    
    # Calculate watson 
    spang_shape = xyz.shape[0:-1] + (util.maxl2maxj(max_l),)
    spang1 = spang.Spang(np.zeros(spang_shape), vox_dim=vox_dim)
    dot = np.einsum('ijkl,ml->ijkm', min_dir, spang1.sphere.vertices)
    k = min_k[...,None]
    watson = np.exp(k*dot**2)/(4*np.pi*hyp1f1(0.5, 1.5, k))
    watson_sh = np.einsum('ijkl,lm', watson, spang1.B)
    watson_sh = watson_sh/watson_sh[...,None,0] # Normalize

    # Cylinder mask
    mask = min_dist < cyl_rad
    spang1.f = np.einsum('ijkl,ijk->ijkl', watson_sh, mask).astype(dtype)
    
    return spang1
Пример #2
0
    def visualize(self, filename, **kwargs):
        # Calculate arrow positions
        X = np.float(self.g.shape[0])
        Y = np.float(self.g.shape[1])
        Z = np.float(self.g.shape[2]) - kwargs['z_shift']
        max_dim = np.max([X, Y, Z])

        tips = np.array([[(X - max_dim) / 2, Y / 2, Z / 2],
                         [X / 2, Y / 2, (Z + max_dim) / 2]])
        rr = 10

        # Visualize each volume
        for i in range(self.g.shape[4]):
            for j in range(self.g.shape[3]):
                o = np.array([X / 2, Y / 2, Z / 2])
                pol = self.pols[i, j, :]
                rexc = tips[i, :] - o
                rdet = tips[(i + 1) % 2, :] - o
                tip = np.cross(rdet, pol)
                tip_n = tip * np.linalg.norm(rexc) / np.linalg.norm(tip)
                if np.dot(tip_n, rexc) < 0:
                    tip_n *= -1

                arrows = np.array([[tip_n + o, rr * pol],
                                   [tip_n + o, -rr * pol]])

                sp = spang.Spang(f=np.zeros(self.g.shape[0:3] + (15, )),
                                 vox_dim=self.vox_dim)  # For visuals only
                sp.f[..., 0] = self.g[..., j, i]
                sp.visualize(filename + 'v' + str(i) + 'p' + str(j),
                             viz_type='Density',
                             arrows=arrows,
                             arrow_color=np.array([1, 0, 0]),
                             **kwargs)
Пример #3
0
def all_directions(px=(15,15,1), vox_dim=(100,100,100)):
    dims = px + (3,)
    # f = np.zeros(dims)
    # tp = np.array(np.meshgrid(np.linspace(0, np.pi/2, px[0]),
    #                           np.linspace(0, np.pi, px[1]),
    #                           np.linspace(0, 0, px[2])))
    # tp = np.moveaxis(tp, [0, 1], [-1, 1])

    # xyz = np.apply_along_axis(util.tp2xyz, -1, tp)
    xyz = util.fibonacci_sphere(np.prod(np.array(px)), xyz=True).reshape(dims)
    f = np.apply_along_axis(util.xyz_sft, -1, xyz, max_l=4)

    return spang.Spang(f, vox_dim=vox_dim)
Пример #4
0
def three_helix(vox_dim=(130,130,130), px=(64,64,64), radius=600, scale=[1,1,1]):
    phant = spang.Spang(np.zeros(px + (15,), dtype=np.float32), vox_dim=vox_dim)
    s = 20
    phant1 = helix_phantom(px=(s,s,s), radius=radius, pitch=1000,
                          vox_dim=vox_dim, max_l=4, center=(0,0,0),
                          normal=0, trange=(-2*np.pi, 2*np.pi))
    phant2 = helix_phantom(px=(s,s,s), radius=radius, pitch=1000,
                          vox_dim=vox_dim, max_l=4, center=(0,0,0),
                          normal=1, trange=(-2*np.pi, 2*np.pi))
    phant3 = helix_phantom(px=(s,s,s), radius=radius, pitch=1000,
                          vox_dim=vox_dim, max_l=4, center=(0,0,0),
                          normal=2, trange=(-2*np.pi, 2*np.pi))
    phant.f[0:s,0:s,0:s] = phant1.f*scale[0]
    phant.f[s:2*s,s:2*s,s:2*s] = phant2.f*scale[1]
    phant.f[2*s:3*s,2*s:3*s,2*s:3*s] = phant3.f*scale[2]
    return phant
Пример #5
0
def bead(orientation=[1,0,0], kappa=None, px=(32,32,32), vox_dim=(100,100,100), sphere=None):
    # orientation sets the axis of rotational symmetry
    # kappa = None: all along single axis
    # kappa = 0: angularly uniform
    # kappa > 0: dumbbell
    # kappa < 0: pancake
    dims = px + (15,)
    f = np.zeros(dims, dtype=np.float32)
    spang1 = spang.Spang(f, vox_dim=vox_dim)
    dot = np.dot(orientation, spang1.sphere.vertices.T)
    if kappa is None:
        spang1.f[px[0]//2, px[1]//2, px[2]//2, :] = util.xyz_sft(orientation, max_l=4)
    else:
        watson = np.exp(kappa*dot**2)/(4*np.pi*hyp1f1(0.5, 1.5, kappa))
        watson_sh = np.matmul(spang1.B.T, watson)
        spang1.f[px[0]//2, px[1]//2, px[2]//2, :] = watson_sh
    
    return spang1
Пример #6
0
    os.makedirs(out_folder)

# Read data and save mips
vox_dim = (130, 130, 130)  # nm
data1 = data.Data(vox_dim=vox_dim, det_nas=[1.1, 0.71])
order = np.array([[2, 1, 0, 3], [2, 3, 0, 1]])
data1.read_tiff(in_folder, order=order)

# Specify voxel dimensions in nm
vox_dim_data = [130, 130, 130]
vox_dim_A = [130, 130, 549]
vox_dim_B = [227, 227, 835.8]

# Model for uniform distributions
# Build microscope model
spang1 = spang.Spang(f=np.zeros(data1.g.shape[0:3] + (15, )), vox_dim=vox_dim)
m = multi.MultiMicroscope(spang1,
                          data1,
                          n_samp=1.33,
                          lamb=525,
                          spang_coupling=True)

## NEW
# Measured values from fluorescent lake
# 561 calibration data. Values measured by hand from unifrom ROIs in
# /Volumes/lacie-win/2018-07-30-pol-dipsim in P0-P4 order (no swaps)
epi_cal = np.array([[8150, 8550, 8650, 8350], [16250, 16750, 17000, 16500]])
ls_cal = np.array([[6050, 5200, 4900, 5800], [9570, 7350, 6700, 8800]])

# Calculate expected values from fluorescent lake
lake_response = m.lake_response(data1)
Пример #7
0
# Generate data using forward model
# set "snr" to a positive number to simulate Poisson noise
data1.g = m.fwd(phant.f, snr=10)

# Save data
data1.save_mips(folder + 'data.pdf')
# try "diSPIM_format=False" for a 5D ImageJ hyperstack (pol = c, view = t)
data1.save_tiff(folder + 'data/', diSPIM_format=True)

# Calculate pseudoinverse solution
# set "eta" to a positive number for Tikhonov regularization
etas = 10**(np.linspace(-5, 0, 10))
errors = []
for i, eta in enumerate(etas):
    phant1 = spang.Spang(np.zeros(phant.f.shape))
    phant1.f = m.pinv(data1.g, eta=eta)

    # Calculate reconstruction statistics and save
    phant1.calc_stats()
    mask = phant.density > 0.1
    # phant.visualize(folder+'phantom-recon/', mask=mask, interact=False, video=True,
    #                 n_frames=15)

    phant1.save_stats(folder + 'phantom-recon-' + str(i) + '/')
    phant1.save_summary(folder + 'phantom-recon-' + str(i) + '.pdf', mask=mask)

    error = np.linalg.norm((phant1.f - phant.f).flatten())
    print(error)
    errors.append(error)