# SIM Pattern Generator

### The Python version

From the SI of the paper:



In [1]:

%pylab inline
#nice plotting
#import seaborn as sns
import numexpr as ne
#for minimizing the difference between the desired frequency and the calculated one
from scipy.optimize import minimize
#Need to be able to do polynomial fitting
from sklearn.preprocessing import PolynomialFeatures
from sklearn import linear_model
#PIL allows us to write binary images, though we need a cludge, see 'Writing Binary Files.ipynb'
from PIL import Image
import os
import zipfile




Populating the interactive namespace from numpy and matplotlib




In [2]:

from scipy.ndimage import gaussian_filter




In [3]:

def pattern_gen(vecA, period, onfrac = 0.5, phase_idx = 0., phase_offset = 0., nphases =5, sizex =2048, sizey =1536, SIM_2D = True):
'''
Generates a binary SLM pattern for SIM

This function follows [Fiolka et al.][1] definition

Parameters
----------
x : array_like
the $\vec{a}$ from [1]. Defines the pattern orientation
period : float
Defines the period of the pattern
onfrac : float
The fraction of on pixels in the pattern
phase_idx : int
The phase of the pattern (see nphases for more info)
phase_offset : float
The offset in phase, mostly used for aligning patterns of different colors
nphases : int
the number of phases
sizex : int
size of the pattern
sizey : int
size of the pattern

Returns
-------
pattern : ndarray
A binary array representing a single bitplane to send to the SLM
'''

if not 0 < onfrac < 1:
raise ValueError('onfrac must have a value between 0 and 1. onfrac = {}'.format(onfrac))

vecN = np.array([[0,1],[-1,0]]).dot(vecA)
vecB = vecN/norm(vecN)*period
area = vecB.dot(vecN)
onpix = area*onfrac
phase_step = vecB/nphases

if SIM_2D:
#Then we only want to take steps of 2pi/n in illumination which means pi/n at the SLM
phase_step/=2

val = (phase_step*phase_idx+phase_offset/(2*pi)*vecB)

#xx, yy = meshgrid(arange(sizex,dtype=float32),arange(sizey,dtype=float32))
#my_grid = dstack((xx,yy))
#my_grid -= val

my_grid = indices((sizey,sizex),dtype=float)-val.reshape(2,1,1)

#Need to reshape to matrix because of BLAS (http://stackoverflow.com/questions/11856293/numpy-dot-product-very-slow-using-ints)
#mydot = my_grid.reshape(sizey*sizex,2).dot(vecN).reshape(sizey, sizex)
mydot = (my_grid.reshape(2,sizey*sizex).T).dot(vecN).reshape(sizey, sizex)
#mydot = my_grid.dot(vecN)
return mod(mydot,area) < onpix




In [4]:

def pattern_gen(vecA, period, onfrac = 0.5, phase_idx = 0., phase_offset = 0., nphases =5, sizex =2048, sizey =1536, SIM_2D = True):
'''
Generates a binary SLM pattern for SIM

This function follows [Fiolka et al.][1] definition

Parameters
----------
x : array_like
the $\vec{a}$ from [1]. Defines the pattern orientation
period : float
Defines the period of the pattern
onfrac : float
The fraction of on pixels in the pattern
phase_idx : int
The phase of the pattern (see nphases for more info)
phase_offset : float
The offset in phase, mostly used for aligning patterns of different colors
nphases : int
the number of phases
sizex : int
size of the pattern
sizey : int
size of the pattern

Returns
-------
pattern : ndarray
A binary array representing a single bitplane to send to the SLM
'''

if not 0 < onfrac < 1:
raise ValueError('onfrac must have a value between 0 and 1. onfrac = {}'.format(onfrac))

vecN = np.array([[0,1],[-1,0]]).dot(vecA)
vecB = vecN/norm(vecN)*period
area = vecB.dot(vecN)
onpix = area*onfrac
phase_step = vecB/nphases

if SIM_2D:
#Then we only want to take steps of 2pi/n in illumination which means pi/n at the SLM
phase_step/=2

val = (phase_step*phase_idx+phase_offset/(2*pi)*vecB)

xx, yy = meshgrid(arange(sizex,dtype=float32),arange(sizey,dtype=float32))
my_grid = dstack((xx,yy))
my_grid -= val

#Need to reshape to matrix because of BLAS (http://stackoverflow.com/questions/11856293/numpy-dot-product-very-slow-using-ints)
mydot = my_grid.reshape(sizey*sizex,2).dot(vecN).reshape(sizey, sizex)
#mydot = my_grid.dot(vecN)
return mod(mydot,area) < onpix




In [5]:

angle = [2,24]
pat =  pattern_gen(array(angle), 8, 0.5, 0, 0, 5,2048,2048)
pat_fft = fftshift(fftn(ifftshift(pat)))
figsize(10,10)
matshow(pat,cmap='Greys')
grid('off')
matshow(log(abs(pat_fft)+0.1),cmap='Greys')
grid('off')
matshow(log(gaussian_filter(abs(pat_fft),1)+0.1),cmap='Greys')
grid('off')







In [4]:

%%timeit
##comparison with mathematica
for i in range(3):
pat0 = pattern_gen([12, -1], 4.8277, 0.5, i, 0., 3, sizex = 1280, sizey = 1024)

name = 'pat-4.83256pixel-0.5DC-Ang0Ph{}_python.bmp'.format(i)
#convert to binary and save
pat_img = Image.fromarray((pat0*255).astype('uint8'),mode='L')
pat_img.convert('1').save(os.path.join(name))




1 loops, best of 3: 470 ms per loop




In [6]:

def angles(phi, num_angles, amp):
thetas = arange(0., num_angles)*pi/1./num_angles + phi
return np.round(amp*array([cos(thetas), sin(thetas)])).T




In [7]:

@vectorize
def angle_diff(phi, num_angles, amp):
my_angles = angles(phi,num_angles,amp)
return mean(abs(pi/num_angles - abs(diff(arctan2(my_angles[:,0],my_angles[:,1])))))




In [8]:

def print_best_angles(num_angles, amp):
x = linspace(0,pi/2,100*amp)
my_diffs = angle_diff(x,3,12)
b = argmin(my_diffs)
best_offset = x[b]
plot(x,my_diffs)
plot(best_offset, my_diffs[b],'o')

print_best_angles(3,12)







In [9]:

def best_angles(num_angles, amp):
x = linspace(0,2*pi,100*amp)
my_diffs = angle_diff(x,3,12)
best_offset = x[argmin(my_diffs)]
return angles(best_offset, num_angles, amp)




In [10]:

def ideal_period(wavelength, NA = 0.85):
'''
All units are in mm
'''
pixel_size = 8.2/1000 #pixel size in mm for QXGA display (4DD)
fl = 250 #focal length of lens in mm
fl2 = 300 #focal length of the second lens
ftube = 200 #focal length of the tube lens, for Nikon this is 200 mm
wl = wavelength/10**6 #wavelength of light
mag = 1/100
sigma = sqrt(2) * 12/pixel_size/4 #std dev of gaussian beam in units of pixels at the SLM
pupil_diameter = 2*NA*mag*fl2    #Size of pupil image at first fourier plane
hole_radius = 2*wl*fl/(2* pi * sigma *sqrt(2) * pixel_size) #this is the limit of hole size
hole_radius = 0.1/2# this is more reasonable (50 um)
period = wl * fl * (1/(pupil_diameter/2 - hole_radius))/ pixel_size #in mm

return period




In [11]:

def pattern_period(vecA, period, onfrac = 0.5, phaseInd = 0., phaseOffset = 0., nphases = 5, sizex =2048, sizey =1536):
'''
Find the precise pattern period

Using 2nd order polynomial fit along either axis
'''

