diff options
Diffstat (limited to 'julia/CrystFEL/src/peaklist.jl')
-rw-r--r-- | julia/CrystFEL/src/peaklist.jl | 117 |
1 files changed, 117 insertions, 0 deletions
diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl new file mode 100644 index 00000000..9eedad27 --- /dev/null +++ b/julia/CrystFEL/src/peaklist.jl @@ -0,0 +1,117 @@ +module PeakLists + +using Printf +import ..CrystFEL: libcrystfel +export PeakList, InternalPeakList + +mutable struct InternalPeak + fs::Cdouble + ss::Cdouble + panelnumber::Cint + intensity::Cdouble + name::Cstring +end + +mutable struct InternalPeakList end + +mutable struct PeakList + internalptr::Ptr{InternalPeakList} +end + + +function PeakList() + out = @ccall libcrystfel.image_feature_list_new()::Ptr{InternalPeakList} + if out == C_NULL + throw(ArgumentError("Failed to create peak list")) + end + finalizer(PeakList(out)) do pl + @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid + end +end + + +Base.copy(::PeakList) = throw(ErrorException("Cannot copy(::PeakList), must deepcopy")) + +function Base.deepcopy(peaklist::PeakList) + out = @ccall libcrystfel.image_feature_list_copy(peaklist.internalptr::Ptr{InternalPeakList})::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Failed to copy peak list")) + end + PeakList(out) +end + +function Base.length(peaklist::PeakList) + @ccall libcrystfel.image_feature_count(peaklist.internalptr::Ptr{InternalPeakList})::Cint +end + +Base.firstindex(peaklist::PeakList) = 1 +Base.lastindex(peaklist::PeakList) = length(peaklist) + + +function Base.push!(peaklist::PeakList, fs, ss, panelnumber, intensity, name=nothing) + + rname = isnothing(name) ? C_NULL : @ccall strdup(name::Cstring)::Cstring + + @ccall libcrystfel.image_add_feature(peaklist.internalptr::Ptr{InternalPeakList}, + fs::Cdouble, ss::Cdouble, panelnumber::Cint, + intensity::Cdouble, rname::Cstring)::Cvoid +end + + +function Base.getindex(peaklist::PeakList, n) + out = @ccall(libcrystfel.image_get_feature(peaklist.internalptr::Ptr{InternalPeakList}, + (n-1)::Cint)::Ptr{InternalPeak}) + if out == C_NULL + throw(BoundsError(peaklist, n)) + end + pdata = unsafe_load(out) + if pdata.name == C_NULL + nname = nothing + else + nname = unsafe_string(pdata.name) + end + return (fs=pdata.fs, ss=pdata.ss, panelnumber=pdata.panelnumber, + intensity=pdata.intensity, name=nname) +end + + +function Base.iterate(peaklist::PeakList) + if length(peaklist) > 0 + return peaklist[1],(1,length(peaklist)) + else + return nothing + end +end + + +function Base.iterate(peaklist::PeakList, state) + let nxt = state[1]+1 + len = state[2] + if nxt == len+1 + return nothing + else + return peaklist[nxt],(nxt,state[2]) + end + end +end + + +function Base.show(io::IO, ::MIME"text/plain", peaklist::PeakList) + println(io, "Peak list with ", length(peaklist), " peaks") + print(io, " fs ss panel intensity name") + let n = 0 + for pk in Iterators.take(peaklist, 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮") + break + end + write(io, "\n") + @printf(io, "%7.2f %7.2f %6i %10.2f %s", + pk.fs, pk.ss, pk.panelnumber, pk.intensity, pk.name) + n += 1 + end + end +end + +end # of module |