10 (multiple-value-bind (ex ey ez
)
11 (psf:electric-field-psf z y x
(* dz z
) (* dx x
) :integrand-evaluations
200)
12 (defparameter *kex
* (fftshift3 (ft3 ex
)))
13 (defparameter *key
* (fftshift3 (ft3 ey
)))
14 (defparameter *kez
* (fftshift3 (ft3 ez
)))
18 (save-stack-ub8 "/home/martin/tmp/kex" (normalize3-cdf/ub8-realpart
*kex
*))
19 (save-stack-ub8 "/home/martin/tmp/key" (normalize3-cdf/ub8-realpart
*key
*))
20 (save-stack-ub8 "/home/martin/tmp/kez" (normalize3-cdf/ub8-realpart
*kez
*))
23 (write-pgm "/home/martin/tmp/kex.pgm"
24 (normalize2-cdf/ub8-abs
(cross-section-xz *kex
*)))
26 ;; calculate volume containing a grating
27 (destructuring-bind (z y x
)
28 (array-dimensions *kex
*)
29 (let* ((grat (make-array (list z y x
) :element-type
'(complex double-float
))))
32 (do-rectangle (j i q
(- y q
) q
(- x q
))
33 (setf (aref grat k j i
) (complex (* 1d0
(mod i
8))))))
34 (defparameter *kgrat
* (fftshift3 (ft3 grat
)))
37 (save-stack-ub8 "/home/martin/tmp/kgrat" (normalize3-cdf/ub8-abs
*kgrat
*))
39 ;; calculate image of grating
40 (destructuring-bind (z y x
)
41 (array-dimensions *kex
*)
42 (let* ((ex (fftshift3 (ift3 (fftshift3 (.
* *kgrat
* *kex
*)))))
43 (ey (fftshift3 (ift3 (fftshift3 (.
* *kgrat
* *key
*)))))
44 (ez (fftshift3 (ift3 (fftshift3 (.
* *kgrat
* *kez
*)))))
45 (intens (make-array (array-dimensions ex
)
46 :element-type
'(complex double-float
))))
47 (do-box (k j i
0 z
0 y
0 x
)
48 (setf (aref intens k j i
)
49 (+ (* (conjugate (aref ex k j i
)) (aref ex k j i
))
50 (* (conjugate (aref ey k j i
)) (aref ey k j i
))
51 (* (conjugate (aref ez k j i
)) (aref ez k j i
)))))
52 (defparameter *intens
* intens
)
53 (save-stack-ub8 "/home/martin/tmp/intens-grat" (normalize3-cdf/ub8-realpart intens
))
54 (write-pgm "/home/martin/tmp/intens-grat.pgm" (normalize2-cdf/ub8-realpart
(cross-section-xz intens
)))))
57 (destructuring-bind (z y x
)
58 (array-dimensions *kex
*)
59 (let* ((ex (ift3 (fftshift3 *kex
*)))
60 (ey (ift3 (fftshift3 *key
*)))
61 (ez (ift3 (fftshift3 *kez
*)))
62 (intens (make-array (array-dimensions ex
)
63 :element-type
'(complex double-float
))))
64 (do-box (k j i
0 z
0 y
0 x
)
65 (setf (aref intens k j i
)
66 (+ (* (conjugate (aref ex k j i
)) (aref ex k j i
))
67 (* (conjugate (aref ey k j i
)) (aref ey k j i
))
68 (* (conjugate (aref ez k j i
)) (aref ez k j i
)))))
69 (defparameter *intens-psf-laser
* intens
)
70 (save-stack-ub8 "/home/martin/tmp/intens-psf-laser" (normalize3-cdf/ub8-realpart intens
))))
73 "/home/martin/tmp/intens-psf-laser.pgm"
74 (normalize2-cdf/ub8-realpart
(cross-section-xz *intens-psf-laser
*)))
78 (save-stack-ub8 "/home/martin/tmp/kintens-grat"
79 (normalize3-cdf/ub8-abs
(fftshift3 (ft3 *intens
*)))))
81 ;; A circular window in the center of the BFP with radius Rap gives
82 ;; rise to rays up to the angle beta into sample space. The radius of
83 ;; the focal sphere is n*f. Therefore one can write
84 ;; sin(beta)=Rap/(n*f). Changing illumination direction of the grating
85 ;; will shear the intensity image. In order to generate an image of
86 ;; limited coherence one has to convolve each plane with a disk. The
87 ;; radius of the disk is: Rd(z)=z*sin(beta) with defocus z.
88 ;; Eliminate sin(beta):
89 ;; Rd(z)=abs(z*Rap/(n*f))
90 ;; for a 63x objective we get f=2.61, with n=1.515
92 (defun draw-disk (radius y x
)
93 (declare (double-float radius
)
95 (values (simple-array (complex double-float
) 2) &optional
))
96 (let ((result (make-array (list y x
) :element-type
'(complex double-float
)))
99 (r2 (* radius radius
)))
100 (do-rectangle (j i
0 y
0 x
)
103 (rr2 (+ (* ii ii
) (* jj jj
))))
105 (setf (aref result j i
) (complex (/ r2
))))))
108 (write-pgm "/home/martin/tmp/disk.pgm"
109 (normalize2-cdf/ub8-realpart
110 (fftshift2 (convolve2-circ
111 (draw-disk 12d0
100 200)
112 (draw-disk 12d0
100 200)))))
114 (sb-alien:define-alien-routine
("j1" bessel-j1
)
116 (arg sb-alien
:double
))
118 ;; isi.ssl.berkeley.edu/~tatebe/whitepapers/FT%20of%20Uniform%20Disk.pdf
119 (defun draw-unit-intensity-disk-precise (radius y x
)
120 (declare (double-float radius
)
122 (values (simple-array (complex double-float
) 2) &optional
))
123 (let ((a (make-array (list y x
)
124 :element-type
'(complex double-float
)))
127 (do-rectangle (j i
0 y
0 x
)
128 (let* ((xx (/ (* 1d0
(- i xh
)) x
))
129 (yy (/ (* 1d0
(- j yh
)) y
))
130 (f (sqrt (+ (* xx xx
) (* yy yy
)))))
131 (setf (aref a j i
) (if (< f
1d-12
)
132 (complex (* pi radius
))
133 (complex (/ (bessel-j1 (* 2d0 pi f radius
))
135 (fftshift2 (ift2 (fftshift2 a
)))))
137 (defun draw-unit-energy-disk-precise (radius y x
)
138 (declare (double-float radius
)
140 (values (simple-array (complex double-float
) 2) &optional
))
141 (let* ((disk (draw-unit-intensity-disk-precise radius y x
))
142 (sum (reduce #'+ (sb-ext:array-storage-vector disk
))))
143 (s*2 (/ (realpart sum
)) disk
)))
146 (write-pgm "/home/martin/tmp/disk.pgm"
147 (normalize2-cdf/ub8-realpart
(draw-unit-energy-disk-precise 12.3d0
300 300)))
149 (time (destructuring-bind (z y x
)
150 (array-dimensions *intens
*)
152 (f (lens:focal-length-from-magnification
63d0
))
155 (result (make-array (array-dimensions *intens
*)
156 :element-type
'(complex double-float
))))
157 ;; center plane doesn't have to be convolved
158 (let ((k (floor z
2)))
159 (do-rectangle (j i
0 y
0 x
)
160 (setf (aref result k j i
) (aref *intens
* k j i
))))
162 ;; convolve all other planes with disks of different sizes
164 (unless (eq k
(floor z
2))
165 (let* ((Rd-pixels (abs (* (- k
(floor z
2)) dz
(/ Rap
(* n f
)))))
166 (disk (draw-unit-energy-disk-precise Rd-pixels y x
))
167 (img (make-array (list y x
) :element-type
'(complex double-float
))))
168 (write-pgm (format nil
"/home/martin/tmp/disk/disk~3,'0d.pgm" k
)
169 (normalize2-cdf/ub8-realpart disk
))
170 (do-rectangle (j i
0 y
0 x
)
171 (setf (aref img j i
) (aref *intens
* k j i
)))
172 (let ((conv (fftshift2 (convolve2-circ img disk
))))
173 (do-rectangle (j i
0 y
0 x
)
174 (setf (aref result k j i
) (+ (aref disk j i
) (aref conv j i
))))))))
175 (defparameter *intens-disk
* result
)
176 (save-stack-ub8 "/home/martin/tmp/intens-grat-conv" (normalize3-cdf/ub8-abs result
))
177 (save-stack-ub8 "/home/martin/tmp/kintens-grat-conv"
178 (normalize3-cdf/ub8-realpart
(ft3 result
)))
179 (write-pgm "/home/martin/tmp/intens-grat-conv.pgm"
180 (normalize2-cdf/ub8-realpart
(cross-section-xz *intens-disk
*))))))