#this is a standin for nextpow2, I don't know if there's a more efficient one, but its not going to
#be a bottle neck
n = 1<<(min(sizex,sizey)-1).bit_length()

my_pat = pattern_gen(vecA, period, onfrac, phaseInd, phaseOffset, nphases, n, n)

my_pat_fft = abs(fftshift(fftn(ifftshift(my_pat))))

#I don't know why the first argument is negative?
my_angle = arctan2(-vecA[0],vecA[1])

peak = np.round(n/(period/array([sin(my_angle), cos(my_angle)])))

#pull the 3x3 region around the peak
region_size = 3
start = -(region_size-1)/2
end = region_size+start

my_pat_fft_subx = my_pat_fft[n/2+peak[0]+start:n/2+peak[0]+end,n/2+peak[1]]
my_pat_fft_suby = my_pat_fft[n/2+peak[0],n/2+peak[1]+start:n/2+peak[1]+end]

x = arange(start,end)

xfit = polyfit(x, my_pat_fft_subx,2)
yfit = polyfit(x, my_pat_fft_suby,2)

x0 = -xfit[1]/(2*xfit[0])
y0 = -yfit[1]/(2*yfit[0])

#precisepeak = peak+poly2dmax(insert(clf.coef_,(3),0))
precisepeak = peak+[x0,y0]
#print(precisepeak)

preciseangle = arctan2(precisepeak[0],precisepeak[1])

#precise_period = n/norm(precisepeak)
precise_period = n/precisepeak[0]*sin(preciseangle)

#print('{:.20f}'.format(precise_period))

return precise_period




In [9]:

#testing different solvers, note that Nelder-Mead and Powell methods are the
#only ones that seem to work for this function.
def objf_l1(period, iperiod, size = 1024):
angle = array([1,12])
data = array([pattern_period(angle, period,phaseInd = n,sizex = size) for n in range(1)])
return mean(abs(data-iperiod))

def objf_l2(*args):
return objf_l1(*args)**2

%timeit minimize(objf_l1, 8.4,method='Powell',args=(ideal_period(568, 0.7),512))

%timeit minimize(objf_l2, 8.4,method='Powell',args=(ideal_period(568, 0.7),512))

res_l1_p = minimize(objf_l1, 8.4,method='Powell',args=(ideal_period(568, 0.7),512))

res_l2_p = minimize(objf_l2, 8.4,method='Powell',args=(ideal_period(568, 0.7),512))




1 loops, best of 3: 1.64 s per loop
1 loops, best of 3: 2.71 s per loop
1 loops, best of 3: 1.39 s per loop
1 loops, best of 3: 3.66 s per loop




In [10]:

print('x values')
print('L1-norm: Nelder-Mead = {}\tPowell = {}'.format(res_l1_nm['x'][0],res_l1_p['x']))
print('L2-norm: Nelder-Mead = {}\tPowell = {}'.format(res_l2_nm['x'][0],res_l2_p['x']))
print('Func Calls')
print('L1-norm: Nelder-Mead = {}\tPowell = {}'.format(res_l1_nm['nfev'],res_l1_p['nfev']))
print('L2-norm: Nelder-Mead = {}\tPowell = {}'.format(res_l2_nm['nfev'],res_l2_p['nfev']))
print('Differences')
print('L1-norm: Nelder-Mead - Powell = {}'.format(res_l1_nm['fun']-res_l1_p['fun']))
print('L1-norm: Nelder-Mead - Powell = {}'.format(res_l1_nm['fun']**2-res_l1_p['fun']**2))
print('L2-norm: Nelder-Mead - Powell = {}'.format(res_l2_nm['fun']-res_l2_p['fun']))




x values
L1-norm: Nelder-Mead = 8.436145019531251	Powell = 8.436047020234469
L2-norm: Nelder-Mead = 8.436145019531251	Powell = 8.436255263697804
Func Calls
L1-norm: Nelder-Mead = 33	Powell = 55
L2-norm: Nelder-Mead = 28	Powell = 73
Differences
L1-norm: Nelder-Mead - Powell = -0.0003552140126465986
L1-norm: Nelder-Mead - Powell = -1.4063966543938126e-07
L2-norm: Nelder-Mead - Powell = -3.68334662853476e-07



It looks like the simplex ('Nelder-Mead') algorithm is the best for this problem. Barring more complex convex methods.



In [24]:

iperiod = ideal_period(568,0.7)

def objf(period, iperiod, size = 1024):
return objf_l1(period, iperiod, size)/iperiod*100

x = linspace(iperiod-0.05,iperiod+0.05,101)
y512 = array([objf(period, iperiod,512) for period in x])
y1024 = array([objf(period, iperiod,1024) for period in x])
y2048 = array([objf(period, iperiod,2048) for period in x])




In [22]:

res_512 = minimize(objf, iperiod ,method='Nelder-Mead',args=(ideal_period(568, 0.7),512))
res_1024 = minimize(objf, iperiod ,method='Nelder-Mead',args=(ideal_period(568, 0.7),1024))
res_2048 = minimize(objf, iperiod ,method='Nelder-Mead',args=(ideal_period(568, 0.7),2048))




In [25]:

plot(x,y512,'b',label='512 x 512')
plot(res_512['x'],res_512['fun'],'bo')#,label='512 Optimized point')
plot(x,y1024,'r',label='1024 x 1024')
plot(res_1024['x'],res_1024['fun'],'ro')#,label='1024 Optimized point')
plot(x,y2048,'g',label='2048 x 2048')
plot(res_2048['x'],res_2048['fun'],'go')#,label='1024 Optimized point')
axis('tight')
axvline(iperiod,color='k',linestyle='dashed',label='Starting Point')
xlabel('Given Period')
ylabel('% Error')
legend(loc='best')
savefig("PeriodOpt.pdf")







In [12]:

def opt_period(iperiod,angle,**kwargs):
def objf_l1(period):
data = array([pattern_period(angle, period, **kwargs) for n in range(1)])
return mean(abs(data-iperiod))




In [16]:

%timeit opt_period(ideal_period(568, 0.85),array([1,12]))




1 loops, best of 3: 28.2 s per loop




In [17]:

my_per = opt_period(ideal_period(568, 0.7),array([1,12]))




In [18]:

pat = pattern_gen([1,12], my_per)

#this is cludgy but seems necessary.
pat_img = Image.fromarray((pat*255).astype('uint8'),mode='L')

#write the image
pat_img.convert('1').save('TestPat.bmp')




In [65]:

seq_dir = os.path.join('HHMI_R11_Seq')
seq_files = ['SEQUENCES']
i = 0
for file in os.listdir(seq_dir):
if '.seq11' in file:
seq_files.append(chr(65+i)+' "'+file+'"')
i += 1

seq_files.append('SEQUENCES_END')
print("\n".join(seq_files))




SEQUENCES
A "48070 HHMI 10ms.seq11"
B "48071 HHMI 50ms.seq11"
C "48075 HHMI 5ms.seq11"
D "48076 HHMI 20ms.seq11"
E "48077 HHMI 24 50ms.seq11"
F "48078 HHMI 24 1ms.seq11"
G "48083 HHMI 1ms 1-bit Lit Balanced.seq11"
H "48084 HHMI 2ms 1-bit Lit Balanced.seq11"
SEQUENCES_END




In [9]:

with zipfile.ZipFile('Rep568.repz11','r') as my_rep:
print(my_rep.namelist())
with my_rep.open('Rep568.rep') as rep:




