Spot Image File Generator Manual This manual explains how to use the Spot Image Generator functions and plug the result into the wavefront curvature reconstruction function, wcs: SpotImageFileGenerator_data SpotImageFileGenerator_synth The _data version is for input of real data in the .fits image format while the _synth version includes extra inputs for generating synthetic spot images. Both functions output a file that contains a Matlab structure, ‘m’, which contains pertinent system constants and the spot images in Matlab array format for use with the wavefront curvature sensing reconstruction function, wcs. The structure of ‘m’ is as follows: focalLength: apertureDiameter: sensorOffset: sensorFactor: padDim: C0: c1: Fno: sensorWidth: sensorSamples: pixelSize: xSensor: ySensor: mask: amask: maskPad: I1: I2: The focal length of the telescope The diameter of the entrance pupil The offset from nominal focus where the two images lie This is a ratio of the physical extent of the image plane captured by the sensor to the projected size of the pupil at the image plane The dimension of the array after padding for use with Fourier space calculations A constant equal to the separation of the object planes corresponding to the two image planes in object space Equal to the focal length divided by the offset, used in creating coordinates for both image planes Equal to the focal length divided by the aperture diameter The physical extent of the image plane captured by the sensor The # of pixels in the sensor. Current implementation assumes a square image sensor The corresponding period of the image sensor pixels A vector used for coordinates at the image plane A vector used for coordinates at the image plane A throughput mask of the pupil as seen from the image sensor Equal to ‘mask’ but scaled such that the edge of the pupil is at the edge of the array Equal to ‘mask’ padded to the dimension of ‘padDim’ The spot image in the –z direction (closer to the pupil) The spot image in the +z direction (further from the pupil) All physical dimensions of length need to be in the same units, typically meters. Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 1 of 16 Masklist Before going in depth into the SpotImageFileGenerator functions, we will look at a structure both functions require, masklist. Masklist is an n x 4 array which multiplicatively specifies a combination of circular includes and excludes to specify the obscuration of the pupil. All of the elements (save the boolean include/exclude) are in normalized coordinates where ‘1’ equals the radius of the pupil. The first element is the center of the circular element in the horizontal direction, ‘x’. Similarly, the second element is the center of the circular element in the vertical direction, ‘y’. The third element is the radius of the element and the fourth is a boolean specifying whether the element is ‘include’ or ‘exclude’ (IEboolean). Masklist always begins with [0 0 1 1] to specify the starting pupil, centered at zero, having a radius of 1, being an ‘include’. Below is an example masklist array and the corresponding mask is constructed as follows: ml = [ centerX1 centerY1 radius1 IEboolean1; centerX2 centerY2 radius2 IEboolean2 ; … ]; example: ml = [ 0 0 1 1 ; -0.25 0.25 0.25*sqrt(2) 0 ; 0.25 -0.25 0.25*sqrt(2) 0]; First row element Second row element Third row element The current implementation of the masklist structure combines the row elements multiplicatively which means any number of obscurations can be added, but any additional elements that perform an ‘include’ operation past the first pupil-defining element will clip the pupil accordingly, not add to it. On axis, the LSST mask would require two rows: one for the full aperture and one for a central obscuration. As one moves off-axis the central obscuration turns into two obscurations separated in opposite directions for three entries in the mask list. Additionally, a fourth entry that is an include, can be used to clip a portion of the pupil that is vignetted. Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 2 of 16 SpotImageFileGenerator_data Next, we will examine the inputs to the _data function: m = SpotImageFileGenerator_data(sensorSamples, padDim, sensorFactor, focalLength, apertureDiameter, offset, masklist, datafile_short, datafile_long, filename) Inputs are as follows: sensorSamples = the physical # of pixels on the sensor padDim = the # of samples used for the Fourier space filtering operation sensorFactor = Sensor Factor: the ratio of the physical extent of the sensor to the projected size of the pupil on the sensor focalLength = effective focal length of the optical system apertureDiameter = aperture diameter offset = distance from paraxial focus of the spot image planes masklist = a nx4 matrix specifying a combination of circular apertures or obscurations in the pupil. Each row is specified as [centerx, centery, normalized radius, pass(1)/block(0)] datafile_short = the filename for the .fits data file corresponding to the –offset image plane, closer to the pupil. If no global path is given, it is assumed the file is located in the working directory. If no filename is given, the user will be asked to find the file via a dialog box. datafile_long = the filename for the .fits data file corresponding to the +offset image plane, further from the pupil. If no global path is given, it is assumed the file is located in the working directory. If no filename is given, the user will be asked to find the file via a dialog box. filename = a name for the file where the model structure will be saved. If no global path is given, it will be saved in the working directory. If no filename is given, the user will be asked for the location to save the file via a dialog box. Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 3 of 16 SpotImageFileGenerator_data Next, we will examine the inputs to the _synth function: function m = SpotImageFileGenerator_synth(sensorSamples, padDim, sensorFactor, focalLength, apertureDiameter, offset, masklist, filename, Zn, rayCount, iter, savetoFITS) Inputs are as follows: sensorSamples = the physical # of pixels on the sensor padDim = the # of samples used for the Fourier space filtering operation sensorFactor = Sensor Factor: the ratio of the physical extent of the sensor to the projected size of the pupil on the sensor focalLength = effective focal length of the optical system apertureDiameter = aperture diameter offset = distance from paraxial focus of the spot image planes masklist = a nx4 matrix specifying a combination of circular apertures or obscurations in the pupil. Each row is specified as [centerx, centery, normalized radius, pass(1)/block(0)] filename = a name for the file where the model structure will be saved. If no global path is given, it will be saved in the working directory. If no filename is given, the user will be asked for the location to save the file via a dialog box. Zn = A vector of Zernike coefficients based on the Noll ordering (JOSA V 66, #3 Mar 1976). Up to 22 terms may be entered. rayCount = Controls the # of rays traced from the exit pupil to form the spot images. A total of rayCount^2 dithered positions are generated across the entire square pupil array. Those locations that aren’t blocked off by the pupil mask are input to a function to find the X & Y slope of the wavefront and used to generate a ray intercept location at the image sensor. These locations are binned to create the spot Image. iter = # of times to repeat the spot image generation. A higher ‘rayCount’ will result in a lower-noise image. However, if the user specifies too high a number for rayCount Matlab will begin to have a problem with memory limitations. One way around that is to simply repeat the process of making a spot image via a for loop with a different set of random ray positions in the pupil then add them. ‘iter’ specifies the number of iterations for the for loop. savetoFITS = A boolean that specifies whether or not to save the synthetic spot images to .fits image files. It should be noted that focalLength, apertureDiameter, offset and Zn should all be in the same units of length, preferably meters to avoid confusion. Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 4 of 16 Plugging into wcs The main function of the wavefront curvature sensing reconstruction is the function wcs. It takes the model structure created by the previous functions and performs the reconstruction. The only inputs are the model, ‘m’ and the number of times to perform the iterative solution refinement. The ‘cookbook’ procedure 1) Specify the system constants common to either method of Spot Image file generation. Be sure to use a consistent system of units. Specifying focal length, aperture diameter, offset and Zernike terms (if used) all in meters is the preferred method. Focal Length Aperture Diameter Offset Masklist Sensor Samples Sensor Factor Padded Fourier space dimension (padDim) Output file name 2) Specify the remaining inputs depending on whether you wish to generate synthetic data or use real data: Synthetic Data: Real Data: Zernike Terms Input data file –offset Ray Count Input data file +offset Iterations 3) Plug input variables into either SpotImageFileGenerator_synth or SpotImageFileGenerator_data 4) Repeat with different input variables as desired 5) Load data from a given output file 6) Plug the model ‘m’ and the number of iterative solution refinement loops desired into wcs. 7) Save the new model ‘m’, which now includes a wavefront estimate, and any other workspace variables to a new file if desired. Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 5 of 16 A ‘cookbook’ example The file “Cookbook1.m” runs through reading a data file and doing a reconstruction. The parameters are incorrect so the results are incorrect. Also some filtering of the data is required. Even so it is informative. Two figures are created and shown below. A similar file “Cookbook2.m” creates and processes simulated data. m.mask I1 (short) 0.01 0 -0.01 -0.01 0.01 Y axis Y axis Y axis 0.01 I2 (long) 0 -0.01 0 0.01 X axis -0.01 0 -0.01 0 0.01 X axis -0.01 Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved 0 0.01 X axis Page 6 of 16 -4 West x 10 15 100 10 Y axis 50 0 5 -50 0 -100 -5 -100 -50 0 X axis 50 100 The code to accomplish this is shown below (Cookbook1.m). Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 7 of 16 % Copyright 2006, William P. Kuhn, Ph.D., LLC % intra_stack.fits is 98 x 99 pixels and extra_stack is 99 x 99. % Let's "fix" this temp = fitsread('intra_stack.fits'); temp2= zeros(99); temp2(1:98,:) = temp; fitswrite( temp2, 'intra_stack2.fits' ); % Now preprocess the FITS files to create a model as a file and in memory % The parameters specified are for the LSST (approximately), which does not % exist. Therefore they must be wrong. m = SpotImageFileGenerator_data( 10.5, 8.4, 20e-3, [0 0 1 1], 256, 1.5, 512, 'intra_stack2.fits', 'extra_stack.fits', 'CookBook1' ); % Do a wavefront reconstruction. m = wcs( m, 2 ); % The reconstruction m.West has incorrect values and there are a couple of % spikes. Preprocessing of the data are required. A second example with synthetic data – Cookbook2.m % Copyright 2006, William P. Kuhn, Ph.D., LLC % Generate a file m = SpotImageFileGenerator_synth( 10.5, 8.4, 20e-3, [0 0 1 1], 256, 1.5, 512, 'Cookbook2', [0 0 0 0 -.5 -.1 .5 .1 0 0 -1]*.5e-6, 1001, 1, 1); % Do a wavefront reconstruction. m = wcs( m, 2 ); Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 8 of 16 Appendix – Matlab code % SIGscript.m % 7/19/06 % This is a script file for generating Spot Image Files. This function includes % calls to SpotImageFileGenerator_synth and/or SpotImageFileGenerator_data % with several useful defaults for the input variables. Simply comment or % uncomment the input variables you wish to input and the % SpotImageFileGenerator function you wish to use and run the script. % Matthew Lang % Copyright 2006, William P. Kuhn, Ph.D., LLC efl = 1; aD = .3; offset = 10e-3; % masklist = [0 0 1 1]; %unobscured masklist = [0 0 1 1;0 0 .2 0]; %Central obscuration % masklist = [0 0 1 1;.4 .45 .3 0;-.05 -.3 .4, 0 ]; %arbitrary obscuration sN = 256; sF = 1.5; padDim = 512; filename = ''; %filename = sprintf('WCS_NOAO_%g_%g_%g.mat',efl,aD*1000,offset*1000); Zn = [0 0 0 0 -.5 -.1 aberrations % Zn = [0 0 0 1 0 0 aberrations rC = 1001; iter = 50; .5 .1 0 0 0 0 .4 0 -1]*.5e-6; %Arbitrary SA, Coma & Astig -1]*.5e-6; %SA & Trifoil test m = SpotImageFileGenerator_synth(efl, aD, offset, masklist, sN, sF, padDim, filename, Zn, rC, iter, 0); % m = SpotImageFileGenerator_data (efl, aD, offset, masklist, sN, sF, padDim, '','', filename); Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 9 of 16 function m = SpotImageFileGenerator_data(focalLength, apertureDiameter, offset, masklist, sensorSamples, sensorFactor, padDim, datafile_short, datafile_long, filename) % % % % % % % % % % % 7/19/06 author - Matthew Lang This function will generate a model with all pertinent constants and image data for use with the wavefront curvature reconstructing function, 'wcs'. The input variables are defined as below: function model = SpotImageFileGenerator_data(focalLength, apertureDiameter, offset, masklist, sensorSamples, sensorFactor, padDim, datafile_short, datafile_long, filename) % The following input variables should have the same units of length, % preferrably meters: focalLength, apertureDiameter, offset % % focalLength = effective focal length of the optical system % apertureDiameter = aperture diameter % offset = distance from paraxial focus of the spot image planes % masklist = a nx4 matrix specifying a combination of circular apertures or % obscurations in the pupil. Each row is specified as % [centerx, centery, normalized radius, pass(1)/block(0)] % sensorSamples = the physical # of pixels on the sensor % sensorFactor = Sensor Factor: the ratio of the physical extent of the sensor % to the projected size of the pupil on the sensor % padDim = the # of samples used for the Fourier space filtering operation % datafile_short = name of .fits datafile where the -offset spot image data % resides. If no filename is given, the user will be % asked to locate it. % datafile_long = name of .fits datafile where the +offset spot image data % resides. If no filename is given, the user will be % asked to locate it. % filename = a name for the file where the model structure will be saved. % If no filename is given, the user will be asked to % specify a location to save the model. % Matthew Lang % Copyright 2006, William P. Kuhn, Ph.D., LLC % Set default values if none are given if nargin < 10 filename = ''; end if nargin < 9 datafile_long = ''; end if nargin < 8 datafile_short = ''; Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 10 of 16 end if nargin < 7 padDim = 512; end if nargin < 6 sensorFactor = 1.5; end if nargin < 5 sensorSamples = 256; end if nargin < 4 masklist = [0 0 1 1]; end if nargin < 3 offset = 20e-3; end if nargin < 2 apertureDiameter = 8.4; end if nargin < 1 focalLength = 10.5; end % Calculate all constants, sampling, and masks m = setModelConstants( focalLength, apertureDiameter, offset, sensorFactor, padDim ); m = setModelSampling( m, sensorSamples ); m = ModelMask( m, masklist ); subplot( 1, 3, 1 ); renderImage( m.mask, m ); title( 'm.mask' );axis square % If user has left both data filenames blank, interactively ask user to find % the data files if isempty(datafile_short) [file path] = uigetfile('.fits','Choose the data set corresponding to the -z Spot Image'); datafile_short = [path file]; end if isempty(datafile_long) [file path] = uigetfile('.fits','Choose the data set corresponding to the +z Spot Image'); datafile_long = [path file]; end % read the .fits images specified m.I1 = fitsread(datafile_short); m.I2 = fitsread(datafile_long); figure(1); subplot( 1, 3, 2 ); Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 11 of 16 renderImage( m.I1, m ); title( 'I1 (short)' ); subplot( 1, 3, 3 ); renderImage( m.I2, m ); title( 'I2 (long)' ); % if no output file name is given, ask user where to save the information if isempty(filename) [file path] = uiputfile('.mat','Save model information:'); filename = [path file]; end fprintf('saving: %s\n', filename); save(filename, 'm','datafile_short','datafile_long'); Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 12 of 16 function m = SpotImageFileGenerator_synth(focalLength, apertureDiameter, offset, masklist, sensorSamples, sensorFactor, padDim, filename, Zn, rayCount, iter, savetoFITS) % 7/19/06 % author - Matthew Lang % This function will generate a model with all pertinent constants and image % data for use with the wavefront curvature reconstructing function, 'wcs'. % The input variables are defined as below: % % % function model = % SpotImageFileGenerator_synth(focalLength, apertureDiameter, offset, masklist, % sensorSamples, sensorFactor, padDim, filename, Zn, rayCount, iter, savetoFITS) % % The following input variables should have the same units of length, % preferrably meters: focalLength, apertureDiameter, offset % % focalLength = effective focal length of the optical system % apertureDiameter = aperture diameter % offset = distance from paraxial focus of the spot image planes % masklist = a nx4 matrix specifying a combination of circular apertures or % obscurations in the pupil. Each row is specified as % [centerx, centery, normalized radius, pass(1)/block(0)] % sensorSamples = the physical # of pixels on the sensor % sensorFactor = Sensor Factor: the ratio of the physical extent of the sensor % to the projected size of the pupil on the sensor % padDim = the # of samples used for the Fourier space filtering operation % filename = a name for the file where the model structure will be saved. % If no filename is given, the user will be asked to % specify a location to save the model. % % Zn = Zernike Terms % rayCount = the # of rays emanating from the pupil (before being masked) is equal to rayCount^2 % iter = # of times to repeat the spot image calculation. This is the % same as tracing iter*rayCount^2 rays % savetoFITS = a boolean specifying whether or not to save spot image data to .fits files % Matthew Lang % Copyright 2006, William P. Kuhn, Ph.D., LLC % Set default values if none are given if nargin < 12 savetoFITS = 1; end Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 13 of 16 if nargin < 11 iter = 1; end if nargin < 10 rayCount = 1001; end if nargin < 9 Zn = [0 0 0 0 -.5 -.1 end if nargin < 8 filename = ''; end if nargin < 7 padDim = 512; end if nargin < 6 sensorFactor = 1.5; end if nargin < 5 sensorSamples = 256; end if nargin < 4 masklist = [0 0 1 1]; end if nargin < 3 offset = 20e-3; end if nargin < 2 apertureDiameter = 8.4; end if nargin < 1 focalLength = 10.5; end .5 .1 0 0 -1]*.5e-6; % Calculate all constants, sampling, and masks m = setModelConstants( focalLength, apertureDiameter, offset, sensorFactor, padDim ); m = setModelSampling( m, sensorSamples ); m = ModelMask( m, masklist ); % Calculate the original wavefront error and Zernike terms [x, y] = zernikeMesh( m.sensorSamples/sensorFactor ); WTrue = zernikeEvalNoll( Zn, x, y ); WTrue(isnan(WTrue)) = 0; WTrue = padArrayB( WTrue, m.sensorSamples ).*m.mask; figure( 2 ); subplot( 2, 3, 1 ); renderImage( WTrue ); title( 'W True' );colorbar('vert');axis square subplot( 2, 3, 4 ); renderImage( m.mask, m ); title( 'm.mask' );colorbar('vert');axis square Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 14 of 16 % Initialize the spot image arrays in the model m.I1 = zeros(sensorSamples); m.I2 = zeros(sensorSamples); t = []; tic; t(end+1) = toc; % for keeping track of loop execution time for ii = 1:iter % generate the Spot Images I1 = spotImage( m, Zn, rayCount, 'short', 1 ); I2 = spotImage( m, Zn, rayCount, 'long', 1 ); % keep a running sum of the Spot Images, save in the model m.I1 = m.I1+I1; m.I2 = m.I2+I2; subplot( 2, 3, 2 ); renderImage( I1, m ); title( 'I1 (short)' ); subplot( 2, 3, 3 ); renderImage( I2, m ); title( 'I2 (long)' ); subplot( 2, 3, 5 ); renderImage( m.I1, m ); title( 'final I1 (short)' ); subplot( 2, 3, 6 ); renderImage( m.I2, m ); title( 'final I2 (long)' ); pause(.1) t(end+1) = toc; titer = (iter-ii)*mean(diff(t(1:end)))/60; fprintf('iteration %d/%d. Time remaining: %fmin\n', ii,iter, titer); end % if no output file name is given, ask user where to save the information if isempty(filename) [file path] = uiputfile('.mat','Save model information:'); filename = [path file]; end fprintf('saving: %s\n', filename); save(filename, 'm','Zn','WTrue','rayCount'); %If the 'savetoFITS' boolean is true(1), then ask the user where to store %the spot image data, then write the images to .fits files Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 15 of 16 if savetoFITS [file path] = uiputfile('.fits','Save spot image data to FITS file:'); fitswrite(m.I1,[path strtok(file,'.') '_short.fits']); fitswrite(m.I2,[path strtok(file,'.') '_long.fits']); end Copyright 2006, William P. Kuhn, Ph.D., LLC All Rights Reserved Page 16 of 16