diff options
author | Thomas White <taw@physics.org> | 2024-01-18 17:55:45 +0100 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2024-02-06 16:59:35 +0100 |
commit | 1b4fdfa5cc1ab4fe9a1cdcbb0bf1602834eaec13 (patch) | |
tree | 03061175385337244c7605c5810db1d6affcd779 /julia | |
parent | ff89f33377133352838f27057525701e71c9df7c (diff) |
Julia: MM semantics for Image.crystals
Diffstat (limited to 'julia')
-rw-r--r-- | julia/CrystFEL/src/image.jl | 42 | ||||
-rw-r--r-- | julia/make-indexed.jl | 26 |
2 files changed, 60 insertions, 8 deletions
diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl index a9d9c28f..3384f0c9 100644 --- a/julia/CrystFEL/src/image.jl +++ b/julia/CrystFEL/src/image.jl @@ -14,6 +14,8 @@ const HEADER_CACHE_SIZE = 128 mutable struct CrystalRefListPair crystal::Ptr{InternalCrystal} reflist::Ptr{InternalRefList} + owns_crystal::Cint + owns_reflist::Cint end mutable struct InternalImage @@ -55,7 +57,7 @@ mutable struct Image end -function makecrystallist(listptr, n) +function makecrystallist(image, listptr, n) crystals = [] @@ -65,16 +67,33 @@ function makecrystallist(listptr, n) for i in 1:n pairptr = unsafe_load(listptr, i) - cr = Crystal(pairptr.crystal) + + # Re-use old Crystal if possible + n = findfirst(getfield(image, :crystals)) do x + x.internalptr == pairptr.crystal + end + + if n !== nothing + cr = getfield(image, :crystals)[n] + else + cr = Crystal(pairptr.crystal) + end + if pairptr.reflist == C_NULL reflist = nothing else reflist = RefList{UnmergedReflection}(pairptr.reflist, SymOpList("1")) + pairptr.owns_reflist = 0 end push!(crystals, (crystal=cr, reflections=reflist)) + pairptr.owns_crystal = 0 + unsafe_store!(listptr, pairptr, i) + # We are now responsible for freeing the Crystal and RefList end - crystals + image.crystals = map(x->x.crystal, crystals) + image.reflists = map(x->x.reflections, crystals) + return crystals end @@ -104,11 +123,12 @@ function Base.getproperty(image::Image, name::Symbol) idata = unsafe_load(image.internalptr) if name === :crystals - return makecrystallist(getproperty(idata, :crystals), - getproperty(idata, :n_crystals)) + return makecrystallist(image, + getfield(idata, :crystals), + getfield(idata, :n_crystals)) else - getproperty(idata, name) + getfield(idata, name) end end end @@ -155,6 +175,12 @@ function Base.setproperty!(image::Image, name::Symbol, val) assert_type(val, AbstractString) val = strdup(val) + elseif name === :crystals + return setfield!(image, :crystals, val) + + elseif name === :reflists + return setfield!(image, :reflists, val) + end idata = unsafe_load(image.internalptr) @@ -202,7 +228,7 @@ function Image(dtempl::DataTemplate) throw(ArgumentError("Failed to create image")) end - image = Image(out, nothing) + image = Image(out, nothing, [], []) finalizer(image) do x ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) @@ -234,7 +260,7 @@ function Image(dtempl::DataTemplate, throw(ArgumentError("Failed to load image")) end - image = Image(out, nothing) + image = Image(out, nothing, [], []) finalizer(image) do x ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) diff --git a/julia/make-indexed.jl b/julia/make-indexed.jl new file mode 100644 index 00000000..7a24f606 --- /dev/null +++ b/julia/make-indexed.jl @@ -0,0 +1,26 @@ +using CrystFEL +using Random + +# "Simulate" a diffraction pattern from the reflections +function sketch_pattern(image, cr) + reflist = predictreflections(cr, image) + peaklist = PeakList() + for refl in reflist + if randn() > 0 + let dpos = refl.detectorposition + push!(peaklist, dpos.fs, dpos.ss, dpos.panelnumber, 100.0) + end + end + end + return peaklist +end + + +dtempl = loaddatatemplate("julia/alignment-test.geom") +cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) +indexer = Indexer("asdf", dtempl, cell, retry=false, multilattice=false, refine=true) + +image = Image(dtempl) +cr = Crystal(rotatecell(cell)) +image.peaklist = sketch_pattern(image, cr) +index(image, indexer) |