['Rep568.rep', '48070 HHMI 10ms.seq11', '48071 HHMI 50ms.seq11', '48075 HHMI 5ms.seq11', '48076 HHMI 20ms.seq11', '48077 HHMI 24 50ms.seq11', '48078 HHMI 24 1ms.seq11', '48083 HHMI 1ms 1-bit Lit Balanced.seq11', '48084 HHMI 2ms 1-bit Lit Balanced.seq11', 'pat-6.92003pixel-0.5DC-Ang0Ph0.bmp', 'pat-6.92003pixel-0.5DC-Ang0Ph1.bmp', 'pat-6.92003pixel-0.5DC-Ang0Ph2.bmp', 'pat-6.92003pixel-0.5DC-Ang0Ph3.bmp', 'pat-6.92003pixel-0.5DC-Ang0Ph4.bmp', 'pat-6.92929pixel-0.5DC-Ang1Ph0.bmp', 'pat-6.92929pixel-0.5DC-Ang1Ph1.bmp', 'pat-6.92929pixel-0.5DC-Ang1Ph2.bmp', 'pat-6.92929pixel-0.5DC-Ang1Ph3.bmp', 'pat-6.92929pixel-0.5DC-Ang1Ph4.bmp', 'pat-6.93262pixel-0.5DC-Ang2Ph0.bmp', 'pat-6.93262pixel-0.5DC-Ang2Ph1.bmp', 'pat-6.93262pixel-0.5DC-Ang2Ph2.bmp', 'pat-6.93262pixel-0.5DC-Ang2Ph3.bmp', 'pat-6.93262pixel-0.5DC-Ang2Ph4.bmp', 'pat-7.36825pixel-0.5DC-Ang0Ph0.bmp', 'pat-7.36825pixel-0.5DC-Ang0Ph1.bmp', 'pat-7.36825pixel-0.5DC-Ang0Ph2.bmp', 'pat-7.36825pixel-0.5DC-Ang0Ph3.bmp', 'pat-7.36825pixel-0.5DC-Ang0Ph4.bmp', 'pat-7.36924pixel-0.5DC-Ang1Ph0.bmp', 'pat-7.36924pixel-0.5DC-Ang1Ph1.bmp', 'pat-7.36924pixel-0.5DC-Ang1Ph2.bmp', 'pat-7.36924pixel-0.5DC-Ang1Ph3.bmp', 'pat-7.36924pixel-0.5DC-Ang1Ph4.bmp', 'pat-7.383pixel-0.5DC-Ang2Ph0.bmp', 'pat-7.383pixel-0.5DC-Ang2Ph1.bmp', 'pat-7.383pixel-0.5DC-Ang2Ph2.bmp', 'pat-7.383pixel-0.5DC-Ang2Ph3.bmp', 'pat-7.383pixel-0.5DC-Ang2Ph4.bmp', 'pat-7.56204pixel-0.5DC-Ang0Ph0.bmp', 'pat-7.56204pixel-0.5DC-Ang0Ph1.bmp', 'pat-7.56204pixel-0.5DC-Ang0Ph2.bmp', 'pat-7.56204pixel-0.5DC-Ang0Ph3.bmp', 'pat-7.56204pixel-0.5DC-Ang0Ph4.bmp', 'pat-7.56204pixel-0.5DC-Ang1Ph0.bmp', 'pat-7.56204pixel-0.5DC-Ang1Ph1.bmp', 'pat-7.56204pixel-0.5DC-Ang1Ph2.bmp', 'pat-7.56204pixel-0.5DC-Ang1Ph3.bmp', 'pat-7.56204pixel-0.5DC-Ang1Ph4.bmp', 'pat-7.56204pixel-0.5DC-Ang2Ph0.bmp', 'pat-7.56204pixel-0.5DC-Ang2Ph1.bmp', 'pat-7.56204pixel-0.5DC-Ang2Ph2.bmp', 'pat-7.56204pixel-0.5DC-Ang2Ph3.bmp', 'pat-7.56204pixel-0.5DC-Ang2Ph4.bmp', 'pat-7.8714pixel-0.5DC-Ang0Ph0.bmp', 'pat-7.8714pixel-0.5DC-Ang0Ph1.bmp', 'pat-7.8714pixel-0.5DC-Ang0Ph2.bmp', 'pat-7.8714pixel-0.5DC-Ang0Ph3.bmp', 'pat-7.8714pixel-0.5DC-Ang0Ph4.bmp', 'pat-7.8714pixel-0.5DC-Ang1Ph0.bmp', 'pat-7.8714pixel-0.5DC-Ang1Ph1.bmp', 'pat-7.8714pixel-0.5DC-Ang1Ph2.bmp', 'pat-7.8714pixel-0.5DC-Ang1Ph3.bmp', 'pat-7.8714pixel-0.5DC-Ang1Ph4.bmp', 'pat-7.8714pixel-0.5DC-Ang2Ph0.bmp', 'pat-7.8714pixel-0.5DC-Ang2Ph1.bmp', 'pat-7.8714pixel-0.5DC-Ang2Ph2.bmp', 'pat-7.8714pixel-0.5DC-Ang2Ph3.bmp', 'pat-7.8714pixel-0.5DC-Ang2Ph4.bmp', 'pat-8.44735pixel-0.5DC-Ang0Ph0.bmp', 'pat-8.44735pixel-0.5DC-Ang0Ph1.bmp', 'pat-8.44735pixel-0.5DC-Ang0Ph2.bmp', 'pat-8.44735pixel-0.5DC-Ang0Ph3.bmp', 'pat-8.44735pixel-0.5DC-Ang0Ph4.bmp', 'pat-8.44735pixel-0.5DC-Ang1Ph0.bmp', 'pat-8.44735pixel-0.5DC-Ang1Ph1.bmp', 'pat-8.44735pixel-0.5DC-Ang1Ph2.bmp', 'pat-8.44735pixel-0.5DC-Ang1Ph3.bmp', 'pat-8.44735pixel-0.5DC-Ang1Ph4.bmp', 'pat-8.44735pixel-0.5DC-Ang2Ph0.bmp', 'pat-8.44735pixel-0.5DC-Ang2Ph1.bmp', 'pat-8.44735pixel-0.5DC-Ang2Ph2.bmp', 'pat-8.44735pixel-0.5DC-Ang2Ph3.bmp', 'pat-8.44735pixel-0.5DC-Ang2Ph4.bmp']
SEQUENCES
A "48070 HHMI 10ms.seq11"
B "48071 HHMI 50ms.seq11"
C "48075 HHMI 5ms.seq11"
D "48076 HHMI 20ms.seq11"
E "48077 HHMI 24 50ms.seq11"
F "48078 HHMI 24 1ms.seq11"
G "48083 HHMI 1ms 1-bit Lit Balanced.seq11"
H "48084 HHMI 2ms 1-bit Lit Balanced.seq11"
SEQUENCES_END

