aboutsummaryrefslogtreecommitdiff
path: root/julia/CrystFEL/src/symmetry.jl
blob: fd3ce7b2d021c9c27e34b9a153966de288b7f6e4 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
module Symmetry

import ..CrystFEL: libcrystfel
export SymOpList, InternalSymOpList, InternalIntegerMatrix
export symmetry_name


# Types for pointers returned by libcrystfel
mutable struct InternalSymOpList end
mutable struct InternalIntegerMatrix end


# Exposed types
mutable struct SymOpList
    internalptr::Ptr{InternalSymOpList}
end


mutable struct SymOp
    internalptr::Ptr{InternalIntegerMatrix}
end


function SymOpList(pointgroup::AbstractString)

    out = ccall((:get_pointgroup, libcrystfel),
                Ptr{InternalSymOpList}, (Cstring,), pointgroup)
    if out == C_NULL
        throw(OutOfMemoryError())
    end

    sym = SymOpList(out)

    finalizer(sym) do x
        ccall((:free_symoplist, libcrystfel),
              Cvoid, (Ptr{InternalSymOpList},), x.internalptr)
    end

    return sym

end


function Base.getindex(sym::SymOpList, i::Int)

    if (i<1) || (i > length(sym))
        throw(BoundsError())
    end

    out = ccall((:get_symop, libcrystfel),
                Ptr{InternalIntegerMatrix},
                (Ptr{InternalSymOpList},Ptr{Cvoid},Cint),
                sym.internalptr,C_NULL,i-1)

    if out == C_NULL
        throw(OutOfMemoryError())
    end

    return SymOp(out)

end


function Base.length(sym::SymOpList)
    return ccall((:num_equivs, libcrystfel),
                 Cint, (Ptr{InternalSymOpList},Ptr{Cvoid}),
                 sym.internalptr, C_NULL)
end


function hkl_op(op::SymOp)
    s = ccall((:name_equiv, libcrystfel),
               Cstring,
               (Ptr{InternalIntegerMatrix},),
               op.internalptr)
    return unsafe_string(s)
end


function symmetry_name(sym::SymOpList)
    s = ccall((:symmetry_name, libcrystfel),
               Cstring,
               (Ptr{InternalSymOpList},),
               sym.internalptr)
    return unsafe_string(s)
end


function Base.iterate(sym::SymOpList)
    return (sym[1], 2)
end


function Base.iterate(sym::SymOpList, i)
    if i > length(sym)
        return nothing
    else
        return (sym[i], i+1)
    end
end


function Base.show(io::IO, ::MIME"text/plain", sym::SymOpList)
    print(io, length(sym), "-element SymOpList (\"", symmetry_name(sym), "\")")
    for op in sym
        print(io, "\n", hkl_op(op))
    end
end


function Base.show(io::IO, sym::SymOpList)
    write(io, "SymOpList(\"", symmetry_name(sym), "\")")
end


function Base.show(io::IO, op::SymOp)
    write(io, "SymOp(")
    write(io, "\"")
    write(io, hkl_op(op))
    write(io, "\")")
end

end  # of module