# The ray trace optical model illustrated

The **ray trace** model for image formation uses information about the main lens to calculate

* geometric distortion * relative illumination * field-height and wavelength-dependent PSF

This script illustrates the ray trace calculation, bringing up an array of figures that show different aspects of the calculation.

The example is based on an aspherical, 2mm lens whose point spread functions were computed in **Zemax** .

For comparison, the optical image is also computed using diffraction limited methods (shift-invariant). The f# and focal length of the diffraction model are set equal to those of the ray trace lens.

See also: rtGeometry, rtPrecomputePSF, rtPrecomputePSFApply

Copyright ImagEval, LLC, 2005

## Contents

- Set up a wide angle scene for the wide angle lens below
- Import wide angle lens optics.
- Set up diffraction limited parameters to match the ray trace numbers
- Compute the distortion and show it in the OI
- Precompute the PSF and then apply
- We choose ray trace by setting the optics method
- Compute using the diffraction-limited method
- Make the FOV smaller to show the ray trace blurring
- Equivalent diffraction limited

ieInit

## Set up a wide angle scene for the wide angle lens below

scene = sceneCreate('gridlines',[384 384], 48); scene = sceneInterpolateW(scene,(550:100:650)); % Small wavelength sample scene = sceneSet(scene,'hfov',45); scene = sceneSet(scene,'name','rtDemo-Large-grid'); % Show the grid line scene ieAddObject(scene); sceneWindow;

## Import wide angle lens optics.

% Set up default optical image oi = oiCreate; % Load in the wide angle lens optics file created by Zemax (zm) opticsFileName = fullfile(isetRootPath,'data','optics','zmWideAngle.mat'); tmp = load(opticsFileName); % Set the oi with the optics loaded from the file oi = oiSet(oi,'optics',tmp.optics); % Retrieve it and print its name to verify and inform user optics = oiGet(oi,'optics'); fprintf('Ray trace optics: %s\n',opticsGet(optics,'lensFile'));

Ray trace optics: wideAngle.zmx

## Set up diffraction limited parameters to match the ray trace numbers

% Now, match the scene properties oi = oiSet(oi,'wangular',sceneGet(scene,'wangular')); oi = oiSet(oi,'spectrum',sceneGet(scene,'spectrum')); % Match the scene distance and the rt distance. They are both essentially % infinite. scene = sceneSet(scene,'distance',2); % Two meters - essentially inf optics = opticsSet(optics,'rtObjectDistance',sceneGet(scene,'distance','mm'));

## Compute the distortion and show it in the OI

% We calculate in the order of (a) Distortion, (b) Relative % illumination, and then (c) OTF blurring The function rtGeometry % calculates the distortion and relative illumination at the same time. irradiance = rtGeometry(scene,optics); % Copy the resulting data into the optical image structure oi = oiSet(oi,'photons',irradiance); oi = oiSet(oi,'name','Geometry only'); ieAddObject(oi); oiWindow;

## Precompute the PSF and then apply

angStep = 20; % Very coarse for speed svPSF = rtPrecomputePSF(oi,angStep); oi = oiSet(oi,'psfStruct',svPSF); % Apply outIrrad = rtPrecomputePSFApply(oi,angStep); oi = oiSet(oi,'photons',outIrrad); oi = oiSet(oi,'name','Stepwise-RT'); ieAddObject(oi); oiWindow;

Eccentricity bands: 0.000 (um) Eccentricity bands: 87.491 (um) Eccentricity bands: 174.981 (um) Eccentricity bands: 262.472 (um) Eccentricity bands: 349.962 (um) Eccentricity bands: 437.453 (um) PSF sample grid: 41 by 41 6 eccentricity bands

## We choose ray trace by setting the optics method

oi = oiSet(oi,'optics model','ray trace'); oi = oiCompute(scene,oi); oi = oiSet(oi,'name','Automated ray trace'); % Have a look - barrell distortion and all ieAddObject(oi); oiWindow; % Here is a horizontal line of illuminance rtData = oiPlot(oi,'illuminance hline',[1,64]);

Geometric distortion ... Starting with existing PSFs ... Applying PSFs. 6 eccentricity bands Done applying PSFs.

## Compute using the diffraction-limited method

oiDL = oiSet(oi,'optics model','diffraction limited'); optics = oiGet(oiDL,'optics'); % Set the diffraction limited f# from the ray trace values fNumber = opticsGet(optics,'rt fnumber'); optics = opticsSet(optics,'fnumber',fNumber); oiDL = oiSet(oiDL,'optics',optics); % Now set the method to diffraction limited and compute oiDL = oiSet(oiDL,'name','DL method'); oiDL = oiCompute(scene,oiDL); % No barrel distortion, less blurring ieAddObject(oiDL); oiWindow; % Here is a horizontal line of illuminance dlData = oiPlot(oiDL,'illuminance hline',[1,64]);

## Make the FOV smaller to show the ray trace blurring

% The first calculation was spatially coarse, and inappropriate % for a geometric calculation such as barrel distortion. % % Here, we make the scene smaller and recalculate. With this % field of view there is no noticeable distortion, but the sample % spacing is much finer so we can see the various point spread % functions % % At this resolution, the calculation takes a little while. sceneSmall = sceneSet(scene,'name','rt-Small-Grid'); sceneSmall = sceneSet(sceneSmall,'fov',20); % Ray trace calculation with distortion and shift-variant blurring oi = oiCompute(sceneSmall,oi); oi = oiSet(oi,'name','rt-Small-RT'); ieAddObject(oi); oiWindow;

Geometric distortion ... Starting with existing PSFs ... Applying PSFs. 4 eccentricity bands Eccentricity bands: 0.000 (um) Eccentricity bands: 87.491 (um) Eccentricity bands: 174.981 (um) Eccentricity bands: 262.472 (um) PSF sample grid: 95 by 95 Done applying PSFs.

## Equivalent diffraction limited

% There is no distortion computed and the scene is small % This calculation is pretty quick. oiDL = oiCompute(sceneSmall,oiDL); oiDL = oiSet(oiDL,'name','rt-Small-DL'); ieAddObject(oiDL); oiWindow;