Posts Tagged ‘ ray tracing

Ray tracing – matrix math

Today was my last day at Reson, and I’m finally getting around to writing the Python version of my ray tracing script.  What I want to do is take sound speed profiles as input, and compute the difference in depth that would result from using one versus the other at different multibeam launch angles.  It’s just a little tool that I’d like to have to figure out how much error I could expect given two profiles.

So far, I’ve read in the profile (from a text file), and parsed the data:

filename = 'ssp.txt'

ssp = []
depth = []

file1 = open(filename)
for line in file1.readlines():
#    print line
    splitup = line.split()
    ssp.append(float(splitup[1]))
    depth.append(float(splitup[0]))

After this, I defined an array of launch angles (relative to horizontal, so +/- 75 degrees was actually 15 – 165), and an array of sound speed values interpolated from the sound speed profile to a certain depth increment (1m), and down to a given water depth (10m).


LaunchAngle = r_[15.:166.:5.] # array of launch angles in degrees
LaunchAngleRadians = LaunchAngle*pi/180
nadirdepth = 100 # nadir depth in meters
DepthIncrement = 0.5 # depth increment in m

if nadirdepth > max(depth):
    ssp.append(0.016*(nadirdepth - max(depth)))
    depth.append(nadirdepth)

if min(depth)>0:
    ssp = insert(ssp,0,ssp[0])
    depth = insert(depth,0,0)

depthvector = r_[0:nadirdepth:DepthIncrement]
interpfun = interp1d(depth,ssp)
sspvector = interpfun(depthvector)

And as if that much wasn’t suspicious enough, I decided that I wanted to do all of the calcs using matrix math. I figured I’d ditch all the loops that were in my original Matlab script, and replace them with some nice streamlined matrices. So efficient. The problem is that there are some exceptions that I need to take care of, that are difficult to deal with when doing everything in a series of matrices. For example, when the sound speed in a certain layer is the same as the sound speed in the first layer – then the gradient is zero, and the radius of curvature is infinite. Here’s what I’ve hacked together so far. It’s not pretty.


thetaLaunch = tile(LaunchAngleRadians,(size(depthvector),1))
depthmat = transpose(tile(depthvector,(size(LaunchAngleRadians),1)))
sspmat = transpose(tile(sspvector,(size(LaunchAngleRadians),1)))

g = (sspmat - sspvector[0]) / DepthIncrement

Rc = -sspvector[0]/(g*cos(thetaLaunch))

thetamat = arccos( ((Rc*cos(thetaLaunch)) - DepthIncrement ) / Rc )

dx = (Rc*sin(thetamat) - Rc*sin(thetaLaunch))
dxnandex = isnan(dx)
dx[dxnandex] = DepthIncrement/tan(thetaLaunch[dxnandex])
dx[0,] = 0
dxsum = cumsum(dx,axis=0)

Yuck. But at least I managed to get some rays that made sense.

The next step is to convert the ray paths to two-way travel times, and then compare the depth that would be calculated if the ray tracing were done with a second sound speed profile.

More ray tracing – doing it right this time

Okay, enough of me and my hack methods of ray tracing.  I’m going to do it right this time.  And in Python.  I’m starting by working with Val – he was kind enough to send me his Matlab ray tracing code, which is very similar to what I would like to do, although he hasn’t exactly designed it for bathymetric purposes.  But hey, ray tracing is ray tracing, right?  So I’m starting out by looking at his code – I love reading through Val’s code, it’s like reading a book.  So well commented!  And so thorough in the background explanations.  Even my little pea brain can understand most of it.  Also, for reference, I’m reading the ray tracing section of “Principles of Underwater Sound” by Robert J. Urick (1983) – p. 123-126 mostly.

One thing that Val mentioned about his Matlab code was that he had a bug in it that cropped up whenever the launch angles of the rays started above the horizontal.  He wanted me to look at it and see if I could find the problem.

Interpolation using Scipy/Numpy

As part of a little script I’m writing, I need to do some simple linear interpolation. The Matlab equivalent of what I’m doing is called ‘interp1′. So far I’ve come across two ways to do 1-d, linear interpolation. One is ‘interp’ in numpy. The other is ‘interp1d’ in scipy.interpolate. I’m not completely sure of the difference. Is one faster? Is one older? I’ve googled around a bit, but still haven’t found a clear answer. For now, I’ve implemented ‘interp1d’, which is less similar to Matlab’s ‘interp1′. You first define an interpolated object given your x and y vectors. Then you call that object with your new x-values to generate the new y-values.

And here is an example, chopped out of my code:

depthvector1 = r_[0:nadirdepth:DepthIncrement]
interpfun1 = interp1d(depth1,ssp1) # my x and y vectors
sspvector1 = interpfun1(depthvector1) # find the new y's for this x

Python – matrices or arrays?

Sometimes I think I have my biggest breakthroughs while biking home. Tonight, for instance, it dawned on me (on the stretch between the beach and Patterson) just how awful the Matlab version of my ray tracing code really is. And I realised that I could vastly improve its simplicity and efficiency by using matrices (Yikes! Why on earth did I implement all of those nested loops?). I pictured the steps and the math involved, the Matlab commands that I would need, and got really excited – until I realized that I don’t know how to do any of the same stuff in Python yet. First of all, I need to figure out how to work with arrays in Matlab. Thankfully, there’s a special page on Scipy.org Matlab users who are trying to migrate to Numpy/Scipy. Yes! And here it is: Numpy for Matlab Users. My first question was, “How do I make it do element-wise operations?” In Matlab, you need to modify the operator, for example using “.*” to multiply by elements, and just “*” to do matrix multiplication. Matlab thinks in linear algebra for 2d matrices. But, as I quickly learned, the default array in Numpy does element by element operations, unless you create a special matrix object. Awesome.

Tkinter and GUI building

I’m back to ray tracing again. And since I’m trying to re-create and expand on the Matlab version of this code, I am finding myself having to learn lots of little details – and big details. One of these things is GUI building. The standard GUI builder that comes with Python is TKinter. I’ve used this a bit before, but now I’m having to think about doing more complicated things with it. The Matlab version of my code used an interactive GUI. In Matlab, there’s a utility called GUIDE that gives you a GUI to build a GUI :-) You can put buttons, sliders, graphs, etc, into your GUI window, and then it will automatically generate a skeleton script that you can fill with commands telling Matlab what to do with it. So now I’m wondering if there’s something I can use with TKinter that does a similar thing. I’m sure there is, and I just need to find it…

Python for ray tracing

I just found some python scripts that I started writing about a year ago, including one in which I was trying to read in a sound speed profile through the water column, and using Snell’s law to compute a *very* simple piecewise ray trace.  So I create several beams that launch from one location (ie. a multibeam head), all departing a different launch angle between -75:75 degrees. The purpose of it is to see how much effect an incorrect sound speed profile will have on the estimate of the seafloor depth for each beam.  I already wrote it in Matlab, so re-writing it in Python was really just an exercise to learn Python.  I’d only ever gotten as far as asking the user which sound speed files to use.  I think it’s a good project for me to work through. :)