aboutsummaryrefslogtreecommitdiff
path: root/julia/CrystFEL/src/crystal.jl
blob: 129c028cd8b31cc0f889733f17908c54af357cd4 (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
module Crystals

import ..CrystFEL: libcrystfel
import ..CrystFEL.RefLists: RefList, InternalRefList, UnmergedReflection
import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell
export Crystal, InternalCrystal

# Represents the real C-side (opaque) structure.
mutable struct InternalCrystal end

mutable struct Crystal
    internalptr::Ptr{InternalCrystal}
    in_image   # if true, this PeakList belongs to an Image struct
end


function Crystal(cell::UnitCell; profileradius=2e6, mosaicity=0)

    out = ccall((:crystal_new, libcrystfel),
                Ptr{InternalCrystal}, ())

    if out == C_NULL
        throw(ArgumentError("Failed to create crystal"))
    end

    # We make a copy of the cell, to avoid memory model shenanigans
    uccopy = ccall((:cell_new_from_cell, libcrystfel),
                   Ptr{InternalUnitCell}, (Ptr{InternalUnitCell},),
                   cell.internalptr)

    ccall((:crystal_set_cell, libcrystfel),
          Cvoid, (Ptr{InternalCrystal},Ptr{InternalUnitCell}),
          out, uccopy)

    ccall((:crystal_set_profile_radius, libcrystfel),
          Cvoid, (Ptr{InternalCrystal},Cdouble),
          out, profileradius)

    ccall((:crystal_set_mosaicity, libcrystfel),
          Cvoid, (Ptr{InternalCrystal},Cdouble),
          out, mosaicity)

    cr = Crystal(out, false)

    finalizer(cr) do x
        if !x.in_image
            ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},),
                  x.internalptr)
        end
    end

    return cr
end


function Base.setproperty!(cr::Crystal, name::Symbol, val)
    if name === :internalptr
        setfield!(cr, :internalptr, val)
    else
        if name === :reflections
            if val isa RefList{UnmergedReflection}
                ccall((:crystal_set_reflections, libcrystfel),
                      Cvoid, (Ptr{InternalCrystal},Ptr{InternalRefList}),
                      cr.internalptr, val.internalptr)
            else
                throw(ArgumentError("Must be a RefList{UnmergedReflection}"))
            end
        end
    end
end


end   # of module