IMAGES
1 "pat-6.92003pixel-0.5DC-Ang0Ph0.bmp"
1 "pat-6.92003pixel-0.5DC-Ang0Ph1.bmp"
1 "pat-6.92003pixel-0.5DC-Ang0Ph2.bmp"
1 "pat-6.92003pixel-0.5DC-Ang0Ph3.bmp"
1 "pat-6.92003pixel-0.5DC-Ang0Ph4.bmp"
1 "pat-6.92929pixel-0.5DC-Ang1Ph0.bmp"
1 "pat-6.92929pixel-0.5DC-Ang1Ph1.bmp"
1 "pat-6.92929pixel-0.5DC-Ang1Ph2.bmp"
1 "pat-6.92929pixel-0.5DC-Ang1Ph3.bmp"
1 "pat-6.92929pixel-0.5DC-Ang1Ph4.bmp"
1 "pat-6.93262pixel-0.5DC-Ang2Ph0.bmp"
1 "pat-6.93262pixel-0.5DC-Ang2Ph1.bmp"
1 "pat-6.93262pixel-0.5DC-Ang2Ph2.bmp"
1 "pat-6.93262pixel-0.5DC-Ang2Ph3.bmp"
1 "pat-6.93262pixel-0.5DC-Ang2Ph4.bmp"
1 "pat-7.36825pixel-0.5DC-Ang0Ph0.bmp"
1 "pat-7.36825pixel-0.5DC-Ang0Ph1.bmp"
1 "pat-7.36825pixel-0.5DC-Ang0Ph2.bmp"
1 "pat-7.36825pixel-0.5DC-Ang0Ph3.bmp"
1 "pat-7.36825pixel-0.5DC-Ang0Ph4.bmp"
1 "pat-7.36924pixel-0.5DC-Ang1Ph0.bmp"
1 "pat-7.36924pixel-0.5DC-Ang1Ph1.bmp"
1 "pat-7.36924pixel-0.5DC-Ang1Ph2.bmp"
1 "pat-7.36924pixel-0.5DC-Ang1Ph3.bmp"
1 "pat-7.36924pixel-0.5DC-Ang1Ph4.bmp"
1 "pat-7.383pixel-0.5DC-Ang2Ph0.bmp"
1 "pat-7.383pixel-0.5DC-Ang2Ph1.bmp"
1 "pat-7.383pixel-0.5DC-Ang2Ph2.bmp"
1 "pat-7.383pixel-0.5DC-Ang2Ph3.bmp"
1 "pat-7.383pixel-0.5DC-Ang2Ph4.bmp"
1 "pat-7.56204pixel-0.5DC-Ang0Ph0.bmp"
1 "pat-7.56204pixel-0.5DC-Ang0Ph1.bmp"
1 "pat-7.56204pixel-0.5DC-Ang0Ph2.bmp"
1 "pat-7.56204pixel-0.5DC-Ang0Ph3.bmp"
1 "pat-7.56204pixel-0.5DC-Ang0Ph4.bmp"
1 "pat-7.56204pixel-0.5DC-Ang1Ph0.bmp"
1 "pat-7.56204pixel-0.5DC-Ang1Ph1.bmp"
1 "pat-7.56204pixel-0.5DC-Ang1Ph2.bmp"
1 "pat-7.56204pixel-0.5DC-Ang1Ph3.bmp"
1 "pat-7.56204pixel-0.5DC-Ang1Ph4.bmp"
1 "pat-7.56204pixel-0.5DC-Ang2Ph0.bmp"
1 "pat-7.56204pixel-0.5DC-Ang2Ph1.bmp"
1 "pat-7.56204pixel-0.5DC-Ang2Ph2.bmp"
1 "pat-7.56204pixel-0.5DC-Ang2Ph3.bmp"
1 "pat-7.56204pixel-0.5DC-Ang2Ph4.bmp"
1 "pat-7.8714pixel-0.5DC-Ang0Ph0.bmp"
1 "pat-7.8714pixel-0.5DC-Ang0Ph1.bmp"
1 "pat-7.8714pixel-0.5DC-Ang0Ph2.bmp"
1 "pat-7.8714pixel-0.5DC-Ang0Ph3.bmp"
1 "pat-7.8714pixel-0.5DC-Ang0Ph4.bmp"
1 "pat-7.8714pixel-0.5DC-Ang1Ph0.bmp"
1 "pat-7.8714pixel-0.5DC-Ang1Ph1.bmp"
1 "pat-7.8714pixel-0.5DC-Ang1Ph2.bmp"
1 "pat-7.8714pixel-0.5DC-Ang1Ph3.bmp"
1 "pat-7.8714pixel-0.5DC-Ang1Ph4.bmp"
1 "pat-7.8714pixel-0.5DC-Ang2Ph0.bmp"
1 "pat-7.8714pixel-0.5DC-Ang2Ph1.bmp"
1 "pat-7.8714pixel-0.5DC-Ang2Ph2.bmp"
1 "pat-7.8714pixel-0.5DC-Ang2Ph3.bmp"
1 "pat-7.8714pixel-0.5DC-Ang2Ph4.bmp"
1 "pat-8.44735pixel-0.5DC-Ang0Ph0.bmp"
1 "pat-8.44735pixel-0.5DC-Ang0Ph1.bmp"
1 "pat-8.44735pixel-0.5DC-Ang0Ph2.bmp"
1 "pat-8.44735pixel-0.5DC-Ang0Ph3.bmp"
1 "pat-8.44735pixel-0.5DC-Ang0Ph4.bmp"
1 "pat-8.44735pixel-0.5DC-Ang1Ph0.bmp"
1 "pat-8.44735pixel-0.5DC-Ang1Ph1.bmp"
1 "pat-8.44735pixel-0.5DC-Ang1Ph2.bmp"
1 "pat-8.44735pixel-0.5DC-Ang1Ph3.bmp"
1 "pat-8.44735pixel-0.5DC-Ang1Ph4.bmp"
1 "pat-8.44735pixel-0.5DC-Ang2Ph0.bmp"
1 "pat-8.44735pixel-0.5DC-Ang2Ph1.bmp"
1 "pat-8.44735pixel-0.5DC-Ang2Ph2.bmp"
1 "pat-8.44735pixel-0.5DC-Ang2Ph3.bmp"
1 "pat-8.44735pixel-0.5DC-Ang2Ph4.bmp"
IMAGES_END

"NA 0.85 5 phases 1 angle"
[HWA

<t(A,0) >
{f (A,0) }
<t(A,1) >
{f (A,1) }
<t(A,2) >
{f (A,2) }
<t(A,3) >
{f (A,3) }
<t(A,4) >
{f (A,4) }
]

"NA 0.80 5 phases 1 angle"
[HWA

<t(A,15) >
{f (A,15) }
<t(A,16) >
{f (A,16) }
<t(A,17) >
{f (A,17) }
<t(A,18) >
{f (A,18) }
<t(A,19) >
{f (A,19) }
]

"NA 0.78 5 phases 1 angle"
[HWA

<t(A,30) >
{f (A,30) }
<t(A,31) >
{f (A,31) }
<t(A,32) >
{f (A,32) }
<t(A,33) >
{f (A,33) }
<t(A,34) >
{f (A,34) }
]

"NA 0.85 3 angles no trig"
[HWA

{(G,0) (G,5) (G,10) }
]

DEFAULT "NA 0.80 3 angles no trig"
[HWA

{(G,15) (G,20) (G,25) }
]

"NA 0.78 3 angles no trig"
[HWA

{(G,30) (G,35) (G,40) }
]

"NA 0.85 1 angles no trig"
[HWA

{(G,0) }
]

"NA 0.80 1 angles no trig"
[HWA

{(G,15) }
]

"NA 0.78 1 angles no trig"
[HWA

{(G,36) }
]

"Linear SIM 0.85 NA"
[HWA

<t(B,0) >
{f (B,0) }
<t(B,1) >
{f (B,1) }
<t(B,2) >
{f (B,2) }
<t(B,3) >
{f (B,3) }
<t(B,4) >
{f (B,4) }
<t(B,5) >
{f (B,5) }
<t(B,6) >
{f (B,6) }
<t(B,7) >
{f (B,7) }
<t(B,8) >
{f (B,8) }
<t(B,9) >
{f (B,9) }
<t(B,10) >
{f (B,10) }
<t(B,11) >
{f (B,11) }
<t(B,12) >
{f (B,12) }
<t(B,13) >
{f (B,13) }
<t(B,14) >
{f (B,14) }
]

"Linear SIM 0.80 NA"
[HWA

<t(B,15) >
{f (B,15) }
<t(B,16) >
{f (B,16) }
<t(B,17) >
{f (B,17) }
<t(B,18) >
{f (B,18) }
<t(B,19) >
{f (B,19) }
<t(B,20) >
{f (B,20) }
<t(B,21) >
{f (B,21) }
<t(B,22) >
{f (B,22) }
<t(B,23) >
{f (B,23) }
<t(B,24) >
{f (B,24) }
<t(B,25) >
{f (B,25) }
<t(B,26) >
{f (B,26) }
<t(B,27) >
{f (B,27) }
<t(B,28) >
{f (B,28) }
<t(B,29) >
{f (B,29) }
]

