Welcome to the online documentation and tutorial pages for the waveform suite for MATLAB!
Within these pages you'll find information to get you up and running with the waveform suite. The waveform suite is a collection of matlab classes that work together to speed up and simplify the import and manipulation of time-series data. Originally conceived to manipulate seismic data, it may be applied to any regularly sampled time-series data that is associated with a location.
This update includes several improvements, minor bug fixes, and allows the access to SAC, ANTELOPE, SEISAN, WINSTON, and Ad-Hoc file systems.
Examples of the waveform suite in use
To find out what things you can do
to an object, type help classname/object.
If you don't include the classname ('waveform' in our examples) you may get the wrong help text. Many of the files I use with waveform objects are overloaded functions (an overloaded function is a function that has the same name as an existing matlab function, but knows how to operate specifically on your object. Don't worry about matlab confusing the function with an existing function-- matlab is designed to use overloaded functions in a contextual basis) .
If you want to know the functions that can be used with a particular object, use the methods command.
The best of both worlds can be found by changing directory to the waveform directory, and then using the help command. Here's an example that's dated to 2/28/2005:
>> cd /home/celso/matlab_objects/@waveform
>> help waveform
ABS Absolute value for the waveform object
ADDFIELD add fields and values to waveform object(s)
CLEARHISTORY reset history of a waveform
ALIGN resamples a waveform at over every specified interval
GET Get waveform properties
CLIP clips a waveform's data at a particular max/min value range
COMBINE merges waveforms based on start/end times and SCNL info.
DELFIELD removes fields from waveform object(s)
DEMEAN remove offset voltage from signal
DETREND remove linear trend from a waveform
DIFF Differentiate waveform
DISP Waveform disp overloaded operator
DISPLAY Waveform Display overloaded operator
DOUBLE returns a waveform's data as a double type
EXTRACT creates a waveform with a subset of another's data.
FILLGAPS - fill missing data with values of your choice
FIX_DATA_LENGTH adjust length of waveform data to allow batch processing
GETM Get MULTIPLE waveform properties
GETPEAKS return mask for peak values for a waveform
GETTIMERANGE returns the list of start and end times from a waveform array
HILBERT (for WAVEFORM objects) Discrete-time analytic Hilbert transform.
HISTORY retrieve the history of a waveform object
INTEGRATE integrates a waveform signal
ISEMPTY returns TRUE if waveform contains no data
ISMEMBER waveform implementation of ismember
LOADOBJ updates older versions of waveform class upon loading
LOADSAC creates a waveform from a SAC file
LOOKUPUNITS checks the antelope database to find out what units are
MIN Largest value of a waveform.
MEAN Average or mean value of waveform's data.
MEDIAN middlemost value of waveform's sorted data.
MIN Smallest value of a waveform.
MINUS (-) Overloaded waveform subtraction w - q
MRDIVIDE (/) Slash or right matrix divide for WAVEFORMS.
MTIMES (*) Overloaded Matrix multiply for waveforms (UNIMPLEMENTED!).
PLOT plots a waveform object
PLUS (+) waveform addition w + q
POWER (.^) waveform implementation of element-by-element power (.^)
RDIVIDE (./) Right array divide for WAVEFORMS.
RESAMPLE resamples a waveform at over every specified interval
RMS root mean square of a waveform
SAVESAC creates a SAC file from a waveform
SET Set properties for waveform object(s)
SMOOTH overloaded smooth function for waveform
STACK stacks data from array of waveforms
STD Standard deviation of a waveform
SUBTIME grabs time-indexed snippets of waveform data.
WAVEFORM = TAPER(WAVEFORM,R) applies a cosine taper to the ends of a
TIMES (.*) overloaded Array multiply for WAVEFORM objects.
- Unary minus.
VAR Variance of a waveform's data
WAVEFORM Waveform Class constructor
WAVEFORM2SOUND generate a wav file from the existing waveform
ADDHISTORY function in charge of adding history to a waveform
waveform is both a directory and a function.
WAVEFORM Waveform Class constructor
w = WAVEFORM(datasource, scnlobjects, starttimes, endtimes)
loads waveform from the specified DATASOURCE
SCNL stands for STATION-CHANNEL-NETWORK-LOCATION.
multiple start-endtime pairs may be used, while station-channel
pairs can be provided as an array of scnlobjects
w = WAVEFORM() creates a blank waveform out of thin air
The default waveform has STATION = '', CHANNEL = '', data = [],
starttime = '1/1/1970', and UNITS = 'counts'
w = WAVEFORM(station, channel, samplerate, starttime, data)
manually puts together a waveform object from the minimum
required fields.
STATION - which seismic station, ex. 'OKCF' (default '')
CHANNEL - 'BHZ', 'SHZ', and the like (default '')
SAMPLERATE - Sampling frequency, in Hz (default nan)
DATA - a vector of seismic amplitudes (default [])
STARTTIME - Start time, in most any format (default '1/1/1970')
ENDTIME - end time, in most any format
---------- USING WAVEFORM WITH ANTELOPE ------------
The Antelope Toolbox must be installed.
---------- USING WAVEFORM WITH WINSTON -------------
To use the waveform files with winston, you need to have the usgs.jar
file. If you have already installed SWARM, then this .jar file already
exist in your swarm/lib directory (or thereabouts).
Edit Matlab's classpath.txt file (located in the toolbox/local
directory) and add the location of this .jar files.
WINSTON WARNING: Currently, data received through winston is not adjusted
for instrument gain, therefore, it is in COUNTS. To fix this, you'll
need to multiply it by the correct gain. Ex. W = W .* 6.67; This
merely scales the data...
------------ EXAMPLE USAGE --------------------------
% This example gets a few minutes of data (starting a day ago) from
% the public avo winston server. Data returned is for the EHZ channel
% at each of the three selected stations.
myStations = {'OKCF','PV6','SSLS'}; myChannels = 'EHZ';
scnlList = scnlobject(myStations,myChannels);
mySource = datasource('avopubwinston');
w = waveform(mySource, scnlList, now - 1, now - .98);
see also SCNLOBJECT, DATASOURCE
wow! There's the useful information -- actually most of these functions may never be used. Now, you can go back to any of those functions from "convert" to "which_archive" and get the help specific to that function. However, you already have enough information to decide if any of these functions will do.
finally, if you don't know
where to find stuff look up lookfor
and which commands.
lookfor will give you a list of functions with the
specified keyword in the first line of their help, and
which tells you where a particular function can be
found.
w =
waveform(datasource, scnlobject, startTime,
endTime)
Retrieves waveform(s) from the
selected datasource, returning all waveforms that are described by
the scnlobject list (ie, matching the correct
station/channel/network/location parameters), for the times
requested. The datasource object allows waveform to retrieve from
any one of a number of sources:
Antelope or
WINSTON databases, SAC
or SEISAN
files, or even waveforms saved as .mat files.
w = waveform
creates a blank waveform. You get a waveform with a blank station
and channel, and a location and network of '--', a frequency of
NaN Hz, and a start time equal to antelope's default start
time '1/1/1970 00:00:00'. Changing any or all of this waveform's
information can be done through the set function.
w =
waveform(station, component, freq, start,
data)
manually puts together a waveform
object using each of these specified values. This is designed to
allow you to create a waveform based on data from other places or
from data that you've conjured up yourself.
When you load data from the antelope database, the waveform object will take out the voltage offset -- i.e. subtract the mean value of the data-- and also apply the station calibration (as found in the antelope database). If the antelope has faulty station calibration information, then your data may be scaled incorrectly. When loading from Winston, the data will NOT be scaled; you can scale the data manually, though.
A waveform object contains only the following information:
You can use the struct(waveform) command to return
the absolutely raw data and see for yourself... struct
returns a structure based on the listed object.
However, much more information can be asked of it via the waveform/get routine.
get(w,'station') - returns the station call-sign.
ie. VNSS, OKCF, etc...get(w,'component') - returns the station
component. ie. SHZ, BHZ, BHE, BHN, SHN, etc...get(w,'fs') - returns the frequency of the sample.
this is an average sample rateget(w,'start') - provides a readable date
associated with this waveform's start timeget(w,'start_antelope') - returns the start time
in Antelope time. That is, the number of seconds elapsed since
1/1/1970get(w,'start_matlab') - returns the start time in
matlab format. That is, the number of days since 00-JAN-0000.
hrs/minutes/seconds are treated as fractions.get(w,'end') - returns the readable date
associated with the waveform's end timeget(w,'end_antelope') and get(w,'end_matlab') work
like 'start_antelope' and 'start_matlab', only for the end of the
data...get(w,'data') - returns the vector of seismic
dataget(w,'nyq') - returns the nyquist frequency of
the sampleget(w,'period') - what else? returns 1 /
Frequency.get(w,'data_length') - gives you the number of
samples in your data setget(w,'duration') - [also:
'duration_matlab', 'duration_antelope']
gives you the time-span of your data set.If w is a matrix of waveforms, you will get back a
same-dimensional matrix of answers, in cell format. (See matlab
help for accessing cells).
Using set, you can change the values of your waveform data. If
the original waveform is a matrix of waveforms, then the change
will be applied to all. The general form of set
is:
modifiedWaveform = set(originalWaveform, 'PropertyToChange', newValue, ...)
set(w,'station',value) - changes the station
call-sign. ie. value is 'VNSS' or 'OKCF', etc...set(w,'component',value) -change the station
component. ie. value is 'SHZ' or 'BHZ' or 'BHE', etc...set(w,'fs', value) - change frequency of the
sample. Be careful using this, as it doesn't change the data, only
how the data is interpreted... better yet, pretend I never
mentioned it.set(w,'start', value) - changes the date
associated with this waveform's start time. Can be a string, or
matlab format or even antelope format (see the get
command above for more detail)set(w,'data', values) - assign a vector of seismic
data to the waveformset(w, 'station', value1, 'component', value2) -
makes both changes to your waveform.set doesn't change your original waveform,
it only changes the waveform you've assigned it to.
PLOT plots a waveform object
h = plot(waveform)
Plots a waveform object, handling the title and axis labeling. The
output parameter h is optional. If used, the handle to the waveform
plots will be returned. These can be used to change properties of the
plotted waveforms.
h = plot(waveform, ...)
Plots a waveform object, passing additional parameters to matlab's PLOT
routine.
h = plot(waveform, 'xunit', xvalue, ...)
sets the xunit property of the graph, which is used to determine how
the times of the waveform are interpereted. Possible values for XVALUE
are 'seconds', 'minutes', 'hours', 'days', 'day_of_year', 'date'.
For multiple waveforms, specifying XUNITs of 'seconds', 'minutes', 'hours' will
cause all the waveforms to be plotted starting at 0. An XUNIT of
'date' will force all waveforms to plot starting at their starttimes.
the default XUNIT is seconds
For the following examples:
% let W be a 10-minute long waveform starting at 04/02/2005 01:00:00
% let W2 be a 1-minute long waveform (same station) starting at 04/02/2005 01:05:00
EXAMPLE 1:
% This example plots the waveforms at their absolute times...
plot(W,'xunit','date'); % plots the waveform in blue
hold on;
h = plot(W2,'xunit','date', 'r', 'linewidth', 1);
%plots your other waveform in red, and with a wider line
EXAMPLE 2:
% This example plots the waveforms, starting at time 0
plot(W); % plots the waveform in blue with seconds on the x axis
hold on;
plot(W2,'xunit','s', 'color', [.5 .5 .5]); % plots your other
% waveform, starting in unison
% with the prev waveform, then
% change the color of the new
% plot to grey (RGB)
For a list of properties you can set (such as color, linestyle, etc...)
type get(h) after plotting something.
also, now Y can be autoscaled with the property pair: 'autoscale',true
although it only works for single waveforms...
if the wave parameter is a vector of waveform objects, then plot will plot them all on the same axis, and to scale. You can also pass formatting comands to the plot function.
Ex. h = plot(wave,'','date', 'r.-', 'linewidth',
1);
This plots your other waveform in a red dash-dotted line, and makes
the line thicker.
This basically just subtracts the mean of the data. One nice
feature is that this is designed to work with arrays of waveform
objects.
ex. fixedWave = demean(VNSS20050403PMwave);
then returns that value as a scalar.
ex. avgVoltageOffset = demean (mySampleWave);
You can also pass this function an array of waveforms, and it will
return a same-shaped array of mean values.
This is great for trying to generate envelopes.
ex. hilbert_envelope = hilbert(mySampleWave);
if you have waveform objects with similar sample rates and durations, you can stack their waveforms.
This clones the first waveform in the array, (station ID, start
time, etc) and then sums the data from each of the included
waveforms. This does no error checking, so it will crash if your
arrays don't overlap. You'll definitely want to change the header
information for the waveform using the get command
after successfully stacking things, so that it becomes obvious that
the data is stacked.
example. (veni1 .. veni4 are waveform
objects)
w = [veni1 veni2 veni3 veni4];
mystack = stack(w);
mystack = set(mystack,'STATION','VNSS_Stack');
So, you want to grab a subset of data from within the waveform? Here's the function to let you do that.
Let's start with a waveform that was loaded like so:
bigWave = waveform('OKCF','SHZ','10/5/2005 12:00','10/5/2005
24:00');
twelve hours of data... that's an awful big wave to have to deal
with, especially at a 100Hz sample rate. Maybe I'd like to work
with the 14:00 - 15:00 subsection... You could go back to
the database and reload. But, maybe you've done some funky
filtering or something else that you don't want to have to repeat.
Here are two ways to do that:
ex1. subWave =
extract(bigWave,'TIME','10/5/2005/14:00','10/5/2005
15:00'); ex2. subWave = extract
(bigWave,'Index&Duration', 100 * 60 * 60 * 2,
'1:00'); Where 100 * 60 * 60 * 2 is the expected
offset of your second hour of data...
Several functions in matlab require using data of the same
length, and this function will do that. By default, it will find
the longest waveform, and then pad all the others with zero to make
them match up..
ex. myWaves = fix_data_length(myWaves);
these commands can be piggybacked.. The following command takes four waveforms, stacks them, renames the station, removes any offset in voltage, and then plots up the results. While this is not great programming practice, (because it's unreadable), it demonstrates some of the versitility of using these waveform objects..
plot(demean(set(stack([veni1 veni2 veni3
veni4]),'station','VNSS_Stack')));