Skip to content

Commit

Permalink
Add basic reading of MicroProf FRT
Browse files Browse the repository at this point in the history
  • Loading branch information
jaakkor2 committed Oct 30, 2024
1 parent a56d8f2 commit 78ebf96
Show file tree
Hide file tree
Showing 4 changed files with 82 additions and 0 deletions.
4 changes: 4 additions & 0 deletions Project.toml
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,11 @@ uuid = "6da23c8c-444c-4310-aaa6-9150b66cb193"
authors = ["Jaakko Ruohio <jaakkor2@gmail.com>"]
version = "0.1.4-DEV"

[deps]
Dates = "ade2ca70-3891-5945-98fb-dc099432e06a"

[compat]
Dates = "1.10"
julia = "1.10"

[extras]
Expand Down
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@

Reader for surface profiler data sets written in Julia language. Implemented formats
* Wyko OPD
* MicroProf FRT

```julia
using SurfaceProfileReaders
Expand Down
5 changes: 5 additions & 0 deletions src/SurfaceProfileReaders.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,16 @@
Readers for surface profiler data sets implemented in Julia.
* Wyko OPD `readopd`
* MicroProf FRT `readfrt`
"""
module SurfaceProfileReaders

using Dates: unix2datetime

export readopd, opdprepplot
export readfrt

include("opd.jl")
include("frt.jl")

end
72 changes: 72 additions & 0 deletions src/frt.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,72 @@
"""
readfrt(fn)
Read Microprof FRT file
"""
function readfrt(fn)
io = open(fn, "r")
magic = String(read(io, 16)) #
magic == "FRTM_GLIDERV1.00" || error("Not a Microprof FRT file.")
blkid1 = read(io, 2)
data = Dict()

push!(data, "images" => Dict())
while true
twobytes = read(io, 2)
isempty(twobytes) && break
blkid = reinterpret(Int16, twobytes)[1] # blkid
n = reinterpret(Int32, read(io, 4))[1] # number of bytes
if blkid == 102 # image header
w, h, nbits = reinterpret(Int32, read(io, n))
push!(data, blkid => (; w, h, nbits))
elseif blkid == 11 # preview image
(; w, h, nbits) = data[102]
T = integertype(nbits)
img = reinterpret(T, read(io, n))
img = reshape(img, (w, h))
push!(data["images"], "preview" => img)
elseif blkid == 125
n_img, dunno = reinterpret(Int32, read(io, 8))
for i in 1:n_img
type, w, h, nbits = reinterpret(Int32, read(io, 16))
T = integertype(nbits)
len = (nbits ÷ 8)*w*h
img = reinterpret(T, read(io, len))
img = reshape(img, (w, h))
type = type in keys(frt_image_types) ? frt_image_types[type] : type
push!(data["images"], type => img)
end
elseif blkid == 103
d = read(io, n)
width, height = reinterpret(Float64, d[1:16])
unknown = d[17:end]
push!(data, "xy_dimensions" => (; width, height, unknown))
elseif blkid == 108
d = read(io, n)
scale = reinterpret(Float64, d[5:12])[1]
unknown = d[1:4]
push!(data, "z_dimensions" => (; scale, unknown))
elseif blkid == 114 # time
t_start, t_stop, dt = reinterpret(Int32, read(io, n))
t_start = unix2datetime(t_start)
t_stop = unix2datetime(t_stop)
push!(data, "timing" => (; dt, t_start, t_stop))
elseif blkid == 172 # user
d = read(io, n)
len = reinterpret(Int32, d[1:4])[1]
user = String(d[(1:len) .+ 4])
user = rstrip(user, '\0')
push!(data, "user" => user)
else
haskey(data, blkid) && @error "Id $blkid already read.."
push!(data, blkid => read(io, n))
end
end

close(io)
return data
end

const frt_image_types = Dict(0x4 => "height", 0x2 => "intensity", 0x10000002 => "intensity_bottom", 0x10000004 => "height_bottom", 0x20800 => "thickness")

integertype(w::Integer) = w == 8 ? Int8 : w == 16 ? Int16 : w == 32 ? Int32 : w == 64 ? Int64 : throw(ArgumentError("Unsupported byte width"))

0 comments on commit 78ebf96

Please sign in to comment.