diff options
-rw-r--r-- | julia/CrystFEL/src/image.jl | 42 | ||||
-rw-r--r-- | julia/make-indexed.jl | 26 | ||||
-rw-r--r-- | libcrystfel/src/image.c | 10 | ||||
-rw-r--r-- | libcrystfel/src/image.h | 2 |
4 files changed, 70 insertions, 10 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) diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index ab4518a9..e91c09d6 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -333,6 +333,8 @@ void image_add_crystal_refls(struct image *image, crs[n].cr = cryst; crs[n].refls = reflist; + crs[n].image_owns_crystal = 1; + crs[n].image_owns_refls = 1; image->crystals = crs; image->n_crystals = n+1; } @@ -373,8 +375,12 @@ void free_all_crystals(struct image *image) int i; if ( image->crystals == NULL ) return; for ( i=0; i<image->n_crystals; i++ ) { - crystal_free(image->crystals[i].cr); - reflist_free(image->crystals[i].refls); + if ( image->crystals[i].image_owns_crystal ) { + crystal_free(image->crystals[i].cr); + } + if ( image->crystals[i].image_owns_refls ) { + reflist_free(image->crystals[i].refls); + } } cffree(image->crystals); image->crystals = NULL; diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h index 74ff6eee..3db7de18 100644 --- a/libcrystfel/src/image.h +++ b/libcrystfel/src/image.h @@ -114,6 +114,8 @@ struct crystal_refls { Crystal *cr; RefList *refls; + int image_owns_crystal; + int image_owns_refls; }; struct image |