"Linear SIM 0.78 NA"
[HWA

<t(B,30) >
{f (B,30) }
<t(B,31) >
{f (B,31) }
<t(B,32) >
{f (B,32) }
<t(B,33) >
{f (B,33) }
<t(B,34) >
{f (B,34) }
<t(B,35) >
{f (B,35) }
<t(B,36) >
{f (B,36) }
<t(B,37) >
{f (B,37) }
<t(B,38) >
{f (B,38) }
<t(B,39) >
{f (B,39) }
<t(B,40) >
{f (B,40) }
<t(B,41) >
{f (B,41) }
<t(B,42) >
{f (B,42) }
<t(B,43) >
{f (B,43) }
<t(B,44) >
{f (B,44) }
]




In [13]:

'''
We can use sets as a way to keep track of images and sequences.

Images and sequences will be denoted by strings referring to the actual file name

A repetoire will only contain a list of RunningOrders and have a method to write out running orders.

It should also have the ability to read in a .rep file

Need a method to return a given running order, by name
'''

class RunningOrder(object):
'''
A class representing a running order for a 4DD SLM
'''

def __init__(self, name, triggered = True):
self._name = name
#we want these properties to be immutable and we don't want duplicates
self._sequences = set()
self._bitplanes = set()
self.triggered = triggered
self._RO = []

@property
def name(self):
return self._name

@property
def sequences(self):
return self._sequences

@property
def bitplanes(self):
return self._bitplanes

@property
def RO(self):
return self._RO

def addbitplane(self, sequence, bitplane, position = None):
'''
A function to add sequence bitplane pairs to a running order
'''

seq_bp = {'sequence' : sequence, 'bitplane' : bitplane}

if position is None:
self._RO.append(seq_bp)
else:
self._RO.insert(position, seq_bp)

class Repetoire(object):
'''
This object holds a list of Running orders. It has the ability to output .rep files

Further functionality will be to read in .rep files.
'''

def __init__(self, listofROs = None):
self._ROs = []
self._sequences = set()
self._bitplanes = set()
if listofROs is not None:
for RO in listofROs:

if isinstance(RO, list):

if not isinstance(RO, RunningOrder):
raise TypeError('Not a RunningOrder')
else:
self._ROs.append(RO)
self._sequences |= RO.sequences
self._bitplanes |= RO.bitplanes

def __str__(self):
'''
This function writes the repetoire
'''

toreturn = ''

#If ROs is empty
if not len(self._ROs):

####################
# MAKING SEQUENCES #
####################

#need to save the letter assignments
seq_dict = {}

seqs = ['SEQUENCES']
for i, seq in enumerate(sorted(self._sequences)):
char = chr(65+i)
seqs.append(char+' "'+seq+'"')
seq_dict[seq] = char

seqs.append('SEQUENCES_END\n\n')

toreturn = "\n".join(seqs)

####################
# MAKING BITPLANES #
####################

bp_dict = {}
bps = ['IMAGES']
for i, bp in enumerate(sorted(self._bitplanes)):
bps.append('1 "'+bp+'"')
bp_dict[bp] = i

bps.append('IMAGES_END\n\n')

toreturn += "\n".join(bps)

#Need to have at least one RunningOrder be Default, why not the first one?
#If no DEFAULT then MetroCon will continue to look for one and fail.
toreturn += 'DEFAULT '
#sort the RunningOrders by name
for RO in self._ROs:#.sort(key=lambda x: x.name):
toreturn += self._writeRO(RO, seq_dict, bp_dict)

@staticmethod
def _writeRO(RO, seq_dict, bp_dict):
'''
This function will write the repetoire based on the sequence dict and image dict

It assumes that all that is wanted is standard SIM sequences
'''

toreturn = ['"{}"'.format(RO.name)]

toreturn.append('[HWA\n')

if not RO.triggered:
toappend = ' {'

for seq_bp in RO.RO:
seq = seq_bp['sequence']
bp = seq_bp['bitplane']
if RO.triggered:
toreturn.append(' <t({0},{1}) >\n {{f ({0},{1}) }}'.format(seq_dict[seq],bp_dict[bp]))
else:
toappend += '({0},{1}) '.format(seq_dict[seq],bp_dict[bp])

if not RO.triggered:
toappend += '}'
toreturn.append(toappend)

toreturn.append(']\n\n')

return '\n'.join(toreturn)




In [64]:

my_seqs = ['test_seq{}.seq11'.format(i) for i in range(5)]
my_bps = ['test_bp{}.bmp'.format(i) for i in range(5)]

ROlist = []

for seq in my_seqs:
my_RO = RunningOrder('My Running Order for {}'.format(seq),triggered=False)
for bp in my_bps:
ROlist.append(my_RO)

my_Rep = Repetoire(ROlist)




In [65]:

print(my_Rep)




SEQUENCES
A "test_seq0.seq11"
B "test_seq1.seq11"
C "test_seq2.seq11"
D "test_seq3.seq11"
E "test_seq4.seq11"
SEQUENCES_END

IMAGES
1 "test_bp0.bmp"
1 "test_bp1.bmp"
1 "test_bp2.bmp"
1 "test_bp3.bmp"
1 "test_bp4.bmp"
IMAGES_END

DEFAULT "My Running Order for test_seq0.seq11"
[HWA

{(A,0) (A,1) (A,2) (A,3) (A,4) }
]

"My Running Order for test_seq1.seq11"
[HWA

{(B,0) (B,1) (B,2) (B,3) (B,4) }
]

"My Running Order for test_seq2.seq11"
[HWA

{(C,0) (C,1) (C,2) (C,3) (C,4) }
]

"My Running Order for test_seq3.seq11"
[HWA

{(D,0) (D,1) (D,2) (D,3) (D,4) }
]

"My Running Order for test_seq4.seq11"
[HWA

{(E,0) (E,1) (E,2) (E,3) (E,4) }
]




In [104]:

with open('test.txt','w') as test:
test.write(str(my_Rep))




In [30]:

for x in linspace(0.78,0.85,8):
print(x)




0.78
0.79
0.8
0.81
0.82
0.83
0.84
0.85




In [17]:

from matplotlib.patches import Circle, Wedge, Polygon




In [18]:

fig,ax = subplots(1,1,squeeze=True, figsize=(6,6))
circle = Circle((0,0),12,fill=False)
ax.set_xlim(-15,15)
ax.set_ylim(-15,15)
colors = ('r','k','b')
for ang, c in zip([[1,12],[11, 5], [-10,7]],colors):







In [15]:

best_angles(3,12)




Out[15]:

array([[  1.,  12.],
[-10.,   7.],
[-11.,  -5.]])




In [29]:

fig,ax = subplots(1,1,squeeze=True, figsize=(6,6))
circle = Circle((0,0),1,fill=False)
ax.set_xlim(-1.5,1.5)
ax.set_ylim(-1.5,1.5)
colors = ('r','g','b')
ax.invert_yaxis()
for i in range(10,21):
for ang, c in zip(best_angles(3,i),colors):
ang /= norm(ang)
figsize(5,5)
#pat =  pattern_gen(array(ang), 8, 0.5, 0, 0, 5,128,128)
#matshow(pat,cmap='Greys')







In [19]:

##Regular SIM for 488 and 561
onfrac = 0.5
my_angles = best_angles(3,12)

num_phases = 3

name = 'SIM 2D 488 and 561'

#open zip file, make sure the compression is set to ZIP_DEFLATED (8)
with zipfile.ZipFile('{}.repz11'.format(name), 'w', compression=zipfile.ZIP_DEFLATED) as myzip:

opt = True

