Beyond the Mouse LAB 4: Control Structures
September 19, 21
Instructor: Jeff Freymueller
x7286 Elvey 413B jfreymueller@alaska.eduTA: Shanshan Li
Last Updated: September 12, 2016
Due: Tuesday September 26, before class
Lab slides
NONE.
Introduction
In this week's lecture we introduced constructs that allow you to increase the complexity of problems
you can solve with your programs. Flow control language features like if-else
, for
,
or while
allow you to create tree like structures of code rather than one long list of function calls. Great!
Today you'll expand the problem we worked on last week - the GPS time series. The goal is to have you create
a Matlab script which will process a bunch of data files: load data, put it in an array of structs, create figures.
Exercise
You will use the data from last week. Download this archive (zip) to get the data files and necessary functions. This time we are going to do the exercise in a somehwat more sophisticated, and much more generalized, way. Some of you might have gotten partway to here in your solution to last week's exercise. You should be able to re-use some of the code from last week, but think about what changes before you just copy and paste.
Let me write out in detail what I expect you to do:
- Create a cell array that contains the names of the three GPS stations: BZ09, FAIR and WHIT.
- Create a cell array or struct array to hold your data (your choice). Either way, I will refer to it below as an "array of structs".
- Operate on each element of the station list cell array using its length as a terminating condition;
use a
for
-loop. Each time through thefor
loop, do the following: - Add a new struct to an array of structs; the struct contains the 5 fields: 'time', 'lon', 'lat', 'height', and 'name', much like you did last week.
- Add the name of the GPS station you are currently working on to the name field
- Create a variable that contains the filename that contains the data for this station using the entry
in the cell-array you are currently iterating through, the format is: /path/to/STATIONAME.dat
(note that this is a unixy/Linuxy way of dscribing the pathname, and it will look
different on windows, starting with a drive letter and using backslashes).
There are at least three equivalent ways to construct a composite string:
filename = ['/path/to/' STATIONAME '.dat'];
filename = sprintf('/path/to/%s.dat', STATIONAME);
filename = strcat('/path/to/', STATIONAME, '.dat');
- Call the function read_gps_data. Use the variable that holds the filename as input parameter and populate the other fields of your structure with the return values you get from this call.
- The next thing you will do is plot the timeseries for each GPS station. We want you to use a
while
loop. Not necessarily because it's the best thing to do (in fact, it isn't), we just want you to have used it. - Define and initialize a counter variable
- Start your while loop and use the length of your array as the termination condition.
- Call the plot_gps_timeseries function provided in the files. You will get the figure handle as a return value; assign it to a variable!
- You want Matlab to automatically save the resulting figure (hence the need for a figure handle). First create a new output filename. This time make sure it ends in one of the graphics formats supported by the saveas function.
- Save your figure by calling
saveas
and handing it the figure handle, filename, and optionally a format defintion it's supposed to use (i.e. if you want colored postscript, add 'psc2' as third parameter). - increment your counter
- CONGRATULATIONS, YOU JUST CREATED PUBLISHABLE FIGURES THAT ARE REPRODUCIBLE! AND WE'RE ONLY A MONTH IN THE SEMESTER.
- If you finish this really quickly, save multiple versions of the plot, for example both png and postscript.
Now add some better error checking:
textread
will complain (throw an error) if a file does not exist.
Given that you might be dealing with hundreds of stations at a time
it would be frustrating to stop possibly lenghty processing whenever
there is a typo in the list of site names, or if certain
files are just not there. Guess what: try-catch will help!
Try putting the read_gps_data function call in a try-block and catch possible errors. Give a useful error message (see the lecture notes) OR display your very own error message, i.e. file X does not exist, where X is the parameter you handed to read_gps_data. Then add a bogus station name to the cell array that holds the station names and run your script. You should get at least one empty plot and a meaningful message, but the script should not abort - yeah!
Are you done already? Extra credit
Take a look at the code below, which uses the dir function to get a list of the files matching
the name wildcard *.dat
.
listing = dir('*.dat');
nfiles = length(listing);
listing(3).name
strrep(listing(3).name, '.dat', '')
Make another version of your script that gets a list of the available data files and
plots each one, instead of depending on you to make up the list of names.
You will either want to put each name into an element of the cell array, or
else change your code to use the struct array listing to provide the station names.
You can get the station name from the file name by using the function strrep
to replace the string '.dat'
with ''
(an empty string).
Does this example show you why it is really useful to use a systematic scheme for naming files?
Helpful Matlab Functions:
Here is a list of functions that might be of help.
figure
: create a canvas to plot on; get a handle so you can refer to itlength
,size
: determine the length/size of arrays/matricessaveas
: save a figure in a specified formatstruct
: create a structsprintf
: create a formatted stringstrcat
: concatenate many strings to get one single stringstrrep
: replace text within a string
Dr. Jeffrey T. Freymueller
Professor of Geophysics
Geophysical Institute
University of Alaska, Fairbanks
Fairbanks, AK 99775-7320