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 DetGeoms
export Panel, DetGeom
guardian = []
function protect(guardian, obj)
push!(guardian, obj)
obj
end
function unprotect(guardian, obj)
let pos = findfirst(==(obj), guardian)
if pos !== nothing
deleteat!(guardian, pos)
end
end
end
mutable struct Panel
name::Cstring
cx::Cdouble
cy::Cdouble
cz::Cdouble
pixel_pitch::Cdouble
adu_per_photon::Cdouble
max_adu::Cdouble
fsx::Cdouble
fsy::Cdouble
fsz::Cdouble
ssx::Cdouble
ssy::Cdouble
ssz::Cdouble
w::Cint
h::Cint
group::Ptr{Cvoid}
end
mutable struct DetGeom
panels::Ptr{Panel}
n_panels::Cint
top_group::Ptr{Cvoid}
end
"""
Panel(name, width, height, (cnx, cny), clen, (fsx,fsy,fsz), (ssx,ssy,ssz), pixelsize, aduperphoton)
Create a panel for a CrystFEL `DetGeom`.
* `cnx` and `cny`: Corner position in pixel units
* `clen`: Corner z-position in meters
* `(fsx,fsy,fsz)`: Fast scan vector in pixel units
* `(ssx,ssy,ssz)`: Slow scan vector in pixel units
* `pixelsize`: Conversion factor from pixels to meters
* `aduperphoton`: Detector units per quantum, for error estimation
Additional keyword arguments:
* `max_adu`=Inf: Saturation value
* `group`: Panel group (for hierarchy)
"""
function Panel(name, width, height, corner::Tuple{Real, Real}, clen,
fs::Tuple{Real,Real,Real}, ss::Tuple{Real,Real,Real},
pixel_pitch, adu_per_photon,
max_adu=Inf, group=C_NULL)
myname = protect(guardian, deepcopy(name))
p = Panel(pointer(myname),
corner[1], corner[2], clen/pixel_pitch,
pixel_pitch, adu_per_photon, max_adu,
fs[1], fs[2], fs[3],
ss[1], ss[2], ss[3],
width, height, group)
finalizer(p) do x
unprotect(guardian, myname)
end
end
function Base.show(io::IO, p::Panel)
write(io, "Panel(")
write(io, "name=\"")
write(io, unsafe_string(p.name))
write(io, "\", center=(")
show(io, p.cx); write(io, ", "); show(io, p.cy); write(io, ", "); show(io, p.cz)
write(io, "), fs=(")
show(io, p.fsx); write(io, ", "); show(io, p.fsy); write(io, ", "); show(io, p.fsz)
write(io, "), ss=(")
show(io, p.ssx); write(io, ", "); show(io, p.ssy); write(io, ", "); show(io, p.ssz)
write(io, "), size=(")
show(io, p.w); write(io, ", "); show(io, p.h)
write(io, "))")
end
"""
DetGeom(panels; topgroup=g)
Create a CrystFEL `DetGeom` from a vector of `Panel`s. Optionally set the
panel group which should be the top of the hierarchy.
"""
function DetGeom(panels; topgroup=C_NULL)
pmem = Base.Libc.malloc(sizeof(panels[1])*length(panels))
for (i,panel) in enumerate(panels)
Base.unsafe_copyto!(pmem, pointer(panel), 1)
end
dg = DetGeom(pmem, length(panels), topgroup)
finalize(dg) do x
Base.Libc.free(dg.panels)
end
end
end # of module
|