Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
9 changes: 1 addition & 8 deletions storm_analysis/L1H/setup_A_matrix.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,6 @@
import pickle
import scipy.io
from scipy.interpolate import griddata
import sys


def createCoordinates(inner_size, scale, boundary_scale, pad = [0,0]):
Expand Down Expand Up @@ -232,13 +231,7 @@ def loadAMatrix(file_name):

with open(file_name, 'rb') as fp:

# Python 3
if (sys.version_info > (3, 0)):
matrix = pickle.load(fp, encoding='latin1')

# Python 2
else:
matrix = pickle.load(fp)
matrix = pickle.load(fp, encoding='latin1')

return matrix

Expand Down
2 changes: 1 addition & 1 deletion storm_analysis/admm/admm_lasso_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ def newImage(self, image, background):
c_image = numpy.ascontiguousarray(image_no_bg, dtype=numpy.float64)
admm_lasso.newImage(self.c_admm_lasso, c_image)

def run(self, a_lamba, iterations):
def run(self, a_lambda, iterations):
admm_lasso.run(self.c_admm_lasso, a_lambda, iterations)


Expand Down
2 changes: 0 additions & 2 deletions storm_analysis/diagnostics/spliner_configure_common.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,8 +23,6 @@
import storm_analysis.spliner.measure_psf_utils as measurePSFUtils
import storm_analysis.spliner.psf_to_spline as psfToSpline

import storm_analysis.diagnostics.spliner.settings as settings


def configure(settings, use_dh, no_splines):

Expand Down
2 changes: 1 addition & 1 deletion storm_analysis/jupyter_examples/multiplane_measure_psf.py
Original file line number Diff line number Diff line change
Expand Up @@ -221,5 +221,5 @@ def sCMOSSingleFrameXML():
makeCMOSCalibration()
makeMapping()
makeSampleData()
sCMOSSinglePlaneXML()
sCMOSSingleFrameXML()

7 changes: 2 additions & 5 deletions storm_analysis/multi_plane/analysis_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,12 @@
"""
import numpy
import os
import sys

from xml.etree import ElementTree

import storm_analysis.sa_library.analysis_io as analysisIO
import storm_analysis.sa_library.sa_h5py as saH5Py
import storm_analysis.sa_library.static_background as static_background

import storm_analysis.multi_plane.mp_utilities as mpUtil

Expand Down Expand Up @@ -56,10 +56,7 @@ def __init__(self, parameters = None, sa_type = None, **kwds):

# Save analysis parameters.
etree = parameters.toXMLElementTree(False)
if (sys.version_info > (3, 0)):
self.h5.addMetadata(ElementTree.tostring(etree, 'unicode'))
else:
self.h5.addMetadata(ElementTree.tostring(etree, 'ISO-8859-1'))
self.h5.addMetadata(ElementTree.tostring(etree, 'unicode'))

# Save pixel size.
self.h5.setPixelSize(parameters.getAttr("pixel_size"))
Expand Down
6 changes: 3 additions & 3 deletions storm_analysis/multi_plane/fitting_mp.py
Original file line number Diff line number Diff line change
Expand Up @@ -600,9 +600,9 @@ def setVariances(self, variances):

# Save a pictures of the PSFs for debugging purposes.
if self.check_mode:
print("psf max", numpy.max(psf))
filename = "psf_z0.0_c{1:d}.tif".format(j)
tifffile.imwrite(filename, psf.astype(numpy.float32))
print("psf max", numpy.max(psf_norm))
filename = "psf_z0.0_c{0:d}.tif".format(i)
tifffile.imwrite(filename, psf_norm.astype(numpy.float32))

# This handles the rest of the initialization.
#
Expand Down
2 changes: 1 addition & 1 deletion storm_analysis/multi_plane/mp_fit_arb_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,7 +103,7 @@ def setWeights(self, weights, verbose = True):
"x" : numpy.ones((2, self.n_channels))/float(self.n_channels),
"y" : numpy.ones((2, self.n_channels))/float(self.n_channels),
"z" : numpy.ones((2, self.n_channels))/float(self.n_channels)}
super(MPSFFnFit, self).setWeights(weights, 0.0, 0.0, verbose = verbose)
super(MPPSFFnFit, self).setWeights(weights, 0.0, 0.0, verbose = verbose)

else:
zmax = self.psf_objects[0].getZMax() * 1.0e-3
Expand Down
1 change: 0 additions & 1 deletion storm_analysis/rolling_ball_bgr/rolling_ball_lib_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,6 @@
import scipy.ndimage

import ctypes
import numpy
from numpy.ctypeslib import ndpointer

import storm_analysis.sa_library.loadclib as loadclib
Expand Down
6 changes: 1 addition & 5 deletions storm_analysis/sa_library/analysis_io.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
"""
import numpy
import os
import sys

