Skip to content

Commit

Permalink
Upgrade libmseed library to v3.0.16
Browse files Browse the repository at this point in the history
The new v3.0.16 of libmseed has a different API to the previous
unstable v3 versions, so a minor upgrade of the library is needed.

- Update installation instructions since the package is registered.
- Update C types to match new libmseed structs.
- Add tests for Julia type constructors.
  • Loading branch information
anowacki committed Jul 25, 2023
1 parent eb198a7 commit 0e1cfe4
Show file tree
Hide file tree
Showing 9 changed files with 64 additions and 24 deletions.
8 changes: 8 additions & 0 deletions NEWS.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,11 @@
# LibMseed.jl v0.3.0 release notes

## libmseed library version

- libmseed version v3.0.16 is required. This is the first stable
version of libmseed v3.


# LibMseed.jl v0.2.1 release notes

## Notable bug fixes
Expand Down
4 changes: 2 additions & 2 deletions Project.toml
Original file line number Diff line number Diff line change
@@ -1,15 +1,15 @@
name = "LibMseed"
uuid = "1f77302d-495a-4b02-8d15-b81beb84162e"
authors = ["Andy Nowacki <a.nowacki@leeds.ac.uk>"]
version = "0.2.1"
version = "0.3.0"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"
libmseed_jll = "ccc2c699-b150-5417-88f2-a95a0d1581d9"

[compat]
julia = "1.6"
libmseed_jll = "3.0.10"
libmseed_jll = "3.0.16"

[extras]
Test = "8dfed614-e22c-5e08-85e1-65c5234f0b40"
Expand Down
9 changes: 6 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -15,9 +15,12 @@ and writing data in the miniSEED format.
You can install LibMseed.jl from Julia's package manager like so:

```julia
julia> using Pkg; Pkg.add(url="https://github.com/anowacki/LibMseed.jl")
julia> using Pkg; Pkg.add("LibMseed")
```

You do not need to separately install the `libmseed` library. Instead,
LibMseed.jl installs its own version automatically.

## Using the package

`LibMseed` exports several functions with common names, such as `read_file`
Expand All @@ -40,7 +43,7 @@ MseedTraceList:
```

### Reading data from memory
Use the unexported `LibMseed.read_buffer` function to read miniSEED data
Use the `LibMseed.read_buffer` function to read miniSEED data
from memory. This data should be a `Vector` of `UInt8`s.

```julia
Expand Down Expand Up @@ -118,7 +121,7 @@ set to `nothing`.

### Writing data
To write a continuous set of evenly-spaced samples to disk in miniSEED
format, use the unexported `LibMseed.write_file` function.
format, use the `LibMseed.write_file` function.

Here we create some random data, set the necessary parameters (including
the date of the first sample) and write it to a new file, `"example2.mseed"`.
Expand Down
19 changes: 11 additions & 8 deletions src/c_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -48,11 +48,11 @@ const MSF_MAINTAINMSTL = 0x0200
const nstime_t = Int64

# C structs used for libmseed
struct MS3Record
@eval struct MS3Record
record::Cstring
reclen::Int32
swapflag::UInt8
sid::NTuple{64, UInt8}
sid::NTuple{$LM_SIDLEN, UInt8}
formatversion::UInt8
flags::UInt8
starttime::nstime_t
Expand Down Expand Up @@ -116,22 +116,25 @@ struct MS3TraceSeg
next::Ptr{MS3TraceSeg}
end

struct MS3TraceID
sid::NTuple{64, UInt8}
const MSTRACEID_SKIPLIST_HEIGHT = 8

@eval struct MS3TraceID
sid::NTuple{$LM_SIDLEN, UInt8}
pubversion::UInt8
earliest::nstime_t
latest::nstime_t
prvtptr::Ptr{Cvoid}
numsegments::UInt32
first::Ptr{MS3TraceSeg}
last::Ptr{MS3TraceSeg}
next::Ptr{MS3TraceID}
next::NTuple{$MSTRACEID_SKIPLIST_HEIGHT, Ptr{MS3TraceID}}
height::UInt8
end

struct MS3TraceList
numtraces::UInt32
traces::Ptr{MS3TraceID}
last::Ptr{MS3TraceID}
numtraceids::UInt32
traces::MS3TraceID
prngstate::UInt64
end

