Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add segy endian check #21

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions src/SegyIO.jl
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@ module SegyIO
include("types/SeisCon.jl")

#Reader
include("read/endianness.jl")
include("read/read_fileheader.jl")
include("read/read_traceheader.jl")
include("read/read_trace.jl")
Expand Down
28 changes: 28 additions & 0 deletions src/read/endianness.jl
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
"""
bswap_needed(s::IO)

Checks whether SEGY and host machine's byte order are same or not.

NOTE: comparison is done based on binary file header value (Data Sample Format)
thus stream (s::IO) must be opened from the begining of the file.

# Examples

s = open("/my/segy.segy", "r")
swap_bytes = bswap_needed(s)
"""
function bswap_needed(s::IO)
bfh = BinaryFileHeader()
fh_b2s = fh_byte2sample()

old_pos = position(s)
seek(s, fh_b2s["DataSampleFormat"])
dsf = read(s, typeof(bfh.DataSampleFormat))
seek(s, old_pos)

if dsf >= 1 && dsf <= 16
return false
else
return true
end
end
3 changes: 2 additions & 1 deletion src/read/read_block.jl
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@ end
function read_block!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, tmp_data, tmp_headers)

f = open(b.file)
swap_bytes = bswap_needed(f)
seek(f, b.startbyte)
brange = b.endbyte - b.startbyte
s = IOBuffer(read(f, brange))
Expand All @@ -29,6 +30,6 @@ function read_block!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, tm
tracee = min(trace + TRACE_CHUNKSIZE - 1, ntraces)
chunk = length(trace:tracee)*trace_size
sloc = IOBuffer(read(s, chunk))
read_traces!(sloc, view(tmp_headers, trace:tracee), view(tmp_data, :, trace:tracee), keys, th_b2s)
read_traces!(sloc, view(tmp_headers, trace:tracee), view(tmp_data, :, trace:tracee), keys, th_b2s; swap_bytes=swap_bytes)
end
end
6 changes: 4 additions & 2 deletions src/read/read_block_headers.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ export read_block_headers!
function read_block_headers!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf::Int, headers)