from xml.etree import ElementTree

Expand Down Expand Up @@ -156,10 +155,7 @@ def __init__(self, parameters = None, sa_type = None, **kwds):

# Save analysis parameters.
etree = parameters.toXMLElementTree(False)
if (sys.version_info > (3, 0)):
self.h5.addMetadata(ElementTree.tostring(etree, 'unicode'))
else:
self.h5.addMetadata(ElementTree.tostring(etree, 'ISO-8859-1'))
self.h5.addMetadata(ElementTree.tostring(etree, 'unicode'))

# Save pixel size.
self.h5.setPixelSize(parameters.getAttr("pixel_size"))
Expand Down
5 changes: 1 addition & 4 deletions storm_analysis/sa_library/loadclib.py
Original file line number Diff line number Diff line change
Expand Up @@ -44,10 +44,7 @@ def loadCLibrary(library_filename):
ctypes.windll.kernel32.SetErrorMode(0)

# Push the storm-analysis directory into the DLL search path.
if (sys.version_info > (3, 0)):
ctypes.windll.kernel32.SetDllDirectoryW(c_lib_path)
else:
ctypes.windll.kernel32.SetDllDirectoryW(unicode(c_lib_path))
ctypes.windll.kernel32.SetDllDirectoryW(c_lib_path)

# Try to load the library.
c_lib = ctypes.cdll.LoadLibrary(os.path.join(c_lib_path, library_filename))
Expand Down
6 changes: 1 addition & 5 deletions storm_analysis/sa_utilities/bin_to_hdf5.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
Hazen 12/17
"""
import os
import sys

from xml.etree import ElementTree

Expand Down Expand Up @@ -55,10 +54,7 @@ def BinToHDF5(bin_name, hdf5_name):

# Set metadata.
if params_xml is not None:
if (sys.version_info > (3, 0)):
h5.addMetadata(ElementTree.tostring(params_xml, 'unicode'))
else:
h5.addMetadata(ElementTree.tostring(params_xml, 'ISO-8859-1'))
h5.addMetadata(ElementTree.tostring(params_xml, 'unicode'))

# Convert data.
i3 = readinsight3.I3Reader(bin_name)
Expand Down
2 changes: 1 addition & 1 deletion storm_analysis/simulator/emitters_on_lines.py
Original file line number Diff line number Diff line change
Expand Up @@ -133,7 +133,7 @@ def emittersOnLines(h5_name, nlines, nemitters, sx = 256, sy = 256, maxl = 200,

emittersOnLines(args.hdf5,
args.nlines,
argls.nemitters,
args.nemitters,
sx = args.sx,
sy = args.sy,
maxl = args.maxl,
Expand Down
4 changes: 2 additions & 2 deletions storm_analysis/simulator/pupil_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -184,7 +184,7 @@ def aberrationOPD(self, z_stage, z_p, smp_index):
sin_theta_1 = (self.wavelength/self.imm_index)*self.k
theta_1 = numpy.arcsin(sin_theta_1 + 0j)

sin_theta_2 = (n1/n2)*sin_theta_1
sin_theta_2 = (self.imm_index/smp_index)*sin_theta_1
theta_2 = numpy.arcsin(sin_theta_2 + 0j)

z_o = smp_index/self.imm_index * z_stage
Expand All @@ -206,7 +206,7 @@ def aberrationOPD(self, z_stage, z_p, smp_index):
# decrease exponentially with increasing distance from coverslip.
#
pf_ab = numpy.exp(-1j * t4)
return self.appylNARestriction(pf_ab)
return self.applyNARestriction(pf_ab)

def applyNARestriction(self, pupil_fn):
"""
Expand Down
4 changes: 2 additions & 2 deletions storm_analysis/spliner/spline1D.py
Original file line number Diff line number Diff line change
Expand Up @@ -97,7 +97,7 @@ def f(self, x):