my_dir = os.path.join(name,'')
if not os.path.isdir(my_dir):
print('Making '+my_dir)
os.mkdir(my_dir)

NAs = linspace(0.78,0.85,8)

ROlist = []

seq = '48070 HHMI 10ms.seq11'

myzip.write(os.path.join('HHMI_R11_Seq',seq),arcname=seq)

for wl in [488, 561]:
for NA in NAs:
print('{} NA {}'.format(wl, NA))

iperiod = ideal_period(wl,NA=NA)
super_RO = RunningOrder('{} SIM NA {}'.format(wl,NA))

RO_all_t = RunningOrder('{} NA {} All Orientations Triggered'.format(wl,NA))
RO_all = RunningOrder('{} NA {} All Orientations'.format(wl,NA),triggered=False)

patall =zeros((1536, 2048)).astype(bool)

for angle in my_angles:

#calculate degree from angle for filename
degree = arctan2(angle[0],angle[1])*180/pi

RO1orient = RunningOrder('{} NA {} {:+.2f} degrees'.format(wl, NA, degree), triggered=False)

#optimize the angle
if opt:
print('Optimizing angle = {:+.2f} degrees'.format(degree))
my_per = opt_period(iperiod,angle)
else:
my_per = iperiod

for phase in range(num_phases):
#generate pattern
pat = pattern_gen(angle, my_per,onfrac=onfrac,phase_idx=phase,nphases=num_phases)

#make image object
pat_img = Image.fromarray((pat*255).astype('uint8'),mode='L')

#generate filename, put orientation in front, so that its consistent
name = 'pat-{:.2f}NA{:+.1f}deg-{:02d}ph-{:.4f}pix-{:.2f}DC.bmp'.format(NA, degree,phase,my_per[0],onfrac)

#convert to binary and save
pat_img.convert('1').save(os.path.join(my_dir,name))

#move to zip file and save
myzip.write(os.path.join(my_dir,name),arcname=name)

if not phase:
patall |= pat

print('Wrote file: {}'.format(name))

ROlist.append(RO1orient)

#make image object for all
patall_img = Image.fromarray((patall*255).astype('uint8'),mode='L')

#generate filename, put orientation in front, so that its consistent
nameall = 'pat-{:.2f}NA-{:.4f}pix-{:.2f}DC_allangles.bmp'.format(NA,my_per[0],onfrac)

#convert to binary and save
patall_img.convert('1').save(os.path.join(my_dir,nameall))

#move to zip file and save
myzip.write(os.path.join(my_dir,nameall),arcname=nameall)

ROlist.append(super_RO)
ROlist.append(RO_all_t)
ROlist.append(RO_all)

my_Rep = Repetoire(ROlist)

#write the rep file
with open(os.path.join(my_dir,'{}.rep'.format(name)),'w') as repfile:
repfile.write(str(my_Rep))

#now add the file to the zip
myzip.write(os.path.join(my_dir,'{}.rep'.format(name)),arcname='{}.rep'.format(name))

print(my_Rep)