struct MS3Tolerance
Expand Down
2 changes: 1 addition & 1 deletion src/io.jl
Original file line number Diff line number Diff line change
Expand Up @@ -402,7 +402,7 @@ _file_message(file) = file !== nothing ? " in file '$file'" : ""
If `time_tolerance` is not `nothing`, create a closure over
`time_tolerance` and return a `Base.CFunction` and an `MS3Tolerance`
containing a reference to
containing a reference to the function.
`func_pointer` should be guarded in a `Base.@GC_preserve` block when
`tolerance` is used to avoid the former being garbage collected.
Expand Down
29 changes: 19 additions & 10 deletions src/julia_types.jl
Original file line number Diff line number Diff line change
Expand Up @@ -112,24 +112,30 @@ This function builds a full `MseedTraceList` and copies the data from
`mstl`.
"""
function MseedTraceList(mstl::Ref{Ptr{MS3TraceList}})
@debug "Making MseedTraceList from $(mstl[])"
if mstl[] == C_NULL
throw(ArgumentError("cannot create a MseedTraceList from a null pointer"))
end

this_tracelist = unsafe_load(mstl[])
numtraces = Int32(this_tracelist.numtraces)
tracelist = MseedTraceList(Vector{MseedTraceID}(undef, numtraces))
numtraceids = Int32(this_tracelist.numtraceids)
tracelist = MseedTraceList(Vector{MseedTraceID}(undef, numtraceids))

# Follow linked list through MS3TraceIDs
this_traceid = unsafe_load(this_tracelist.traces) # First
for itraceid in 1:numtraces
# Follow skip list through MS3TraceIDs
@debug "Attempting to load trace id $(this_tracelist.traces.next[1])"
this_traceid = unsafe_load(this_tracelist.traces.next[1]) # First
for itraceid in 1:numtraceids
tracelist.traces[itraceid] = MseedTraceID(this_traceid)

# Move to the next trace id
if itraceid != numtraces && this_traceid.next == C_NULL
if itraceid != numtraceids && this_traceid.next[1] == C_NULL
error("unexpectedly reached end of trace id list")
elseif itraceid == numtraces && this_traceid.next != C_NULL
elseif itraceid == numtraceids && this_traceid.next[1] != C_NULL
@warn("unexpected extra trace ids in list")
break
end
if itraceid != numtraces
this_traceid = unsafe_load(this_traceid.next)
if itraceid != numtraceids
this_traceid = unsafe_load(this_traceid.next[1])
end
end

Expand Down Expand Up @@ -183,7 +189,10 @@ from a call to one of `libmseed`'s functions.
function MseedTraceSegment(T, this_traceseg::MS3TraceSeg)
starttime = NanosecondDateTime(this_traceseg.starttime)
endtime = NanosecondDateTime(this_traceseg.endtime)
sample_rate = this_traceseg.samprate
# Note that negative sampling rates mean a sampling interval
sample_rate = this_traceseg.samprate >= 0 ?
this_traceseg.samprate :
-1/this_traceseg.samprate
sample_count = this_traceseg.samplecnt
numsamples = Int(this_traceseg.numsamples)
samples_ptr = convert(Ptr{T}, this_traceseg.datasamples)
Expand Down
4 changes: 4 additions & 0 deletions src/nanoseconddatetime.jl
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,10 @@ to the millisecond resolution that `DateTime` offers.
# Other functions
- [`nearest_datetime`](@ref): Return the `Dates.DateTime` nearest to the
`NanosecondDateTime`.
# Extended `Dates` functions
- `Date`: Return the `Date` part of a `NanosecondDateTime`.
- `Time`: Return the `Time` part of a `NanosecondDateTime` to full ns precision.
"""
struct NanosecondDateTime
"`DateTime`, to millisecond resolution"
Expand Down
12 changes: 12 additions & 0 deletions test/julia_types.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
using Test
using LibMseed

@testset "MseedTraceList" begin
@testset "Construction" begin
@testset "Errors" begin
@test_throws ArgumentError MseedTraceList(
Ref(Ptr{LibMseed.MS3TraceList}(C_NULL))
)
end
end
end
1 change: 1 addition & 0 deletions test/runtests.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,7 @@ using Test

@testset "All tests" begin
include("nanoseconddatetime.jl")
include("julia_types.jl")
include("io.jl")
include("channel_codes.jl")
end

0 comments on commit 0e1cfe4

Please sign in to comment.