First Steps¶
SeisIO is designed around easy, fluid, and fast data access. At the most basic level, SeisIO uses an array-like structure called a SeisChannel for single-channel data, and a multichannel structure named SeisData.
Start Here¶
Create a new, empty SeisChannel object with
Ch = SeisChannel()
The meanings of the field names are explained here; you can also type
?SeisChannel
at the Julia prompt. You can edit field values manually, e.g.,
returning to the code block above,
Ch = SeisChannel()
Ch.loc = GeoLoc(lat=-90.0, lon=0.0, el=2835.0, az=0.0, inc=0.0)
Ch.name = "South pole"
or you can set them with keywords at creation:
Ch = SeisChannel(name="Templo de San José de La Floresta, Ajijic", fs=40.0)
Note that Strings in field names support full Unicode, so even graffiti can be saved and read back in. This is useful for data containing non-English characters.
SeisData structures are collections of channel data. They can be created with the SeisData() command, which can optionally create any number of empty channels at a time, e.g.,
S = SeisData() # empty structure, no channels
S1 = SeisData(12) # empty 12-channel structure
They can be explored similarly:
S = SeisData(1)
S.name[1] = "South pole"
S.loc[1] = GeoLoc(lat=-90.0, lon=0.0, el=2835.0, az=0.0, inc=0.0)
A collection of channels becomes a SeisData structure; for example,
L = GeoLoc(lat=46.1967, lon=-122.1875, el=1440.0, az=0.0, inc=0.0)
S = SeisData(SeisChannel(), SeisChannel())
S = SeisData(randSeisData(5), SeisChannel(),
SeisChannel(id="UW.SEP..EHZ", name="Darth Exploded", loc=L))
You can push channels onto existing SeisData structures, like adding one key to a dictionary. For example,
push!(S, Ch)
copies Ch to a new channel in S. Note that the new S[3] is not a view into Ch.
This is deliberate, as otherwise the workspace quickly becomes a mess of
redundant channels. Clean up with Ch = []
to free memory before moving on.
Operations on SeisData structures¶
We’re now ready for a short tutorial of what we can do with data structures. In the commands below, as in most of this documentation, Ch is a SeisChannel object and S is a SeisData object.
Adding channels to a SeisData structure¶
You’ve already seen one way to add a channel to SeisData: push!(S, SeisChannel()) adds an empty channel. Here are others:
S = randSeisData(4)
n = 3
append!(S, SeisData(n))
This initializes an empty n-channel SeisData structure and appends it to the end of S, similar to appending one array to another. S will have 7 channels, but the last three are empty.
The addition operator, +, calls push! and add!, with one key difference: to ensure reflexivity (i.e., S1 + S2 == S2 + S1), the + operator sorts the output (command sort!) and prunes empty channels (command prune!). Thus,
S = SeisData(2)
S1 = randSeisData(3)
S += S1
outputs only the three channels of random data initialized in the second line of the code block; in addition, they’re sorted by ID, so it’s likely that S != S1.
Search, Sort, and Prune¶
The easiest way to find channels of interest in a data structure is to use
findid or findchan. findid(id, S)
returns the numeric index i of the first channel in S where S.id[i] == id
. findchan(cha, S)
returns an array of numeric indices in S to all channels whose IDs satisfy occursin(cha, S.id[i])
.
For example:
L = GeoLoc(lat=46.1967, lon=-122.1875, el=1440.0, az=0.0, inc=0.0)
S = SeisData(randSeisData(5), SeisChannel(id="YY.STA1..EHZ"),
SeisChannel(id="UW.SEP..EHZ", name="Darth Exploded", loc=L))
findid("UW.SEP..EHZ", S) # 7
findchan("EHZ", S) # [6, 7], maybe others (depending on randSeisData)
You can sort channels in a structure by channel ID with the sort! command.
Several functions exist to prune empty and unwanted channels from SeisData structures. Revisiting the previous code block, for example, try these:
deleteat!(S, 1:2) # Delete first two channels of S
S -= 3 # Delete third channel of S
# Extract S[1] as a SeisChannel, removing it from S
C = pull(S, 1)
# Delete channels containing ".SEP."
delete!(S, ".SEP.", exact=false)
# Delete all channels whose S.x is empty
prune!(S)
S
S should have one channel left.
In the delete! command, specifying exact=false means that any channel whose
ID partly matches the string “.SEP.” gets deleted; by default,
delete!(S, str)
only matches channels where str is the exact ID. This is
an efficient way to remove unresponsive subnets and unwanted channel types, but
beware of accidental over-matching.
Next Steps¶
Because tracking arbitrary operations can be difficult, several functions have been written to keep track of data and operations in a semi-automated way. See the next section, working with data, for detailed discussion of managing data from the Julia command prompt.