f = open(b.file)
swap_bytes = bswap_needed(f)
seek(f, b.startbyte)
brange = b.endbyte - b.startbyte
s = IOBuffer(read(f, brange))
Expand All @@ -23,7 +24,7 @@ function read_block_headers!(b::BlockScan, keys::Array{String, 1}, ns::Int, dsf:
tmph = zeros(UInt8, 240)
# Read each traceheader
for trace in 1:ntraces
read_traceheader!(s, keys, th_b2s, headers[trace]; th=tmph)
read_traceheader!(s, keys, th_b2s, headers[trace]; swap_bytes=swap_bytes, th=tmph)
skip(s, ns*4)
end

Expand All @@ -32,6 +33,7 @@ end
function read_block_headers!(b::BlockScan, ns::Int, dsf::Int, headers)

f = open(b.file)
swap_bytes = bswap_needed(f)
seek(f, b.startbyte)
brange = b.endbyte - b.startbyte
s = IOBuffer(read(f, brange))
Expand All @@ -50,7 +52,7 @@ function read_block_headers!(b::BlockScan, ns::Int, dsf::Int, headers)
th_b2s = th_byte2sample()
# Read each traceheader
for trace in 1:ntraces
read_traceheader!(s, th_b2s, headers[trace])
read_traceheader!(s, th_b2s, headers[trace]; swap_bytes=swap_bytes)
skip(s, ns*4)
end

Expand Down
7 changes: 5 additions & 2 deletions src/read/read_file.jl
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,11 @@ Read entire SEGY file from stream 's', only reading the header values in 'keys'.
"""
function read_file(s::IO, keys::Array{String, 1}, warn_user::Bool;
start_byte::Int = 3600, end_byte::Int = position(seekend(s)))

swap_bytes = bswap_needed(s)

# Read File Header
fh = read_fileheader(s)
fh = read_fileheader(s; swap_bytes=swap_bytes)

# Move to start of block
seek(s, start_byte)
Expand Down Expand Up @@ -53,7 +56,7 @@ function read_file(s::IO, keys::Array{String, 1}, warn_user::Bool;
tracee = min(trace + TRACE_CHUNKSIZE - 1, ntraces)
chunk = length(trace:tracee)*trace_size
sloc = IOBuffer(read(s, chunk))
read_traces!(sloc, view(headers, trace:tracee), view(data, :, trace:tracee), keys, th_b2s)
read_traces!(sloc, view(headers, trace:tracee), view(data, :, trace:tracee), keys, th_b2s; swap_bytes=swap_bytes)
end

return SeisBlock(fh, headers, data)
Expand Down
12 changes: 6 additions & 6 deletions src/read/read_fileheader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,17 +4,17 @@ export read_fileheader
"""
# Info

Use: fileheader = read_fileheader(s::IO; bigendian::Bool = true)
Use: fileheader = read_fileheader(s::IO; swap_bytes::Bool = bswap_needed(s))

Returns a binary file header formed using bytes 3200-3600 from the stream 's'.
"""
function read_fileheader(s::IO; bigendian::Bool = true)
return read_fileheader(s, fh_keys(); bigendian=bigendian)
function read_fileheader(s::IO; swap_bytes::Bool = bswap_needed(s))
return read_fileheader(s, fh_keys(); swap_bytes=swap_bytes)
end


"""
Use: fileheader = read_fileheader(s::IO, keys::Array{String,1}; bigendian::Bool = true)
Use: fileheader = read_fileheader(s::IO, keys::Array{String,1}; swap_bytes::Bool = bswap_needed(s))

Return a fileheader from stream 's' with the fields defined in 'keys'.

Expand All @@ -41,7 +41,7 @@ Read only the sample interval and number of traces from the file header.
0, 0, 0, 0, 0, 0, 0, 0, 0, 0, Dict("expf"=>3226,"sfe"=>3234,"rgc"=>3250,"jobid"=>3200,
"dt"=>3216,"nsfr"=>3222,"slen"=>3236,"vpol"=>3258,"renum"=>3208,"dsf"=>3224…))
"""
function read_fileheader(s::IO, keys::Array{String,1}; bigendian::Bool = true)
function read_fileheader(s::IO, keys::Array{String,1}; swap_bytes::Bool = bswap_needed(s))

# Return to start of stream
seekstart(s)
Expand All @@ -52,7 +52,7 @@ function read_fileheader(s::IO, keys::Array{String,1}; bigendian::Bool = true)
# Initialize binary file header
bfh = BinaryFileHeader()
fh_b2s = fh_byte2sample()
swp(x) = bigendian ? bswap(x) : x
swp(x) = swap_bytes ? bswap(x) : x

for k in keys

Expand Down
27 changes: 13 additions & 14 deletions src/read/read_trace.jl
Original file line number Diff line number Diff line change
@@ -1,54 +1,53 @@
export read_trace
export read_traces

"""
Use: read_trace!(s::IO,
Use: read_traces!(s::IO,
fh::BinaryFileHeader,
datatype::Type,
headers::AbstractArray{BinaryTraceHeader,1},
data::AbstractArray{<:Union{IBMFloat32, Float32}, 2},
trace::Int,
th_byte2sample::Dict{String,Int32})
th_byte2sample::Dict{String,Int32};
swap_bytes::Bool)

Reads 'trace' from the current position of stream 's' into 'headers' and
'data'.
"""
function read_traces!(s::IO, headers::AbstractVector{BinaryTraceHeader},
data::AbstractMatrix{<:Union{IBMFloat32, Float32}},
th_byte2sample::Dict{String,Int32})
th_byte2sample::Dict{String,Int32};
swap_bytes::Bool)

return read_traces!(s, headers, data, collect(keys(th_byte2sample)), th_byte2sample)
return read_traces!(s, headers, data, collect(keys(th_byte2sample)), th_byte2sample; swap_bytes=swap_bytes)
end

"""
Use: read_trace!(s::IO,
Use: read_traces!(s::IO,
fh::BinaryFileHeader,
datatype::Type,
headers::AbstractArray{BinaryTraceHeader,1},
data::AbstractArray{<:Union{IBMFloat32, Float32}, 2},
trace::Int,
keys::Array{String,1},
th_byte2sample::Dict{String,Int32})
th_byte2sample::Dict{String,Int32};
swap_bytes::Bool)

