aboutsummaryrefslogtreecommitdiff
path: root/julia/CrystFEL/src/datatemplates.jl
blob: 7ede6843e2ede5b952628564c65af259da363f6f (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
module DataTemplates

import ..CrystFEL: libcrystfel
export DataTemplate, InternalDataTemplate, loaddatatemplate
export wavelength, cameralength
export translategroup!

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

# The Julia-side structure, needed to house the pointer to the C structure
# Without this, we would only ever have a Ptr{DataTemplate}, not a DataTemplate.
mutable struct DataTemplate
    internalptr::Ptr{InternalDataTemplate}
end

"""
    loaddatatemplate(filename)

Creates a CrystFEL DataTemplate by loading a geometry file.

Corresponds to CrystFEL C API function `data_template_new_from_file()`.
"""
function loaddatatemplate(filename::AbstractString)

    out = ccall((:data_template_new_from_file, libcrystfel),
                Ptr{InternalDataTemplate}, (Cstring,), filename)
    if out == C_NULL
        throw(ArgumentError("Failed to load geometry file"))
    end

    dt = DataTemplate(out)

    finalizer(dt) do x
        ccall((:data_template_free, libcrystfel),
              Cvoid, (Ptr{InternalDataTemplate},), x.internalptr)
    end

    return dt
end


"""
    wavelength(datatemplate)

Retrieves the radiation wavelength from a `DataTemplate`, if possible.

It's not always possible to do this.  Some geometry files declare the
wavelength as a parameter to be retrieved fom each image's metadata.  A
program using this routine should take this possibility into account.

Corresponds to CrystFEL C API function `data_template_get_wavelength_if_possible`.
"""
function wavelength(dtempl::DataTemplate)
    wl = ccall((:data_template_get_wavelength_if_possible, libcrystfel),
               Cdouble, (Ptr{InternalDataTemplate},), dtempl.internalptr)
    if isnan(wl)
        return nothing
    else
        return wl
    end
end


"""
    cameralength(datatemplate)

Retrieves the camera length from a `DataTemplate`, if possible.

It's not always possible to do this.  Some geometry files declare the
detector position(s) as a parameter to be retrieved fom each image's metadata.  A
program using this routine should take this possibility into account.

Corresponds to CrystFEL C API function `data_template_get_clen_if_possible`.
"""
function cameralength(dtempl::DataTemplate)
    clen = ccall((:data_template_get_clen_if_possible, libcrystfel),
                 Cdouble, (Ptr{InternalDataTemplate},), dtempl.internalptr)
    if isnan(clen)
        return nothing
    else
        return clen
    end
end


"""
    translategroup!(datatemplate, groupname, xshift, yshift, zshift)

Modifies `DataTemplate` by moving the specified panel group by the specified
amount (in metres).

Corresponds to CrystFEL C API function `data_template_translate_group`.
"""
function translategroup!(dtempl::DataTemplate, groupname, xshift, yshift, zshift)
    r = @ccall libcrystfel.data_template_translate_group_m(dtempl.internalptr::Ptr{InternalDataTemplate},
                                                             groupname::Cstring,
                                                             xshift::Cdouble,
                                                             yshift::Cdouble,
                                                             zshift::Cdouble)::Cint
    if r != 0
        throw(ErrorException("Failed to shift DataTemplate"))
    end

end


end  # of module