xv = []
yv = []
for i in range(x.size/10):
for i in range(x.size//10):
xv.append(x[i*10])
yv.append(y[i*10])
xv.append(x[-1])
Expand All @@ -120,5 +120,5 @@ def f(self, x):
pw.plot(x,ys)
#pw.plot(x,dxs)

raw_input("return to continue")
input("return to continue")

2 changes: 2 additions & 0 deletions storm_analysis/test/test_clusters_sa_h5py.py
Original file line number Diff line number Diff line change
Expand Up @@ -343,6 +343,8 @@ def test_cl_sa_h5py_7():
test_cl_sa_h5py_5()
test_cl_sa_h5py_6()
test_cl_sa_h5py_7()
test_cl_sa_h5py_z_is_loaded()
test_cl_sa_h5py_drops_invalid_z()



3 changes: 2 additions & 1 deletion storm_analysis/test/test_drift_correction.py
Original file line number Diff line number Diff line change
Expand Up @@ -480,7 +480,8 @@ def test_drift_correction_10():


if (__name__ == "__main__"):
_test_drift_correction_1()
test_drift_correction_1()
test_drift_correction_1_xy_failure()
test_drift_correction_2()
test_drift_correction_3()
test_drift_correction_4()
Expand Down
98 changes: 98 additions & 0 deletions storm_analysis/test/test_fitting_mp.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,98 @@
#!/usr/bin/env python
"""
Tests of multi_plane.fitting_mp
"""
import glob
import numpy
import os
import pickle
import tifffile

import storm_analysis
import storm_analysis.sa_library.fitting as fitting
import storm_analysis.sa_library.parameters as parameters

import storm_analysis.multi_plane.fitting_mp as fittingMp


im_size = (20, 18)
n_channels = 2


def configureTest():
"""
Build the parameters and the mapping file that MPPeakFinderDao needs.
"""
map_name = storm_analysis.getPathOutputTest("test_fitting_mp.map")

mappings = {}
for i in range(n_channels):
mappings["0_" + str(i) + "_x"] = numpy.array([0.0, 1.0, 0.0])
mappings["0_" + str(i) + "_y"] = numpy.array([0.0, 0.0, 1.0])
mappings[str(i) + "_0_x"] = numpy.array([0.0, 1.0, 0.0])
mappings[str(i) + "_0_y"] = numpy.array([0.0, 0.0, 1.0])
with open(map_name, "wb") as fp:
pickle.dump(mappings, fp)

params = parameters.ParametersMultiplaneDao()
params.setAttr("background_sigma", "float", 8.0)
params.setAttr("find_max_radius", "int", 2)
params.setAttr("foreground_sigma", "float", 1.5)
params.setAttr("iterations", "int", 1)
params.setAttr("mapping", "filename", map_name)
params.setAttr("no_fitting", "int", 0)
params.setAttr("pixel_size", "float", 100.0)
params.setAttr("roi_size", "int", 10)
params.setAttr("sigma", "float", 1.5)
params.setAttr("threshold", "float", 6.0)

return params


def test_fitting_mp_check_mode():
"""
MPPeakFinderDao.setVariances() saves a picture of each channel's PSF
when check_mode is on.

That block was copied from the arbitrary PSF version, where the PSF is
called 'psf' and the channel index is 'j'. Here the PSF is 'psf_norm'
and the index is 'i', so it raised NameError, and the filename kept
"{1:d}" from the two argument version, so it would have raised
IndexError once the names were fixed.
"""
params = configureTest()

# check_mode writes into the working directory.
cwd = os.getcwd()
os.chdir(storm_analysis.getPathOutputTest(""))
try:
for name in glob.glob("psf_z0.0_c*.tif"):
os.remove(name)

finder = fittingMp.MPPeakFinderDao(parameters = params,
n_channels = n_channels)
finder.check_mode = True

variances = [numpy.ones(im_size) for i in range(n_channels)]
finder.setVariances(variances)

# One image per channel, named by the channel index.
written = sorted(glob.glob("psf_z0.0_c*.tif"))
assert(written == ["psf_z0.0_c0.tif", "psf_z0.0_c1.tif"])

# And it is the normalized PSF that was saved, computed here
# independently of the finder. The variances are padded by the
# margin before the filters are built.
padded = (im_size[0] + 2*finder.margin, im_size[1] + 2*finder.margin)
expected = fitting.gaussianPSF(padded, 1.5).astype(numpy.float32)

for name in written:
psf = tifffile.imread(name)
assert(psf.shape == padded)
assert(numpy.allclose(psf, expected))
finally:
os.chdir(cwd)


if (__name__ == "__main__"):
test_fitting_mp_check_mode()
2 changes: 2 additions & 0 deletions storm_analysis/test/test_fitz_c.py
Original file line number Diff line number Diff line change
Expand Up @@ -271,4 +271,6 @@ def test_fitz_c_5():
test_fitz_c_3()
test_fitz_c_4()
test_fitz_c_5()
test_fitz_c_marker_survives_drift()
test_fitz_c_marker_propagates_to_tracks()

42 changes: 42 additions & 0 deletions storm_analysis/test/test_pupil_math.py
Original file line number Diff line number Diff line change
Expand Up @@ -82,9 +82,51 @@ def test_pupil_math_5():
psf_c = geo_c.pfToPSF(pf, z_vals, scaling_factor = gsf)


def test_pupil_math_aberration_opd():
"""
aberrationOPD() had two names wrong and could not run at all.

sin_theta_2 was computed from n1 and n2, neither of which exists, and
the return statement called self.appylNARestriction(). The first
raised NameError, and fixing only that moved the failure to an
AttributeError from the second.

Snell's law here is between the immersion medium and the sample,
which is what the sibling aberration() uses:

sin_theta_2 = (self.imm_index/smp_index)*sin_theta_1

This geometry deliberately puts most of the grid outside the NA, so
that the restriction being applied is observable rather than vacuous.
"""
geo = pupilMath.Geometry(32, 0.05, 0.6, 1.5, 1.2)

# applyNARestriction() masks on the normalized radius, geo.r > 1.0.
# geo.r_max is a different quantity, the NA edge in grid units.
outside = (geo.r > 1.0)
assert(numpy.count_nonzero(outside) > 0)

ab = geo.aberrationOPD(1.0, 0.5, 1.33)

assert(ab.shape == (32, 32))
assert(numpy.all(numpy.isfinite(ab)))

# applyNARestriction() zeros everything beyond the NA.
assert(numpy.all(ab[outside] == 0.0))
assert(numpy.any(ab[~outside] != 0.0))

# At zero defocus and a matched sample index there is no aberration,
# so the function is identically 1 inside the NA.
flat = geo.aberrationOPD(0.0, 0.0, 1.5)
assert(numpy.allclose(flat[~outside], 1.0 + 0j))


if (__name__ == "__main__"):
test_pupil_math_1()
test_pupil_math_2()
test_pupil_math_3()
test_pupil_math_4()
test_pupil_math_5()
test_pupil_math_aberration_opd()


Loading