Reads 'trace' from the current position of stream 's' into 'headers' and
'data'. Only the header values in 'keys' and read.
"""
function read_traces!(s::IO, headers::AbstractVector{BinaryTraceHeader},
data::AbstractMatrix{DT}, keys::Array{String,1},
th_byte2sample::Dict{String,Int32}) where {DT<:Union{IBMFloat32, Float32}}
th_byte2sample::Dict{String,Int32}; swap_bytes::Bool) where {DT<:Union{IBMFloat32, Float32}}

ntrace = size(data, 2)
ntrace == 0 && return
swp = swp_func(DT)
tmph = zeros(UInt8, 240)
for trace_loc=0:ntrace-1
# Read trace header
read_traceheader!(s, keys, th_byte2sample, headers[trace_loc+1]; th=tmph)
read_traceheader!(s, keys, th_byte2sample, headers[trace_loc+1]; swap_bytes=swap_bytes, th=tmph)
# Read trace
read!(s, view(data, :, trace_loc+1))
end
map!(swp, data, data)
(swap_bytes) && (data = bswap.(data))
nothing
end

swp_func(::Type{Float32}) = bswap
swp_func(::Any) = x -> x
22 changes: 11 additions & 11 deletions src/read/read_traceheader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,34 +3,34 @@ export read_traceheader
"""
# Info

Use: fileheader = read_fileheader(s::IO; bigendian::Bool = true)
Use: fileheader = read_fileheader(s::IO; swap_bytes::Bool)


Returns a binary trace header formed from the current position in the stream 's'.
"""
function read_traceheader(s::IO, th_byte2sample::Dict{String,Int32}; bigendian::Bool=true, th=zeros(UInt8, 240))
return read_traceheader(s, collect(keys(th_byte2sample)), th_byte2sample; bigendian=bigendian, th=th)
function read_traceheader(s::IO, th_byte2sample::Dict{String,Int32}; swap_bytes::Bool, th=zeros(UInt8, 240))
return read_traceheader(s, collect(keys(th_byte2sample)), th_byte2sample; swap_bytes=swap_bytes, th=th)
end

"""
Use: fileheader = read_traceheader(s::IO, keys = Array{String,1}; bigendian::Bool = true)
Use: fileheader = read_traceheader(s::IO, keys = Array{String,1}; swap_bytes::Bool)