Making SIM 2D 488 and 561\
488 NA 0.78
Optimizing angle = +4.76 degrees
Wrote file: pat-0.78NA+4.8deg-00ph-6.4920pix-0.50DC.bmp
Wrote file: pat-0.78NA+4.8deg-01ph-6.4920pix-0.50DC.bmp
Wrote file: pat-0.78NA+4.8deg-02ph-6.4920pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.78NA-55.0deg-00ph-6.4949pix-0.50DC.bmp
Wrote file: pat-0.78NA-55.0deg-01ph-6.4949pix-0.50DC.bmp
Wrote file: pat-0.78NA-55.0deg-02ph-6.4949pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.78NA-114.4deg-00ph-6.4953pix-0.50DC.bmp
Wrote file: pat-0.78NA-114.4deg-01ph-6.4953pix-0.50DC.bmp
Wrote file: pat-0.78NA-114.4deg-02ph-6.4953pix-0.50DC.bmp
488 NA 0.79
Optimizing angle = +4.76 degrees
Wrote file: pat-0.79NA+4.8deg-00ph-6.4094pix-0.50DC.bmp
Wrote file: pat-0.79NA+4.8deg-01ph-6.4094pix-0.50DC.bmp
Wrote file: pat-0.79NA+4.8deg-02ph-6.4094pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.79NA-55.0deg-00ph-6.4147pix-0.50DC.bmp
Wrote file: pat-0.79NA-55.0deg-01ph-6.4147pix-0.50DC.bmp
Wrote file: pat-0.79NA-55.0deg-02ph-6.4147pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.79NA-114.4deg-00ph-6.4161pix-0.50DC.bmp
Wrote file: pat-0.79NA-114.4deg-01ph-6.4161pix-0.50DC.bmp
Wrote file: pat-0.79NA-114.4deg-02ph-6.4161pix-0.50DC.bmp
488 NA 0.8
Optimizing angle = +4.76 degrees
Wrote file: pat-0.80NA+4.8deg-00ph-6.3290pix-0.50DC.bmp
Wrote file: pat-0.80NA+4.8deg-01ph-6.3290pix-0.50DC.bmp
Wrote file: pat-0.80NA+4.8deg-02ph-6.3290pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.80NA-55.0deg-00ph-6.3312pix-0.50DC.bmp
Wrote file: pat-0.80NA-55.0deg-01ph-6.3312pix-0.50DC.bmp
Wrote file: pat-0.80NA-55.0deg-02ph-6.3312pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.80NA-114.4deg-00ph-6.3312pix-0.50DC.bmp
Wrote file: pat-0.80NA-114.4deg-01ph-6.3312pix-0.50DC.bmp
Wrote file: pat-0.80NA-114.4deg-02ph-6.3312pix-0.50DC.bmp
488 NA 0.81
Optimizing angle = +4.76 degrees
Wrote file: pat-0.81NA+4.8deg-00ph-6.2509pix-0.50DC.bmp
Wrote file: pat-0.81NA+4.8deg-01ph-6.2509pix-0.50DC.bmp
Wrote file: pat-0.81NA+4.8deg-02ph-6.2509pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.81NA-55.0deg-00ph-6.2498pix-0.50DC.bmp
Wrote file: pat-0.81NA-55.0deg-01ph-6.2498pix-0.50DC.bmp
Wrote file: pat-0.81NA-55.0deg-02ph-6.2498pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.81NA-114.4deg-00ph-6.2490pix-0.50DC.bmp
Wrote file: pat-0.81NA-114.4deg-01ph-6.2490pix-0.50DC.bmp
Wrote file: pat-0.81NA-114.4deg-02ph-6.2490pix-0.50DC.bmp
488 NA 0.82
Optimizing angle = +4.76 degrees
Wrote file: pat-0.82NA+4.8deg-00ph-6.1750pix-0.50DC.bmp
Wrote file: pat-0.82NA+4.8deg-01ph-6.1750pix-0.50DC.bmp
Wrote file: pat-0.82NA+4.8deg-02ph-6.1750pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.82NA-55.0deg-00ph-6.1751pix-0.50DC.bmp
Wrote file: pat-0.82NA-55.0deg-01ph-6.1751pix-0.50DC.bmp
Wrote file: pat-0.82NA-55.0deg-02ph-6.1751pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.82NA-114.4deg-00ph-6.1681pix-0.50DC.bmp
Wrote file: pat-0.82NA-114.4deg-01ph-6.1681pix-0.50DC.bmp
Wrote file: pat-0.82NA-114.4deg-02ph-6.1681pix-0.50DC.bmp
488 NA 0.83
Optimizing angle = +4.76 degrees
Wrote file: pat-0.83NA+4.8deg-00ph-6.1005pix-0.50DC.bmp
Wrote file: pat-0.83NA+4.8deg-01ph-6.1005pix-0.50DC.bmp
Wrote file: pat-0.83NA+4.8deg-02ph-6.1005pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.83NA-55.0deg-00ph-6.0979pix-0.50DC.bmp
Wrote file: pat-0.83NA-55.0deg-01ph-6.0979pix-0.50DC.bmp
Wrote file: pat-0.83NA-55.0deg-02ph-6.0979pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.83NA-114.4deg-00ph-6.1014pix-0.50DC.bmp
Wrote file: pat-0.83NA-114.4deg-01ph-6.1014pix-0.50DC.bmp
Wrote file: pat-0.83NA-114.4deg-02ph-6.1014pix-0.50DC.bmp
488 NA 0.84
Optimizing angle = +4.76 degrees
Wrote file: pat-0.84NA+4.8deg-00ph-6.0273pix-0.50DC.bmp
Wrote file: pat-0.84NA+4.8deg-01ph-6.0273pix-0.50DC.bmp
Wrote file: pat-0.84NA+4.8deg-02ph-6.0273pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.84NA-55.0deg-00ph-6.0242pix-0.50DC.bmp
Wrote file: pat-0.84NA-55.0deg-01ph-6.0242pix-0.50DC.bmp
Wrote file: pat-0.84NA-55.0deg-02ph-6.0242pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.84NA-114.4deg-00ph-6.0242pix-0.50DC.bmp
Wrote file: pat-0.84NA-114.4deg-01ph-6.0242pix-0.50DC.bmp
Wrote file: pat-0.84NA-114.4deg-02ph-6.0242pix-0.50DC.bmp
488 NA 0.85
Optimizing angle = +4.76 degrees
Wrote file: pat-0.85NA+4.8deg-00ph-5.9554pix-0.50DC.bmp
Wrote file: pat-0.85NA+4.8deg-01ph-5.9554pix-0.50DC.bmp
Wrote file: pat-0.85NA+4.8deg-02ph-5.9554pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.85NA-55.0deg-00ph-5.9487pix-0.50DC.bmp
Wrote file: pat-0.85NA-55.0deg-01ph-5.9487pix-0.50DC.bmp
Wrote file: pat-0.85NA-55.0deg-02ph-5.9487pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.85NA-114.4deg-00ph-5.9481pix-0.50DC.bmp
Wrote file: pat-0.85NA-114.4deg-01ph-5.9481pix-0.50DC.bmp
Wrote file: pat-0.85NA-114.4deg-02ph-5.9481pix-0.50DC.bmp
561 NA 0.78
Optimizing angle = +4.76 degrees
Wrote file: pat-0.78NA+4.8deg-00ph-7.4641pix-0.50DC.bmp
Wrote file: pat-0.78NA+4.8deg-01ph-7.4641pix-0.50DC.bmp
Wrote file: pat-0.78NA+4.8deg-02ph-7.4641pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.78NA-55.0deg-00ph-7.4707pix-0.50DC.bmp
Wrote file: pat-0.78NA-55.0deg-01ph-7.4707pix-0.50DC.bmp
Wrote file: pat-0.78NA-55.0deg-02ph-7.4707pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.78NA-114.4deg-00ph-7.4709pix-0.50DC.bmp
Wrote file: pat-0.78NA-114.4deg-01ph-7.4709pix-0.50DC.bmp
Wrote file: pat-0.78NA-114.4deg-02ph-7.4709pix-0.50DC.bmp
561 NA 0.79
Optimizing angle = +4.76 degrees
Wrote file: pat-0.79NA+4.8deg-00ph-7.3782pix-0.50DC.bmp
Wrote file: pat-0.79NA+4.8deg-01ph-7.3782pix-0.50DC.bmp
Wrote file: pat-0.79NA+4.8deg-02ph-7.3782pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.79NA-55.0deg-00ph-7.3728pix-0.50DC.bmp
Wrote file: pat-0.79NA-55.0deg-01ph-7.3728pix-0.50DC.bmp
Wrote file: pat-0.79NA-55.0deg-02ph-7.3728pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.79NA-114.4deg-00ph-7.3795pix-0.50DC.bmp
Wrote file: pat-0.79NA-114.4deg-01ph-7.3795pix-0.50DC.bmp
Wrote file: pat-0.79NA-114.4deg-02ph-7.3795pix-0.50DC.bmp
561 NA 0.8
Optimizing angle = +4.76 degrees
Wrote file: pat-0.80NA+4.8deg-00ph-7.2764pix-0.50DC.bmp
Wrote file: pat-0.80NA+4.8deg-01ph-7.2764pix-0.50DC.bmp
Wrote file: pat-0.80NA+4.8deg-02ph-7.2764pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.80NA-55.0deg-00ph-7.2776pix-0.50DC.bmp
Wrote file: pat-0.80NA-55.0deg-01ph-7.2776pix-0.50DC.bmp
Wrote file: pat-0.80NA-55.0deg-02ph-7.2776pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.80NA-114.4deg-00ph-7.2734pix-0.50DC.bmp
Wrote file: pat-0.80NA-114.4deg-01ph-7.2734pix-0.50DC.bmp
Wrote file: pat-0.80NA-114.4deg-02ph-7.2734pix-0.50DC.bmp
561 NA 0.81
Optimizing angle = +4.76 degrees
Wrote file: pat-0.81NA+4.8deg-00ph-7.1909pix-0.50DC.bmp
Wrote file: pat-0.81NA+4.8deg-01ph-7.1909pix-0.50DC.bmp
Wrote file: pat-0.81NA+4.8deg-02ph-7.1909pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.81NA-55.0deg-00ph-7.1851pix-0.50DC.bmp
Wrote file: pat-0.81NA-55.0deg-01ph-7.1851pix-0.50DC.bmp
Wrote file: pat-0.81NA-55.0deg-02ph-7.1851pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.81NA-114.4deg-00ph-7.1852pix-0.50DC.bmp
Wrote file: pat-0.81NA-114.4deg-01ph-7.1852pix-0.50DC.bmp
Wrote file: pat-0.81NA-114.4deg-02ph-7.1852pix-0.50DC.bmp
561 NA 0.82
Optimizing angle = +4.76 degrees
Wrote file: pat-0.82NA+4.8deg-00ph-7.0985pix-0.50DC.bmp
Wrote file: pat-0.82NA+4.8deg-01ph-7.0985pix-0.50DC.bmp
Wrote file: pat-0.82NA+4.8deg-02ph-7.0985pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.82NA-55.0deg-00ph-7.0954pix-0.50DC.bmp
Wrote file: pat-0.82NA-55.0deg-01ph-7.0954pix-0.50DC.bmp
Wrote file: pat-0.82NA-55.0deg-02ph-7.0954pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.82NA-114.4deg-00ph-7.0996pix-0.50DC.bmp
Wrote file: pat-0.82NA-114.4deg-01ph-7.0996pix-0.50DC.bmp
Wrote file: pat-0.82NA-114.4deg-02ph-7.0996pix-0.50DC.bmp
561 NA 0.83
Optimizing angle = +4.76 degrees
Wrote file: pat-0.83NA+4.8deg-00ph-7.0040pix-0.50DC.bmp
Wrote file: pat-0.83NA+4.8deg-01ph-7.0040pix-0.50DC.bmp
Wrote file: pat-0.83NA+4.8deg-02ph-7.0040pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.83NA-55.0deg-00ph-7.0082pix-0.50DC.bmp
Wrote file: pat-0.83NA-55.0deg-01ph-7.0082pix-0.50DC.bmp
Wrote file: pat-0.83NA-55.0deg-02ph-7.0082pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.83NA-114.4deg-00ph-7.0161pix-0.50DC.bmp
Wrote file: pat-0.83NA-114.4deg-01ph-7.0161pix-0.50DC.bmp
Wrote file: pat-0.83NA-114.4deg-02ph-7.0161pix-0.50DC.bmp
561 NA 0.84
Optimizing angle = +4.76 degrees
Wrote file: pat-0.84NA+4.8deg-00ph-6.9288pix-0.50DC.bmp
Wrote file: pat-0.84NA+4.8deg-01ph-6.9288pix-0.50DC.bmp
Wrote file: pat-0.84NA+4.8deg-02ph-6.9288pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.84NA-55.0deg-00ph-6.9232pix-0.50DC.bmp
Wrote file: pat-0.84NA-55.0deg-01ph-6.9232pix-0.50DC.bmp
Wrote file: pat-0.84NA-55.0deg-02ph-6.9232pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.84NA-114.4deg-00ph-6.9197pix-0.50DC.bmp
Wrote file: pat-0.84NA-114.4deg-01ph-6.9197pix-0.50DC.bmp
Wrote file: pat-0.84NA-114.4deg-02ph-6.9197pix-0.50DC.bmp
561 NA 0.85
Optimizing angle = +4.76 degrees
Wrote file: pat-0.85NA+4.8deg-00ph-6.8383pix-0.50DC.bmp
Wrote file: pat-0.85NA+4.8deg-01ph-6.8383pix-0.50DC.bmp
Wrote file: pat-0.85NA+4.8deg-02ph-6.8383pix-0.50DC.bmp
Optimizing angle = -55.01 degrees
Wrote file: pat-0.85NA-55.0deg-00ph-6.8404pix-0.50DC.bmp
Wrote file: pat-0.85NA-55.0deg-01ph-6.8404pix-0.50DC.bmp
Wrote file: pat-0.85NA-55.0deg-02ph-6.8404pix-0.50DC.bmp
Optimizing angle = -114.44 degrees
Wrote file: pat-0.85NA-114.4deg-00ph-6.8421pix-0.50DC.bmp
Wrote file: pat-0.85NA-114.4deg-01ph-6.8421pix-0.50DC.bmp
Wrote file: pat-0.85NA-114.4deg-02ph-6.8421pix-0.50DC.bmp
SEQUENCES
A "48070 HHMI 10ms.seq11"
SEQUENCES_END

