Skip to content

Commit 8f1bdca

Browse files
dcjonesBen J. Ward
authored andcommitted
Julia 1.0 support (#18)
1 parent 35f1fb7 commit 8f1bdca

25 files changed

+175
-185
lines changed

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ os:
44
- linux
55
- osx
66
julia:
7-
- 0.6
7+
- 0.7
88
- nightly
99
matrix:
1010
allow_failures:

REQUIRE

Lines changed: 9 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,9 @@
1-
julia 0.6
2-
Automa 0.6.1
3-
BGZFStreams 0.1.4
4-
BioCore 1.4
5-
BioSequences 0.8.3
6-
BioSymbols 2.0
7-
BufferedStreams 0.4
8-
GenomicFeatures 0.2.1
9-
IntervalTrees 0.4.1
1+
julia 0.7
2+
Automa 0.7.0
3+
BGZFStreams 0.3.0
4+
BioCore 2.0.2
5+
BioSequences 1.0.0
6+
BioSymbols 3.1.0
7+
BufferedStreams 1.0.0
8+
GenomicFeatures 1.0.0
9+
IntervalTrees 1.0.0

appveyor.yml

Lines changed: 23 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,18 @@
11
environment:
22
matrix:
3-
- JULIA_URL: "https://julialang-s3.julialang.org/bin/winnt/x64/0.6/julia-0.6-latest-win64.exe"
4-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
3+
- julia_version: 0.7
4+
- julia_version: 1
5+
- julia_version: nightly
56

6-
matrix:
7-
allow_failures:
8-
- JULIA_URL: "https://julialangnightlies-s3.julialang.org/bin/winnt/x64/julia-latest-win64.exe"
7+
platform:
8+
# - x86 # 32-bit
9+
- x64 # 64-bit
10+
11+
# # Uncomment the following lines to allow failures on nightly julia
12+
# # (tests will run but not make your overall status red)
13+
# matrix:
14+
# allow_failures:
15+
# - julia_version: nightly
916

1017
branches:
1118
only:
@@ -19,24 +26,18 @@ notifications:
1926
on_build_status_changed: false
2027

2128
install:
22-
- ps: "[System.Net.ServicePointManager]::SecurityProtocol = [System.Net.SecurityProtocolType]::Tls12"
23-
# If there's a newer build queued for the same PR, cancel this one
24-
- ps: if ($env:APPVEYOR_PULL_REQUEST_NUMBER -and $env:APPVEYOR_BUILD_NUMBER -ne ((Invoke-RestMethod `
25-
https://ci.appveyor.com/api/projects/$env:APPVEYOR_ACCOUNT_NAME/$env:APPVEYOR_PROJECT_SLUG/history?recordsNumber=50).builds | `
26-
Where-Object pullRequestId -eq $env:APPVEYOR_PULL_REQUEST_NUMBER)[0].buildNumber) { `
27-
throw "There are newer queued builds for this pull request, failing early." }
28-
# Download most recent Julia Windows binary
29-
- ps: (new-object net.webclient).DownloadFile(
30-
$env:JULIA_URL,
31-
"C:\projects\julia-binary.exe")
32-
# Run installer silently, output to C:\projects\julia
33-
- C:\projects\julia-binary.exe /S /D=C:\projects\julia
29+
- ps: iex ((new-object net.webclient).DownloadString("https://raw.githubusercontent.com/JuliaCI/Appveyor.jl/version-1/bin/install.ps1"))
3430

3531
build_script:
36-
# Need to convert from shallow to complete for Pkg.clone to work
37-
- IF EXIST .git\shallow (git fetch --unshallow)
38-
- C:\projects\julia\bin\julia -e "versioninfo();
39-
Pkg.clone(pwd(), \"BioAlignments\"); Pkg.build(\"BioAlignments\")"
32+
- echo "%JL_BUILD_SCRIPT%"
33+
- C:\julia\bin\julia -e "%JL_BUILD_SCRIPT%"
4034

4135
test_script:
42-
- C:\projects\julia\bin\julia -e "Pkg.test(\"BioAlignments\")"
36+
- echo "%JL_TEST_SCRIPT%"
37+
- C:\julia\bin\julia -e "%JL_TEST_SCRIPT%"
38+
39+
# # Uncomment to support code coverage upload. Should only be enabled for packages
40+
# # which would have coverage gaps without running on Windows
41+
#on_success:
42+
# - echo "%JL_CODECOV_SCRIPT%"
43+
# - C:\julia\bin\julia -e "%JL_CODECOV_SCRIPT%"

src/BioAlignments.jl

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -90,6 +90,7 @@ import BioSequences
9090
import BioSymbols
9191
import GenomicFeatures: eachoverlap
9292
import IntervalTrees
93+
using LinearAlgebra: diagind
9394

9495
include("operations.jl")
9596
include("anchors.jl")

src/alignment.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ function cigar(aln::Alignment)
155155
for i in 2:length(anchors)
156156
n = max(anchors[i].seqpos - anchors[i-1].seqpos,
157157
anchors[i].refpos - anchors[i-1].refpos)
158-
print(out, n, Char(anchors[i].op))
158+
print(out, n, convert(Char, anchors[i].op))
159159
end
160160
return String(take!(out))
161161
end
@@ -171,7 +171,7 @@ function check_alignment_anchors(anchors)
171171
error("Alignments must begin with on OP_START anchor.")
172172
end
173173

174-
for i in 2:endof(anchors)
174+
for i in 2:lastindex(anchors)
175175
if anchors[i].refpos < anchors[i-1].refpos ||
176176
anchors[i].seqpos < anchors[i-1].seqpos
177177
error("Alignment anchors must be sorted.")
@@ -208,7 +208,7 @@ end
208208
quote
209209
anchors = aln.anchors
210210
lo = 1
211-
hi = endof(anchors)
211+
hi = lastindex(anchors)
212212
if !(anchors[lo].$pos < i anchors[hi].$pos)
213213
return 0
214214
end

src/bam/auxdata.jl

Lines changed: 8 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
# BAM Auxiliary Data
22
# ==================
33

4-
struct AuxData <: Associative{String,Any}
4+
struct AuxData <: AbstractDict{String,Any}
55
data::Vector{UInt8}
66
end
77

@@ -21,15 +21,11 @@ function Base.length(aux::AuxData)
2121
return len
2222
end
2323

24-
function Base.start(aux::AuxData)
25-
return 1
26-
end
27-
28-
function Base.done(aux::AuxData, pos)
29-
return pos > length(aux.data)
30-
end
24+
function Base.iterate(aux::AuxData, pos=1)
25+
if pos > length(aux.data)
26+
return nothing
27+
end
3128

32-
function Base.next(aux::AuxData, pos)
3329
data = aux.data
3430
@label doit
3531
t1 = data[pos]
@@ -95,14 +91,14 @@ end
9591
function loadauxvalue(data::Vector{UInt8}, p::Int, ::Type{Vector{T}}) where T
9692
n = unsafe_load(Ptr{Int32}(pointer(data, p)))
9793
p += 4
98-
xs = Vector{T}(n)
99-
unsafe_copy!(pointer(xs), Ptr{T}(pointer(data, p)), n)
94+
xs = Vector{T}(undef, n)
95+
unsafe_copyto!(pointer(xs), Ptr{T}(pointer(data, p)), n)
10096
return p + n * sizeof(T), xs
10197
end
10298

10399
function loadauxvalue(data::Vector{UInt8}, p::Int, ::Type{String})
104100
dataptr = pointer(data, p)
105-
endptr = ccall(:memchr, Ptr{Void}, (Ptr{Void}, Cint, Csize_t),
101+
endptr = ccall(:memchr, Ptr{Cvoid}, (Ptr{Cvoid}, Cint, Csize_t),
106102
dataptr, '\0', length(data) - p + 1)
107103
q::Int = p + (endptr - dataptr) - 1
108104
return q + 2, String(data[p:q])

src/bam/bai.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ struct BAI
1212
index::GenomicFeatures.Indexes.BGZFIndex
1313

1414
# number of unmapped reads
15-
n_no_coors::Nullable{Int}
15+
n_no_coors::Union{Nothing, Int}
1616
end
1717

1818
"""
@@ -48,9 +48,9 @@ function read_bai(input::IO)
4848
n_refs = read(input, Int32)
4949
index = GenomicFeatures.Indexes.read_bgzfindex(input, n_refs)
5050
if !eof(input)
51-
n_no_coors = Nullable{Int}(read(input, UInt64))
51+
n_no_coors = read(input, UInt64)
5252
else
53-
n_no_coors = Nullable{Int}()
53+
n_no_coors = nothing
5454
end
5555

5656
return BAI(index, n_no_coors)

src/bam/overlap.jl

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -7,7 +7,7 @@ struct OverlapIterator{T}
77
interval::UnitRange{Int}
88
end
99

10-
function Base.iteratorsize(::Type{OverlapIterator{T}}) where T
10+
function Base.IteratorSize(::Type{OverlapIterator{T}}) where T
1111
return Base.SizeUnknown()
1212
end
1313

@@ -45,43 +45,39 @@ mutable struct OverlapIteratorState
4545
record::Record
4646
end
4747

48-
function Base.start(iter::OverlapIterator)
49-
refindex = findfirst(iter.reader.refseqnames, iter.refname)
48+
function Base.iterate(iter::OverlapIterator)
49+
refindex = findfirst(isequal(iter.refname), iter.reader.refseqnames)
5050
if refindex == 0
5151
throw(ArgumentError("sequence name $(iter.refname) is not found in the header"))
5252
end
53-
@assert !isnull(iter.reader.index)
54-
chunks = GenomicFeatures.Indexes.overlapchunks(get(iter.reader.index).index, refindex, iter.interval)
53+
@assert iter.reader.index !== nothing
54+
chunks = GenomicFeatures.Indexes.overlapchunks(iter.reader.index.index, refindex, iter.interval)
5555
if !isempty(chunks)
5656
seek(iter.reader, first(chunks).start)
5757
end
58-
return OverlapIteratorState(refindex, chunks, 1, Record())
58+
state = OverlapIteratorState(refindex, chunks, 1, Record())
59+
return iterate(iter, state)
5960
end
6061

61-
function Base.done(iter::OverlapIterator, state)
62-
while state.chunkid endof(state.chunks)
62+
function Base.iterate(iter::OverlapIterator, state)
63+
while state.chunkid lastindex(state.chunks)
6364
chunk = state.chunks[state.chunkid]
6465
while BGZFStreams.virtualoffset(iter.reader.stream) < chunk.stop
6566
read!(iter.reader, state.record)
6667
c = compare_intervals(state.record, (state.refindex, iter.interval))
6768
if c == 0
68-
# overlapping
69-
return false
69+
return copy(state.record), state
7070
elseif c > 0
7171
# no more overlapping records in this chunk since records are sorted
7272
break
7373
end
7474
end
7575
state.chunkid += 1
76-
if state.chunkid endof(state.chunks)
76+
if state.chunkid lastindex(state.chunks)
7777
seek(iter.reader, state.chunks[state.chunkid].start)
7878
end
7979
end
80-
return true
81-
end
82-
83-
function Base.next(::OverlapIterator, state)
84-
return copy(state.record), state
80+
return nothing
8581
end
8682

8783
function compare_intervals(record::Record, interval::Tuple{Int,UnitRange{Int}})

src/bam/reader.jl

Lines changed: 9 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ mutable struct Reader{T} <: BioCore.IO.AbstractReader
1616
start_offset::BGZFStreams.VirtualOffset
1717
refseqnames::Vector{String}
1818
refseqlens::Vector{Int}
19-
index::Nullable{BAI}
19+
index::Union{Nothing, BAI}
2020
end
2121

2222
function Base.eltype(::Type{Reader{T}}) where T
@@ -55,7 +55,7 @@ If `fillSQ` is `true`, this function fills missing "SQ" metainfo in the header.
5555
function header(reader::Reader; fillSQ::Bool=false)::SAM.Header
5656
header = reader.header
5757
if fillSQ
58-
if !isempty(find(reader.header, "SQ"))
58+
if !isempty(findall(reader.header, "SQ"))
5959
throw(ArgumentError("SAM header already has SQ records"))
6060
end
6161
header = copy(header)
@@ -78,15 +78,10 @@ function Base.seekstart(reader::Reader)
7878
seek(reader.stream, reader.start_offset)
7979
end
8080

81-
function Base.start(reader::Reader)
82-
return Record()
83-
end
84-
85-
function Base.done(reader::Reader, rec)
86-
return eof(reader)
87-
end
88-
89-
function Base.next(reader::Reader, rec)
81+
function Base.iterate(reader::Reader, rec=Record())
82+
if eof(reader)
83+
return nothing
84+
end
9085
read!(reader, rec)
9186
return copy(rec), rec
9287
end
@@ -104,15 +99,15 @@ function init_bam_reader(input::BGZFStreams.BGZFStream)
10499

105100
# SAM header
106101
textlen = read(input, Int32)
107-
samreader = SAM.Reader(IOBuffer(read(input, UInt8, textlen)))
102+
samreader = SAM.Reader(IOBuffer(read(input, textlen)))
108103

109104
# reference sequences
110105
refseqnames = String[]
111106
refseqlens = Int[]
112107
n_refs = read(input, Int32)
113108
for _ in 1:n_refs
114109
namelen = read(input, Int32)
115-
data = read(input, UInt8, namelen)
110+
data = read(input, namelen)
116111
seqname = unsafe_string(pointer(data))
117112
seqlen = read(input, Int32)
118113
push!(refseqnames, seqname)
@@ -128,7 +123,7 @@ function init_bam_reader(input::BGZFStreams.BGZFStream)
128123
voffset,
129124
refseqnames,
130125
refseqlens,
131-
Nullable{BAI}())
126+
nothing)
132127
end
133128

134129
function init_bam_reader(input::IO)

src/bam/record.jl

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ See also `BAM.cigar_rle`.
341341
function cigar(record::Record, checkCG::Bool = true)::String
342342
buf = IOBuffer()
343343
for (op, len) in zip(cigar_rle(record, checkCG)...)
344-
print(buf, len, Char(op))
344+
print(buf, len, convert(Char, op))
345345
end
346346
return String(take!(buf))
347347
end
@@ -503,9 +503,9 @@ Get the segment sequence of `record`.
503503
function sequence(record::Record)::BioSequences.DNASequence
504504
checkfilled(record)
505505
seqlen = seqlength(record)
506-
data = Vector{UInt64}(cld(seqlen, 16))
506+
data = Vector{UInt64}(undef, cld(seqlen, 16))
507507
src::Ptr{UInt64} = pointer(record.data, seqname_length(record) + n_cigar_op(record, false) * 4 + 1)
508-
for i in 1:endof(data)
508+
for i in 1:lastindex(data)
509509
# copy data flipping high and low nybble
510510
x = unsafe_load(src, i)
511511
data[i] = (x & 0x0f0f0f0f0f0f0f0f) << 4 | (x & 0xf0f0f0f0f0f0f0f0) >> 4

0 commit comments

Comments
 (0)