Returns a binary trace header formed from the current position in the stream 's', only reading
header values denoted in 'keys'.
"""
function read_traceheader(s::IO, keys::Array{String,1}, th_byte2sample::Dict{String, Int32};
bigendian::Bool = true, th=zeros(UInt8, 240))
swap_bytes::Bool, th=zeros(UInt8, 240))

# Initialize binary file header
traceheader = BinaryTraceHeader()

read_traceheader!(s, keys, th_byte2sample, traceheader; bigendian=bigendian, th=th)
read_traceheader!(s, keys, th_byte2sample, traceheader; swap_bytes=swap_bytes, th=th)
return traceheader
end

function read_traceheader!(s::IO, keys::Array{String,1}, th_byte2sample::Dict{String, Int32}, hdr::BinaryTraceHeader;
bigendian::Bool = true, th=zeros(UInt8, 240))

swap_bytes::Bool, th=zeros(UInt8, 240))
# read full trace header then split
read!(s, th)

Expand All @@ -40,11 +40,11 @@ function read_traceheader!(s::IO, keys::Array{String,1}, th_byte2sample::Dict{St
nb = sizeof(getfield(hdr, sym)) - 1
bst = th_byte2sample[k]+1
val = reinterpret(typeof(getfield(hdr, sym)), th[bst:bst+nb])[1]
bigendian && (val = bswap(val))
swap_bytes && (val = bswap(val))
setfield!(hdr, sym, val)
end
nothing
end

read_traceheader!(s::IO, thb::Dict{String, Int32}, hdr::BinaryTraceHeader; be::Bool = true, th=zeros(UInt8, 240)) =
read_traceheader!(s, collect(keys(thb)), thb, hdr; be=be, th=th)
read_traceheader!(s::IO, thb::Dict{String, Int32}, hdr::BinaryTraceHeader; swap_bytes::Bool, th=zeros(UInt8, 240)) =
read_traceheader!(s, collect(keys(thb)), thb, hdr; swap_bytes=swap_bytes, th=th)
8 changes: 6 additions & 2 deletions src/scan/scan_block.jl
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@ export scan_block

function scan_block(buf::IO, mem_block::Int, mem_trace::Int, keys::Array{String,1},
chunk_start::Int, file::String, th_byte2sample::Dict{String, Int32})


f = open(file)
swap_bytes = bswap_needed(f)
close(f)

# Calc info about this block
startbyte = position(buf) + chunk_start
ntraces_block = Int(mem_block/mem_trace)
Expand All @@ -12,7 +16,7 @@ function scan_block(buf::IO, mem_block::Int, mem_trace::Int, keys::Array{String,
# Read all headers and record end byte
while !eof(buf) && count<ntraces_block
count += 1
read_traceheader!(buf, keys, th_byte2sample, headers[count] )
read_traceheader!(buf, keys, th_byte2sample, headers[count]; swap_bytes=swap_bytes)
skip(buf, mem_trace-240)
end
endbyte = position(buf) + chunk_start
Expand Down
6 changes: 5 additions & 1 deletion src/scan/scan_shots.jl
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ export scan_shots
function scan_shots!(s::IO, mem_chunk::Int, mem_trace::Int,
keys::Array{String,1}, file::AbstractString, scan::Array{BlockScan,1}, fl_eof::Bool)

f = open(file)
swap_bytes = bswap_needed(f)
close(f)

# Load chunk into memory
chunk_start = position(s)
buf = IOBuffer(read(s, mem_chunk))
Expand All @@ -14,7 +18,7 @@ function scan_shots!(s::IO, mem_chunk::Int, mem_trace::Int,
# Get headers from chunk
th = zeros(UInt8, 240)
for i in 1:ntraces
read_traceheader!(buf, keys, SegyIO.th_b2s, headers[i]; th=th)
read_traceheader!(buf, keys, SegyIO.th_b2s, headers[i]; swap_bytes=swap_bytes, th=th)
skip(buf, mem_trace-240)
end

Expand Down
6 changes: 5 additions & 1 deletion src/types/IBMFloat32.jl
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ primitive type IBMFloat32 32 end
ieeeOfPieces(fr::UInt32, exp::Int32, sgn::UInt32) =
reinterpret(Float32, convert(UInt32,fr >>> 9) | convert(UInt32,exp << 23) | sgn) :: Float32

import Base.convert, Base.Float32
import Base.convert, Base.Float32, Base.bswap

function convert(::Type{Float32}, ibm::IBMFloat32)
local fr::UInt32 = ntoh(reinterpret(UInt32, ibm))
Expand All @@ -29,3 +29,7 @@ function convert(::Type{Float32}, ibm::IBMFloat32)
end
Float32(ibm::IBMFloat32) = convert(Float32,ibm)
## From JuliaSeis

function bswap(ibm::IBMFloat32)
return reinterpret(IBMFloat32, bswap(reinterpret(UInt32, ibm)))
end
4 changes: 2 additions & 2 deletions src/write/write_fileheader.jl
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ function write_fileheader(s::IO, fh::FileHeader)
##3200
# Write first section of assigned values
for field in fieldnames(typeof(fh.bfh))[1:27]
write(s, bswap(getfield(fh.bfh, field)))
write(s, getfield(fh.bfh, field))
end

##3260
Expand All @@ -34,7 +34,7 @@ function write_fileheader(s::IO, fh::FileHeader)
##3500
# Write second section of assigned values
for field in fieldnames(typeof(fh.bfh))[28:end]
write(s, bswap(getfield(fh.bfh, field)))
write(s, getfield(fh.bfh, field))
end

##3506
Expand Down
4 changes: 2 additions & 2 deletions src/write/write_trace.jl
Original file line number Diff line number Diff line change
Expand Up @@ -5,10 +5,10 @@ function write_trace(s::IO, block::SeisBlock, t::Int)
##000
# Write Header
for field in fieldnames(typeof(block.traceheaders[t]))
write(s, bswap(getfield(block.traceheaders[t], field)))
write(s, getfield(block.traceheaders[t], field))
end

##240
# Write trace
write(s, bswap.(Float32.(block.data[:,t])))
write(s, Float32.(block.data[:,t]))
end
Loading