aboutsummaryrefslogtreecommitdiff
path: root/julia/CrystFEL/src/peaklist.jl
diff options
context:
space:
mode:
Diffstat (limited to 'julia/CrystFEL/src/peaklist.jl')
-rw-r--r--julia/CrystFEL/src/peaklist.jl117
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