IMAGES
1 "pat-0.78NA+4.8deg-00ph-6.4920pix-0.50DC.bmp"
1 "pat-0.78NA+4.8deg-00ph-7.4641pix-0.50DC.bmp"
1 "pat-0.78NA+4.8deg-01ph-6.4920pix-0.50DC.bmp"
1 "pat-0.78NA+4.8deg-01ph-7.4641pix-0.50DC.bmp"
1 "pat-0.78NA+4.8deg-02ph-6.4920pix-0.50DC.bmp"
1 "pat-0.78NA+4.8deg-02ph-7.4641pix-0.50DC.bmp"
1 "pat-0.78NA-114.4deg-00ph-6.4953pix-0.50DC.bmp"
1 "pat-0.78NA-114.4deg-00ph-7.4709pix-0.50DC.bmp"
1 "pat-0.78NA-114.4deg-01ph-6.4953pix-0.50DC.bmp"
1 "pat-0.78NA-114.4deg-01ph-7.4709pix-0.50DC.bmp"
1 "pat-0.78NA-114.4deg-02ph-6.4953pix-0.50DC.bmp"
1 "pat-0.78NA-114.4deg-02ph-7.4709pix-0.50DC.bmp"
1 "pat-0.78NA-55.0deg-00ph-6.4949pix-0.50DC.bmp"
1 "pat-0.78NA-55.0deg-00ph-7.4707pix-0.50DC.bmp"
1 "pat-0.78NA-55.0deg-01ph-6.4949pix-0.50DC.bmp"
1 "pat-0.78NA-55.0deg-01ph-7.4707pix-0.50DC.bmp"
1 "pat-0.78NA-55.0deg-02ph-6.4949pix-0.50DC.bmp"
1 "pat-0.78NA-55.0deg-02ph-7.4707pix-0.50DC.bmp"
1 "pat-0.78NA-6.4953pix-0.50DC_allangles.bmp"
1 "pat-0.78NA-7.4709pix-0.50DC_allangles.bmp"
1 "pat-0.79NA+4.8deg-00ph-6.4094pix-0.50DC.bmp"
1 "pat-0.79NA+4.8deg-00ph-7.3782pix-0.50DC.bmp"
1 "pat-0.79NA+4.8deg-01ph-6.4094pix-0.50DC.bmp"
1 "pat-0.79NA+4.8deg-01ph-7.3782pix-0.50DC.bmp"
1 "pat-0.79NA+4.8deg-02ph-6.4094pix-0.50DC.bmp"
1 "pat-0.79NA+4.8deg-02ph-7.3782pix-0.50DC.bmp"
1 "pat-0.79NA-114.4deg-00ph-6.4161pix-0.50DC.bmp"
1 "pat-0.79NA-114.4deg-00ph-7.3795pix-0.50DC.bmp"
1 "pat-0.79NA-114.4deg-01ph-6.4161pix-0.50DC.bmp"
1 "pat-0.79NA-114.4deg-01ph-7.3795pix-0.50DC.bmp"
1 "pat-0.79NA-114.4deg-02ph-6.4161pix-0.50DC.bmp"
1 "pat-0.79NA-114.4deg-02ph-7.3795pix-0.50DC.bmp"
1 "pat-0.79NA-55.0deg-00ph-6.4147pix-0.50DC.bmp"
1 "pat-0.79NA-55.0deg-00ph-7.3728pix-0.50DC.bmp"
1 "pat-0.79NA-55.0deg-01ph-6.4147pix-0.50DC.bmp"
1 "pat-0.79NA-55.0deg-01ph-7.3728pix-0.50DC.bmp"
1 "pat-0.79NA-55.0deg-02ph-6.4147pix-0.50DC.bmp"
1 "pat-0.79NA-55.0deg-02ph-7.3728pix-0.50DC.bmp"
1 "pat-0.79NA-6.4161pix-0.50DC_allangles.bmp"
1 "pat-0.79NA-7.3795pix-0.50DC_allangles.bmp"
1 "pat-0.80NA+4.8deg-00ph-6.3290pix-0.50DC.bmp"
1 "pat-0.80NA+4.8deg-00ph-7.2764pix-0.50DC.bmp"
1 "pat-0.80NA+4.8deg-01ph-6.3290pix-0.50DC.bmp"
1 "pat-0.80NA+4.8deg-01ph-7.2764pix-0.50DC.bmp"
1 "pat-0.80NA+4.8deg-02ph-6.3290pix-0.50DC.bmp"
1 "pat-0.80NA+4.8deg-02ph-7.2764pix-0.50DC.bmp"
1 "pat-0.80NA-114.4deg-00ph-6.3312pix-0.50DC.bmp"
1 "pat-0.80NA-114.4deg-00ph-7.2734pix-0.50DC.bmp"
1 "pat-0.80NA-114.4deg-01ph-6.3312pix-0.50DC.bmp"
1 "pat-0.80NA-114.4deg-01ph-7.2734pix-0.50DC.bmp"
1 "pat-0.80NA-114.4deg-02ph-6.3312pix-0.50DC.bmp"
1 "pat-0.80NA-114.4deg-02ph-7.2734pix-0.50DC.bmp"
1 "pat-0.80NA-55.0deg-00ph-6.3312pix-0.50DC.bmp"
1 "pat-0.80NA-55.0deg-00ph-7.2776pix-0.50DC.bmp"
1 "pat-0.80NA-55.0deg-01ph-6.3312pix-0.50DC.bmp"
1 "pat-0.80NA-55.0deg-01ph-7.2776pix-0.50DC.bmp"
1 "pat-0.80NA-55.0deg-02ph-6.3312pix-0.50DC.bmp"
1 "pat-0.80NA-55.0deg-02ph-7.2776pix-0.50DC.bmp"
1 "pat-0.