diff options
author | Thomas White <taw@physics.org> | 2024-04-18 14:32:14 +0200 |
---|---|---|
committer | Thomas White <taw@physics.org> | 2024-04-18 14:32:14 +0200 |
commit | 52bde38abbcb53d163355a71fc9e99332ffe3dee (patch) | |
tree | 54bf334103708bcbf0b821c583b06f66769edf22 | |
parent | 536d1a563e5c93cbbefb3556ea897acaf8fa70ce (diff) | |
parent | 62a2fdee1b7e69a1fe1ecb58e286866c41b6bb81 (diff) |
Merge branch 'julia'
90 files changed, 4657 insertions, 1847 deletions
diff --git a/doc/articles/julia.rst b/doc/articles/julia.rst new file mode 100644 index 00000000..0b6cabeb --- /dev/null +++ b/doc/articles/julia.rst @@ -0,0 +1,223 @@ +========================== +Using libCrystFEL in Julia +========================== + +CrystFEL's shared library component, *libcrystfel*, can be accessed from +`Julia <https://www.julialang.org/>`_. This way, you can carry out almost any +process available in the CrystFEL tools, and much more besides. + +The Julia package for CrystFEL is found in the ``julia`` directory of the +CrystFEL source code package. The easiest way to get started is to use +``Pkg.develop``. Start Julia, press ``]``, then run the following command, +substituting the correct location of the CrystFEL package on your system:: + + (@v1.9) pkg> dev /home/twhite/crystfel/julia/CrystFEL + +Afterwards, import the CrystFEL package as follows:: + + julia> using CrystFEL + +It's imperative that the same version of the Julia package is used as CrystFEL +itself, otherwise you are likely to experience spontaneous crashes of the +whole Julia session. + +You only need to perform the ``pkg dev`` process once, not every session. Should +you ever need to, you can remove the CrystFEL package in the usual way:: + + (@v1.9) pkg> rm CrystFEL + +The Julia package for CrystFEL is a fairly thin wrapper around the +`libcrystfel C API <https://www.desy.de/~twhite/crystfel/reference/index.html>`_, +so you can read the API documentation for some idea of the possibilities. +Below is a brief overview. + + +Unit cells +========== + +Create a ``UnitCell`` object as follows:: + + cell = UnitCell(MonoclinicLattice, PrimitiveCell, UniqueAxisB, 123, 45, 80, 90, 97, 90) + +The arguments are, in order: + +* Lattice type, one of ``TriclinicLattice``, ``MonoclinicLattice``, + ``OrthorhombicLattice``, ``TetragonalLattice``, ``HexagonalLattice``, + ``RhombohedralLattice`` or ``CubicLattice``. +* Centering, one of ``PrimitiveCell`` (P), ``ACenteredCell``, ``BCenteredCell``, + ``CCenteredCell``, ``BodyCenteredCell`` (I), ``FaceCenteredCell`` (F), + ``RhombohedralCell`` (R) or ``RhombohedralCellOnHexagonalAxes`` ("H"). +* Unique axis, one of ``UniqueAxisA``, ``UniqueAxisB``, ``UniqueAxisC``, + ``NoUniqueAxis`` (for lattice types that do not have a unique axis, e.g. cubic), + or ``UnknownUniqueAxis`` (which should be avoided, but is sometimes necessary). +* Cell axis lengths a,b,c, in Angstroms. +* Cell angles α,β,γ, in degrees. + +For many cases, you don't need to specify every parameter. Where possible, the +unique axis will be determined from the cell parameters, and can be omitted:: + + cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) + +Cell axis lengths, angles and centering types can be omitted if they are fixed +by the lattice type. For example:: + + julia> UnitCell(CubicLattice, FaceCenteredCell, 40) + UnitCell(CubicLattice, FaceCenteredCell, NoUniqueAxis, + 40.0 Å, 40.0 Å, 40.0 Å, 90.0°, 90.0°, 90.0°) + +or:: + + julia> UnitCell(RhombohedralLattice, 23, 75) + UnitCell(RhombohedralLattice, RhombohedralCell, NoUniqueAxis, + 23.0 Å, 23.0 Å, 23.0 Å, 75.0°, 75.0°, 75.0°) + + +Reflection lists +================ + +A ``RefList`` is a container for reflection data. In Julia, a distinction is +made between merged and unmerged reflections. Merged reflections have +multiplicities (number of contributing measurements), whereas unmerged +reflections have detector locations, background levels and parameters related +to diffraction geometry such as excitation errors and +Lorentz factors. + +No such distinction exists in CrystFEL's C API, and in "reality", both types of +reflection have all fields. The distinction controls how the objects are +printed, and may help in writing clearer programs. + +Load a reflection list from a data file (".hkl file") using ``loadreflist``:: + + julia> q = loadreflist("example.hkl") + Merged reflection list in point group mmm + h k l intensity σ(intens) nmeas + 0 0 5 23.45 124.51 11 + 0 0 6 32302.69 10091.34 8 + 0 0 7 -87.37 167.23 5 + 0 0 8 8051.75 3828.24 6 + 0 0 9 94.13 128.59 3 + 0 0 10 3703.07 1118.85 5 + 0 0 11 4.81 31.46 5 + 0 0 12 27287.94 14143.77 6 + 0 0 13 148.50 32.46 2 + 0 0 14 818.33 447.23 3 + ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ + +This produces a merged reflection list:: + + julia> typeof(q) + RefList{MergedReflection} + +Unmerged reflection lists (``RefList{UnmergedReflection}``) come from spot +prediction - see below. + +Reflection lists can be iterated over. For example:: + + julia> for refl in q + println(refl) + end + MergedReflection((0, 0, 5), intensity=23.450000762939453, σ(intensity)=124.51000213623047, nmeasurements=11) + MergedReflection((0, 0, 6), intensity=32302.689453125, σ(intensity)=10091.33984375, nmeasurements=8) + MergedReflection((0, 0, 7), intensity=-87.37000274658203, σ(intensity)=167.22999572753906, nmeasurements=5) + MergedReflection((0, 0, 8), intensity=8051.75, σ(intensity)=3828.239990234375, nmeasurements=6) + MergedReflection((0, 0, 9), intensity=94.12999725341797, σ(intensity)=128.58999633789062, nmeasurements=3) + MergedReflection((0, 0, 10), intensity=3703.070068359375, σ(intensity)=1118.8499755859375, nmeasurements=5) + MergedReflection((0, 0, 11), intensity=4.809999942779541, σ(intensity)=31.459999084472656, nmeasurements=5) + MergedReflection((0, 0, 12), intensity=27287.939453125, σ(intensity)=14143.76953125, nmeasurements=6) + MergedReflection((0, 0, 13), intensity=148.5, σ(intensity)=32.459999084472656, nmeasurements=2) + MergedReflection((0, 0, 14), intensity=818.3300170898438, σ(intensity)=447.2300109863281, nmeasurements=3) + ... + +You can subscript a RefList using Miller indices:: + + julia> q[1, 13, 43] + MergedReflection((1, 13, 43), intensity=-28.18000030517578, σ(intensity)=7.230000019073486, nmeasurements=6) + +Linear indexing is **not** supported, so you **can't** do things like +``q[10:end]``. + + +Symmetry +======== + +Symmetry operations are represented by ``SymOp`` objects, which are contained +within ``SymOpList`` objects. A point group is therefore represented by a +``SymOpList``, but note that not all ``SymOpList`` objects represent a symmetry +group (in the sense of group theory). One counterexample is lists of indexing +ambiguity operations. + +Create a point group from the Herman-Mauguin symbol as follows:: + + julia> s = SymOpList("2/m") + 4-element SymOpList ("2/m") + -h,-k,l + h,k,-l + hkl + -h,-k,-l + +The list can be subscripted linearly:: + + julia> s[1] + SymOp("-h,-k,l") + + +Images and DataTemplates +======================== + +A ``DataTemplate`` represents the contents of a CrystFEL geometry file, which +describes the layout of information in the data, the physical positions of +parts of the detector, and the values of various items of metadata (or +information about where to get those values). Create a ``DataTemplate`` by +loading a geometry file:: + + dtempl = loaddatatemplate("/path/to/my.geom") + +An ``Image`` is an overall container structure representing one frame of a +serial crystallography dataset. Create one by loading an image from file:: + + image = Image(dtempl, "/path/to/mydata.cxi", "//32") + +You can use any kind of file supported by CrystFEL here. In the example, +``//32`` is the frame ID - leave it out if there is only one frame per file. + +If you're simulating data, you can create an empty image like this:: + + image = Image(dtempl) + +However, several caveats apply to doing this. The ``DataTemplate`` must not +say that any metadata values (e.g. the wavelength) should be taken from file +headers, because there is no file in this case. An error will be thrown if +there is any problem. + + +Peak lists +========== + +A ``PeakList`` represents a list of positions on the detector surface. Create +it and add peaks like this:: + + peaklist = PeakList() + push!(peaklist, 10.0, 20.0, 1, 2000.0) + +The arguments to ``push!(::PeakList, ...)`` are, in order, the fast scan +coordinate, slow scan coordinate (both relative to the panel corner), panel +number (indexed from zero) and the spot intensity in detector units. + +You can assign your peaklist to an ``Image`` by setting ``image.peaklist``. +Note that any ``PeakList`` can only be assigned to a single ``Image``. An +error will be thrown if you try to add the same ``PeakList`` again (even to the +same ``Image``). If necessary, you can make a copy using ``deepcopy``. + + +Crystals +======== + + + +Indexing +======== + + +Prediction +========== + diff --git a/julia/CrystFEL/Manifest.toml b/julia/CrystFEL/Manifest.toml new file mode 100644 index 00000000..e4ee3ce8 --- /dev/null +++ b/julia/CrystFEL/Manifest.toml @@ -0,0 +1,23 @@ +# This file is machine-generated - editing it directly is not advised + +julia_version = "1.9.2" +manifest_format = "2.0" +project_hash = "4cf05e6854a627b02f001d01f38d3c0cbfcf00bd" + +[[deps.Printf]] +deps = ["Unicode"] +uuid = "de0858da-6303-5e67-8744-51eddeeeb8d7" + +[[deps.Random]] +deps = ["SHA", "Serialization"] +uuid = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" + +[[deps.SHA]] +uuid = "ea8e919c-243c-51af-8825-aaa63cd721ce" +version = "0.7.0" + +[[deps.Serialization]] +uuid = "9e88b42a-f829-5b0c-bbe9-9e923198166b" + +[[deps.Unicode]] +uuid = "4ec0a83e-493e-50e2-b9ac-8f72acf5a8f5" diff --git a/julia/CrystFEL/Project.toml b/julia/CrystFEL/Project.toml new file mode 100644 index 00000000..8c81af0f --- /dev/null +++ b/julia/CrystFEL/Project.toml @@ -0,0 +1,8 @@ +name = "CrystFEL" +uuid = "02864af1-98e3-4af5-94a7-a156d2a4edba" +authors = ["Thomas White <taw@physics.org>"] +version = "0.1.0" + +[deps] +Printf = "de0858da-6303-5e67-8744-51eddeeeb8d7" +Random = "9a3f8284-a2c9-5f02-9a11-845980a1fd5c" diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl new file mode 100644 index 00000000..897d2614 --- /dev/null +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -0,0 +1,94 @@ +""" + CrystFEL + +Julia bindings for CrystFEL data structures and routines + +## Quick start +```julia + using CrystFEL + ... +``` +""" +module CrystFEL + +libcrystfel = "libcrystfel.so" + +# Configure libcrystfel to use Julia's memory management. This is needed so +# that the Julia GC knows about the memory we allocate via libcrystfel +# routines. Otherwise, potentially very large objects will be kept hanging +# around in memory because Julia thinks it's using a very small amount of +# memory, and rarely runs the GC. In the case of image structures, the +# difference between apparent and true memory use can be a factor of a million! +function __init__() + @ccall libcrystfel.set_mm_funcs(cglobal(:jl_malloc)::Ptr{Cvoid}, + cglobal(:jl_free)::Ptr{Cvoid}, + cglobal(:jl_calloc)::Ptr{Cvoid}, + cglobal(:jl_realloc)::Ptr{Cvoid})::Cint +end + +include("cell.jl") +using .UnitCells +export UnitCell, LatticeType, CenteringType, UniqueAxis +export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice +export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice +export PrimitiveCell, ACenteredCell, BCenteredCell, CCenteredCell +export BodyCenteredCell, FaceCenteredCell, RhombohedralCell, RhombohedralCellOnHexagonalAxes +export NoUniqueAxis, UnknownUniqueAxis, UniqueAxisA, UniqueAxisB, UniqueAxisC +export rotatecell + +include("detgeom.jl") +using .DetGeoms +export Panel, DetGeom + +include("symmetry.jl") +using .Symmetry +export SymOpList, asymmetricindices + +include("datatemplates.jl") +using .DataTemplates +export DataTemplate, loaddatatemplate, wavelength, cameralength +export translategroup!, rotategroup! + +include("peaklist.jl") +using .PeakLists +export PeakList + +include("reflists.jl") +using .RefLists +export RefList, loadreflist, savereflist! +export Reflection, MergedReflection, UnmergedReflection + +include("crystal.jl") +using .Crystals +export Crystal, InternalCrystal + +include("image.jl") +using .Images +export Image + +include("diffcalc.jl") +using .DiffractionCalculations +export predictreflections, calculatepartialities! +export PartialityModel, UnityModel, XSphereModel, OffsetModel, RandomModel, GeneralGaussianModel + +include("indexing.jl") +using .Indexing +export Indexer, index + +include("streams.jl") +using .Streams +export Stream, chunkwrite, chunkread, allcrystals + +include("millepede.jl") +using .Millepede +export Mille + +include("peaksearch.jl") +using .PeakSearch +export zaefpeaks, peakfinder8, peakfinder9 + +include("mergeutils.jl") +using .MergeUtils +export @addmeasurement, cstddev, mergereflections + +end # of module diff --git a/julia/CrystFEL/src/cell.jl b/julia/CrystFEL/src/cell.jl new file mode 100644 index 00000000..a18810bb --- /dev/null +++ b/julia/CrystFEL/src/cell.jl @@ -0,0 +1,430 @@ +module UnitCells + +using Random +using Printf + +import ..CrystFEL: libcrystfel +export UnitCell, LatticeType, CenteringType, UniqueAxis +export TriclinicLattice, MonoclinicLattice, OrthorhombicLattice +export TetragonalLattice, HexagonalLattice, RhombohedralLattice, CubicLattice +export PrimitiveCell, ACenteredCell, BCenteredCell, CCenteredCell +export BodyCenteredCell, FaceCenteredCell, RhombohedralCell, RhombohedralCellOnHexagonalAxes +export NoUniqueAxis, UnknownUniqueAxis, UniqueAxisA, UniqueAxisB, UniqueAxisC +export rotatecell + + +# Represents the real C-side (opaque) structure. +mutable struct InternalUnitCell 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 UnitCell + internalptr::Ptr{InternalUnitCell} +end + + +""" +Enumeration of the seven Bravais lattice types: `TriclinicLattice`, +`MonoclinicLattice`, `OrthorhombicLattice`, `TetragonalLattice`, +`RhombohedralLattice`, `HexagonalLattice`, `CubicLattice`. +""" +@enum LatticeType begin + TriclinicLattice + MonoclinicLattice + OrthorhombicLattice + TetragonalLattice + RhombohedralLattice + HexagonalLattice + CubicLattice +end + + +""" +Enumeration of unit cell centering possibilities: `PrimitiveCell`, +`ACenteredCell`, `BCenteredCell`, `CCenteredCell`, `BodyCenteredCell` +(I-centering), `FaceCenteredCell` (F-centering), and `RhombohedralCell` +(R-centering, primitive rhombohedral cell). `RhombohedralCellOnHexagonalAxes` +indicates "H-centering" as used by the protein data bank, which is different +from the "triple hexagonal cell" described in the International Tables. +""" +@enum CenteringType begin + PrimitiveCell = Int('P') + ACenteredCell = Int('A') + BCenteredCell = Int('B') + CCenteredCell = Int('C') + BodyCenteredCell = Int('I') + FaceCenteredCell = Int('F') + RhombohedralCell = Int('R') + RhombohedralCellOnHexagonalAxes = Int('H') +end + + +""" +Enumeration of unique axis possibilities. The possibilities are `UniqueAxisA`, +`UniqueAxisB` and `UniqueAxisC`. Alternatively, use `NoUniqueAxis` if the type +of unit cell does not have a unique axis (triclinic, orthorhombic, cubic or +rhombohedral). `UnknownUniqueAxis` means that the unique axis is not known. +""" +@enum UniqueAxis begin + NoUniqueAxis = Int('*') + UnknownUniqueAxis = Int('?') + UniqueAxisA = Int('a') + UniqueAxisB = Int('b') + UniqueAxisC = Int('c') +end + + +""" + UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) + +Creates a CrystFEL UnitCell, in an undefined orientation, from the given +parameters. The axis lengths (a, b, c) should be in *Ångstroms*, and the +angles (α, β, γ) should be in *degrees* - note that this is different to the +equivalent function in CrystFEL's C API. + +See the documentation for `LatticeType`, `CenteringType` and `UniqueAxis` for +possible values. You can also use the characters `'a'`, `'b'` and `'c'` for +`uniqueaxis`, or `'P'`, `'A'`, `'B'`, `'C'`, `'I'`, `'F'`, `'R'` and `'H`' for +`centering. + +Corresponds to CrystFEL C API function `cell_new_from_parameters` with follow-up +calls to `cell_set_centering`, `cell_set_lattice_type` and `cell_set_unique_axis`. +""" +function UnitCell(latticetype, centering, uniqueaxis, a, b, c, α, β, γ) + + ninety(a) = isapprox(a, 90, atol=0.1) + + if latticetype == OrthorhombicLattice + if !(ninety(α) && ninety(β) && ninety(γ)) + throw(ArgumentError("All angles must be 90°")) + end + + elseif latticetype == TetragonalLattice + if !(ninety(α) && ninety(β) && ninety(γ)) + throw(ArgumentError("All angles must be 90°")) + end + + elseif latticetype == CubicLattice + if !(ninety(α) && ninety(β) && ninety(γ)) + throw(ArgumentError("All angles must be 90°")) + end + + elseif latticetype == HexagonalLattice + if uniqueaxis == UniqueAxisA + if !isapprox(b, c, rtol=0.01) + throw(ArgumentError("b and c lengths should be equal")) + end + elseif uniqueaxis == UniqueAxisB + if !isapprox(a, c, rtol=0.01) + throw(ArgumentError("a and c lengths should be equal")) + end + elseif uniqueaxis == UniqueAxisC + if !isapprox(a, b, rtol=0.01) + throw(ArgumentError("a and b lengths should be equal")) + end + else + throw(ArgumentError("Hexagonal cell requires a unique axis")) + end + end + + out = ccall((:cell_new_from_parameters, libcrystfel), + Ptr{InternalUnitCell}, + (Cdouble,Cdouble,Cdouble,Cdouble,Cdouble,Cdouble), + a/1e10, b/1e10, c/1e10, deg2rad(α), deg2rad(β), deg2rad(γ)) + if out == C_NULL + throw(ArgumentError("Failed to create unit cell")) + end + + ccall((:cell_set_centering, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},Cchar), + out, centering) + + ccall((:cell_set_unique_axis, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},Cchar), + out, uniqueaxis) + + ccall((:cell_set_lattice_type, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},Cint), + out, latticetype) + + cell = UnitCell(out) + + finalizer(cell) do x + ccall((:cell_free, libcrystfel), + Cvoid, (Ptr{InternalUnitCell},), x.internalptr) + end + + return cell +end + + + +""" + UnitCell(latticetype, centering, a, b, c, α, β, γ) + +A convenience constructor which attempts to determine the unique axis +automatically from the cell parameters. If the unique axis is not obvious, +an `ArgumentError` will be thrown. +""" +function UnitCell(latticetype, centering, a, b, c, α, β, γ) + + notninety(a) = !isapprox(a, 90, atol=0.5) + ninety(a) = isapprox(a, 90, atol=0.1) + onetwenty(a) = isapprox(a, 120, atol=0.1) + + if latticetype == TriclinicLattice + ua = NoUniqueAxis + elseif latticetype == OrthorhombicLattice + ua = NoUniqueAxis + elseif latticetype == RhombohedralLattice + ua = NoUniqueAxis + elseif latticetype == CubicLattice + ua = NoUniqueAxis + + elseif latticetype == MonoclinicLattice + if notninety(α) && ninety(β) && ninety(γ) + ua = UniqueAxisA + elseif ninety(α) && notninety(β) && ninety(γ) + ua = UniqueAxisB + elseif ninety(α) && ninety(β) && notninety(γ) + ua = UniqueAxisC + else + throw(ArgumentError("Can't determine unique axis")) + end + + elseif latticetype == TetragonalLattice + if isapprox(b, c, rtol=0.01) && !isapprox(a, b, rtol=0.05) + ua = UniqueAxisA + elseif isapprox(a, c, rtol=0.01) && !isapprox(a, b, rtol=0.05) + ua = UniqueAxisB + elseif isapprox(a, b, rtol=0.01) && !isapprox(c, b, rtol=0.05) + ua = UniqueAxisC + else + throw(ArgumentError("Can't determine unique axis")) + end + + elseif latticetype == HexagonalLattice + if onetwenty(α) && ninety(β) && ninety(γ) + ua = UniqueAxisA + elseif ninety(α) && onetwenty(β) && ninety(γ) + ua = UniqueAxisB + elseif ninety(α) && ninety(β) && onetwenty(γ) + ua = UniqueAxisC + else + throw(ArgumentError("Can't determine unique axis")) + end + end + + UnitCell(latticetype, centering, ua, a, b, c, α, β, γ) + +end + + +""" + UnitCell(latticetype, centering, a, b, c) + +Construct a `UnitCell` for an `OrthorhombicLattice`, `TetragonalLattice` or +`CubicLattice`. +""" +function UnitCell(latticetype::LatticeType, centering::CenteringType, a::Real, b::Real, c::Real) + if latticetype in (OrthorhombicLattice, TetragonalLattice, CubicLattice) + UnitCell(latticetype, centering, a, b, c, 90, 90, 90) + else + throw(ArgumentError("More parameters needed for this type of lattice")) + end +end + + +""" + UnitCell(CubicLattice, centering, a) + +Construct a `UnitCell` for a `CubicLattice`. +""" +function UnitCell(latticetype::LatticeType, centering::CenteringType, a::Real) + if latticetype == CubicLattice + UnitCell(latticetype, centering, a, a, a, 90, 90, 90) + else + throw(ArgumentError("More parameters needed for this type of lattice")) + end +end + + +""" + UnitCell(RhombohedralLattice, a, α) + +Construct a `UnitCell` for a `RhombohedralLattice`. +""" +function UnitCell(latticetype::LatticeType, a::Real, α::Real) + if latticetype == RhombohedralLattice + UnitCell(latticetype, RhombohedralCell, a, a, a, α, α, α) + else + throw(ArgumentError("More parameters needed for this type of lattice")) + end +end + + +function getlatticetype(cell) + lt = ccall((:cell_get_lattice_type, libcrystfel), + Cint, (Ptr{InternalUnitCell},), cell.internalptr) + cen = ccall((:cell_get_centering, libcrystfel), + Cchar, (Ptr{InternalUnitCell},), cell.internalptr) + ua = ccall((:cell_get_unique_axis, libcrystfel), + Cchar, (Ptr{InternalUnitCell},), cell.internalptr) + return LatticeType(lt),CenteringType(cen),UniqueAxis(ua) +end + + +function getcellparams(cell) + let a=Ref{Cdouble}(0), + b=Ref{Cdouble}(0), + c=Ref{Cdouble}(0), + α=Ref{Cdouble}(0), + β=Ref{Cdouble}(0), + γ=Ref{Cdouble}(0) + ccall((:cell_get_parameters, libcrystfel), + Cvoid, (Ptr{InternalUnitCell}, + Ref{Cdouble},Ref{Cdouble},Ref{Cdouble}, + Ref{Cdouble},Ref{Cdouble},Ref{Cdouble}), + cell.internalptr, a, b, c, α, β, γ) + return (a=a[], b=b[], c=c[], α=α[], β=β[], γ=γ[]) + end +end + + +# Returns the direct-space basis vectors as a Julia matrix +# See matrix-notation.pdf for information. This returns an "M-matrix". +function directcartesianmatrix(uc) + ax = Ref{Cdouble}(0) + ay = Ref{Cdouble}(0) + az = Ref{Cdouble}(0) + bx = Ref{Cdouble}(0) + by = Ref{Cdouble}(0) + bz = Ref{Cdouble}(0) + cx = Ref{Cdouble}(0) + cy = Ref{Cdouble}(0) + cz = Ref{Cdouble}(0) + out = @ccall libcrystfel.cell_get_cartesian(uc.internalptr::Ptr{InternalUnitCell}, + ax::Ref{Cdouble}, ay::Ref{Cdouble}, az::Ref{Cdouble}, + bx::Ref{Cdouble}, by::Ref{Cdouble}, bz::Ref{Cdouble}, + cx::Ref{Cdouble}, cy::Ref{Cdouble}, cz::Ref{Cdouble})::Cint + if out != 0 + throw(ErrorException("Failed to convert cell parameters")) + end + return [ax[] bx[] cx[]; ay[] by[] cy[]; az[] bz[] cz[]] +end + + +# Returns the reciprocal-space basis vectors as a Julia matrix +# See matrix-notation.pdf for information. This returns an "R-matrix". +function reciprocalcartesianmatrix(uc) + ax = Ref{Cdouble}(0) + ay = Ref{Cdouble}(0) + az = Ref{Cdouble}(0) + bx = Ref{Cdouble}(0) + by = Ref{Cdouble}(0) + bz = Ref{Cdouble}(0) + cx = Ref{Cdouble}(0) + cy = Ref{Cdouble}(0) + cz = Ref{Cdouble}(0) + out = @ccall libcrystfel.cell_get_reciprocal(uc.internalptr::Ptr{InternalUnitCell}, + ax::Ref{Cdouble}, ay::Ref{Cdouble}, az::Ref{Cdouble}, + bx::Ref{Cdouble}, by::Ref{Cdouble}, bz::Ref{Cdouble}, + cx::Ref{Cdouble}, cy::Ref{Cdouble}, cz::Ref{Cdouble})::Cint + if out != 0 + throw(ErrorException("Failed to convert cell parameters")) + end + return [ax[] ay[] az[]; bx[] by[] bz[]; cx[] cy[] cz[]] +end + + +function Base.propertynames(uc::UnitCell; private=false) + (:a, :b, :c, :α, :β, :γ, :latticetype, :cellparams, + :directcartesian, :reciprocalcartesian, + :internalptr) +end + + +function Base.getproperty(uc::UnitCell, name::Symbol) + if name === :internalptr + getfield(uc, :internalptr) + elseif name === :cellparams + return getcellparams(uc) + elseif name === :latticetype + return getlatticetype(uc) + elseif name === :a + return getcellparams(uc).a + elseif name === :b + return getcellparams(uc).b + elseif name === :c + return getcellparams(uc).c + elseif name === :α + return getcellparams(uc).α + elseif name === :β + return getcellparams(uc).β + elseif name === :γ + return getcellparams(uc).γ + elseif name === :directcartesian + return directcartesianmatrix(uc) + elseif name === :reciprocalcartesian + return reciprocalcartesianmatrix(uc) + end +end + + +function Base.show(io::IO, uc::UnitCell) + write(io, "UnitCell(") + lt,cen,ua = uc.latticetype + show(io, lt); write(io, ", ") + show(io, cen); write(io, ", ") + show(io, ua); write(io, ",\n ") + @printf(io, "%.3f Å, %.3f Å, %.3f Å, %.3f°, %.3f°, %.3f°", + uc.a*1e10, uc.b*1e10, uc.c*1e10, + rad2deg(uc.α), rad2deg(uc.β), rad2deg(uc.γ)) + write(io, ")") +end + + +# This type is for talking to libcrystfel, and is named to avoid conflicting +# with other quaternion libraries. +mutable struct CrystFELQuaternion + w::Cdouble + x::Cdouble + y::Cdouble + z::Cdouble +end + +function randomquat() + r = ()->2.0*rand(Float64)-1.0 + q = [r(), r(), r(), r()] + q ./ √(sum(q.^2)) +end + + +""" + rotatecell(uc::UnitCell, quaternion) + +Rotate a unit cell according to a quaternion (represented as a vector of 4 floats). +""" +function rotatecell(uc, quat) + q = CrystFELQuaternion(quat...) + out = @ccall libcrystfel.cell_rotate(uc.internalptr::Ptr{InternalUnitCell}, + q::CrystFELQuaternion)::Ptr{InternalUnitCell} + if out == C_NULL + throw(ErrorException("Failed to rotate unit cell")) + end + UnitCell(out) +end + + +""" + rotatecell(uc::UnitCell) + +Rotate a unit cell at random in three dimensions. Use this routine for +simulating serial crystallography datasets. + +Equivalent to CrystFEL routine `cell_rotate(uc, random_quaternion(<rng>))`. +""" +rotatecell(uc) = rotatecell(uc, randomquat()) + + +end # of module diff --git a/julia/CrystFEL/src/crystal.jl b/julia/CrystFEL/src/crystal.jl new file mode 100644 index 00000000..f05f651f --- /dev/null +++ b/julia/CrystFEL/src/crystal.jl @@ -0,0 +1,121 @@ +module Crystals + +using Printf + +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} + cell +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, nothing) + + finalizer(cr) do x + ccall((:crystal_free, libcrystfel), Cvoid, (Ptr{InternalCrystal},), + x.internalptr) + end + + return cr +end + + +function Base.setproperty!(cr::Crystal, name::Symbol, val) + if name === :internalptr + setfield!(cr, :internalptr, val) + end +end + + +function getcell(cr) + out = @ccall libcrystfel.crystal_relinquish_cell(cr.internalptr::Ptr{InternalCrystal})::Ptr{InternalUnitCell} + if getfield(cr, :cell) === nothing || getfield(cr, :cell).internalptr != out + if out != C_NULL + setfield!(cr, :cell, UnitCell(out)) + else + setfield!(cr, :cell, nothing) + end + end + return getfield(cr, :cell) +end + + +function Base.getproperty(cr::Crystal, name::Symbol) + if name === :internalptr + getfield(cr, :internalptr) + elseif name === :cell + return getcell(cr) + elseif name === :Bfac + return @ccall libcrystfel.crystal_get_Bfac(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :osf + return @ccall libcrystfel.crystal_get_osf(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :mos + return @ccall libcrystfel.crystal_get_mosaicity(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :r + return @ccall libcrystfel.crystal_get_profile_radius(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :resolution + return @ccall libcrystfel.crystal_get_resolution_limit(cr.internalptr::Ptr{InternalCrystal})::Cdouble + elseif name === :flag + return @ccall libcrystfel.crystal_get_user_flag(cr.internalptr::Ptr{InternalCrystal})::Cint + else + throw(ErrorException("Type Crystal has no field "*String(name))) + end +end + + +function Base.show(io::IO, mime::MIME"text/plain", cr::Crystal) + @printf(io, "CrystFEL.Crystal(%p):\n\n", cr.internalptr) + if cr.cell !== nothing + show(io, cr.cell) + write(io, "\n\n") + else + write(io, "Unit cell parameters not set\n\n") + end + println(io, " Linear scale factor: ", cr.osf) + println(io, " Debye-Walle factor: ", cr.Bfac) + println(io, " Mosaicity: ", cr.mos) + println(io, " Profile radius: ", cr.r/1e9, " nm⁻¹") + println(io, " Resolution limit: ", cr.resolution) + println(io, " Flag: ", cr.flag) +end + + +function Base.show(io::IO, cr::Crystal) + @printf(io, "CrystFEL.Crystal(%p)", cr.internalptr) +end + + +end # of module diff --git a/julia/CrystFEL/src/datatemplates.jl b/julia/CrystFEL/src/datatemplates.jl new file mode 100644 index 00000000..b063aa90 --- /dev/null +++ b/julia/CrystFEL/src/datatemplates.jl @@ -0,0 +1,127 @@ +module DataTemplates + +import ..CrystFEL: libcrystfel +export DataTemplate, InternalDataTemplate, loaddatatemplate +export wavelength, cameralength +export translategroup!, rotategroup! + +# 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_m`. +""" +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 + + +""" + rotategroup!(datatemplate, groupname, angle, axis) + +Modifies `DataTemplate` by rotating the specified panel group by the specified +amount (in degrees) about the specified xaxis (:x, :y or :z). + +Corresponds to CrystFEL C API function `data_template_rotate_group`. +""" +function rotategroup!(dtempl::DataTemplate, groupname, angle, axis) + r = @ccall libcrystfel.data_template_rotate_group(dtempl.internalptr::Ptr{InternalDataTemplate}, + groupname::Cstring, + deg2rad(angle)::Cdouble, + String(axis)[1]::Cchar)::Cint + if r != 0 + throw(ErrorException("Failed to rotate DataTemplate")) + end + +end + +end # of module diff --git a/julia/CrystFEL/src/detgeom.jl b/julia/CrystFEL/src/detgeom.jl new file mode 100644 index 00000000..ba943d98 --- /dev/null +++ b/julia/CrystFEL/src/detgeom.jl @@ -0,0 +1,47 @@ +module DetGeoms +export Panel + +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 + + +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 + + +end # of module diff --git a/julia/CrystFEL/src/diffcalc.jl b/julia/CrystFEL/src/diffcalc.jl new file mode 100644 index 00000000..1c6aea9c --- /dev/null +++ b/julia/CrystFEL/src/diffcalc.jl @@ -0,0 +1,44 @@ +module DiffractionCalculations + +import ..CrystFEL: libcrystfel +import ..CrystFEL.Images: InternalImage, Image +import ..CrystFEL.Crystals: InternalCrystal, Crystal +import ..CrystFEL.RefLists: RefList, UnmergedReflection, InternalRefList +import ..CrystFEL.Symmetry: SymOpList +export predictreflections, calculatepartialities! +export PartialityModel, UnityModel, XSphereModel, OffsetModel, RandomModel, GeneralGaussianModel + + +""" +Enumeration of the available partiality models. +""" +@enum PartialityModel begin + UnityModel + XSphereModel + OffsetModel + RandomModel + GeneralGaussianModel +end + + +function predictreflections(cr::Crystal, image::Image; maxres=1e10) + + refls = @ccall libcrystfel.predict_to_res(cr.internalptr::Ptr{InternalCrystal}, + image.internalptr::Ptr{InternalImage}, + maxres::Cdouble)::Ptr{InternalRefList} + sym = SymOpList("1") + return RefList{UnmergedReflection}(refls, sym) +end + + +function calculatepartialities!(reflist::RefList{UnmergedReflection}, + cr::Crystal, image::Image; model=XSphereModel, maxres=1e10) + + @ccall libcrystfel.calculate_partialities(reflist.internalptr::Ptr{InternalRefList}, + cr.internalptr::Ptr{InternalCrystal}, + image.internalptr::Ptr{InternalImage}, + model::Cint)::Cvoid +end + + +end # of module diff --git a/julia/CrystFEL/src/image.jl b/julia/CrystFEL/src/image.jl new file mode 100644 index 00000000..4090dc61 --- /dev/null +++ b/julia/CrystFEL/src/image.jl @@ -0,0 +1,356 @@ +module Images + +using Printf + +import ..CrystFEL: libcrystfel +import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate +import ..CrystFEL.DetGeoms: DetGeom +import ..CrystFEL.PeakLists: PeakList, InternalPeakList +import ..CrystFEL.Crystals: Crystal, InternalCrystal +import ..CrystFEL.RefLists: RefList, InternalRefList, UnmergedReflection +import ..CrystFEL.Symmetry: SymOpList +export Image + +const HEADER_CACHE_SIZE = 128 + +mutable struct CrystalRefListPair + crystal::Ptr{InternalCrystal} + reflist::Ptr{InternalRefList} + owns_crystal::Cint + owns_reflist::Cint +end + +mutable struct InternalImage + dp::Ptr{Ptr{Cfloat}} + bad::Ptr{Ptr{Cint}} + sat::Ptr{Ptr{Cfloat}} + hit::Cint + crystals::Ptr{CrystalRefListPair} + n_crystals::Cint + indexed_by::Cint + n_indexing_tries::Cint + detgeom::Ptr{DetGeom} + data_source_type::Cint + filename::Cstring + ev::Cstring + data_block::Ptr{Cvoid} + data_block_size::Csize_t + meta_data::Cstring + header_cache::NTuple{HEADER_CACHE_SIZE, Ptr{Cvoid}} + n_cached_headers::Cint + id::Cint + serial::Cint + spectrum::Ptr{Cvoid} + lambda::Cdouble + div::Cdouble + bw::Cdouble + peak_resolution::Cdouble + peaklist::Ptr{InternalPeakList} + ida::Ptr{Cvoid} + owns_peaklist::Cint +end + + +mutable struct Image + internalptr::Ptr{InternalImage} + peaklist::Union{Nothing,PeakList} + crystals + reflists +end + + +function makecrystallist(image, listptr, n) + + crystals = [] + + if listptr == C_NULL + return crystals + end + + for i in 1:n + pairptr = unsafe_load(listptr, i) + + # 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, nothing) + end + + if pairptr.reflist == C_NULL + reflist = nothing + else + reflist = RefList{UnmergedReflection}(pairptr.reflist, SymOpList("1")) + pairptr.owns_reflist = 0 + finalizer(reflist) do x + @ccall libcrystfel.reflist_free(x.internalptr::Ptr{InternalRefList})::Cvoid + end + end + push!(crystals, (crystal=cr, reflections=reflist)) + pairptr.owns_crystal = 0 + unsafe_store!(listptr, pairptr, i) + finalizer(cr) do x + @ccall libcrystfel.crystal_free(x.internalptr::Ptr{InternalCrystal})::Cvoid + end + end + + image.crystals = map(x->x.crystal, crystals) + image.reflists = map(x->x.reflections, crystals) + return crystals + +end + + +function getpeaklist(image) + idata = unsafe_load(image.internalptr) + if (getfield(image, :peaklist) === nothing) || + (idata.peaklist != getfield(image, :peaklist).internalptr) + if idata.peaklist != C_NULL + setfield!(image, :peaklist, PeakList(idata.peaklist)) + # From now on, Julia is completely responsible for freeing the peaklist + idata.owns_peaklist = 0 + unsafe_store!(image.internalptr, idata) + else + setfield!(image, :peaklist, nothing) + end + end + return getfield(image, :peaklist) +end + + +function Base.getproperty(image::Image, name::Symbol) + if name === :internalptr + getfield(image, :internalptr) + elseif name === :peaklist + getpeaklist(image) + else + idata = unsafe_load(image.internalptr) + + if name === :crystals + return makecrystallist(image, + getfield(idata, :crystals), + getfield(idata, :n_crystals)) + + else + getfield(idata, name) + end + end +end + + +strdup(str) = @ccall libcrystfel.cfstrdup(str::Cstring)::Cstring + + +function assert_type(val, type) + if !(val isa type) + throw(ArgumentError("Must be a "*string(type)*" (have "*string(typeof(val))*" instead)")) + end +end + + +function set_peaklist(image, new_pl) + + assert_type(new_pl, PeakList) + + idata = unsafe_load(image.internalptr) + if (idata.owns_peaklist == 1) && (idata.peaklist != C_NULL) + @ccall libcrystfel.image_feature_list_free(idata.peaklist::Ptr{InternalPeakList})::Cvoid + end + idata.peaklist = new_pl.internalptr + idata.owns_peaklist = 0 + unsafe_store!(image.internalptr, idata) + setfield!(image, :peaklist, new_pl) + +end + + +function Base.setproperty!(image::Image, name::Symbol, val) + if name === :internalptr + setfield!(image, :internalptr, val) + else + + if name === :peaklist + return set_peaklist(image, val) + + elseif name === :filename + assert_type(val, AbstractString) + val = strdup(val) + + elseif name === :ev + 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) + setproperty!(idata, name, val) + unsafe_store!(image.internalptr, idata) + + end +end + + +function Base.propertynames(image::Image; private=false) + if private + fieldnames(InternalImage) + else + tuple(fieldnames(InternalImage)..., :internalptr) + end +end + + +function Base.push!(image::Image, cr::Crystal) + @ccall libcrystfel.image_add_crystal(image.internalptr::Ptr{InternalImage}, + cr.internalptr::Ptr{InternalCrystal})::Cvoid + + idata = unsafe_load(image.internalptr) + ncryst = idata.n_crystals + pairptr = unsafe_load(idata.crystal_refls, ncryst) + pairptr.owns_crystal = 0 + unsafe_store!(idata.crystal_refls, pairptr, ncryst) + push!(getfield(image, :crystals), cr) +end + + +function Base.push!(image::Image, cr::Crystal, reflections::RefList{UnmergedReflection}) + @ccall libcrystfel.image_add_crystal_refls(image.internalptr::Ptr{InternalImage}, + cr.internalptr::Ptr{InternalCrystal}, + reflections.internalptr::Ptr{InternalRefList})::Cvoid + idata = unsafe_load(image.internalptr) + ncryst = idata.n_crystals + pairptr = unsafe_load(idata.crystals, ncryst) + pairptr.owns_crystal = 0 + pairptr.owns_reflist = 0 + unsafe_store!(idata.crystals, pairptr, ncryst) + push!(getfield(image, :crystals), cr) + push!(getfield(image, :reflists), reflections) +end + + +""" + Image(dtempl::DataTemplate) + +Creates a CrystFEL image structure, not linked to any file or data block, +i.e. for simulation purposes. This will fail if `dtempl` contains any +references to metadata fields, e.g. `photon_energy = /LCLS/photon_energy eV`. + +Corresponds to CrystFEL C API function `image_create_for_simulation()`. +""" +function Image(dtempl::DataTemplate) + + out = ccall((:image_create_for_simulation, libcrystfel), + Ptr{Image}, (Ref{InternalDataTemplate},), dtempl.internalptr) + if out == C_NULL + throw(ArgumentError("Failed to create image")) + end + + image = Image(out, nothing, [], []) + + finalizer(image) do x + ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) + end + + return image +end + + +""" + Image(dtempl::DataTemplate, filename::AbstractString, event::AbstractString, + no_image_data=false, no_mask_data=false) + +Loads an image from the filesystem. + +Corresponds to CrystFEL C API function `image_read()`. +""" +function Image(dtempl::DataTemplate, + filename::AbstractString, + event::AbstractString="//", + no_image_data=false, + no_mask_data=false) + + out = @ccall libcrystfel.image_read(dtempl.internalptr::Ptr{InternalDataTemplate}, + filename::Cstring, event::Cstring, + no_image_data::Cint, no_mask_data::Cint, + C_NULL::Ptr{Cvoid})::Ptr{Image} + if out == C_NULL + throw(ArgumentError("Failed to load image")) + end + + image = Image(out, nothing, [], []) + + finalizer(image) do x + ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) + end + + return image +end + + +function Base.show(io::IO, mime::MIME"text/plain", image::Image) + + idata = unsafe_load(image.internalptr) + @printf(io, "CrystFEL.Image(%p):\n\n", image.internalptr) + + println(io, " Serial number: ", idata.serial) + write(io, " Filename: ") + if idata.filename == C_NULL + write(io, "<not set>") + else + write(io, unsafe_string(idata.filename)) + end + write(io, "\n") + + write(io, " Frame ID: ") + if idata.ev == C_NULL + write(io, "<not set>") + else + write(io, unsafe_string(idata.ev)) + end + write(io, "\n") + + write(io, "\n") + println(io, " Wavelength: ", idata.lambda*1e10, " Å") + println(io, " Bandwidth: ", idata.bw*100, " %") + println(io, " Divergence: ", idata.div*1e3, " mrad") + + write(io, "\n") + if idata.peaklist != C_NULL + let npk = @ccall libcrystfel.image_feature_count(idata.peaklist::Ptr{InternalPeakList})::Cint + println(io, " Number of peaks: ", npk) + end + else + println(io, " Number of peaks: 0 (no peak list)") + end + + println(io, " Estimated resolution: ", 1e10/idata.peak_resolution, " Å") + write(io, " Hit flag: ") + if idata.hit != 0 + write(io, "set") + else + write(io, "not set") + end + write(io, "\n") + + write(io, "\n") + println(io, " Number of crystals: ", idata.n_crystals) + println(io, " Number of indexing attempts made: ", idata.n_crystals) + println(io, " Indexed by algorithm: ", idata.indexed_by) +end + + +function Base.show(io::IO, image::Image) + @printf(io, "CrystFEL.Image(%p)", image.internalptr) +end + + +end # of module diff --git a/julia/CrystFEL/src/indexing.jl b/julia/CrystFEL/src/indexing.jl new file mode 100644 index 00000000..543246ec --- /dev/null +++ b/julia/CrystFEL/src/indexing.jl @@ -0,0 +1,151 @@ +module Indexing + +import ..CrystFEL: libcrystfel +import ..CrystFEL.UnitCells: UnitCell, InternalUnitCell +import ..CrystFEL.Images: Image, InternalImage +import ..CrystFEL.DataTemplates: wavelength, cameralength +export Indexer, index + +mutable struct IndexingPriv end + +mutable struct Indexer + indexingpriv::Ptr{IndexingPriv} +end + + +function indexflags(retry, multilattice, refine, peakcheck, cellcheck) + flags = 0 + if retry + flags |= 1 + end + if multilattice + flags |= 2 + end + if refine + flags |= 4 + end + if peakcheck + flags |= 32 + end + if cellcheck + flags |= 64 + end + return flags +end + + +""" + Indexer(methods, dtempl, cell; + tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), + retry=true, multilattice=false, refine=true, + peakcheck=true, cellcheck=true, + wavelength_estimate=nothing, clen_estimate=missing, + n_threads=1) + +Creates a new CrystFEL indexing engine, which you can later apply to CrystFEL +`Image` structures using `index()`. +""" +function Indexer(methods, dtempl, cell; tolerances=(0.05,0.05,0.05,1.5,1.5,1.5), + retry=true, multilattice=false, refine=true, peakcheck=true, cellcheck=true, + wavelength_estimate=nothing, clen_estimate=missing, n_threads=1) + + taketwoopts = Ref{Ptr{Cvoid}}(C_NULL) + xgandalfopts = Ref{Ptr{Cvoid}}(C_NULL) + pinkindexeropts = Ref{Ptr{Cvoid}}(C_NULL) + felixopts = Ref{Ptr{Cvoid}}(C_NULL) + fromfileopts = Ref{Ptr{Cvoid}}(C_NULL) + asdfopts = Ref{Ptr{Cvoid}}(C_NULL) + + @ccall libcrystfel.default_method_options(taketwoopts::Ref{Ptr{Cvoid}}, + xgandalfopts::Ref{Ptr{Cvoid}}, + pinkindexeropts::Ref{Ptr{Cvoid}}, + felixopts::Ref{Ptr{Cvoid}}, + fromfileopts::Ref{Ptr{Cvoid}}, + asdfopts::Ref{Ptr{Cvoid}})::Cvoid + + flags = indexflags(retry, multilattice, refine, peakcheck, cellcheck) + + let wlfromdtempl = wavelength(dtempl) + if !isnothing(wlfromdtempl) + wavelength_estimate = wlfromdtempl + else + if isnothing(wavelength_estimate) + throw(ArgumentError("Wavelength cannot be determined from data template. "* + "Use Indexer(wavelength_estimate=...)")) + end + end + end + + let clenfromdtempl = cameralength(dtempl) + if !isnothing(clenfromdtempl) + clen_estimate = clenfromdtempl + else + if isnothing(clen_estimate) + throw(ArgumentError("Camera length cannot be determined from data template. "* + "Use Indexer(clen_estimate=...)")) + end + end + end + + tols = Vector{Cfloat}(undef, 6) + tols[1] = tolerances[1] + tols[2] = tolerances[2] + tols[3] = tolerances[3] + tols[4] = deg2rad(tolerances[4]) + tols[5] = deg2rad(tolerances[5]) + tols[6] = deg2rad(tolerances[6]) + + out = @ccall libcrystfel.setup_indexing(methods::Cstring, + cell.internalptr::Ptr{InternalUnitCell}, + tols::Ptr{Cfloat}, + flags::Cint, + wavelength_estimate::Cdouble, + clen_estimate::Cdouble, + n_threads::Cint, + taketwoopts[]::Ptr{Cvoid}, + xgandalfopts[]::Ptr{Cvoid}, + pinkindexeropts[]::Ptr{Cvoid}, + felixopts[]::Ptr{Cvoid}, + fromfileopts[]::Ptr{Cvoid}, + asdfopts[]::Ptr{Cvoid})::Ptr{IndexingPriv} + + if out == C_NULL + throw(ErrorException("Indexing setup failed")) + end + + indexer = Indexer(out) + + finalizer(indexer) do x + @ccall libcrystfel.cleanup_indexing(x.indexingpriv::Ptr{IndexingPriv})::Cvoid + end + + return indexer + +end + + +""" + index(image::Image, indexer::Indexer; mille=nothing) + +Index `image` using `indexer`. + +If `mille` is a valid `Mille` object, detector geometry alignment data will +be written. +""" +function index(image::Image, idxr::Indexer; mille=nothing) + + if mille === nothing + imille = C_NULL + else + imille = mille.internalptr + end + + @ccall libcrystfel.index_pattern_4(image.internalptr::Ptr{InternalImage}, + idxr.indexingpriv::Ptr{IndexingPriv}, + C_NULL::Ptr{Cvoid}, + C_NULL::Ptr{Cvoid}, + imille::Ptr{Cvoid})::Cvoid +end + + +end # of module diff --git a/julia/CrystFEL/src/mergeutils.jl b/julia/CrystFEL/src/mergeutils.jl new file mode 100644 index 00000000..701992db --- /dev/null +++ b/julia/CrystFEL/src/mergeutils.jl @@ -0,0 +1,78 @@ +module MergeUtils + +import ..CrystFEL: libcrystfel +using ..CrystFEL.RefLists +using ..CrystFEL.Symmetry +import ..CrystFEL.UnitCells: InternalUnitCell +export @addmeasurement, cstddev, mergereflections + + +macro addmeasurement(measurement, weight, + mean, sumweight, wksp) + return quote + delta = $(esc(measurement)) - $(esc(mean)) + newsumweight = $(esc(sumweight)) + $(esc(weight)) + R = delta * $(esc(weight)) / newsumweight + $(esc(mean)) += R + $(esc(wksp)) += $(esc(sumweight)) * delta * R + $(esc(sumweight)) = newsumweight + end +end + +cstddev(nmeas, work1, work2) = sqrt(work2/work1)/sqrt(nmeas) + + +struct Polarisation + fraction::Cdouble + angle::Cdouble + disable::Cint +end + +function polarisation_correction!(reflist, cell, polfrac, polangle) + pol = Polarisation(polfrac, rad2deg(polangle), 0) + @ccall libcrystfel.polarisation_correction(reflist.internalptr::Ptr{InternalRefList}, + cell.internalptr::Ptr{InternalUnitCell}, + pol::Ref{Polarisation})::Cvoid +end + + +function mergereflections(correction, crystalrefls, sym) + + merged = RefList{MergedReflection}(sym) + + for (cr,reflections) in crystalrefls + + polarisation_correction!(reflections, cr.cell, 1.0, 0.0) + + for refl in reflections + + indices = asymmetricindices(sym, refl.indices) + model_version = get!(merged, indices) + @addmeasurement(correction(refl, cr), 1.0, + model_version.intensity, + model_version.temp1, + model_version.temp2) + model_version.nmeasurements += 1 + + end + end + + for refl in merged + if refl.nmeasurements > 1 + refl.sigintensity = cstddev(refl.nmeasurements, refl.temp1, refl.temp2) + else + # Cannot delete a reflection from a list (especially not + # while iterating), but setting nmeasurements to zero + # prevents it from being written to the output file. + refl.nmeasurements = 0 + end + end + + return merged + +end + +mergereflections(crystalrefls, sym) = mergereflections((refl,cr)->refl.intensity, crystalrefls, sym) + + +end # of module diff --git a/julia/CrystFEL/src/millepede.jl b/julia/CrystFEL/src/millepede.jl new file mode 100644 index 00000000..a65256dc --- /dev/null +++ b/julia/CrystFEL/src/millepede.jl @@ -0,0 +1,42 @@ +module Millepede + +import ..CrystFEL: libcrystfel +export Mille + +mutable struct InternalMille end + +mutable struct Mille + internalptr::Ptr{InternalMille} +end + + +""" + Mille(filename) + +Creates a new "Mille" object, which can be passed to `CrystFEL.Indexing.index()` +to accumulate detector geometry alignment information in the specified file. + +When you've finished adding data, call `close()` on the Mille object. This will +be done automatically when the object is freed by the garbage collector, but +that might not happen until Julia exits. + +Corresponds to CrystFEL C API routine `crystfel_mille_new`. +""" +function Mille(filename::AbstractString) + out = @ccall libcrystfel.crystfel_mille_new(filename::Cstring)::Ptr{InternalMille} + if out == C_NULL + throw(ArgumentError("Failed to create Millepede object")) + end + finalizer(close, Mille(out)) +end + + +function Base.close(x::Mille) + if x.internalptr != C_NULL + @ccall libcrystfel.crystfel_mille_free(x.internalptr::Ptr{InternalMille})::Cvoid + x.internalptr = C_NULL + end +end + + +end # of module diff --git a/julia/CrystFEL/src/peaklist.jl b/julia/CrystFEL/src/peaklist.jl new file mode 100644 index 00000000..9eedad27 --- /dev/null +++ b/julia/CrystFEL/src/peaklist.jl @@ -0,0 +1,117 @@ +module PeakLists + +using Printf +import ..CrystFEL: libcrystfel +export PeakList, InternalPeakList + +mutable struct InternalPeak + fs::Cdouble + ss::Cdouble + panelnumber::Cint + intensity::Cdouble + name::Cstring +end + +mutable struct InternalPeakList end + +mutable struct PeakList + internalptr::Ptr{InternalPeakList} +end + + +function PeakList() + out = @ccall libcrystfel.image_feature_list_new()::Ptr{InternalPeakList} + if out == C_NULL + throw(ArgumentError("Failed to create peak list")) + end + finalizer(PeakList(out)) do pl + @ccall libcrystfel.image_feature_list_free(pl.internalptr::Ptr{InternalPeakList})::Cvoid + end +end + + +Base.copy(::PeakList) = throw(ErrorException("Cannot copy(::PeakList), must deepcopy")) + +function Base.deepcopy(peaklist::PeakList) + out = @ccall libcrystfel.image_feature_list_copy(peaklist.internalptr::Ptr{InternalPeakList})::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Failed to copy peak list")) + end + PeakList(out) +end + +function Base.length(peaklist::PeakList) + @ccall libcrystfel.image_feature_count(peaklist.internalptr::Ptr{InternalPeakList})::Cint +end + +Base.firstindex(peaklist::PeakList) = 1 +Base.lastindex(peaklist::PeakList) = length(peaklist) + + +function Base.push!(peaklist::PeakList, fs, ss, panelnumber, intensity, name=nothing) + + rname = isnothing(name) ? C_NULL : @ccall strdup(name::Cstring)::Cstring + + @ccall libcrystfel.image_add_feature(peaklist.internalptr::Ptr{InternalPeakList}, + fs::Cdouble, ss::Cdouble, panelnumber::Cint, + intensity::Cdouble, rname::Cstring)::Cvoid +end + + +function Base.getindex(peaklist::PeakList, n) + out = @ccall(libcrystfel.image_get_feature(peaklist.internalptr::Ptr{InternalPeakList}, + (n-1)::Cint)::Ptr{InternalPeak}) + if out == C_NULL + throw(BoundsError(peaklist, n)) + end + pdata = unsafe_load(out) + if pdata.name == C_NULL + nname = nothing + else + nname = unsafe_string(pdata.name) + end + return (fs=pdata.fs, ss=pdata.ss, panelnumber=pdata.panelnumber, + intensity=pdata.intensity, name=nname) +end + + +function Base.iterate(peaklist::PeakList) + if length(peaklist) > 0 + return peaklist[1],(1,length(peaklist)) + else + return nothing + end +end + + +function Base.iterate(peaklist::PeakList, state) + let nxt = state[1]+1 + len = state[2] + if nxt == len+1 + return nothing + else + return peaklist[nxt],(nxt,state[2]) + end + end +end + + +function Base.show(io::IO, ::MIME"text/plain", peaklist::PeakList) + println(io, "Peak list with ", length(peaklist), " peaks") + print(io, " fs ss panel intensity name") + let n = 0 + for pk in Iterators.take(peaklist, 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮") + break + end + write(io, "\n") + @printf(io, "%7.2f %7.2f %6i %10.2f %s", + pk.fs, pk.ss, pk.panelnumber, pk.intensity, pk.name) + n += 1 + end + end +end + +end # of module diff --git a/julia/CrystFEL/src/peaksearch.jl b/julia/CrystFEL/src/peaksearch.jl new file mode 100644 index 00000000..aaaee16c --- /dev/null +++ b/julia/CrystFEL/src/peaksearch.jl @@ -0,0 +1,74 @@ +module PeakSearch + +import ..CrystFEL: libcrystfel +import ..CrystFEL.Images: InternalImage +import ..CrystFEL.PeakLists: PeakList, InternalPeakList + +export zaefpeaks, peakfinder8, peakfinder9 + + +function tf10(val) + if val + return 1 + else + return 0 + end +end + + +function zaefpeaks(image; threshold=100, mingrad=100000, minsnr=5, + radiusinn=4, radiusmid=5, radiusout=7, usesaturated=true) + out = @ccall libcrystfel.search_peaks(image.internalptr::Ptr{InternalImage}, + threshold::Cfloat, + mingrad::Cfloat, + minsnr::Cfloat, + radiusinn::Cdouble, + radiusmid::Cdouble, + radiusout::Cdouble, + tf10(usesaturated)::Cint)::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Peak search failed")) + end + PeakList(out) +end + + + +function peakfinder8(image; threshold=100, minsnr=5, minpix=2, maxpix=200, + localbg=3, minres=0, maxres=5000, usesaturated=true, maxpeaks=2000) + out = @ccall libcrystfel.peakfinder8(image.internalptr::Ptr{InternalImage}, + maxpeaks::Cint, + threshold::Cfloat, + minsnr::Cfloat, + minpix::Cint, + maxpix::Cint, + localbg::Cint, + minres::Cint, + maxres::Cint, + tf10(usesaturated)::Cint, + 0::Cint, + C_NULL::Ptr{Cvoid})::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Peak search failed")) + end + PeakList(out) +end + + +function peakfinder9(image; minsnrbig=7, minsnrpeak=6, minsnrwhole=5, minbgsig=11, + brightpxcut=-Inf, window=5) + out = @ccall libcrystfel.search_peaks_peakfinder9(image.internalptr::Ptr{InternalImage}, + minsnrbig::Cfloat, + minsnrpeak::Cfloat, + minsnrwhole::Cfloat, + minbgsig::Cfloat, + brightpxcut::Cfloat, + window::Cint)::Ptr{InternalPeakList} + if out == C_NULL + throw(ErrorException("Peak search failed")) + end + PeakList(out) +end + + +end # of module diff --git a/julia/CrystFEL/src/reflists.jl b/julia/CrystFEL/src/reflists.jl new file mode 100644 index 00000000..ba7311da --- /dev/null +++ b/julia/CrystFEL/src/reflists.jl @@ -0,0 +1,411 @@ +module RefLists + +using Printf +import ..CrystFEL: libcrystfel +import ..CrystFEL.Symmetry: SymOpList, InternalSymOpList, symmetry_name +export RefList, loadreflist, savereflist! +export Reflection, UnmergedReflection, MergedReflection +export InternalRefList + + +# The internal libcrystfel structures, not exposed directly +# We only ever have e.g. a Ptr{InternalRefList}, never a real InternalRefList +mutable struct InternalRefList end +mutable struct InternalReflection end +mutable struct InternalRefListIterator end + +# The Julian exposed types +abstract type Reflection end + +mutable struct RefList{T<:Reflection} + internalptr::Ptr{InternalRefList} + symmetry::SymOpList +end + +mutable struct RefListIterator + lastrefl::Ptr{InternalReflection} + internalptr::Ptr{InternalRefListIterator} +end + +mutable struct MergedReflection <: Reflection + internalptr::Ptr{InternalReflection} +end + +mutable struct UnmergedReflection <: Reflection + internalptr::Ptr{InternalReflection} +end + + +function RefList{MergedReflection}(sym::SymOpList) + out = @ccall libcrystfel.reflist_new()::Ptr{InternalRefList} + if out == C_NULL + throw(ErrorException("Failed to create RefList")) + end + finalizer(RefList{MergedReflection}(out, sym)) do x + @ccall libcrystfel.reflist_free(x.internalptr::Ptr{InternalRefList})::Cvoid + end +end + + +function Base.iterate(reflist::RefList{T}) where T + + rli = Ref{Ptr{InternalRefListIterator}}(C_NULL) + refl = ccall((:first_refl, libcrystfel), + Ptr{InternalReflection}, (Ptr{InternalRefList},Ref{Ptr{InternalRefListIterator}}), + reflist.internalptr, rli) + + if refl == C_NULL + return nothing # no reflections! + end + + iter = RefListIterator(refl,rli[]) + finalizer(iter) do x + ccall((:free_reflistiterator, libcrystfel), + Cvoid, (Ptr{InternalRefListIterator},), x.internalptr) + end + + return T(refl),iter + +end + + +function Base.iterate(::RefList{T}, iter) where T + + refl = ccall((:next_refl, libcrystfel), + Ptr{InternalReflection}, (Ptr{InternalReflection},Ptr{InternalRefListIterator}), + iter.lastrefl, iter.internalptr) + + if refl == C_NULL + iter.internalptr = C_NULL # libcrystfel already freed it + return nothing + end + + iter.lastrefl = refl + + return T(refl),iter + +end + + +Base.IteratorEltype(::RefList{T}) where T = T +Base.isdone(iter::RefListIterator) = ((iter.internalptr == C_NULL) && (iter.lastrefl != C_NULL)) +Base.length(reflist::RefList) = ccall((:num_reflections, libcrystfel), + Cint, (Ptr{InternalRefList},), reflist.internalptr) + + +function Base.getindex(reflist::RefList{T}, indices) where T + + refl = @ccall libcrystfel.find_refl(reflist.internalptr::Ptr{InternalRefList}, + indices[1]::Cint, + indices[2]::Cint, + indices[3]::Cint)::Ptr{InternalReflection} + + if refl == C_NULL + return nothing + else + return T(refl) + end +end + + +function Base.get!(reflist::RefList{T}, indices) where T + + refl = @ccall libcrystfel.find_refl(reflist.internalptr::Ptr{InternalRefList}, + indices[1]::Cint, + indices[2]::Cint, + indices[3]::Cint)::Ptr{InternalReflection} + + if refl == C_NULL + return push!(reflist, indices) + else + return T(refl) + end +end + + +function Base.push!(reflist::RefList{T}, indices) where T + + refl = @ccall libcrystfel.add_refl(reflist.internalptr::Ptr{InternalRefList}, + indices[1]::Cint, + indices[2]::Cint, + indices[3]::Cint)::Ptr{InternalReflection} + + if refl == C_NULL + return nothing + else + return T(refl) + end +end + + +function loadreflist(filename::AbstractString) + + psym = Ref{Cstring}() + out = ccall((:read_reflections_2, libcrystfel), + Ptr{InternalRefList}, (Cstring,Ref{Cstring}), + filename, psym) + if out == C_NULL + throw(ArgumentError("Failed to load reflection list")) + end + + symmetryname = unsafe_string(psym[]) + return RefList{MergedReflection}(out, SymOpList(symmetryname)) + +end + + +function savereflist!(reflist::RefList{MergedReflection}, filename::AbstractString) + + r = @ccall libcrystfel.write_reflist_2(filename::Cstring, + reflist.internalptr::Ptr{InternalRefList}, + reflist.symmetry.internalptr::Ptr{InternalSymOpList})::Cint + + if r != 0 + throw(ErrorException("Failed to save reflection list")) + end + +end + + +function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{MergedReflection}) + println(io, "Merged reflection list in point group ", symmetry_name(reflist.symmetry)) + print(io, " h k l intensity σ(intens) nmeas") + let n = 0 + for refl in Iterators.take(reflist, 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮ ⋮") + break + end + let ind = refl.indices + write(io, "\n") + @printf(io, "%4i %4i %4i %10.2f %10.2f %5i", ind[1], ind[2], ind[3], + refl.intensity, refl.sigintensity, refl.nmeasurements) + n += 1 + end + end + end +end + + +function Base.show(io::IO, ::MIME"text/plain", reflist::RefList{UnmergedReflection}) + println(io, "Unmerged reflection list in point group ", symmetry_name(reflist.symmetry)) + print(io, " h k l intensity σ(intens) fs ss panel") + let n = 0 + for refl in Iterators.take(reflist, 11) + if n == 10 + # We have printed 10 already, and are here again. Truncate... + print(io, "\n ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮ ⋮") + break + end + let ind = refl.indices, + pos = refl.detectorposition + write(io, "\n") + @printf(io, "%4i %4i %4i %10.2f %10.2f %7.2f %7.2f %6i", + ind[1], ind[2], ind[3], refl.intensity, refl.sigintensity, + pos.fs, pos.ss, pos.panelnumber) + n += 1 + end + end + end +end + + +function detectorpos(refl::Reflection) + pfs = Ref{Cdouble}(0) + pss = Ref{Cdouble}(0) + pn = ccall((:get_panel_number, libcrystfel), + Cint, (Ptr{InternalReflection},), refl.internalptr) + ccall((:get_detector_pos, libcrystfel), + Cint, (Ptr{InternalReflection},Ref{Cdouble},Ref{Cdouble}), + refl.internalptr, pfs, pss) + (fs=pfs[], ss=pss[], panelnumber=pn) +end + + +function indices(refl::Reflection) + h = Ref{Cint}(0) + k = Ref{Cint}(0) + l = Ref{Cint}(0) + ccall((:get_indices, libcrystfel), + Cint, (Ptr{InternalReflection},Ref{Cint},Ref{Cint},Ref{Cint}), + refl.internalptr, h, k, l) + [h[], k[], l[]] +end + + +function symmetricindices(refl::Reflection) + h = Ref{Cint}(0) + k = Ref{Cint}(0) + l = Ref{Cint}(0) + ccall((:get_symmetric_indices, libcrystfel), + Cint, (Ptr{InternalReflection},Ref{Cint},Ref{Cint},Ref{Cint}), + refl.internalptr, h, k, l) + [h[], k[], l[]] +end + + +function Base.getproperty(refl::Reflection, name::Symbol) + if name === :intensity + ccall((:get_intensity, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :sigintensity + ccall((:get_esd_intensity, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :partiality + ccall((:get_partiality, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :khalf + ccall((:get_khalf, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :kpred + ccall((:get_kpred, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :excitationerror + ccall((:get_exerr, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :lorentzfactor + ccall((:get_lorentz, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :phase + ccall((:get_phase, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :peak + ccall((:get_peak, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :meanbackground + ccall((:get_mean_bg, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :temp1 + ccall((:get_temp1, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :temp2 + ccall((:get_temp2, libcrystfel), + Cdouble, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :nmeasurements + ccall((:get_redundancy, libcrystfel), + Cint, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :flag + ccall((:get_flag, libcrystfel), + Cint, (Ptr{InternalReflection},), refl.internalptr) + elseif name === :detectorposition + detectorpos(refl) + elseif name === :indices + indices(refl) + elseif name === :symmetricindices + symmetricindices(refl) + else + getfield(refl, name) + end +end + + +function Base.setproperty!(refl::Reflection, name::Symbol, val) + if name === :intensity + @ccall libcrystfel.set_intensity(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :sigintensity + @ccall libcrystfel.set_esd_intensity(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :partiality + @ccall libcrystfel.set_partiality(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :khalf + @ccall libcrystfel.set_khalf(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :kpred + @ccall libcrystfel.set_kpred(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :excitationerror + @ccall libcrystfel.set_exerr(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :lorentzfactor + @ccall libcrystfel.set_lorentz(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :phase + @ccall libcrystfel.set_phase(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :peak + @ccall libcrystfel.set_peak(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :meanbackground + @ccall libcrystfel.set_mean_bg(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :temp1 + @ccall libcrystfel.set_temp1(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :temp2 + @ccall libcrystfel.set_temp2(refl.internalptr::Ptr{InternalReflection}, + val::Cdouble)::Cvoid + elseif name === :nmeasurements + @ccall libcrystfel.set_redundancy(refl.internalptr::Ptr{InternalReflection}, + val::Cint)::Cvoid + elseif name === :flag + @ccall libcrystfel.set_flag(refl.internalptr::Ptr{InternalReflection}, + val::Cint)::Cvoid + elseif name === :detectorposition + @ccall libcrystfel.set_detector_pos(refl.internalptr::Ptr{InternalReflection}, + val.fs::Cdouble, val.ss::Cdouble)::Cvoid + @ccall libcrystfel.set_panel_number(refl.internalptr::Ptr{InternalReflection}, + val.panelnumber::Cint)::Cvoid + elseif name === :indices + throw(ErrorException("Cannot set the indices of a Reflection")) + elseif name === :symmetricindices + @ccall libcrystfel.set_symmetric_indices(refl.internalptr::Ptr{InternalReflection}, + val[1]::Cint, val[2]::Cint, val[3]::Cint)::Cvoid + else + setfield!(refl, name, val) + end +end + + +function Base.propertynames(::UnmergedReflection; private=false) + names = (:intensity,:sigintensity,:partiality,:khalf,:kpred,:lorentzfactor, + :excitationerror,:phase,:peak,:meanbackground,:temp1,:temp2, + :nmeasurements,:flag,:detectorposition,:indices,:symmetricindices) + if private + tuple(names..., :internalptr) + else + names + end +end + + +function Base.propertynames(::MergedReflection; private=false) + names = (:intensity,:sigintensity,:phase,:temp1,:temp2, + :nmeasurements,:flag,:indices,:symmetricindices) + if private + tuple(names..., :internalptr) + else + names + end +end + + +function Base.show(io::IO, refl::MergedReflection) + write(io, "MergedReflection(") + show(io, refl.indices) + write(io, ", intensity=") + show(io, refl.intensity) + write(io, ", σ(intensity)=") + show(io, refl.sigintensity) + write(io, ", nmeasurements=") + show(io, refl.nmeasurements) + write(io, ")") +end + + +function Base.show(io::IO, refl::UnmergedReflection) + write(io, "UnmergedReflection(") + show(io, refl.indices) + write(io, " at "); + show(io, refl.detectorposition) + write(io, ", intensity=") + show(io, refl.intensity) + write(io, ", σ(intensity)=") + show(io, refl.sigintensity) + write(io, ")") +end + + +end # of module diff --git a/julia/CrystFEL/src/streams.jl b/julia/CrystFEL/src/streams.jl new file mode 100644 index 00000000..ce75c906 --- /dev/null +++ b/julia/CrystFEL/src/streams.jl @@ -0,0 +1,138 @@ +module Streams + +import ..CrystFEL: libcrystfel +import ..CrystFEL.DataTemplates: DataTemplate, InternalDataTemplate +import ..CrystFEL.Images: Image, InternalImage +export Stream, chunkwrite, chunkread, allcrystals + +# Represents the real C-side (opaque) structure. +mutable struct InternalStream end + +# The Julia-side structure, needed to house the pointer to the C structure +mutable struct Stream + internalptr::Ptr{InternalStream} +end + + +""" + Stream(filename, "w", dtempl) + +Opens a CrystFEL stream for writing. Note that you must provide a `DataTemplate`, +which is needed to translate "panel coordinates" to "file coordinates". + +Corresponds to CrystFEL C API routine `stream_open_for_write`. +""" +function Stream(filename, mode::AbstractString, dtempl::DataTemplate) + + if mode == "w" + out = @ccall libcrystfel.stream_open_for_write(filename::Cstring, + dtempl.internalptr::Ptr{InternalDataTemplate})::Ptr{InternalStream} + if out == C_NULL + throw(ErrorException("Failed to open stream for reading")) + end + + @ccall libcrystfel.stream_write_data_template(out::Ptr{InternalStream}, + dtempl.internalptr::Ptr{InternalDataTemplate})::Cvoid + + finalizer(close, Stream(out)) + + elseif mode =="r" + throw(ArgumentError("To open a stream for reading, don't provide the DataTemplate")) + + else + throw(ArgumentError("Unrecognised CrystFEL stream mode"*mode)) + end +end + + +""" + Stream(filename, "r") + +Opens a CrystFEL stream for reading. + +Close the stream with `close` when you've finished (this will happen +automatically when the `Stream` object is finalized). + +Corresponds to CrystFEL C API routine `stream_open_for_read`. +""" +function Stream(filename, mode::AbstractString) + + if mode == "r" + out = @ccall libcrystfel.stream_open_for_read(filename::Cstring)::Ptr{InternalStream} + if out == C_NULL + throw(ErrorException("Failed to open stream for reading")) + end + finalizer(close, Stream(out)) + + elseif mode == "w" + throw(ArgumentError("To open a stream for writing, you must provide " + *"a DataTemplate: use Stream(filename, \"w\", dtempl)")) + + else + throw(ArgumentError("Unrecognised CrystFEL stream mode"*mode)) + end +end + + +function Base.close(st::Stream) + if st.internalptr != C_NULL + @ccall libcrystfel.stream_close(st.internalptr::Ptr{InternalStream})::Cvoid + st.internalptr = C_NULL + end +end + + +function streamflags(peaks, reflections, imagedata) + flags = 0 + if reflections + flags |= 2 + end + if peaks + flags |= 4 + end + if imagedata + flags |= 8 + end + return flags +end + + +function chunkwrite(st::Stream, image::Image; peaks=true, reflections=true) + st.internalptr == C_NULL && throw(ErrorException("Stream is closed")) + flags = streamflags(peaks, reflections, false) + @ccall libcrystfel.stream_write_chunk(st.internalptr::Ptr{InternalStream}, + image.internalptr::Ptr{InternalImage}, + flags::Cint)::Cvoid +end + + +function chunkread(st::Stream; peaks=true, reflections=true, datageom=true) + + st.internalptr == C_NULL && throw(ErrorException("Stream is closed")) + + flags = streamflags(peaks, reflections, datageom) + out = @ccall libcrystfel.stream_read_chunk(st.internalptr::Ptr{InternalStream}, + flags::Cint)::Ptr{InternalImage} + out == C_NULL && return nothing + + finalizer(Image(out, nothing, [], [])) do x + ccall((:image_free, libcrystfel), Cvoid, (Ptr{InternalImage},), x.internalptr) + end + +end + + +function allcrystals(st) + Channel() do ch + while true + image = chunkread(st, peaks=false, reflections=true, datageom=false) + image === nothing && break + for cr in image.crystals + put!(ch, (cr.crystal, cr.reflections)) + end + end + end +end + + +end # of module diff --git a/julia/CrystFEL/src/symmetry.jl b/julia/CrystFEL/src/symmetry.jl new file mode 100644 index 00000000..4b4caa4d --- /dev/null +++ b/julia/CrystFEL/src/symmetry.jl @@ -0,0 +1,134 @@ +module Symmetry + +import ..CrystFEL: libcrystfel +export SymOpList, InternalSymOpList, InternalIntegerMatrix +export symmetry_name, asymmetricindices + + +# Types for pointers returned by libcrystfel +mutable struct InternalSymOpList end +mutable struct InternalIntegerMatrix end + + +# Exposed types +mutable struct SymOpList + internalptr::Ptr{InternalSymOpList} +end + + +mutable struct SymOp + internalptr::Ptr{InternalIntegerMatrix} +end + + +function SymOpList(pointgroup::AbstractString) + + out = ccall((:get_pointgroup, libcrystfel), + Ptr{InternalSymOpList}, (Cstring,), pointgroup) + if out == C_NULL + throw(OutOfMemoryError()) + end + + sym = SymOpList(out) + + finalizer(sym) do x + ccall((:free_symoplist, libcrystfel), + Cvoid, (Ptr{InternalSymOpList},), x.internalptr) + end + + return sym + +end + + +function Base.getindex(sym::SymOpList, i::Int) + + if (i<1) || (i > length(sym)) + throw(BoundsError()) + end + + out = ccall((:get_symop, libcrystfel), + Ptr{InternalIntegerMatrix}, + (Ptr{InternalSymOpList},Ptr{Cvoid},Cint), + sym.internalptr,C_NULL,i-1) + + if out == C_NULL + throw(OutOfMemoryError()) + end + + return SymOp(out) + +end + + +function Base.length(sym::SymOpList) + return ccall((:num_equivs, libcrystfel), + Cint, (Ptr{InternalSymOpList},Ptr{Cvoid}), + sym.internalptr, C_NULL) +end + + +function hkl_op(op::SymOp) + s = ccall((:name_equiv, libcrystfel), + Cstring, + (Ptr{InternalIntegerMatrix},), + op.internalptr) + return unsafe_string(s) +end + + +function symmetry_name(sym::SymOpList) + s = ccall((:symmetry_name, libcrystfel), + Cstring, + (Ptr{InternalSymOpList},), + sym.internalptr) + return unsafe_string(s) +end + + +function Base.iterate(sym::SymOpList) + return (sym[1], 2) +end + + +function Base.iterate(sym::SymOpList, i) + if i > length(sym) + return nothing + else + return (sym[i], i+1) + end +end + + +function asymmetricindices(sym::SymOpList, indices) + ho = Ref{Cint}(0) + ko = Ref{Cint}(0) + lo = Ref{Cint}(0) + @ccall libcrystfel.get_asymm(sym.internalptr::Ptr{InternalSymOpList}, + indices[1]::Cint, indices[2]::Cint, indices[3]::Cint, + ho::Ref{Cint}, ko::Ref{Cint}, lo::Ref{Cint})::Cvoid + (ho[], ko[], lo[]) +end + + +function Base.show(io::IO, ::MIME"text/plain", sym::SymOpList) + print(io, length(sym), "-element SymOpList (\"", symmetry_name(sym), "\")") + for op in sym + print(io, "\n", hkl_op(op)) + end +end + + +function Base.show(io::IO, sym::SymOpList) + write(io, "SymOpList(\"", symmetry_name(sym), "\")") +end + + +function Base.show(io::IO, op::SymOp) + write(io, "SymOp(") + write(io, "\"") + write(io, hkl_op(op)) + write(io, "\")") +end + +end # of module diff --git a/julia/alignment-test.geom b/julia/alignment-test.geom new file mode 100644 index 00000000..b2be83c6 --- /dev/null +++ b/julia/alignment-test.geom @@ -0,0 +1,51 @@ +adu_per_photon = 1 +res = 10000 +clen = 100.0 mm +photon_energy = 9000 eV + +dim0 = % +dim1 = ss +dim2 = fs +data = /data/data + +q0/dim0 = 0 +q0/min_fs = 0 +q0/min_ss = 0 +q0/max_fs = 1024 +q0/max_ss = 1024 +q0/fs = x +q0/ss = y +q0/corner_x = -1054 +q0/corner_y = 30 + +q1/dim0 = 1 +q1/min_fs = 0 +q1/min_ss = 0 +q1/max_fs = 1024 +q1/max_ss = 1024 +q1/fs = x +q1/ss = y +q1/corner_x = 30 +q1/corner_y = 30 + +q2/dim0 = 2 +q2/min_fs = 0 +q2/min_ss = 0 +q2/max_fs = 1024 +q2/max_ss = 1024 +q2/fs = x +q2/ss = y +q2/corner_x = 30 +q2/corner_y = -1054 + +q3/dim0 = 3 +q3/min_fs = 0 +q3/min_ss = 0 +q3/max_fs = 1024 +q3/max_ss = 1024 +q3/fs = x +q3/ss = y +q3/corner_x = -1054 +q3/corner_y = -1054 + +group_all = q0,q1,q2,q3 diff --git a/julia/alignment-test.jl b/julia/alignment-test.jl new file mode 100644 index 00000000..0c64a588 --- /dev/null +++ b/julia/alignment-test.jl @@ -0,0 +1,114 @@ +using CrystFEL +using Random +using Plots +using MillepedeII + +# "Simulate" a diffraction pattern +function sketch_pattern(image, cr) + reflist = predictreflections(cr, image) + peaklist = PeakList() + for refl in reflist + if randn() > 0 + let dpos = refl.detectorposition + push!(peaklist, round(dpos.fs), round(dpos.ss), dpos.panelnumber, 100.0) + end + end + end + return peaklist +end + + +function simulate_and_index(cell, image_true, dtempl_moved, mille, n) + + indexer = Indexer("asdf", dtempl_moved, cell, retry=false, multilattice=false, refine=true) + + nidx = 0 + for i in 1:n + + # Create a diffraction pattern for a random orientation + cr = Crystal(rotatecell(cell)) + peaklist = sketch_pattern(image_true, cr) + + # Make an image with the correct spot positions, + # but with an incorrect geometry + image_moved = Image(dtempl_moved) + image_moved.peaklist = peaklist + + # Index the pattern (and store Mille data), + # based on the incorrect geometry + index(image_moved, indexer, mille=mille) + + if image_moved.n_crystals > 0 + nidx += 1 + end + + if i % 100 == 0 + print("*") + else + print(".") + end + + end + println("") + + println("Indexed ", nidx, " out of ", n, " frames") + +end + + +dtempl_true = loaddatatemplate("julia/alignment-test.geom") +image_true = Image(dtempl_true) +cell = UnitCell(MonoclinicLattice, PrimitiveCell, 123, 45, 80, 90, 97, 90) +dtempl_moved = loaddatatemplate("julia/alignment-test.geom") +translategroup!(dtempl_moved, "q1", 200e-6, 0, 0) +let mille = Mille("mille.dat") + simulate_and_index(cell, image_true, dtempl_moved, mille, 100) + close(mille) +end + + +function ploth(a, n, offs, label) + histogram(map(x->x.residual/x.esd, + filter(x->in(n, keys(x.globalgradients)), + a[offs:3:end])), + label=label) +end + + +function plotfs(filename) + + t = loadmille(filename) + l = @layout([q0 q1; q2 q3]) + a = collect(Iterators.flatten(t)) + + q0 = ploth(a, 101, 1, "q0") + q1 = ploth(a, 201, 1, "q1") + q2 = ploth(a, 301, 1, "q2") + q3 = ploth(a, 401, 1, "q3") + plot(q0, q1, q2, q3, layout=l, plot_title="Fast scan residual") + +end + + +function plotss(filename) + + t = loadmille(filename) + l = @layout([q0 q1; q2 q3]) + a = collect(Iterators.flatten(t)) + + q0 = ploth(a, 102, 2, "q0") + q1 = ploth(a, 202, 2, "q1") + q2 = ploth(a, 302, 2, "q2") + q3 = ploth(a, 402, 2, "q3") + plot(q0, q1, q2, q3, layout=l, plot_title="Slow scan residual") + +end + + +function plotr(filename) + t = loadmille(filename) + l = @layout([q0 q1; q2 q3]) + a = collect(Iterators.flatten(t)) + meas = histogram(map(x->x.residual, a[3:3:end])) + plot(meas, plot_title="Excitation error residual") +end 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/julia/partial_sim.jl b/julia/partial_sim.jl new file mode 100644 index 00000000..efc621f9 --- /dev/null +++ b/julia/partial_sim.jl @@ -0,0 +1,30 @@ +using CrystFEL + +dtempl = loaddatatemplate("input.geom") +cell = UnitCell(OrthorhombicLattice, PrimitiveCell, 40.0, 50.0, 60.0) +full = loadreflist("input.hkl") +let st = Stream("partials.stream", "w", dtempl) + for i in 1:10 + println("Writing image ", i) + image = Image(dtempl) + image.serial = i + image.filename = "simulation_" * string(i) + image.ev = "//" + cr = Crystal(rotatecell(cell)) + reflections = predictreflections(cr, image) + calculatepartialities!(reflections, cr, image, model=XSphereModel) + for refl in reflections + f = full[asymmetricindices(full.symmetry, refl.indices...)...] + if f !== nothing + refl.intensity = f.intensity * refl.partiality * refl.lorentzfactor + else + # No matching "full" intensity - can't do anything + # Reflections with zero measurements won't be written to file + refl.nmeasurements = 0 + println("Not found: ", refl.indices) + end + end + push!(image, cr, reflections) + chunkwrite(st, image) + end +end diff --git a/julia/process_hkl.jl b/julia/process_hkl.jl new file mode 100644 index 00000000..34e6104e --- /dev/null +++ b/julia/process_hkl.jl @@ -0,0 +1,7 @@ +using CrystFEL +using LinearAlgebra + +let st = Stream("/home/twhite/experiments/cxidb-193/short.stream", "r"), + merged = mergereflections(allcrystals(st), SymOpList("mmm")) + savereflist!(merged, "merged.hkl") +end diff --git a/libcrystfel/src/cell-utils.c b/libcrystfel/src/cell-utils.c index 2398c5f2..d751172e 100644 --- a/libcrystfel/src/cell-utils.c +++ b/libcrystfel/src/cell-utils.c @@ -996,14 +996,14 @@ UnitCell *load_cell_from_file(const char *filename) n1 = assplode(line, " \t", &bits, ASSPLODE_NONE); if ( n1 < 3 ) { - for ( i=0; i<n1; i++ ) free(bits[i]); - free(bits); + for ( i=0; i<n1; i++ ) cffree(bits[i]); + cffree(bits); continue; } if ( bits[0][0] == ';' ) { - for ( i=0; i<n1; i++ ) free(bits[i]); - free(bits); + for ( i=0; i<n1; i++ ) cffree(bits[i]); + cffree(bits); continue; } @@ -1061,8 +1061,8 @@ UnitCell *load_cell_from_file(const char *filename) ERROR("Unrecognised field '%s'\n", bits[0]); } - for ( i=0; i<n1; i++ ) free(bits[i]); - free(bits); + for ( i=0; i<n1; i++ ) cffree(bits[i]); + cffree(bits); } while ( rval != NULL ); @@ -1588,12 +1588,12 @@ static Rational *find_candidates(double len, double *a, double *b, double *c, int ia, ib, ic; int i; - cands = malloc(max_cand * sizeof(struct cand)); + cands = cfmalloc(max_cand * sizeof(struct cand)); if ( cands == NULL ) return NULL; rat = rtnl_list(-5, 5, 1, csl ? 4 : 1, &nrat); if ( rat == NULL ) { - free(cands); + cffree(cands); return NULL; } @@ -1632,7 +1632,7 @@ static Rational *find_candidates(double len, double *a, double *b, double *c, /* Sort by difference from reference vector length */ qsort(cands, ncand, sizeof(struct cand), cmpcand); - r = malloc(ncand * 3 * sizeof(Rational)); + r = cfmalloc(ncand * 3 * sizeof(Rational)); if ( r == 0 ) return NULL; for ( i=0; i<ncand; i++ ) { @@ -1640,7 +1640,7 @@ static Rational *find_candidates(double len, double *a, double *b, double *c, r[3*i+1] = cands[i].abc[1]; r[3*i+2] = cands[i].abc[2]; } - free(cands); + cffree(cands); *pncand = ncand; return r; @@ -1823,9 +1823,9 @@ int compare_derivative_cell_parameters(UnitCell *cell_in, UnitCell *reference_in } rtnl_mtx_free(M); - free(cand_a); - free(cand_b); - free(cand_c); + cffree(cand_a); + cffree(cand_b); + cffree(cand_c); if ( CiAMCB == NULL ) { *pmb = NULL; diff --git a/libcrystfel/src/cell.c b/libcrystfel/src/cell.c index 775567e3..60f6ef58 100644 --- a/libcrystfel/src/cell.c +++ b/libcrystfel/src/cell.c @@ -109,7 +109,7 @@ UnitCell *cell_new() { UnitCell *cell; - cell = malloc(sizeof(UnitCell)); + cell = cfmalloc(sizeof(UnitCell)); if ( cell == NULL ) return NULL; cell->a = 1.0; @@ -140,7 +140,7 @@ UnitCell *cell_new() void cell_free(UnitCell *cell) { if ( cell == NULL ) return; - free(cell); + cffree(cell); } diff --git a/libcrystfel/src/crystal.c b/libcrystfel/src/crystal.c index 71d707d6..0cf246ae 100644 --- a/libcrystfel/src/crystal.c +++ b/libcrystfel/src/crystal.c @@ -3,11 +3,11 @@ * * A class representing a single crystal * - * Copyright © 2013-2021 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2013-2024 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2013-2020 Thomas White <taw@physics.org> + * 2013-2024 Thomas White <taw@physics.org> * 2016 Valerio Mariani * * This file is part of CrystFEL. @@ -31,7 +31,6 @@ #include "crystal.h" #include "utils.h" -#include "reflist-utils.h" /** @@ -41,33 +40,19 @@ struct _crystal { - /* The image containing the crystal */ - struct image *image; - - /* Information about the crystal */ - UnitCell *cell; + UnitCell *cell; + int owns_cell; double m; /* Mosaicity in radians */ double osf; double Bfac; double profile_radius; - int pr_dud; double resolution_limit; - - /* Integrated (or about-to-be-integrated) reflections */ - RefList *reflections; - long long int n_saturated; /* Number of overloads */ - long long int n_implausible; /* Number of implausibly - * negative reflectionss */ - - /* User flag, e.g. for "this is a bad crystal". */ + long long int n_saturated; /* Number of overloads */ + long long int n_implausible; /* Number of implausibly negative reflectionss */ int user_flag; - - /* Text notes, which go in the stream */ - char *notes; - - /* Detector shift in metres */ - double det_shift_x; - double det_shift_y; + char *notes; /* Text notes, which go in the stream */ + double det_shift_x; /* Detector x-shift in metres */ + double det_shift_y; /* Detector y-shift in metres */ }; @@ -84,16 +69,20 @@ Crystal *crystal_new() { Crystal *cryst; - cryst = malloc(sizeof(Crystal)); + cryst = cfmalloc(sizeof(Crystal)); if ( cryst == NULL ) return NULL; cryst->cell = NULL; - cryst->reflections = NULL; + cryst->owns_cell = 1; + cryst->m = 0.0; + cryst->osf = 1.0; + cryst->Bfac = 0.0; + cryst->profile_radius = 0.0; cryst->resolution_limit = INFINITY; cryst->n_saturated = 0; cryst->n_implausible = 0; - cryst->notes = NULL; cryst->user_flag = 0; + cryst->notes = NULL; cryst->det_shift_x = 0; cryst->det_shift_y = 0; @@ -104,38 +93,14 @@ Crystal *crystal_new() /** * \param cryst: A \ref Crystal to copy. * - * Creates a new \ref Crystal which is a copy of \p cryst. The copy is a "shallow - * copy", which means that copies are NOT made of the data structures which - * \p cryst contains references to, for example its \ref RefList. - * - * \returns A (shallow) copy of \p cryst, or NULL on failure. - * - */ -Crystal *crystal_copy(const Crystal *cryst) -{ - Crystal *c; - - c = crystal_new(); - if ( c == NULL ) return NULL; - - memcpy(c, cryst, sizeof(Crystal)); - if ( c->notes != NULL ) c->notes = strdup(c->notes); - - return c; -} - - -/** - * \param cryst: A \ref Crystal to copy. - * * Creates a new \ref Crystal which is a copy of \p cryst. The copy is a "deep * copy", which means that copies ARE made of the data structures which - * \p cryst contains references to, for example its \ref RefList. + * \p cryst contains references to, for example its \ref UnitCell. * * \returns A (deep) copy of \p cryst, or NULL on failure. * */ -Crystal *crystal_copy_deep(const Crystal *cryst) +Crystal *crystal_copy(const Crystal *cryst) { Crystal *c; @@ -143,7 +108,7 @@ Crystal *crystal_copy_deep(const Crystal *cryst) if ( c == NULL ) return NULL; memcpy(c, cryst, sizeof(Crystal)); - if ( c->notes != NULL ) c->notes = strdup(c->notes); + if ( c->notes != NULL ) c->notes = cfstrdup(c->notes); if ( cryst->cell != NULL ) { UnitCell *cell; @@ -152,13 +117,6 @@ Crystal *crystal_copy_deep(const Crystal *cryst) c->cell = cell; } - if ( cryst->reflections != NULL ) { - RefList *refls; - refls = copy_reflist(cryst->reflections); - if ( refls == NULL ) return NULL; - c->reflections = refls; - } - return c; } @@ -172,8 +130,9 @@ Crystal *crystal_copy_deep(const Crystal *cryst) void crystal_free(Crystal *cryst) { if ( cryst == NULL ) return; - free(cryst->notes); - free(cryst); + if ( cryst->owns_cell ) cell_free(cryst->cell); + cffree(cryst->notes); + cffree(cryst); } @@ -186,21 +145,22 @@ UnitCell *crystal_get_cell(Crystal *cryst) } -const UnitCell *crystal_get_cell_const(const Crystal *cryst) +UnitCell *crystal_relinquish_cell(Crystal *cryst) { + cryst->owns_cell = 0; return cryst->cell; } -double crystal_get_profile_radius(const Crystal *cryst) +const UnitCell *crystal_get_cell_const(const Crystal *cryst) { - return cryst->profile_radius; + return cryst->cell; } -RefList *crystal_get_reflections(Crystal *cryst) +double crystal_get_profile_radius(const Crystal *cryst) { - return cryst->reflections; + return cryst->profile_radius; } @@ -222,18 +182,6 @@ long long int crystal_get_num_implausible_reflections(Crystal *cryst) } -struct image *crystal_get_image(Crystal *cryst) -{ - return cryst->image; -} - - -const struct image *crystal_get_image_const(const Crystal *cryst) -{ - return cryst->image; -} - - double crystal_get_osf(Crystal *cryst) { return cryst->osf; @@ -277,7 +225,9 @@ void crystal_get_det_shift(Crystal *cryst, double* shift_x, double *shift_y) void crystal_set_cell(Crystal *cryst, UnitCell *cell) { + if ( cryst->owns_cell ) cell_free(cryst->cell); cryst->cell = cell; + cryst->owns_cell = 1; } @@ -287,12 +237,6 @@ void crystal_set_profile_radius(Crystal *cryst, double r) } -void crystal_set_reflections(Crystal *cryst, RefList *reflist) -{ - cryst->reflections = reflist; -} - - void crystal_set_resolution_limit(Crystal *cryst, double res) { cryst->resolution_limit = res; @@ -311,12 +255,6 @@ void crystal_set_num_implausible_reflections(Crystal *cryst, long long int n) } -void crystal_set_image(Crystal *cryst, struct image *image) -{ - cryst->image = image; -} - - void crystal_set_osf(Crystal *cryst, double osf) { cryst->osf = osf; @@ -343,8 +281,8 @@ void crystal_set_mosaicity(Crystal *cryst, double m) void crystal_set_notes(Crystal *cryst, const char *notes) { - free(cryst->notes); /* free(NULL) is OK */ - cryst->notes = strdup(notes); + cffree(cryst->notes); /* free(NULL) is OK */ + cryst->notes = cfstrdup(notes); } @@ -359,7 +297,7 @@ void crystal_add_notes(Crystal *cryst, const char *notes_add) } len = strlen(notes_add) + strlen(cryst->notes) + 2; - nnotes = malloc(len); + nnotes = cfmalloc(len); if ( nnotes == NULL ) { ERROR("Failed to add notes to crystal.\n"); return; @@ -368,7 +306,7 @@ void crystal_add_notes(Crystal *cryst, const char *notes_add) strcpy(nnotes, cryst->notes); strcat(nnotes, "\n"); strcat(nnotes, notes_add); - free(cryst->notes); + cffree(cryst->notes); cryst->notes = nnotes; } diff --git a/libcrystfel/src/crystal.h b/libcrystfel/src/crystal.h index 5a4ca3f6..1804fa35 100644 --- a/libcrystfel/src/crystal.h +++ b/libcrystfel/src/crystal.h @@ -3,11 +3,11 @@ * * A class representing a single crystal * - * Copyright © 2013-2021 Deutsches Elektronen-Synchrotron DESY, + * Copyright © 2013-2024 Deutsches Elektronen-Synchrotron DESY, * a research centre of the Helmholtz Association. * * Authors: - * 2013-2020 Thomas White <taw@physics.org> + * 2013-2024 Thomas White <taw@physics.org> * 2016 Valerio Mariani * * This file is part of CrystFEL. @@ -43,51 +43,39 @@ **/ typedef struct _crystal Crystal; -#include "reflist.h" - #ifdef __cplusplus extern "C" { #endif extern Crystal *crystal_new(void); extern Crystal *crystal_copy(const Crystal *cryst); -extern Crystal *crystal_copy_deep(const Crystal *cryst); extern void crystal_free(Crystal *cryst); extern UnitCell *crystal_get_cell(Crystal *cryst); -extern const UnitCell *crystal_get_cell_const(const Crystal *cryst); +extern UnitCell *crystal_relinquish_cell(Crystal *cryst); extern double crystal_get_profile_radius(const Crystal *cryst); -extern RefList *crystal_get_reflections(Crystal *cryst); extern double crystal_get_resolution_limit(Crystal *cryst); -extern long long int crystal_get_num_saturated_reflections(Crystal *cryst); -extern long long int crystal_get_num_implausible_reflections(Crystal *cryst); extern int crystal_get_user_flag(Crystal *cryst); extern double crystal_get_osf(Crystal *cryst); extern double crystal_get_Bfac(Crystal *cryst); -extern struct image *crystal_get_image(Crystal *cryst); -extern const struct image *crystal_get_image_const(const Crystal *cryst); extern double crystal_get_mosaicity(Crystal *cryst); extern const char *crystal_get_notes(Crystal *cryst); -extern void crystal_get_det_shift(Crystal *cryst, - double *shift_x, double* shift_y); +extern void crystal_get_det_shift(Crystal *cryst, double *shift_x, double *shift_y); +extern long long int crystal_get_num_saturated_reflections(Crystal *cryst); +extern long long int crystal_get_num_implausible_reflections(Crystal *cryst); extern void crystal_set_cell(Crystal *cryst, UnitCell *cell); extern void crystal_set_profile_radius(Crystal *cryst, double r); -extern void crystal_set_reflections(Crystal *cryst, RefList *reflist); extern void crystal_set_resolution_limit(Crystal *cryst, double res); -extern void crystal_set_num_saturated_reflections(Crystal *cryst, - long long int n); -extern void crystal_set_num_implausible_reflections(Crystal *cryst, - long long int n); extern void crystal_set_user_flag(Crystal *cryst, int flag); extern void crystal_set_osf(Crystal *cryst, double osf); extern void crystal_set_Bfac(Crystal *cryst, double B); -extern void crystal_set_image(Crystal *cryst, struct image *image); extern void crystal_set_mosaicity(Crystal *cryst, double m); extern void crystal_set_notes(Crystal *cryst, const char *notes); -extern void crystal_set_det_shift(Crystal *cryst, - double shift_x, double shift_y); extern void crystal_add_notes(Crystal *cryst, const char *notes_add); +extern void crystal_set_det_shift(Crystal *cryst, double shift_x, double shift_y); +extern void crystal_set_num_saturated_reflections(Crystal *cryst, long long int n); +extern void crystal_set_num_implausible_reflections(Crystal *cryst, long long int n); #ifdef __cplusplus } diff --git a/libcrystfel/src/crystfel-mille.c b/libcrystfel/src/crystfel-mille.c index 8eacaa60..3d02e527 100644 --- a/libcrystfel/src/crystfel-mille.c +++ b/libcrystfel/src/crystfel-mille.c @@ -106,8 +106,8 @@ static void mille_add_measurement(Mille *m, new_max_entries *= 2; } - new_float_arr = realloc(m->float_arr, new_max_entries*sizeof(float)); - new_int_arr = realloc(m->int_arr, new_max_entries*sizeof(int)); + new_float_arr = cfrealloc(m->float_arr, new_max_entries*sizeof(float)); + new_int_arr = cfrealloc(m->int_arr, new_max_entries*sizeof(int)); if ( (new_float_arr == NULL) || (new_int_arr == NULL) ) return; m->float_arr = new_float_arr; @@ -266,17 +266,17 @@ void write_mille(Mille *mille, int n, UnitCell *cell, mille_add_measurement(mille, nl, local_gradients_fs, j, global_gradients_fs, labels, - fs_dev(&rps[i], image->detgeom), 0.22); + fs_dev(&rps[i], image->detgeom), 0.3); /* Add ss measurement */ mille_add_measurement(mille, nl, local_gradients_ss, j, global_gradients_ss, labels, - ss_dev(&rps[i], image->detgeom), 0.22); + ss_dev(&rps[i], image->detgeom), 0.3); /* Add excitation error "measurement" (local-only) */ mille_add_measurement(mille, nl, local_gradients_r, - 0, NULL, NULL, r_dev(&rps[i]), 1.0); + 0, NULL, NULL, r_dev(&rps[i]), 0.2); } } @@ -285,7 +285,7 @@ Mille *crystfel_mille_new(const char *outFileName) { Mille *m; - m = malloc(sizeof(Mille)); + m = cfmalloc(sizeof(Mille)); if ( m == NULL ) return NULL; m->max_entries = 0; @@ -296,7 +296,7 @@ Mille *crystfel_mille_new(const char *outFileName) m->fh = fopen(outFileName, "wb"); if ( m->fh == NULL ) { ERROR("Failed to open Mille file '%s'\n", outFileName); - free(m); + cffree(m); return NULL; } @@ -309,9 +309,9 @@ void crystfel_mille_free(Mille *m) { if ( m == NULL ) return; fclose(m->fh); - free(m->float_arr); - free(m->int_arr); - free(m); + cffree(m->float_arr); + cffree(m->int_arr); + cffree(m); } diff --git a/libcrystfel/src/datatemplate.c b/libcrystfel/src/datatemplate.c index f03ca6ce..df0ad343 100644 --- a/libcrystfel/src/datatemplate.c +++ b/libcrystfel/src/datatemplate.c @@ -73,14 +73,14 @@ static struct panel_group_template *add_group(const char *name, DataTemplate *dt return NULL; } - gt = malloc(sizeof(struct panel_group_template)); + gt = cfmalloc(sizeof(struct panel_group_template)); if ( gt == NULL ) return NULL; - gt->name = strdup(name); + gt->name = cfstrdup(name); gt->n_children = 0; if ( gt->name == NULL ) { - free(gt); + cffree(gt); return NULL; } @@ -140,8 +140,8 @@ static int parse_group(const char *name, DataTemplate *dt, const char *val) } - for ( i=0; i<n_members; i++ ) free(members[i]); - free(members); + for ( i=0; i<n_members; i++ ) cffree(members[i]); + cffree(members); return fail; } @@ -156,14 +156,14 @@ static struct panel_template *new_panel(DataTemplate *det, int i; det->n_panels++; - det->panels = realloc(det->panels, - det->n_panels*sizeof(struct panel_template)); + det->panels = cfrealloc(det->panels, + det->n_panels*sizeof(struct panel_template)); new = &det->panels[det->n_panels-1]; memcpy(new, defaults, sizeof(struct panel_template)); /* Set name */ - new->name = strdup(name); + new->name = cfstrdup(name); /* Copy strings */ new->data = safe_strdup(defaults->data); @@ -186,7 +186,7 @@ static struct dt_badregion *new_bad_region(DataTemplate *det, const char *name) struct dt_badregion *new; det->n_bad++; - det->bad = realloc(det->bad, det->n_bad*sizeof(struct dt_badregion)); + det->bad = cfrealloc(det->bad, det->n_bad*sizeof(struct dt_badregion)); new = &det->bad[det->n_bad-1]; new->min_x = NAN; @@ -257,12 +257,12 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) /* Add plus at start if no sign there already */ if ( (a_orig[0] != '+') && (a_orig[0] != '-') ) { len += 1; - a = malloc(len+1); + a = cfmalloc(len+1); snprintf(a, len+1, "+%s", a_orig); a[len] = '\0'; } else { - a = strdup(a_orig); + a = cfstrdup(a_orig); } /* Count the expressions */ @@ -271,7 +271,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( (a[i] == '+') || (a[i] == '-') ) nexp++; } - bits = calloc(nexp, sizeof(char *)); + bits = cfcalloc(nexp, sizeof(char *)); /* Break the string up */ idx = -1; @@ -288,7 +288,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( (ch == '+') || (ch == '-') ) { if ( idx >= 0 ) bits[idx][istr] = '\0'; idx++; - bits[idx] = malloc(len+1); + bits[idx] = cfmalloc(len+1); istr = 0; } @@ -306,7 +306,7 @@ static int assplode_algebraic(const char *a_orig, char ***pbits) if ( idx >= 0 ) bits[idx][istr] = '\0'; *pbits = bits; - free(a); + cffree(a); return nexp; } @@ -381,10 +381,10 @@ static int dir_conv(const char *a, double *sx, double *sy, double *sz) break; } - free(bits[i]); + cffree(bits[i]); } - free(bits); + cffree(bits); return 0; } @@ -454,7 +454,7 @@ static int parse_mask(struct panel_template *panel, return 1; } - key = strdup(key_orig); + key = cfstrdup(key_orig); if ( key == NULL ) return 1; key[4] = '_'; @@ -463,16 +463,16 @@ static int parse_mask(struct panel_template *panel, * Double underscore is deliberate! */ if ( strcmp(key, "mask__file") == 0 ) { - panel->masks[n].filename = strdup(val); + panel->masks[n].filename = cfstrdup(val); } else if ( strcmp(key, "mask__data") == 0 ) { if ( strncmp(val, "/", 1) != 0 ) { ERROR("Invalid mask location '%s'\n", val); - free(key); + cffree(key); return 1; } - panel->masks[n].data_location = strdup(val); + panel->masks[n].data_location = cfstrdup(val); } else if ( strcmp(key, "mask__goodbits") == 0 ) { @@ -482,7 +482,7 @@ static int parse_mask(struct panel_template *panel, if ( end != val ) { panel->masks[n].good_bits = v; } else { - free(key); + cffree(key); return 1; } @@ -494,19 +494,19 @@ static int parse_mask(struct panel_template *panel, if ( end != val ) { panel->masks[n].bad_bits = v; } else { - free(key); + cffree(key); return 1; } } else { ERROR("Invalid mask directive '%s'\n", key_orig); - free(key); + cffree(key); return 1; } panel->masks[n].mask_default = def; - free(key); + cffree(key); return 0; } @@ -542,8 +542,8 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key, reject = 1; } else if ( strcmp(key, "data") == 0 ) { - free(panel->data); - panel->data = strdup(val); + cffree(panel->data); + panel->data = cfstrdup(val); panel->data_default = def; } else if ( strcmp(key, "mask_edge_pixels") == 0 ) { @@ -567,10 +567,10 @@ static int parse_field_for_panel(struct panel_template *panel, const char *key, reject = parse_mask(panel, key, val, def); } else if ( strcmp(key, "saturation_map") == 0 ) { - panel->satmap = strdup(val); + panel->satmap = cfstrdup(val); panel->satmap_default = def; } else if ( strcmp(key, "saturation_map_file") == 0 ) { - panel->satmap_file = strdup(val); + panel->satmap_file = cfstrdup(val); panel->satmap_file_default = def; } else if ( strcmp(key, "coffset") == 0) { @@ -689,7 +689,7 @@ static int parse_field_bad(struct dt_badregion *badr, const char *key, badr->max_ss = atof(val); reject = check_badr_fsss(badr, 1); } else if ( strcmp(key, "panel") == 0 ) { - badr->panel_name = strdup(val); + badr->panel_name = cfstrdup(val); } else { ERROR("Unrecognised field '%s'\n", key); } @@ -705,13 +705,13 @@ static int parse_electron_voltage(const char *val, char *valcpy; char *sp; - valcpy = strdup(val); + valcpy = cfstrdup(val); if ( valcpy == NULL ) return 1; /* "electron_voltage" directive must have explicit units */ sp = strchr(valcpy, ' '); if ( sp == NULL ) { - free(valcpy); + cffree(valcpy); return 1; } @@ -720,7 +720,7 @@ static int parse_electron_voltage(const char *val, } else if ( strcmp(sp+1, "kV") == 0 ) { *punit = WAVELENGTH_ELECTRON_KV; } else { - free(valcpy); + cffree(valcpy); return 1; } @@ -737,13 +737,13 @@ static int parse_wavelength(const char *val, char *valcpy; char *sp; - valcpy = strdup(val); + valcpy = cfstrdup(val); if ( valcpy == NULL ) return 1; /* "wavelength" directive must have explicit units */ sp = strchr(valcpy, ' '); if ( sp == NULL ) { - free(valcpy); + cffree(valcpy); return 1; } @@ -752,7 +752,7 @@ static int parse_wavelength(const char *val, } else if ( strcmp(sp+1, "A") == 0 ) { *punit = WAVELENGTH_A; } else { - free(valcpy); + cffree(valcpy); return 1; } @@ -769,7 +769,7 @@ static int parse_photon_energy(const char *val, char *valcpy; char *sp; - valcpy = strdup(val); + valcpy = cfstrdup(val); if ( valcpy == NULL ) return 1; /* "photon_energy" is the only one of the wavelength @@ -785,7 +785,7 @@ static int parse_photon_energy(const char *val, sp[0] = '\0'; } else { /* Unit specified, but unrecognised */ - free(valcpy); + cffree(valcpy); return 1; } @@ -823,13 +823,13 @@ static int parse_toplevel(DataTemplate *dt, int *defaults_updated) { if ( strcmp(key, "detector_shift_x") == 0 ) { - dt->shift_x_from = strdup(val); + dt->shift_x_from = cfstrdup(val); } else if ( strcmp(key, "detector_shift_y") == 0 ) { - dt->shift_y_from = strdup(val); + dt->shift_y_from = cfstrdup(val); } else if ( strcmp(key, "clen") == 0 ) { - dt->cnz_from = strdup(val); + dt->cnz_from = cfstrdup(val); } else if ( strcmp(key, "photon_energy") == 0 ) { return parse_photon_energy(val, @@ -847,7 +847,7 @@ static int parse_toplevel(DataTemplate *dt, &dt->wavelength_unit); } else if ( strcmp(key, "peak_list") == 0 ) { - dt->peak_list = strdup(val); + dt->peak_list = cfstrdup(val); } else if ( strcmp(key, "peak_list_type") == 0 ) { return parse_peak_layout(val, &dt->peak_list_type); @@ -1028,7 +1028,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) struct panel_template defaults; int have_unused_defaults = 0; - dt = calloc(1, sizeof(DataTemplate)); + dt = cfcalloc(1, sizeof(DataTemplate)); if ( dt == NULL ) return NULL; dt->n_panels = 0; @@ -1082,7 +1082,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) defaults.satmap_default = 1; defaults.satmap_file = NULL; defaults.satmap_file_default = 1; - defaults.data = strdup("/data/data"); + defaults.data = cfstrdup("/data/data"); defaults.data_default = 1; defaults.name = NULL; defaults.dims[0] = DIM_SS; @@ -1090,7 +1090,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) for ( i=2; i<MAX_DIMS; i++ ) defaults.dims[i] = DIM_UNDEFINED; for ( i=0; i<MAX_DIMS; i++ ) defaults.dims_default[i] = 1; - string = strdup(string_in); + string = cfstrdup(string_in); if ( string == NULL ) return NULL; len = strlen(string); for ( i=0; i<len; i++ ) { @@ -1110,11 +1110,11 @@ DataTemplate *data_template_new_from_string(const char *string_in) const char *nl = strchr(string, '\n'); if ( nl != NULL ) { size_t nlen = nl - string; - line = strndup(string, nlen); + line = cfstrndup(string, nlen); line[nlen] = '\0'; string += nlen+1; } else { - line = strdup(string); + line = cfstrdup(string); done = 1; } @@ -1123,8 +1123,8 @@ DataTemplate *data_template_new_from_string(const char *string_in) char *line_orig = line; while ( (line_orig[i] == ' ') || (line_orig[i] == '\t') ) i++; - line = strdup(line+i); - free(line_orig); + line = cfstrdup(line+i); + cffree(line_orig); /* Stop at comment symbol */ char *comm = strchr(line, ';'); @@ -1133,7 +1133,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) /* Nothing left? Entire line was commented out, * and can be silently ignored */ if ( line[0] == '\0' ) { - free(line); + cffree(line); continue; } @@ -1141,7 +1141,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) char *eq = strchr(line, '='); if ( eq == NULL ) { ERROR("Bad line in geometry file: '%s'\n", line); - free(line); + cffree(line); reject = 1; continue; } @@ -1171,7 +1171,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) line); reject = 1; } - free(line); + cffree(line); continue; } @@ -1199,13 +1199,13 @@ DataTemplate *data_template_new_from_string(const char *string_in) if ( parse_field_bad(badregion, key, val) ) reject = 1; } - free(line); + cffree(line); } while ( !done ); if ( dt->n_panels == 0 ) { ERROR("No panel descriptions in geometry file.\n"); - free(dt); + cffree(dt); return NULL; } @@ -1394,10 +1394,10 @@ DataTemplate *data_template_new_from_string(const char *string_in) } } - free(defaults.data); + cffree(defaults.data); for ( i=0; i<MAX_MASKS; i++ ) { - free(defaults.masks[i].data_location); - free(defaults.masks[i].filename); + cffree(defaults.masks[i].data_location); + cffree(defaults.masks[i].filename); } /* If this is a single-panel detector, there should only be one group @@ -1406,7 +1406,7 @@ DataTemplate *data_template_new_from_string(const char *string_in) parse_group("all", dt, dt->groups[0]->name); } - free(string_orig); + cffree(string_orig); if ( reject ) return NULL; @@ -1426,7 +1426,7 @@ DataTemplate *data_template_new_from_file(const char *filename) } dt = data_template_new_from_string(contents); - free(contents); + cffree(contents); return dt; } @@ -1441,33 +1441,33 @@ void data_template_free(DataTemplate *dt) int j; - free(dt->panels[i].name); - free(dt->panels[i].data); - free(dt->panels[i].satmap); - free(dt->panels[i].satmap_file); + cffree(dt->panels[i].name); + cffree(dt->panels[i].data); + cffree(dt->panels[i].satmap); + cffree(dt->panels[i].satmap_file); for ( j=0; j<MAX_MASKS; j++ ) { - free(dt->panels[i].masks[j].filename); - free(dt->panels[i].masks[j].data_location); + cffree(dt->panels[i].masks[j].filename); + cffree(dt->panels[i].masks[j].data_location); } } for ( i=0; i<dt->n_headers_to_copy; i++ ) { - free(dt->headers_to_copy[i]); + cffree(dt->headers_to_copy[i]); } for ( i=0; i<dt->n_groups; i++ ) { - free(dt->groups[i]->name); - free(dt->groups[i]); + cffree(dt->groups[i]->name); + cffree(dt->groups[i]); } - free(dt->wavelength_from); - free(dt->peak_list); - free(dt->cnz_from); + cffree(dt->wavelength_from); + cffree(dt->peak_list); + cffree(dt->cnz_from); - free(dt->panels); - free(dt->bad); - free(dt); + cffree(dt->panels); + cffree(dt->bad); + cffree(dt); } @@ -1568,7 +1568,7 @@ void data_template_add_copy_header(DataTemplate *dt, return; } - dt->headers_to_copy[dt->n_headers_to_copy++] = strdup(header); + dt->headers_to_copy[dt->n_headers_to_copy++] = cfstrdup(header); } @@ -1686,14 +1686,14 @@ static int separate_value_and_units(const char *from, if ( from == NULL ) return 1; - fromcpy = strdup(from); + fromcpy = cfstrdup(from); if ( fromcpy == NULL ) return 1; sp = strchr(fromcpy, ' '); if ( sp == NULL ) { unitscpy = NULL; } else { - unitscpy = strdup(sp+1); + unitscpy = cfstrdup(sp+1); sp[0] = '\0'; } @@ -1729,14 +1729,14 @@ static int im_get_length(struct image *image, const char *from, if ( convert_float(value_str, pval) == 0 ) { /* Literal value with no units */ - free(value_str); + cffree(value_str); return 0; } else { int r; r = image_read_header_float(image, value_str, pval); - free(value_str); + cffree(value_str); if ( r == 0 ) { /* Value read from headers with no units */ @@ -1760,16 +1760,16 @@ static int im_get_length(struct image *image, const char *from, scale = 1.0; } else { ERROR("Invalid length unit '%s'\n", units); - free(value_str); - free(units); + cffree(value_str); + cffree(units); return 1; } if ( convert_float(value_str, pval) == 0 ) { /* Literal value, units specified */ - free(value_str); - free(units); + cffree(value_str); + cffree(units); *pval *= scale; return 0; @@ -1777,7 +1777,7 @@ static int im_get_length(struct image *image, const char *from, int r; r = image_read_header_float(image, value_str, pval); - free(value_str); + cffree(value_str); if ( r == 0 ) { /* Value read from headers, units specified */ @@ -1853,10 +1853,10 @@ static struct detgeom_panel_group *walk_group(const DataTemplate *dtempl, if ( gt == NULL ) return NULL; - gr = malloc(sizeof(struct detgeom_panel_group)); + gr = cfmalloc(sizeof(struct detgeom_panel_group)); if ( gr == NULL ) return NULL; - gr->name = strdup(gt->name); + gr->name = cfstrdup(gt->name); gr->n_children = gt->n_children; if ( gr->n_children == 0 ) { @@ -1892,9 +1892,9 @@ static struct detgeom_panel_group *walk_group(const DataTemplate *dtempl, double tz = 0.0; gr->panel = NULL; - gr->children = malloc(gt->n_children*sizeof(struct detgeom_panel_group *)); + gr->children = cfmalloc(gt->n_children*sizeof(struct detgeom_panel_group *)); if ( gr->children == NULL ) { - free(gr); + cffree(gr); return NULL; } @@ -1932,14 +1932,14 @@ struct detgeom *create_detgeom(struct image *image, return NULL; } - detgeom = malloc(sizeof(struct detgeom)); + detgeom = cfmalloc(sizeof(struct detgeom)); if ( detgeom == NULL ) return NULL; detgeom->top_group = NULL; - detgeom->panels = malloc(dtempl->n_panels*sizeof(struct detgeom_panel)); + detgeom->panels = cfmalloc(dtempl->n_panels*sizeof(struct detgeom_panel)); if ( detgeom->panels == NULL ) { - free(detgeom); + cffree(detgeom); return NULL; } @@ -1950,8 +1950,8 @@ struct detgeom *create_detgeom(struct image *image, || (dtempl->shift_x_from != NULL) || (dtempl->shift_y_from != NULL) ) { - free(detgeom->panels); - free(detgeom); + cffree(detgeom->panels); + cffree(detgeom); return NULL; } } @@ -2684,7 +2684,7 @@ struct dg_group_info *data_template_group_info(const DataTemplate *dtempl, int * int i; struct panel_group_template *group; - ginfo = malloc(sizeof(struct dg_group_info)*dtempl->n_groups); + ginfo = cfmalloc(sizeof(struct dg_group_info)*dtempl->n_groups); if ( ginfo == NULL ) return NULL; group = find_group(dtempl, "all"); diff --git a/libcrystfel/src/detgeom.c b/libcrystfel/src/detgeom.c index b4835317..39b00663 100644 --- a/libcrystfel/src/detgeom.c +++ b/libcrystfel/src/detgeom.c @@ -74,9 +74,9 @@ static void free_group(struct detgeom_panel_group *g) free_group(g->children[i]); } - free(g->name); - free(g->children); - free(g); + cffree(g->name); + cffree(g->children); + cffree(g); } @@ -87,12 +87,12 @@ void detgeom_free(struct detgeom *detgeom) if ( detgeom == NULL ) return; for ( i=0; i<detgeom->n_panels; i++ ) { - free(detgeom->panels[i].name); + cffree(detgeom->panels[i].name); } free_group(detgeom->top_group); - free(detgeom->panels); - free(detgeom); + cffree(detgeom->panels); + cffree(detgeom); } @@ -250,7 +250,7 @@ gsl_matrix **make_panel_minvs(struct detgeom *dg) int i; gsl_matrix **Minvs; - Minvs = malloc(dg->n_panels * sizeof(gsl_matrix *)); + Minvs = cfmalloc(dg->n_panels * sizeof(gsl_matrix *)); if ( Minvs == NULL ) return NULL; for ( i=0; i<dg->n_panels; i++ ) { diff --git a/libcrystfel/src/filters.c b/libcrystfel/src/filters.c index 4bc41f3d..e3316b1d 100644 --- a/libcrystfel/src/filters.c +++ b/libcrystfel/src/filters.c @@ -136,7 +136,7 @@ void filter_median(struct image *image, int size) nn = nn*nn; /* "localBg" is way too big, but guaranteed big enough */ - buffer = calloc(nn, sizeof(float)); + buffer = cfcalloc(nn, sizeof(float)); if ( buffer == NULL ) { ERROR("Failed to allocate LB buffer.\n"); return; @@ -153,7 +153,7 @@ void filter_median(struct image *image, int size) p = &image->detgeom->panels[pn]; - localBg = calloc(p->w*p->h, sizeof(float)); + localBg = cfcalloc(p->w*p->h, sizeof(float)); if ( localBg == NULL ) { ERROR("Failed to allocate LB buffer.\n"); return; @@ -195,8 +195,8 @@ void filter_median(struct image *image, int size) image->dp[pn][i] -= localBg[i]; } - free(localBg); + cffree(localBg); } - free(buffer); + cffree(buffer); } diff --git a/libcrystfel/src/fom.c b/libcrystfel/src/fom.c index e0149e6e..8c105533 100644 --- a/libcrystfel/src/fom.c +++ b/libcrystfel/src/fom.c @@ -78,14 +78,14 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) struct fom_context *fctx; int i; - fctx = malloc(sizeof(struct fom_context)); + fctx = cfmalloc(sizeof(struct fom_context)); if ( fctx == NULL ) return NULL; fctx->fom = fom; fctx->nshells = nshells; - fctx->cts = malloc(nshells*sizeof(int)); + fctx->cts = cfmalloc(nshells*sizeof(int)); if ( fctx->cts == NULL ) { - free(fctx); + cffree(fctx); return NULL; } for ( i=0; i<nshells; i++ ) { @@ -106,8 +106,8 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) switch ( fctx->fom ) { case FOM_RANORSPLIT : - fctx->num2 = malloc(nshells*sizeof(double)); - fctx->den2 = malloc(nshells*sizeof(double)); + fctx->num2 = cfmalloc(nshells*sizeof(double)); + fctx->den2 = cfmalloc(nshells*sizeof(double)); if ( (fctx->num2 == NULL) || (fctx->den2 == NULL) ) goto out; for ( i=0; i<nshells; i++ ) { fctx->num2[i] = 0.0; @@ -123,8 +123,8 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_MEAN_INTENSITY : case FOM_SNR : case FOM_REDUNDANCY : - fctx->num = malloc(nshells*sizeof(double)); - fctx->den = malloc(nshells*sizeof(double)); + fctx->num = cfmalloc(nshells*sizeof(double)); + fctx->den = cfmalloc(nshells*sizeof(double)); if ( (fctx->num == NULL) || (fctx->den == NULL) ) goto out; for ( i=0; i<nshells; i++ ) { fctx->num[i] = 0.0; @@ -137,7 +137,7 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) break; case FOM_NUM_MEASUREMENTS : - fctx->n_meas = calloc(nshells, sizeof(long int)); + fctx->n_meas = cfcalloc(nshells, sizeof(long int)); if ( fctx->n_meas == NULL ) goto out; break; @@ -145,20 +145,20 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_CCSTAR : case FOM_CCANO : case FOM_CRDANO : - fctx->vec1 = malloc(nshells*sizeof(double *)); - fctx->vec2 = malloc(nshells*sizeof(double *)); + fctx->vec1 = cfmalloc(nshells*sizeof(double *)); + fctx->vec2 = cfmalloc(nshells*sizeof(double *)); if ( (fctx->vec1 == NULL) || (fctx->vec2 == NULL) ) goto out; for ( i=0; i<nshells; i++ ) { fctx->vec1[i] = NULL; fctx->vec2[i] = NULL; } for ( i=0; i<nshells; i++ ) { - fctx->vec1[i] = malloc(nmax*sizeof(double)); + fctx->vec1[i] = cfmalloc(nmax*sizeof(double)); if ( fctx->vec1[i] == NULL ) goto out; - fctx->vec2[i] = malloc(nmax*sizeof(double)); + fctx->vec2[i] = cfmalloc(nmax*sizeof(double)); if ( fctx->vec2[i] == NULL ) goto out; } - fctx->n = malloc(nshells*sizeof(int)); + fctx->n = cfmalloc(nshells*sizeof(int)); if ( fctx->n == NULL ) goto out; for ( i=0; i<nshells; i++ ) { fctx->n[i] = 0; @@ -168,7 +168,7 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) case FOM_D1SIG : case FOM_D2SIG : - fctx->n_within = malloc(nshells*sizeof(int)); + fctx->n_within = cfmalloc(nshells*sizeof(int)); if ( fctx->n_within == NULL ) goto out; for ( i=0; i<nshells; i++ ) { fctx->n_within[i] = 0; @@ -180,26 +180,26 @@ static struct fom_context *init_fom(enum fom_type fom, int nmax, int nshells) return fctx; out: - free(fctx->num2); - free(fctx->den2); - free(fctx->num); - free(fctx->den); - free(fctx->n_meas); + cffree(fctx->num2); + cffree(fctx->den2); + cffree(fctx->num); + cffree(fctx->den); + cffree(fctx->n_meas); if ( fctx->vec1 != NULL ) { for ( i=0; i<nshells; i++ ) { - free(fctx->vec1[i]); + cffree(fctx->vec1[i]); } - free(fctx->vec1); + cffree(fctx->vec1); } if ( fctx->vec2 != NULL ) { for ( i=0; i<nshells; i++ ) { - free(fctx->vec2[i]); + cffree(fctx->vec2[i]); } - free(fctx->vec2); + cffree(fctx->vec2); } - free(fctx->n); - free(fctx->n_within); - free(fctx); + cffree(fctx->n); + cffree(fctx->n_within); + cffree(fctx); return NULL; } @@ -404,8 +404,8 @@ double fom_overall_value(struct fom_context *fctx) case FOM_CC : case FOM_CCSTAR : case FOM_CCANO : - overall_vec1 = malloc(fctx->nmax*sizeof(double)); - overall_vec2 = malloc(fctx->nmax*sizeof(double)); + overall_vec1 = cfmalloc(fctx->nmax*sizeof(double)); + overall_vec2 = cfmalloc(fctx->nmax*sizeof(double)); overall_n = 0; for ( i=0; i<fctx->nshells; i++ ) { int j; @@ -417,13 +417,13 @@ double fom_overall_value(struct fom_context *fctx) } cc = gsl_stats_correlation(overall_vec1, 1, overall_vec2, 1, overall_n); - free(overall_vec1); - free(overall_vec2); + cffree(overall_vec1); + cffree(overall_vec2); break; case FOM_CRDANO : - overall_along_diagonal = malloc(fctx->nmax*sizeof(double)); - overall_perpend_diagonal = malloc(fctx->nmax*sizeof(double)); + overall_along_diagonal = cfmalloc(fctx->nmax*sizeof(double)); + overall_perpend_diagonal = cfmalloc(fctx->nmax*sizeof(double)); overall_n = 0; for ( i=0; i<fctx->nshells; i++ ) { int j; @@ -443,8 +443,8 @@ double fom_overall_value(struct fom_context *fctx) 1, overall_n, 0.0); cc = sqrt(variance_signal / variance_error ); - free(overall_along_diagonal); - free(overall_perpend_diagonal); + cffree(overall_along_diagonal); + cffree(overall_perpend_diagonal); break; case FOM_D1SIG : @@ -566,8 +566,8 @@ double fom_shell_value(struct fom_context *fctx, int i) (2.0*(fctx->num2[i]/fctx->den2[i]) / sqrt(2.0)); case FOM_CRDANO : - along_diagonal = malloc(fctx->n[i] * sizeof(double)); - perpend_diagonal = malloc(fctx->n[i] * sizeof(double)); + along_diagonal = cfmalloc(fctx->n[i] * sizeof(double)); + perpend_diagonal = cfmalloc(fctx->n[i] * sizeof(double)); for ( j=0; j<fctx->n[i]; j++ ) { along_diagonal[j] = ( fctx->vec1[i][j] + fctx->vec2[i][j] ) / sqrt(2.0); @@ -578,8 +578,8 @@ double fom_shell_value(struct fom_context *fctx, int i) fctx->n[i], 0.0); variance_error = gsl_stats_variance_m(perpend_diagonal, 1, fctx->n[i], 0.0); - free(along_diagonal); - free(perpend_diagonal); + cffree(along_diagonal); + cffree(perpend_diagonal); return sqrt(variance_signal / variance_error); case FOM_D1SIG : @@ -616,17 +616,17 @@ struct fom_shells *fom_make_resolution_shells(double rmin, double rmax, double total_vol, vol_per_shell; int i; - s = malloc(sizeof(struct fom_shells)); + s = cfmalloc(sizeof(struct fom_shells)); if ( s == NULL ) return NULL; - s->rmins = malloc(nshells*sizeof(double)); - s->rmaxs = malloc(nshells*sizeof(double)); + s->rmins = cfmalloc(nshells*sizeof(double)); + s->rmaxs = cfmalloc(nshells*sizeof(double)); if ( (s->rmins==NULL) || (s->rmaxs==NULL) ) { ERROR("Couldn't allocate memory for resolution shells.\n"); - free(s->rmins); - free(s->rmaxs); - free(s); + cffree(s->rmins); + cffree(s->rmaxs); + cffree(s); return NULL; } @@ -705,8 +705,8 @@ static int wilson_scale(RefList *list1, RefList *list2, UnitCell *cell) double G, B; double c0, c1, cov00, cov01, cov11, chisq; - x = malloc(max_n*sizeof(double)); - y = malloc(max_n*sizeof(double)); + x = cfmalloc(max_n*sizeof(double)); + y = cfmalloc(max_n*sizeof(double)); if ( (x==NULL) || (y==NULL) ) { ERROR("Failed to allocate memory for scaling.\n"); return 1; @@ -772,8 +772,8 @@ static int wilson_scale(RefList *list1, RefList *list2, UnitCell *cell) STATUS("A positive relative B factor means that the second reflection " "list falls off with resolution more quickly than the first.\n"); - free(x); - free(y); + cffree(x); + cffree(y); /* Apply the scaling factor */ for ( refl2 = first_refl(list2, &iter); @@ -808,12 +808,12 @@ static int calculate_possible(struct fom_context *fctx, double cx, cy, cz; signed int h, k, l; - fctx->possible = calloc(fctx->nshells, sizeof(long int)); + fctx->possible = cfcalloc(fctx->nshells, sizeof(long int)); if ( fctx->possible == NULL ) return 1; counted = reflist_new(); if ( counted == NULL ) { - free(fctx->possible); + cffree(fctx->possible); return 1; } diff --git a/libcrystfel/src/geometry.c b/libcrystfel/src/geometry.c index 674fe4d0..10a7fa19 100644 --- a/libcrystfel/src/geometry.c +++ b/libcrystfel/src/geometry.c @@ -425,14 +425,15 @@ static Reflection *check_reflection(struct image *image, Crystal *cryst, /** * \param cryst: A \ref Crystal + * \param image: An image structure * \param max_res: Maximum resolution to predict to (m^-1) * - * Calculates reflection positions for \p crys, up to maximum 1/d value - * \p max_res + * Calculates reflection positions for \p crys, as seen in \p image, + * up to maximum 1/d value \p max_res * * \returns A list of predicted reflections */ -RefList *predict_to_res(Crystal *cryst, double max_res) +RefList *predict_to_res(Crystal *cryst, struct image *image, double max_res) { double ax, ay, az; double bx, by, bz; @@ -445,7 +446,6 @@ RefList *predict_to_res(Crystal *cryst, double max_res) double mres; signed int h, k, l; UnitCell *cell; - struct image *image; cell = crystal_get_cell(cryst); if ( cell == NULL ) return NULL; @@ -462,7 +462,6 @@ RefList *predict_to_res(Crystal *cryst, double max_res) cell_get_cartesian(cell, &ax, &ay, &az, &bx, &by, &bz, &cx, &cy, &cz); - image = crystal_get_image(cryst); mres = detgeom_max_resolution(image->detgeom, image->lambda); if ( mres > max_res ) mres = max_res; @@ -498,7 +497,7 @@ RefList *predict_to_res(Crystal *cryst, double max_res) yl = h*asy + k*bsy + l*csy; zl = h*asz + k*bsz + l*csz; - refl = check_reflection(crystal_get_image(cryst), cryst, + refl = check_reflection(image, cryst, h, k, l, xl, yl, zl, NULL); if ( refl != NULL ) { @@ -513,13 +512,11 @@ RefList *predict_to_res(Crystal *cryst, double max_res) } -static void set_unity_partialities(Crystal *cryst) +static void set_unity_partialities(RefList *list) { - RefList *list; Reflection *refl; RefListIterator *iter; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; @@ -534,32 +531,23 @@ static void set_unity_partialities(Crystal *cryst) } -static void set_random_partialities(Crystal *cryst) +static void set_random_partialities(RefList *list, int image_serial) { - RefList *list; Reflection *refl; RefListIterator *iter; - struct image *image; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; } - image = crystal_get_image(cryst); - if ( image == NULL ) { - ERROR("No image structure for partiality calculation!\n"); - return; - } - for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { signed int h, k, l; get_symmetric_indices(refl, &h, &k, &l); - set_partiality(refl, random_partiality(h, k, l, image->serial)); + set_partiality(refl, random_partiality(h, k, l, image_serial)); set_lorentz(refl, 1.0); } } @@ -682,28 +670,19 @@ static double do_integral(double q2, double zl, double R, } -static void ginn_spectrum_partialities(Crystal *cryst) +static void ginn_spectrum_partialities(RefList *list, Crystal *cryst, struct image *image) { - RefList *list; Reflection *refl; RefListIterator *iter; double r0, m; - struct image *image; UnitCell *cell; double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; } - image = crystal_get_image(cryst); - if ( image == NULL ) { - ERROR("No image for partiality calculation!\n"); - return; - } - cell = crystal_get_cell(cryst); if ( cell == NULL ) { ERROR("No unit cell for partiality calculation!\n"); @@ -716,7 +695,7 @@ static void ginn_spectrum_partialities(Crystal *cryst) r0 = fabs(crystal_get_profile_radius(cryst)); m = crystal_get_mosaicity(cryst); - for ( refl = first_refl(crystal_get_reflections(cryst), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -753,28 +732,19 @@ static void ginn_spectrum_partialities(Crystal *cryst) } -static void ewald_offset_partialities(Crystal *cryst) +static void ewald_offset_partialities(RefList *list, Crystal *cryst, struct image *image) { - RefList *list; Reflection *refl; RefListIterator *iter; double r0, m; - struct image *image; UnitCell *cell; double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - list = crystal_get_reflections(cryst); if ( list == NULL ) { ERROR("No reflections for partiality calculation!\n"); return; } - image = crystal_get_image(cryst); - if ( image == NULL ) { - ERROR("No image for partiality calculation!\n"); - return; - } - cell = crystal_get_cell(cryst); if ( cell == NULL ) { ERROR("No unit cell for partiality calculation!\n"); @@ -787,7 +757,7 @@ static void ewald_offset_partialities(Crystal *cryst) r0 = fabs(crystal_get_profile_radius(cryst)); m = crystal_get_mosaicity(cryst); - for ( refl = first_refl(crystal_get_reflections(cryst), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -815,35 +785,40 @@ static void ewald_offset_partialities(Crystal *cryst) /** + * \param list A \ref RefList * \param cryst A \ref Crystal + * \param image An image structure * \param pmodel A \ref PartialityModel * - * Calculates the partialities for the reflections in \p cryst, given the current - * crystal and image parameters. The crystal's image and reflection lists - * must be set. The specified \ref PartialityModel will be used. + * Calculates the partialities for the reflections in \p list, given the current + * state of \p cryst and \p image. + * + * If \p pmodel is PMODEL_RANDOM or PMODEL_UNITY, then \p cryst can be NULL. + * If \p pmodel is PMODEL_UNITY, then \p image can also be NULL. * * You must not have changed the crystal or image parameters since you last * called \ref predict_to_res or \ref update_predictions, because this function * relies on the limiting wavelength values calculated by those functions. */ -void calculate_partialities(Crystal *cryst, PartialityModel pmodel) +void calculate_partialities(RefList *list, Crystal *cryst, struct image *image, + PartialityModel pmodel) { switch ( pmodel ) { case PMODEL_UNITY : - set_unity_partialities(cryst); + set_unity_partialities(list); break; case PMODEL_XSPHERE : - ginn_spectrum_partialities(cryst); + ginn_spectrum_partialities(list, cryst, image); break; case PMODEL_OFFSET : - ewald_offset_partialities(cryst); + ewald_offset_partialities(list, cryst, image); break; case PMODEL_RANDOM : - set_random_partialities(cryst); + set_random_partialities(list, image->serial); break; case PMODEL_GGPM : @@ -860,28 +835,29 @@ void calculate_partialities(Crystal *cryst, PartialityModel pmodel) /** + * \param list A \ref RefList * \param cryst A \ref Crystal + * \param image An image structure * * Updates the predicted reflections (positions and excitation errors, but not - * the actual partialities) of \p cryst's reflections according to - * the current state of the crystal (e.g. its unit cell parameters). + * the actual partialities) in \p list, to match the current statea of + * \p crys as seen in \p image. * * If you need to update the partialities as well, call * \ref calculate_partialities afterwards. */ -void update_predictions(Crystal *cryst) +void update_predictions(RefList *list, Crystal *cryst, struct image *image) { Reflection *refl; RefListIterator *iter; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; - struct image *image = crystal_get_image(cryst); cell_get_reciprocal(crystal_get_cell(cryst), &asx, &asy, &asz, &bsx, &bsy, &bsz, &csx, &csy, &csz); - for ( refl = first_refl(crystal_get_reflections(cryst), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { diff --git a/libcrystfel/src/geometry.h b/libcrystfel/src/geometry.h index d05c8832..217cb9ea 100644 --- a/libcrystfel/src/geometry.h +++ b/libcrystfel/src/geometry.h @@ -35,6 +35,7 @@ #include "cell.h" #include "crystal.h" #include "detgeom.h" +#include "image.h" #ifdef __cplusplus extern "C" { @@ -77,11 +78,14 @@ struct polarisation }; -extern RefList *predict_to_res(Crystal *cryst, double max_res); +extern RefList *predict_to_res(Crystal *cryst, struct image *image, double max_res); -extern void calculate_partialities(Crystal *cryst, PartialityModel pmodel); +extern void calculate_partialities(RefList *list, + Crystal *cryst, + struct image *image, + PartialityModel pmodel); -extern void update_predictions(Crystal *cryst); +extern void update_predictions(RefList *list, Crystal *cryst, struct image *image); extern struct polarisation parse_polarisation(const char *text); extern void polarisation_correction(RefList *list, UnitCell *cell, struct polarisation p); diff --git a/libcrystfel/src/image-cbf.c b/libcrystfel/src/image-cbf.c index 0fb3b61c..c0e38283 100644 --- a/libcrystfel/src/image-cbf.c +++ b/libcrystfel/src/image-cbf.c @@ -302,7 +302,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) gzbuffer(gzfh, 128*1024); #endif - buf = malloc(bufsz); + buf = cfmalloc(bufsz); if ( buf == NULL ) return NULL; len = 0; @@ -322,7 +322,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) fh = fmemopen(buf, len, "rb"); if ( fh == NULL ) { - free(buf); + cffree(buf); return NULL; } @@ -365,7 +365,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) const char *elbo = line+29; if ( strcmp(elbo, "LITTLE_ENDIAN") != 0 ) { ERROR("Unsupported endianness: %s\n", elbo); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -380,7 +380,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) data_conversion = CBF_PACKED; } else if ( strstr(line, "conversions=") != NULL ) { ERROR("Unrecognised CBF content conversion: %s\n", line); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -393,7 +393,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) if ( data_type == CBF_NO_TYPE ) { ERROR("Unrecognised element type: %s\n", eltype); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -418,29 +418,29 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) if ( data_compressed_len == 0 ) { ERROR("Found CBF data before X-Binary-Size!\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } if ( (*w == 0) || (*h == 0) ) { ERROR("Found CBF data before dimensions!\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } if ( data_compressed_len > 100*1024*1024 ) { ERROR("Stated CBF data size too big\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } - data_compressed = malloc(data_compressed_len); + data_compressed = cfmalloc(data_compressed_len); if ( data_compressed == NULL ) { ERROR("Failed to allocate memory for CBF data\n"); - free(buf); + cffree(buf); fclose(fh); return NULL; } @@ -449,18 +449,18 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) len_read = fread(data_compressed, 1, data_compressed_len, fh); if ( len_read < data_compressed_len ) { ERROR("Couldn't read entire CBF data\n"); - free(buf); - free(data_compressed); + cffree(buf); + cffree(data_compressed); fclose(fh); return NULL; } nmemb_exp = (*w) * (*h); - data_out = malloc(nmemb_exp*sizeof(float)); + data_out = cfmalloc(nmemb_exp*sizeof(float)); if ( data_out == NULL ) { ERROR("Failed to allocate memory for CBF data\n"); - free(buf); - free(data_compressed); + cffree(buf); + cffree(data_compressed); fclose(fh); return NULL; } @@ -483,23 +483,23 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) case CBF_CANONICAL: ERROR("Don't yet know how to decompress " "CBF_PACKED or CBF_CANONICAL\n"); - free(buf); - free(data_compressed); + cffree(buf); + cffree(data_compressed); fclose(fh); return NULL; } - free(data_compressed); + cffree(data_compressed); if ( r ) { - free(buf); - free(data_out); + cffree(buf); + cffree(data_out); fclose(fh); return NULL; } - free(buf); + cffree(buf); fclose(fh); return data_out; @@ -508,7 +508,7 @@ static float *read_cbf_data(const char *filename, int gz, int *w, int *h) } while ( rval != NULL ); ERROR("Reached end of CBF file before finding data.\n"); - free(buf); /* might be NULL */ + cffree(buf); /* might be NULL */ return NULL; } @@ -598,7 +598,7 @@ int image_cbf_read(struct image *image, ERROR("Failed to read CBF data\n"); return 1; } - free(data); + cffree(data); //cbf_fill_in_beam_parameters(image->beam, f, image); //cbf_fill_in_clen(image->det, f); diff --git a/libcrystfel/src/image-hdf5.c b/libcrystfel/src/image-hdf5.c index 66b93d90..a148c307 100644 --- a/libcrystfel/src/image-hdf5.c +++ b/libcrystfel/src/image-hdf5.c @@ -60,7 +60,7 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) int n_plvals = 0; char *start; - plvals = malloc(MAX_PATH_PARTS*sizeof(char *)); + plvals = cfmalloc(MAX_PATH_PARTS*sizeof(char *)); if ( plvals == NULL ) return NULL; if ( ev_orig == NULL ) { @@ -69,9 +69,9 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) return plvals; } - ev = strdup(ev_orig); + ev = cfstrdup(ev_orig); if ( ev == NULL ) { - free(plvals); + cffree(plvals); return NULL; } @@ -87,8 +87,8 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) * must at least have // */ ERROR("Couldn't read path parts ('%s')\n", start); - free(ev); - free(plvals); + cffree(ev); + cffree(plvals); return NULL; } @@ -97,19 +97,19 @@ char **read_path_parts(const char *ev_orig, int *pn_plvals) if ( n_plvals == MAX_PATH_PARTS ) { ERROR("Too many path parts: %s\n", ev_orig); - free(ev); - free(plvals); + cffree(ev); + cffree(plvals); return NULL; } sep[0] = '\0'; - plvals[n_plvals++] = strdup(start); + plvals[n_plvals++] = cfstrdup(start); start = sep+1; } while ( 1 ); - free(ev); + cffree(ev); *pn_plvals = n_plvals; return plvals; } @@ -135,7 +135,7 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) ev = strstr(ev_orig, "//"); if ( ev == NULL ) return NULL; - dvals = malloc(MAX_DIMS*sizeof(int)); + dvals = cfmalloc(MAX_DIMS*sizeof(int)); if ( dvals == NULL ) return NULL; if ( ev[2] == '\0' ) { @@ -144,9 +144,9 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) return dvals; /* NB Not NULL */ } - ev = strdup(ev+2); + ev = cfstrdup(ev+2); if ( ev == NULL ) { - free(dvals); + cffree(dvals); return NULL; } @@ -164,15 +164,15 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) if ( n_dvals == MAX_PATH_PARTS ) { ERROR("Too many path parts: %s\n", ev_orig); - free(ev); - free(dvals); + cffree(ev); + cffree(dvals); return NULL; } if ( start[0] == '\0' ) { ERROR("Missing dimension: %s\n", ev_orig); - free(ev); - free(dvals); + cffree(ev); + cffree(dvals); return NULL; } @@ -182,7 +182,7 @@ int *read_dim_parts(const char *ev_orig, int *pn_dvals) } while ( !done ); - free(ev); + cffree(ev); *pn_dvals = n_dvals; return dvals; } @@ -247,19 +247,19 @@ char *substitute_path(const char *ev, const char *pattern, int skip_ok) if ( n_pl_exp == 0 ) { /* No placeholders in path */ for ( i=0; i<n_plvals; i++ ) { - free(plvals[i]); + cffree(plvals[i]); } - free(plvals); - return strdup(pattern); + cffree(plvals); + return cfstrdup(pattern); } total_len = strlen(pattern) - n_pl_exp; for ( i=0; i<n_plvals; i++ ) { total_len += strlen(plvals[i]); } - subs = malloc(total_len+1); + subs = cfmalloc(total_len+1); if ( subs == NULL ) { - free(plvals); + cffree(plvals); return NULL; } @@ -277,7 +277,7 @@ char *substitute_path(const char *ev, const char *pattern, int skip_ok) /* Add the placeholder's value */ strcat(subs, plvals[i]); - free(plvals[i]); + cffree(plvals[i]); /* Add the chars up to the next placeholder... */ pl_pos = strchr(start, '%'); @@ -289,7 +289,7 @@ char *substitute_path(const char *ev, const char *pattern, int skip_ok) start = pl_pos+1; } - free(plvals); + cffree(plvals); return subs; } @@ -400,12 +400,12 @@ static int load_hdf5_hyperslab(struct panel_template *p, ERROR("Cannot open data for panel %s (%s)\n", p->name, panel_full_path); profile_end("H5Dopen2"); - free(panel_full_path); + cffree(panel_full_path); return 1; } profile_end("H5Dopen2"); - free(panel_full_path); + cffree(panel_full_path); /* Set up dataspace for file * (determine where to read the data from) */ @@ -446,12 +446,12 @@ static int load_hdf5_hyperslab(struct panel_template *p, n_dt_dims = total_dt_dims; } - f_offset = malloc(ndims*sizeof(hsize_t)); - f_count = malloc(ndims*sizeof(hsize_t)); + f_offset = cfmalloc(ndims*sizeof(hsize_t)); + f_count = cfmalloc(ndims*sizeof(hsize_t)); if ( (f_offset == NULL) || (f_count == NULL ) ) { ERROR("Failed to allocate offset or count.\n"); - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); H5Dclose(dh); return 1; } @@ -492,15 +492,15 @@ static int load_hdf5_hyperslab(struct panel_template *p, } } - free(dim_vals); + cffree(dim_vals); check = H5Sselect_hyperslab(dataspace, H5S_SELECT_SET, f_offset, NULL, f_count, NULL); if ( check < 0 ) { ERROR("Error selecting file dataspace for panel %s\n", p->name); - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); H5Dclose(dh); return 1; } @@ -515,15 +515,15 @@ static int load_hdf5_hyperslab(struct panel_template *p, if ( r < 0 ) { ERROR("Couldn't read data for panel %s\n", p->name); - free(f_offset); - free(f_count); - free(data); + cffree(f_offset); + cffree(f_count); + cffree(data); H5Dclose(dh); return 1; } - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); if ( orig_type != NULL ) { *orig_type = H5Dget_type(dh); @@ -679,7 +679,7 @@ int image_hdf5_read_mask(struct panel_template *p, return 1; } - mask = malloc(p_w*p_h*sizeof(int)); + mask = cfmalloc(p_w*p_h*sizeof(int)); if ( mask == NULL ) return 1; if ( load_hdf5_hyperslab(p, fh, event, @@ -687,7 +687,7 @@ int image_hdf5_read_mask(struct panel_template *p, sizeof(int), 1, mask_location, NULL) ) { ERROR("Failed to load mask data\n"); - free(mask); + cffree(mask); return 1; } @@ -703,7 +703,7 @@ int image_hdf5_read_mask(struct panel_template *p, } - free(mask); + cffree(mask); return 0; } @@ -724,7 +724,7 @@ static char *read_single_fixed_string(hid_t dh) sh = H5Screate(H5S_SCALAR); type = H5Dget_type(dh); size = H5Tget_size(type); - tmp = malloc(size+1); + tmp = cfmalloc(size+1); if ( tmp == NULL ) { H5Tclose(type); return NULL; @@ -733,7 +733,7 @@ static char *read_single_fixed_string(hid_t dh) H5Sclose(sh); H5Tclose(type); if ( r < 0 ) { - free(tmp); + cffree(tmp); ERROR("Couldn't read scalar string\n"); return NULL; } else { @@ -802,7 +802,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) dh = H5Dopen2(fh, subst_name, H5P_DEFAULT); if ( dh < 0 ) { ERROR("No such numeric field '%s'\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } @@ -822,7 +822,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) ERROR("HDF5 header is not a recognised type (%s).\n", subst_name); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } @@ -833,7 +833,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( ndims > 64 ) { ERROR("Too many dimensions for numeric value\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } H5Sget_simple_extent_dims(sh, size, NULL); @@ -855,12 +855,12 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read scalar value from %s.\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } image_cache_header_float(image, name, val); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_INTEGER ) { @@ -871,12 +871,12 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read scalar value from %s.\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } image_cache_header_int(image, name, val); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_STRING ) { @@ -902,7 +902,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( val != NULL ) { image_cache_header_str(image, name, val); - free(val); + cffree(val); rv = 0; } else { ERROR("Failed to read string '%s'\n", @@ -910,14 +910,14 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) rv = 1; } - free(subst_name); + cffree(subst_name); close_hdf5(fh); return rv; } else { /* Should never be reached */ ERROR("Invalid HDF5 class %i\n", class); - free(subst_name); + cffree(subst_name); return 1; } } @@ -926,16 +926,16 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( dim_vals == NULL ) { ERROR("Couldn't parse event '%s'\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } - f_offset = malloc(ndims*sizeof(hsize_t)); - f_count = malloc(ndims*sizeof(hsize_t)); + f_offset = cfmalloc(ndims*sizeof(hsize_t)); + f_count = cfmalloc(ndims*sizeof(hsize_t)); if ( (f_offset == NULL) || (f_count == NULL) ) { ERROR("Couldn't allocate dimension arrays\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } @@ -953,8 +953,8 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) subst_name, i, dim_vals[dim_val_pos], size[i]); close_hdf5(fh); - free(subst_name); - free(dim_vals); + cffree(subst_name); + cffree(dim_vals); return 1; } @@ -970,21 +970,21 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) } } - free(dim_vals); + cffree(dim_vals); check = H5Sselect_hyperslab(sh, H5S_SELECT_SET, f_offset, NULL, f_count, NULL); if ( check < 0 ) { ERROR("Error selecting dataspace for header value\n"); - free(f_offset); - free(f_count); - free(subst_name); + cffree(f_offset); + cffree(f_count); + cffree(subst_name); close_hdf5(fh); return 1; } - free(f_offset); - free(f_count); + cffree(f_offset); + cffree(f_count); ms = H5Screate_simple(1,msdims,NULL); check = H5Sselect_hyperslab(ms, H5S_SELECT_SET, @@ -992,7 +992,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( check < 0 ) { ERROR("Error selecting memory dataspace for header value\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } @@ -1003,13 +1003,13 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read value.\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } image_cache_header_float(image, name, val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_INTEGER ) { @@ -1019,13 +1019,13 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( r < 0 ) { ERROR("Couldn't read value.\n"); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } image_cache_header_int(image, name, val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } else if ( class == H5T_STRING ) { @@ -1044,16 +1044,16 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) if ( rv < 0 ) { ERROR("Can't read HDF5 vlen string from array - %s\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return 1; } else { chomp(val); image_cache_header_str(image, name, val); - free(val); + cffree(val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } @@ -1066,10 +1066,10 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) size_t ssize; ssize = H5Tget_size(stype); - val = malloc(ssize+1); + val = cfmalloc(ssize+1); if ( val == NULL ) { close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } rv = H5Dread(dh, stype, ms, sh, H5P_DEFAULT, val); @@ -1078,16 +1078,16 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) ERROR("Couldn't read HDF5 fixed string from array - %s\n", subst_name); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } else { val[ssize] = '\0'; chomp(val); image_cache_header_str(image, name, val); - free(val); + cffree(val); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 0; } @@ -1098,7 +1098,7 @@ int image_hdf5_read_header_to_cache(struct image *image, const char *name) /* Should never be reached */ ERROR("Invalid HDF5 class %i\n", class); close_hdf5(fh); - free(subst_name); + cffree(subst_name); return 1; } } @@ -1279,7 +1279,7 @@ static float *read_peak_line(hid_t fh, char *path, int line, return NULL; } - buf = malloc(size[1]*sizeof(float)); + buf = cfmalloc(size[1]*sizeof(float)); if ( buf == NULL ) return NULL; r = H5Dread(dh, H5T_NATIVE_FLOAT, mh, sh, H5P_DEFAULT, buf); if ( r < 0 ) { @@ -1336,19 +1336,19 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, dim_vals = read_dim_parts(event, &n_dim_vals); if ( dim_vals == NULL ) { ERROR("Couldn't parse event '%s'\n"); - free(subst_name); + cffree(subst_name); return NULL; } if ( n_dim_vals < 1 ) { ERROR("Not enough dimensions in event ID to use CXI " "peak lists (%i)\n", n_dim_vals); - free(subst_name); + cffree(subst_name); return NULL; } line = dim_vals[0]; - free(dim_vals); + cffree(dim_vals); snprintf(path_n, 1024, "%s/nPeaks", subst_name); snprintf(path_x, 1024, "%s/peakXPosRaw", subst_name); @@ -1358,37 +1358,37 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, fh = H5Fopen(filename, H5F_ACC_RDONLY, H5P_DEFAULT); if ( fh < 0 ) { ERROR("Couldn't open file (peaks/cxi): %s\n", filename); - free(subst_name); + cffree(subst_name); return NULL; } r = read_peak_count(fh, path_n, line, &num_peaks); if ( r != 0 ) { close_hdf5(fh); - free(subst_name); + cffree(subst_name); return NULL; } buf_x = read_peak_line(fh, path_x, line, num_peaks); if ( buf_x == NULL ) { close_hdf5(fh); - free(subst_name); + cffree(subst_name); return NULL; } buf_y = read_peak_line(fh, path_y, line, num_peaks); if ( buf_y == NULL ) { - free(buf_x); - free(subst_name); + cffree(buf_x); + cffree(subst_name); close_hdf5(fh); return NULL; } buf_i = read_peak_line(fh, path_i, line, num_peaks); if ( buf_i == NULL ) { - free(buf_x); - free(buf_y); - free(subst_name); + cffree(buf_x); + cffree(buf_y); + cffree(subst_name); close_hdf5(fh); return NULL; } @@ -1410,16 +1410,15 @@ ImageFeatureList *image_hdf5_read_peaks_cxi(const DataTemplate *dtempl, ERROR("Failed to convert %i,%i to " "panel-relative coordinates\n", fs, ss); } else { - image_add_feature(features, fs, ss, pn, - NULL, val, NULL); + image_add_feature(features, fs, ss, pn, val, NULL); } } - free(buf_x); - free(buf_y); - free(buf_i); - free(subst_name); + cffree(buf_x); + cffree(buf_y); + cffree(buf_i); + cffree(subst_name); close_hdf5(fh); @@ -1471,11 +1470,11 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, dh = H5Dopen2(fh, subst_name, H5P_DEFAULT); if ( dh < 0 ) { ERROR("Peak list (%s) not found.\n", subst_name); - free(subst_name); + cffree(subst_name); close_hdf5(fh); return NULL; } - free(subst_name); + cffree(subst_name); sh = H5Dget_space(dh); if ( sh < 0 ) { @@ -1501,7 +1500,7 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, return NULL; } - buf = malloc(sizeof(float)*size[0]*size[1]); + buf = cfmalloc(sizeof(float)*size[0]*size[1]); if ( buf == NULL ) { ERROR("Couldn't reserve memory for the peak list.\n"); close_hdf5(fh); @@ -1537,13 +1536,12 @@ ImageFeatureList *image_hdf5_read_peaks_hdf5(const DataTemplate *dtempl, ERROR("Failed to convert %i,%i to " "panel-relative coordinates\n", fs, ss); } else { - image_add_feature(features, fs, ss, pn, - NULL, val, NULL); + image_add_feature(features, fs, ss, pn, val, NULL); } } - free(buf); + cffree(buf); close_hdf5(fh); return features; @@ -1557,7 +1555,7 @@ static char *matches_pattern(const char *name, const char *pattern, const char *ev_str_old) { if ( strcmp(pattern, "%") == 0 ) { - char *nstr = malloc(strlen(ev_str_old)+strlen(name)+2); + char *nstr = cfmalloc(strlen(ev_str_old)+strlen(name)+2); if ( nstr == NULL ) { ERROR("Couldn't allocate memory\n"); return NULL; @@ -1568,7 +1566,7 @@ static char *matches_pattern(const char *name, const char *pattern, return nstr; } else { if ( strcmp(name, pattern) == 0 ) { - return strdup(ev_str_old); + return cfstrdup(ev_str_old); } else { return NULL; } @@ -1588,14 +1586,14 @@ struct ev_list static int add_ev_to_list(struct ev_list *list, char *ev_str) { if ( list->n_events == list->max_events ) { - char **new_events = realloc(list->events, - (list->max_events+128)*sizeof(char *)); + char **new_events = cfrealloc(list->events, + (list->max_events+128)*sizeof(char *)); if ( new_events == NULL ) return 1; list->max_events += 128; list->events = new_events; } - list->events[list->n_events++] = strdup(ev_str); + list->events[list->n_events++] = cfstrdup(ev_str); return 0; } @@ -1606,9 +1604,9 @@ static char *demunge_event(const char *orig) size_t len = strlen(orig); char *slash; - if ( len == 0 ) return strdup("//"); + if ( len == 0 ) return cfstrdup("//"); - slash = malloc(len+3); + slash = cfmalloc(len+3); if ( slash == NULL ) return NULL; strcpy(slash, orig+1); strcat(slash, "//"); @@ -1643,7 +1641,7 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, return 1; } - name = malloc(size+1); + name = cfmalloc(size+1); if ( name == NULL ) { ERROR("Couldn't allocate memory\n"); return 1; @@ -1660,7 +1658,7 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, ev_str_new = matches_pattern(name, pattern_bits[0], ev_str); if ( ev_str_new == NULL ) { - free(name); + cffree(name); continue; } @@ -1668,8 +1666,8 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, H5_ITER_INC, i, &obj_info, 0) < 0 ) { ERROR("Couldn't get info\n"); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } @@ -1680,16 +1678,16 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, if ( n_pattern_bits == 1 ) { ERROR("Pattern doesn't match file" " (too short)\n"); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } child_gh = H5Gopen1(gh, name); if ( child_gh < 0 ) { ERROR("Couldn't open '%s'\n", name); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } @@ -1698,12 +1696,12 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, &pattern_bits[1], n_pattern_bits - 1) ) { - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } - free(ev_str_new); + cffree(ev_str_new); H5Gclose(child_gh); } else if ( obj_info.type == H5O_TYPE_DATASET ) { @@ -1714,21 +1712,21 @@ static int rec_expand_paths(hid_t gh, struct ev_list *list, ERROR("Pattern doesn't match file" " (too long by %i)\n", n_pattern_bits); - free(name); - free(ev_str_new); + cffree(name); + cffree(ev_str_new); return 1; } addme = demunge_event(ev_str_new); if ( addme != NULL ) { add_ev_to_list(list, addme); - free(addme); + cffree(addme); } - free(ev_str_new); + cffree(ev_str_new); } - free(name); + cffree(name); } @@ -1757,7 +1755,7 @@ char **expand_paths(hid_t fh, char *pattern, int *n_evs) if ( pattern[i] == '/' ) n_sep++; } - pattern_bits = malloc(n_sep*sizeof(char *)); + pattern_bits = cfmalloc(n_sep*sizeof(char *)); if ( pattern_bits == NULL ) return NULL; start = pattern+1; @@ -1766,7 +1764,7 @@ char **expand_paths(hid_t fh, char *pattern, int *n_evs) if ( sep == NULL ) { sep = start+strlen(start); } - pattern_bits[i] = strndup(start, sep-start); + pattern_bits[i] = cfstrndup(start, sep-start); if ( pattern_bits[i] == NULL ) return NULL; start = sep+1; } @@ -1778,9 +1776,9 @@ char **expand_paths(hid_t fh, char *pattern, int *n_evs) rec_expand_paths(fh, &list, "", pattern_bits, n_sep); for ( i=0; i<n_sep; i++ ) { - free(pattern_bits[i]); + cffree(pattern_bits[i]); } - free(pattern_bits); + cffree(pattern_bits); *n_evs = list.n_events; return list.events; @@ -1797,7 +1795,7 @@ static int rec_expand_dims(struct ev_list *list, size_t len; len = strlen(path_ev); - dim_ev = malloc(len+16); + dim_ev = cfmalloc(len+16); if ( dim_ev == NULL ) return 1; if ( n_placeholder_dims == 1 ) { @@ -1817,7 +1815,7 @@ static int rec_expand_dims(struct ev_list *list, } - free(dim_ev); + cffree(dim_ev); return 0; } @@ -1955,8 +1953,8 @@ char **image_hdf5_expand_frames(const DataTemplate *dtempl, return NULL; } - size = malloc(dims*sizeof(hsize_t)); - placeholder_sizes = malloc(dims*sizeof(int)); + size = cfmalloc(dims*sizeof(hsize_t)); + placeholder_sizes = cfmalloc(dims*sizeof(int)); if ( (size == NULL) || (placeholder_sizes == NULL) ) { ERROR("Failed to allocate dimensions\n"); close_hdf5(fh); @@ -1975,7 +1973,7 @@ char **image_hdf5_expand_frames(const DataTemplate *dtempl, placeholder_sizes[n_placeholder_dims++] = size[j]; } } - free(size); + cffree(size); /* Path event ID ends with //, but expand_dims will * add a slash. So, remove one slash */ @@ -1992,10 +1990,10 @@ char **image_hdf5_expand_frames(const DataTemplate *dtempl, for ( j=0; j<n_evs_this_path; j++ ) { add_ev_to_list(&full_evs, evs_this_path[j]); - free(evs_this_path[j]); + cffree(evs_this_path[j]); } - free(evs_this_path); + cffree(evs_this_path); } else { @@ -2004,14 +2002,14 @@ char **image_hdf5_expand_frames(const DataTemplate *dtempl, } - free(placeholder_sizes); - free(path); - free(path_evs[i]); + cffree(placeholder_sizes); + cffree(path); + cffree(path_evs[i]); } close_hdf5(fh); - free(path_evs); + cffree(path_evs); *pn_frames = full_evs.n_events; return full_evs.events; } diff --git a/libcrystfel/src/image-msgpack.c b/libcrystfel/src/image-msgpack.c index 0fdb104c..f305f9be 100644 --- a/libcrystfel/src/image-msgpack.c +++ b/libcrystfel/src/image-msgpack.c @@ -220,8 +220,7 @@ ImageFeatureList *image_msgpack_read_peaks(const DataTemplate *dtempl, ERROR("Failed to convert %i,%i to " "panel-relative coordinates\n", fs, ss); } else { - image_add_feature(features, fs, ss, pn, - NULL, val, NULL); + image_add_feature(features, fs, ss, pn, val, NULL); } } @@ -235,7 +234,7 @@ static char *terminate_str(const char *ptr, size_t len) char *str; if ( len < 1 ) return NULL; if ( len > 16*1024 ) return NULL; - str = malloc(len+1); + str = cfmalloc(len+1); if ( str == NULL ) return NULL; strncpy(str, ptr, len); str[len] = '\0'; @@ -302,7 +301,7 @@ int image_msgpack_read_header_to_cache(struct image *image, } image_cache_header_str(image, name, str); - free(str); + cffree(str); msgpack_unpacked_destroy(&unpacked); return 0; @@ -357,23 +356,23 @@ static int load_msgpack_data(struct panel_template *p, ERROR("Data 'type' isn't a string\n"); return 1; } - dtype = strndup(type_obj->via.str.ptr, type_obj->via.str.size); + dtype = cfstrndup(type_obj->via.str.ptr, type_obj->via.str.size); shape_obj = find_msgpack_kv(obj, "shape"); if ( shape_obj == NULL ) { ERROR("Data 'shape' not found\n"); - free(dtype); + cffree(dtype); return 1; } if ( shape_obj->type != MSGPACK_OBJECT_ARRAY ) { ERROR("Data 'shape' isn't an array\n"); - free(dtype); + cffree(dtype); return 1; } if ( shape_obj->via.array.size != 2 ) { ERROR("Data 'shape' has wrong number of dimensions (%i)\n", shape_obj->via.array.size); - free(dtype); + cffree(dtype); return 1; } data_size_ss = shape_obj->via.array.ptr[0].via.u64; @@ -394,12 +393,12 @@ static int load_msgpack_data(struct panel_template *p, data_obj = find_msgpack_kv(obj, "data"); if ( data_obj == NULL ) { ERROR("Data 'data' not found\n"); - free(dtype); + cffree(dtype); return 1; } if ( data_obj->type != MSGPACK_OBJECT_BIN ) { ERROR("Data 'data' isn't binary\n"); - free(dtype); + cffree(dtype); return 1; } @@ -435,7 +434,7 @@ static int load_msgpack_data(struct panel_template *p, ERROR("Unrecognised data type '%s'\n", dtype); } - free(dtype); + cffree(dtype); return 0; } diff --git a/libcrystfel/src/image-seedee.c b/libcrystfel/src/image-seedee.c index 2a4328ec..1b68aead 100644 --- a/libcrystfel/src/image-seedee.c +++ b/libcrystfel/src/image-seedee.c @@ -170,20 +170,20 @@ int image_seedee_read(struct image *image, data_block, data_block_size, &zero_copy, &array); profile_end("seedee-get-size"); - array.data = malloc(array.size); - array.shape = malloc(array.ndims*sizeof(int)); + array.data = cfmalloc(array.size); + array.shape = cfmalloc(array.ndims*sizeof(int)); if ( (array.data == NULL) || (array.shape == NULL) ) { cJSON_Delete(json); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } if ( array.ndims != 2 ) { ERROR("Seedee data has unexpected number of dimensions " "(%i, expected 2)\n", array.ndims); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } @@ -195,8 +195,8 @@ int image_seedee_read(struct image *image, cJSON_Delete(json); if ( r < 0 ) { ERROR("Seedee deserialiation failed.\n"); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } @@ -208,15 +208,15 @@ int image_seedee_read(struct image *image, ERROR("Failed to load data for panel '%s'\n", dtempl->panels[i].name); profile_end("seedee-panel"); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 1; } } profile_end("seedee-panel"); - free(array.data); - free(array.shape); + cffree(array.data); + cffree(array.shape); return 0; } diff --git a/libcrystfel/src/image.c b/libcrystfel/src/image.c index 95bc56e5..e91c09d6 100644 --- a/libcrystfel/src/image.c +++ b/libcrystfel/src/image.c @@ -153,13 +153,12 @@ struct _imagefeaturelist void image_add_feature(ImageFeatureList *flist, double fs, double ss, - int pn, - struct image *parent, double intensity, const char *name) + int pn, double intensity, const char *name) { if ( flist->n_features == flist->max_features ) { struct imagefeature *nf; int nmf = flist->max_features + 128; - nf = realloc(flist->features, nmf*sizeof(struct imagefeature)); + nf = cfrealloc(flist->features, nmf*sizeof(struct imagefeature)); if ( nf == NULL ) return; flist->features = nf; flist->max_features = nmf; @@ -179,7 +178,7 @@ ImageFeatureList *image_feature_list_new() { ImageFeatureList *flist; - flist = malloc(sizeof(ImageFeatureList)); + flist = cfmalloc(sizeof(ImageFeatureList)); flist->n_features = 0; flist->max_features = 0; @@ -208,9 +207,9 @@ ImageFeatureList *image_feature_list_copy(const ImageFeatureList *flist) n = image_feature_list_new(); if ( n == NULL ) return NULL; - n->features = malloc(flist->n_features*sizeof(struct imagefeature)); + n->features = cfmalloc(flist->n_features*sizeof(struct imagefeature)); if ( n->features == NULL ) { - free(n); + cffree(n); return NULL; } @@ -242,8 +241,8 @@ ImageFeatureList *sort_peaks(ImageFeatureList *flist) void image_feature_list_free(ImageFeatureList *flist) { if ( flist == NULL ) return; - free(flist->features); - free(flist); + cffree(flist->features); + cffree(flist); } @@ -318,35 +317,45 @@ void image_remove_feature(ImageFeatureList *flist, int idx) } -void image_add_crystal(struct image *image, Crystal *cryst) +void image_add_crystal_refls(struct image *image, + Crystal *cryst, + RefList *reflist) { - Crystal **crs; + struct crystal_refls *crs; int n; n = image->n_crystals; - crs = realloc(image->crystals, (n+1)*sizeof(Crystal *)); + crs = cfrealloc(image->crystals, (n+1)*sizeof(struct crystal_refls)); if ( crs == NULL ) { ERROR("Failed to allocate memory for crystals.\n"); return; } - crs[n] = cryst; + 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; } +void image_add_crystal(struct image *image, Crystal *cryst) +{ + image_add_crystal_refls(image, cryst, NULL); +} + + int remove_flagged_crystals(struct image *image) { int i; int n_bad = 0; for ( i=0; i<image->n_crystals; i++ ) { - if ( crystal_get_user_flag(image->crystals[i]) ) { + if ( crystal_get_user_flag(image->crystals[i].cr) ) { int j; - Crystal *deleteme = image->crystals[i]; - cell_free(crystal_get_cell(deleteme)); - crystal_free(deleteme); + crystal_free(image->crystals[i].cr); + reflist_free(image->crystals[i].refls); for ( j=i; j<image->n_crystals-1; j++ ) { image->crystals[j] = image->crystals[j+1]; } @@ -366,12 +375,15 @@ void free_all_crystals(struct image *image) int i; if ( image->crystals == NULL ) return; for ( i=0; i<image->n_crystals; i++ ) { - Crystal *cr = image->crystals[i]; - reflist_free(crystal_get_reflections(cr)); - cell_free(crystal_get_cell(cr)); - crystal_free(image->crystals[i]); + 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); + } } - free(image->crystals); + cffree(image->crystals); + image->crystals = NULL; image->n_crystals = 0; } @@ -398,10 +410,10 @@ void image_cache_header_int(struct image *image, } else { struct header_cache_entry *ce; - ce = malloc(sizeof(struct header_cache_entry)); + ce = cfmalloc(sizeof(struct header_cache_entry)); if ( ce != NULL ) { - ce->header_name = strdup(header_name); + ce->header_name = cfstrdup(header_name); ce->val_int = header_val; ce->type = HEADER_INT; image->header_cache[image->n_cached_headers++] = ce; @@ -421,10 +433,10 @@ void image_cache_header_float(struct image *image, } else { struct header_cache_entry *ce; - ce = malloc(sizeof(struct header_cache_entry)); + ce = cfmalloc(sizeof(struct header_cache_entry)); if ( ce != NULL ) { - ce->header_name = strdup(header_name); + ce->header_name = cfstrdup(header_name); ce->val_float = header_val; ce->type = HEADER_FLOAT; image->header_cache[image->n_cached_headers++] = ce; @@ -449,11 +461,11 @@ void image_cache_header_str(struct image *image, } else { struct header_cache_entry *ce; - ce = malloc(sizeof(struct header_cache_entry)); + ce = cfmalloc(sizeof(struct header_cache_entry)); if ( ce != NULL ) { - ce->header_name = strdup(header_name); - ce->val_str = strdup(header_val); + ce->header_name = cfstrdup(header_name); + ce->val_str = cfstrdup(header_val); ce->type = HEADER_STR; image->header_cache[image->n_cached_headers++] = ce; } else { @@ -613,7 +625,7 @@ struct _image_data_arrays ImageDataArrays *image_data_arrays_new() { - ImageDataArrays *ida = malloc(sizeof(struct _image_data_arrays)); + ImageDataArrays *ida = cfmalloc(sizeof(struct _image_data_arrays)); if ( ida == NULL ) return NULL; ida->dp = NULL; @@ -629,14 +641,14 @@ void image_data_arrays_free(ImageDataArrays *ida) int i; for ( i=0; i<ida->np; i++ ) { - if ( ida->dp != NULL ) free(ida->dp[i]); - if ( ida->bad != NULL ) free(ida->bad[i]); + if ( ida->dp != NULL ) cffree(ida->dp[i]); + if ( ida->bad != NULL ) cffree(ida->bad[i]); } - free(ida->dp); - free(ida->bad); + cffree(ida->dp); + cffree(ida->bad); - free(ida); + cffree(ida); } @@ -657,16 +669,16 @@ int image_create_dp_bad(struct image *image, /* Allocate new arrays */ - image->dp = malloc(dtempl->n_panels*sizeof(float *)); + image->dp = cfmalloc(dtempl->n_panels*sizeof(float *)); if ( image->dp == NULL ) { ERROR("Failed to allocate data array.\n"); return 1; } - image->bad = malloc(dtempl->n_panels*sizeof(int *)); + image->bad = cfmalloc(dtempl->n_panels*sizeof(int *)); if ( image->bad == NULL ) { ERROR("Failed to allocate bad pixel mask\n"); - free(image->dp); + cffree(image->dp); return 1; } @@ -680,17 +692,17 @@ int image_create_dp_bad(struct image *image, size_t nel = PANEL_WIDTH(&dtempl->panels[i]) * PANEL_HEIGHT(&dtempl->panels[i]); - image->dp[i] = malloc(nel*sizeof(float)); - image->bad[i] = malloc(nel*sizeof(int)); + image->dp[i] = cfmalloc(nel*sizeof(float)); + image->bad[i] = cfmalloc(nel*sizeof(int)); if ( (image->dp[i] == NULL)|| (image->bad[i] == NULL) ) { ERROR("Failed to allocate panel data arrays\n"); for ( i=0; i<dtempl->n_panels; i++ ) { - free(image->dp[i]); - free(image->bad[i]); + cffree(image->dp[i]); + cffree(image->bad[i]); } - free(image->dp); - free(image->bad); + cffree(image->dp); + cffree(image->bad); return 1; } @@ -1116,7 +1128,7 @@ static int create_satmap(struct image *image, if ( !any ) return 0; - image->sat = malloc(dtempl->n_panels * sizeof(float *)); + image->sat = cfmalloc(dtempl->n_panels * sizeof(float *)); if ( image->sat == NULL ) { ERROR("Failed to allocate saturation map\n"); return 1; @@ -1137,7 +1149,7 @@ static int create_satmap(struct image *image, p_w = p->orig_max_fs - p->orig_min_fs + 1; p_h = p->orig_max_ss - p->orig_min_ss + 1; - image->sat[i] = malloc(p_w*p_h*sizeof(float)); + image->sat[i] = cfmalloc(p_w*p_h*sizeof(float)); if ( image->sat[i] != NULL ) { long int j; @@ -1320,11 +1332,11 @@ struct image *image_read(const DataTemplate *dtempl, return NULL; } - image->filename = strdup(filename); + image->filename = cfstrdup(filename); if ( event != NULL ) { - image->ev = strdup(event); + image->ev = cfstrdup(event); } else { - image->ev = strdup("//"); /* Null event */ + image->ev = cfstrdup("//"); /* Null event */ } image->data_block = NULL; image->data_block_size = 0; @@ -1388,13 +1400,13 @@ void image_free(struct image *image) int i, np; if ( image == NULL ) return; - image_feature_list_free(image->features); + if ( image->owns_peaklist ) image_feature_list_free(image->features); free_all_crystals(image); spectrum_free(image->spectrum); - free(image->filename); - free(image->ev); - free(image->data_block); - free(image->meta_data); + cffree(image->filename); + cffree(image->ev); + cffree(image->data_block); + cffree(image->meta_data); if ( image->detgeom != NULL ) { np = image->detgeom->n_panels; @@ -1406,23 +1418,23 @@ void image_free(struct image *image) if ( image->ida == NULL ) { for ( i=0; i<np; i++ ) { - if ( image->dp != NULL ) free(image->dp[i]); - if ( image->sat != NULL ) free(image->sat[i]); - if ( image->bad != NULL ) free(image->bad[i]); + if ( image->dp != NULL ) cffree(image->dp[i]); + if ( image->sat != NULL ) cffree(image->sat[i]); + if ( image->bad != NULL ) cffree(image->bad[i]); } - free(image->dp); - free(image->sat); - free(image->bad); + cffree(image->dp); + cffree(image->sat); + cffree(image->bad); } /* else the arrays belong to the IDA structure */ for ( i=0; i<image->n_cached_headers; i++ ) { - free(image->header_cache[i]->header_name); - free(image->header_cache[i]); + cffree(image->header_cache[i]->header_name); + cffree(image->header_cache[i]); } - free(image); + cffree(image); } @@ -1430,7 +1442,7 @@ struct image *image_new() { struct image *image; - image = malloc(sizeof(struct image)); + image = cfmalloc(sizeof(struct image)); if ( image == NULL ) return NULL; image->dp = NULL; @@ -1458,6 +1470,7 @@ struct image *image_new() image->bw = -1.0; image->peak_resolution = -1.0; image->features = NULL; + image->owns_peaklist = 1; return image; } @@ -1537,11 +1550,11 @@ char **image_expand_frames(const DataTemplate *dtempl, } else { char **list; - list = malloc(sizeof(char *)); + list = cfmalloc(sizeof(char *)); if ( list == NULL ) return NULL; - list[0] = strdup("//"); + list[0] = cfstrdup("//"); if ( list[0] == NULL ) { - free(list); + cffree(list); return NULL; } *n_frames = 1; diff --git a/libcrystfel/src/image.h b/libcrystfel/src/image.h index eafc5f83..3db7de18 100644 --- a/libcrystfel/src/image.h +++ b/libcrystfel/src/image.h @@ -110,6 +110,14 @@ typedef enum } DataSourceType; +struct crystal_refls +{ + Crystal *cr; + RefList *refls; + int image_owns_crystal; + int image_owns_refls; +}; + struct image { /** The image data, by panel */ @@ -124,8 +132,8 @@ struct image /** Non-zero if the frame was determined to be a "hit" */ int hit; - /**Array of crystals in the image */ - Crystal **crystals; + /** Array of crystals (with reflection lists) in the image */ + struct crystal_refls *crystals; /** The number of crystals in the image (size of \p crystals) */ int n_crystals; @@ -184,6 +192,10 @@ struct image /** Re-usable data array structure, or NULL if not used */ ImageDataArrays *ida; + /** If set, then 'features' should be freed with the image. + * Otherwise, it is managed externally (e.g. by Julia) */ + int owns_peaklist; + }; #ifdef __cplusplus @@ -201,9 +213,7 @@ extern ImageFeatureList *image_feature_list_new(void); extern void image_feature_list_free(ImageFeatureList *flist); extern void image_add_feature(ImageFeatureList *flist, double x, double y, - int pn, - struct image *parent, double intensity, - const char *name); + int pn, double intensity, const char *name); extern void image_remove_feature(ImageFeatureList *flist, int idx); @@ -220,6 +230,8 @@ extern ImageFeatureList *sort_peaks(ImageFeatureList *flist); extern ImageFeatureList *image_feature_list_copy(const ImageFeatureList *flist); extern void image_add_crystal(struct image *image, Crystal *cryst); +extern void image_add_crystal_refls(struct image *image, + Crystal *cryst, RefList *reflist); extern int remove_flagged_crystals(struct image *image); extern void free_all_crystals(struct image *image); diff --git a/libcrystfel/src/index.c b/libcrystfel/src/index.c index d93664b1..12cd9190 100644 --- a/libcrystfel/src/index.c +++ b/libcrystfel/src/index.c @@ -121,7 +121,7 @@ char *base_indexer_str(IndexingMethod indm) { char *str; - str = malloc(256); + str = cfmalloc(256); if ( str == NULL ) { ERROR("Failed to allocate string.\n"); return NULL; @@ -270,11 +270,11 @@ static void *prepare_method(IndexingMethod *m, UnitCell *cell, if ( priv == NULL ) { ERROR("Failed to prepare indexing method %s\n", str); - free(str); + cffree(str); return NULL; } - free(str); + cffree(str); if ( in != *m ) { ERROR("Note: flags were altered to take into account " @@ -296,7 +296,7 @@ IndexingMethod *parse_indexing_methods(const char *method_list, n = assplode(method_list, ",", &method_strings, ASSPLODE_NONE); - methods = malloc(n * sizeof(IndexingMethod)); + methods = cfmalloc(n * sizeof(IndexingMethod)); if ( methods == NULL ) { ERROR("Failed to allocate indexing method list\n"); return NULL; @@ -316,12 +316,12 @@ IndexingMethod *parse_indexing_methods(const char *method_list, ERROR("To disable indexing retry ('noretry'), use --no-retry.\n"); ERROR("To enable multi-lattice indexing by 'delete and retry', use --multi\n"); ERROR("------------------\n"); - free(methods); + cffree(methods); return NULL; } - free(method_strings[i]); + cffree(method_strings[i]); } - free(method_strings); + cffree(method_strings); *pn = n; return methods; @@ -393,13 +393,13 @@ IndexingPrivate *setup_indexing(const char *method_list, } - ipriv = malloc(sizeof(struct _indexingprivate)); + ipriv = cfmalloc(sizeof(struct _indexingprivate)); if ( ipriv == NULL ) { ERROR("Failed to allocate indexing data\n"); return NULL; } - ipriv->engine_private = malloc((n+1) * sizeof(void *)); + ipriv->engine_private = cfmalloc((n+1) * sizeof(void *)); for ( i=0; i<n; i++ ) { @@ -416,14 +416,14 @@ IndexingPrivate *setup_indexing(const char *method_list, asdf_opts); if ( ipriv->engine_private[i] == NULL ) { - free(ipriv->engine_private); + cffree(ipriv->engine_private); return NULL; } for ( j=0; j<i; j++ ) { if ( methods[i] == methods[j] ) { ERROR("Duplicate indexing method.\n"); - free(ipriv->engine_private); + cffree(ipriv->engine_private); return NULL; } } @@ -449,8 +449,8 @@ IndexingPrivate *setup_indexing(const char *method_list, char *str = indexer_str(methods[i]); char *tmp = friendly_indexer_name(methods[i]); STATUS(" %2i: %-25s (%s)\n", i, str, tmp); - free(str); - free(tmp); + cffree(str); + cffree(tmp); } show_indexing_flags(flags); @@ -523,10 +523,10 @@ void cleanup_indexing(IndexingPrivate *ipriv) } - free(ipriv->methods); - free(ipriv->engine_private); + cffree(ipriv->methods); + cffree(ipriv->engine_private); cell_free(ipriv->target_cell); - free(ipriv); + cffree(ipriv); } @@ -552,7 +552,6 @@ static int check_cell(IndexingFlags flags, Crystal *cr, UnitCell *target, if ( out != NULL ) { /* Replace crystal's cell with new one */ - cell_free(crystal_get_cell(cr)); crystal_set_cell(cr, out); rtnl_mtx_free(rm); if ( !right_handed(out) ) STATUS("WARNING: left handed\n"); @@ -699,9 +698,8 @@ static int try_indexer(struct image *image, IndexingMethod indm, int this_crystal = image->n_crystals - i - 1; /* ... starting at the end of the (complete) list ... */ - Crystal *cr = image->crystals[this_crystal]; + Crystal *cr = image->crystals[this_crystal].cr; - crystal_set_image(cr, image); crystal_set_profile_radius(cr, 0.02e9); crystal_set_mosaicity(cr, 0.0); @@ -744,7 +742,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, if ( ipriv->flags & INDEXING_CHECK_PEAKS ) { int mm = ipriv->flags & INDEXING_MULTI; - if ( !indexing_peak_check(image, &cr, 1, mm) ) { + if ( !indexing_peak_check(image, image->features, &cr, 1, mm) ) { crystal_set_user_flag(cr, 1); continue; } @@ -757,7 +755,7 @@ static int try_indexer(struct image *image, IndexingMethod indm, profile_start("cell-compare-to-others"); for ( j=0; j<this_crystal; j++ ) { - Crystal *that_cr = image->crystals[j]; + Crystal *that_cr = image->crystals[j].cr; /* 'tols' is in frac (not %) and radians */ const double tols[] = {0.1, 0.1, 0.1, deg2rad(5.0), @@ -909,7 +907,7 @@ static int finished_retry(IndexingMethod indm, IndexingFlags flags, if ( flags & INDEXING_MULTI ) { /* Remove "used" spots and try for another lattice */ Crystal *cr; - cr = image->crystals[image->n_crystals-1]; + cr = image->crystals[image->n_crystals-1].cr; return delete_explained_peaks(image, cr); } else { return 1; @@ -946,8 +944,7 @@ void index_pattern_4(struct image *image, IndexingPrivate *ipriv, int *ping, if ( ipriv == NULL ) return; - image->crystals = NULL; - image->n_crystals = 0; + free_all_crystals(image); /* No peaks? */ if ( image->features == NULL ) return; @@ -1195,10 +1192,10 @@ IndexingMethod get_indm_from_string_2(const char *str, int *err) return INDEXING_ERROR; } - free(bits[i]); + cffree(bits[i]); } - free(bits); + cffree(bits); if ( !have_method ) return warn_method(str); @@ -1230,7 +1227,7 @@ char *detect_indexing_methods(UnitCell *cell) { char *methods; - methods = malloc(1024); + methods = cfmalloc(1024); if ( methods == NULL ) return NULL; methods[0] = '\0'; @@ -1245,7 +1242,7 @@ char *detect_indexing_methods(UnitCell *cell) //do_probe(pinkIndexer_probe, cell, methods); if ( strlen(methods) == 0 ) { - free(methods); + cffree(methods); return NULL; } diff --git a/libcrystfel/src/indexers/asdf.c b/libcrystfel/src/indexers/asdf.c index 2222144b..919e570f 100644 --- a/libcrystfel/src/indexers/asdf.c +++ b/libcrystfel/src/indexers/asdf.c @@ -132,7 +132,7 @@ struct tvector tvector_new(int n) t.t = gsl_vector_alloc(3); t.n = 0; - t.fits = malloc(sizeof(int) * n); + t.fits = cfmalloc(sizeof(int) * n); return t; } @@ -141,7 +141,7 @@ struct tvector tvector_new(int n) static int tvector_free(struct tvector t) { gsl_vector_free(t.t); - free(t.fits); + cffree(t.fits); return 1; } @@ -155,12 +155,12 @@ static int asdf_cell_free(struct asdf_cell *c) gsl_vector_free(c->reciprocal[i]); } - free(c->reflections); + cffree(c->reflections); for ( i = 0; i < c->N_refls; i++ ) { - free(c->indices[i]); + cffree(c->indices[i]); } - free(c->indices); - free(c); + cffree(c->indices); + cffree(c); return 1; } @@ -169,7 +169,7 @@ static int asdf_cell_free(struct asdf_cell *c) static struct asdf_cell *asdf_cell_new(int n) { struct asdf_cell *c; - c = malloc(sizeof(struct asdf_cell)); + c = cfmalloc(sizeof(struct asdf_cell)); int i; for ( i = 0; i < 3; i++ ) { @@ -178,20 +178,20 @@ static struct asdf_cell *asdf_cell_new(int n) } c->N_refls = n; - c->reflections = malloc(sizeof(int) * n); + c->reflections = cfmalloc(sizeof(int) * n); if (c->reflections == NULL) return NULL; - c->indices = malloc(sizeof(double *) * n); + c->indices = cfmalloc(sizeof(double *) * n); if (c->indices == NULL) { - free(c->reflections); + cffree(c->reflections); return NULL; } for ( i = 0; i < n; i++ ) { - c->indices[i] = malloc(sizeof(double) * 3); + c->indices[i] = cfmalloc(sizeof(double) * 3); if (c->indices[i] == NULL) { - free(c->reflections); - free(c->indices); + cffree(c->reflections); + cffree(c->indices); return NULL; } } @@ -224,7 +224,7 @@ static int asdf_cell_memcpy(struct asdf_cell *dest, struct asdf_cell *src) memcpy(dest->indices[i], src->indices[i], sizeof(double) * 3); } for ( i=n; i<dest->N_refls; i++ ) { - free(dest->indices[i]); + cffree(dest->indices[i]); } dest->N_refls = n; @@ -928,7 +928,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) } *N = N_triplets; - int **triplets = malloc(N_triplets * sizeof(int *)); + int **triplets = cfmalloc(N_triplets * sizeof(int *)); if ( triplets == NULL ) { ERROR("Failed to allocate triplets in generate_triplets!\n"); @@ -940,7 +940,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) // Reservoir sampling: for ( i = 0; i < N_triplets_tot; i++ ) { if ( n < N_triplets ) { - triplets[n] = (int *)malloc(3 * sizeof(int)); + triplets[n] = (int *)cfmalloc(3 * sizeof(int)); if (triplets[n] == NULL) { ERROR("Failed to allocate triplet in generate_triplets!\n"); return NULL; @@ -957,10 +957,10 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) } } else { // Random selection from the whole set: - int *tidx = (int *)malloc(N_triplets * sizeof(int)); + int *tidx = (int *)cfmalloc(N_triplets * sizeof(int)); if ( tidx == NULL ) { ERROR("Failed to allocate tidx in generate_triplets_2!\n"); - free(triplets); + cffree(triplets); return NULL; } while ( n < N_triplets ) { @@ -973,7 +973,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) } } tidx[n] = ri; - triplets[n] = (int *)malloc(3 * sizeof(int)); + triplets[n] = (int *)cfmalloc(3 * sizeof(int)); if ( triplets[n] == NULL ) { ERROR("Failed to allocate triplet in generate_triplets!\n"); return NULL; @@ -981,7 +981,7 @@ static int **generate_triplets(int N_reflections, int N_triplets_max, int *N) get_triplet_by_index(ri, N_reflections, triplets[n]); n += 1; } - free(tidx); + cffree(tidx); } return triplets; } @@ -1002,7 +1002,7 @@ static int index_refls(gsl_vector **reflections, int N_reflections, int N_refl_m gsl_vector **refl_sample; if ( N_reflections > N_refl_max ) { - refl_sample = (gsl_vector **)malloc(N_refl_max * sizeof(gsl_vector *)); + refl_sample = (gsl_vector **)cfmalloc(N_refl_max * sizeof(gsl_vector *)); n = 0; for ( i = 0; i < N_reflections; i++ ) { if (i < N_refl_max) { @@ -1029,18 +1029,18 @@ static int index_refls(gsl_vector **reflections, int N_reflections, int N_refl_m double projections[N_refl_max]; double ds; - int *fits = malloc(N_refl_max * sizeof(int)); + int *fits = cfmalloc(N_refl_max * sizeof(int)); if ( fits == NULL ) { ERROR("Failed to allocate fits in index_refls!\n"); - if ( N_reflections > N_refl_max ) free(refl_sample); + if ( N_reflections > N_refl_max ) cffree(refl_sample); return 0; } - struct tvector *tvectors = malloc(N_triplets * sizeof(struct tvector)); + struct tvector *tvectors = cfmalloc(N_triplets * sizeof(struct tvector)); if ( tvectors == NULL ) { ERROR("Failed to allocate tvectors in index_refls!\n"); - if ( N_reflections > N_refl_max ) free(refl_sample); - free(fits); + if ( N_reflections > N_refl_max ) cffree(refl_sample); + cffree(fits); return 0; } @@ -1113,20 +1113,20 @@ static int index_refls(gsl_vector **reflections, int N_reflections, int N_refl_m } } profile_end("asdf-search"); - free(fits); + cffree(fits); for ( i = 0; i < N_tvectors; i++ ) { tvector_free(tvectors[i]); } - free(tvectors); + cffree(tvectors); for ( i = 0; i < N_triplets; i++ ) { - free(triplets[i]); + cffree(triplets[i]); } - free(triplets); + cffree(triplets); gsl_vector_free(normal); - if ( N_reflections > N_refl_max ) free(refl_sample); + if ( N_reflections > N_refl_max ) cffree(refl_sample); if ( c->n ) return 1; @@ -1262,7 +1262,7 @@ void *asdf_prepare(IndexingMethod *indm, UnitCell *cell, struct asdf_options *as /* Flags that asdf knows about */ *indm &= INDEXING_METHOD_MASK | INDEXING_USE_CELL_PARAMETERS; - dp = malloc(sizeof(struct asdf_private)); + dp = cfmalloc(sizeof(struct asdf_private)); if ( dp == NULL ) return NULL; dp->template = cell; @@ -1279,7 +1279,7 @@ void asdf_cleanup(void *pp) struct asdf_private *p; p = (struct asdf_private *)pp; fftw_vars_free(p->fftw); - free(p); + cffree(p); } @@ -1332,7 +1332,7 @@ int asdf_default_options(struct asdf_options **opts_ptr) { struct asdf_options *opts; - opts = malloc(sizeof(struct asdf_options)); + opts = cfmalloc(sizeof(struct asdf_options)); if ( opts == NULL ) return ENOMEM; opts->fast_execution = 0; diff --git a/libcrystfel/src/indexers/dirax.c b/libcrystfel/src/indexers/dirax.c index 9c427879..88384e11 100644 --- a/libcrystfel/src/indexers/dirax.c +++ b/libcrystfel/src/indexers/dirax.c @@ -118,13 +118,13 @@ static void dirax_parseline(const char *line, struct image *image, #if DIRAX_VERBOSE char *copy; - copy = strdup(line); + copy = cfstrdup(line); for ( i=0; i<strlen(copy); i++ ) { if ( copy[i] == '\r' ) copy[i]='r'; if ( copy[i] == '\n' ) copy[i]='\0'; } STATUS("DirAx: %s\n", copy); - free(copy); + cffree(copy); #endif if ( strstr(line, "reflections from file") ) { @@ -250,13 +250,13 @@ static void dirax_sendline(const char *line, struct dirax_data *dirax) char *copy; int i; - copy = strdup(line); + copy = cfstrdup(line); for ( i=0; i<strlen(copy); i++ ) { if ( copy[i] == '\r' ) copy[i]='\0'; if ( copy[i] == '\n' ) copy[i]='\0'; } STATUS("To DirAx: '%s'\n", copy); - free(copy); + cffree(copy); #endif if ( write(dirax->pty, line, strlen(line)) == -1 ) { @@ -399,7 +399,7 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) case DIRAX_INPUT_LINE : /* Make buffer a bit too big to keep Valgrind * quiet about alignment errors */ - block_buffer = malloc(i+4); + block_buffer = cfmalloc(i+4); memcpy(block_buffer, dirax->rbuffer, i); block_buffer[i] = '\0'; @@ -408,7 +408,7 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) } dirax_parseline(block_buffer, image, dirax); - free(block_buffer); + cffree(block_buffer); endbit_length = i+2; break; @@ -441,8 +441,7 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) - endbit_length; new_rbuflen = dirax->rbuflen - endbit_length; if ( new_rbuflen == 0 ) new_rbuflen = 256; - dirax->rbuffer = realloc(dirax->rbuffer, - new_rbuflen); + dirax->rbuffer = cfrealloc(dirax->rbuffer, new_rbuflen); dirax->rbuflen = new_rbuflen; } else { @@ -450,8 +449,8 @@ static int dirax_readable(struct image *image, struct dirax_data *dirax) if ( dirax->rbufpos == dirax->rbuflen ) { /* More buffer space is needed */ - dirax->rbuffer = realloc(dirax->rbuffer, - dirax->rbuflen + 256); + dirax->rbuffer = cfrealloc(dirax->rbuffer, + dirax->rbuflen + 256); dirax->rbuflen = dirax->rbuflen + 256; /* The new space gets used at the next * read, shortly... */ @@ -511,7 +510,7 @@ int run_dirax(struct image *image, void *ipriv) write_drx(image); - dirax = malloc(sizeof(struct dirax_data)); + dirax = cfmalloc(sizeof(struct dirax_data)); if ( dirax == NULL ) { ERROR("Couldn't allocate memory for DirAx data.\n"); return 0; @@ -538,7 +537,7 @@ int run_dirax(struct image *image, void *ipriv) } - dirax->rbuffer = malloc(256); + dirax->rbuffer = cfmalloc(256); dirax->rbuflen = 256; dirax->rbufpos = 0; @@ -595,7 +594,7 @@ int run_dirax(struct image *image, void *ipriv) } while ( !rval && !dirax->success ); close(dirax->pty); - free(dirax->rbuffer); + cffree(dirax->rbuffer); waitpid(dirax->pid, &status, 0); if ( dirax->finished_ok == 0 ) { @@ -603,7 +602,7 @@ int run_dirax(struct image *image, void *ipriv) } rval = dirax->success; - free(dirax); + cffree(dirax); return rval; } @@ -621,7 +620,7 @@ void *dirax_prepare(IndexingMethod *indm, UnitCell *cell) /* Flags that DirAx knows about */ *indm &= INDEXING_METHOD_MASK; - dp = malloc(sizeof(struct dirax_private)); + dp = cfmalloc(sizeof(struct dirax_private)); if ( dp == NULL ) return NULL; dp->template = cell; @@ -635,7 +634,7 @@ void dirax_cleanup(void *pp) { struct dirax_private *p; p = (struct dirax_private *)pp; - free(p); + cffree(p); } diff --git a/libcrystfel/src/indexers/felix.c b/libcrystfel/src/indexers/felix.c index db7da8c4..d6632e42 100644 --- a/libcrystfel/src/indexers/felix.c +++ b/libcrystfel/src/indexers/felix.c @@ -277,7 +277,7 @@ static int felix_readable(struct image *image, struct felix_data *gs) unsigned int endbit_length; char *block_buffer = NULL; - block_buffer = malloc(i+1); + block_buffer = cfmalloc(i+1); memcpy(block_buffer, gs->rbuffer, i); block_buffer[i] = '\0'; @@ -286,7 +286,7 @@ static int felix_readable(struct image *image, struct felix_data *gs) } gs_parseline(block_buffer, image, gs); - free(block_buffer); + cffree(block_buffer); endbit_length = i+2; /* Now the block's been parsed, it should be @@ -299,7 +299,7 @@ static int felix_readable(struct image *image, struct felix_data *gs) gs->rbufpos = gs->rbufpos - endbit_length; new_rbuflen = gs->rbuflen - endbit_length; if ( new_rbuflen == 0 ) new_rbuflen = 256; - gs->rbuffer = realloc(gs->rbuffer, new_rbuflen); + gs->rbuffer = cfrealloc(gs->rbuffer, new_rbuflen); gs->rbuflen = new_rbuflen; } else { @@ -307,8 +307,8 @@ static int felix_readable(struct image *image, struct felix_data *gs) if ( gs->rbufpos == gs->rbuflen ) { /* More buffer space is needed */ - gs->rbuffer = realloc(gs->rbuffer, - gs->rbuflen + 256); + gs->rbuffer = cfrealloc(gs->rbuffer, + gs->rbuflen + 256); gs->rbuflen = gs->rbuflen + 256; /* The new space gets used at the next * read, shortly... */ @@ -374,7 +374,7 @@ static char *write_ini(struct image *image, struct felix_private *gp) char gveFilename[1024]; char logFilename[1024]; - filename = malloc(1024); + filename = cfmalloc(1024); if ( filename == NULL ) return NULL; snprintf(filename, 1023, "xfel.ini"); @@ -384,7 +384,7 @@ static char *write_ini(struct image *image, struct felix_private *gp) fh = fopen(filename, "w"); if ( !fh ) { ERROR("Couldn't open temporary file '%s'\n", filename); - free(filename); + cffree(filename); return NULL; } @@ -413,7 +413,7 @@ static char *write_ini(struct image *image, struct felix_private *gp) fprintf(fh, "orispace octa\n"); } else{ ERROR("No felix supported orispace specified.\n"); - free(filename); + cffree(filename); filename = NULL; } @@ -450,7 +450,7 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) return 0; } - felix = malloc(sizeof(struct felix_data)); + felix = cfmalloc(sizeof(struct felix_data)); if ( felix == NULL ) { ERROR("Couldn't allocate memory for Felix data.\n"); return 0; @@ -483,9 +483,9 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) } - free(ini_filename); + cffree(ini_filename); - felix->rbuffer = malloc(256); + felix->rbuffer = cfmalloc(256); felix->rbuflen = 256; felix->rbufpos = 0; @@ -534,18 +534,18 @@ int felix_index(struct image *image, IndexingPrivate *ipriv) } while ( !rval ); close(felix->pty); - free(felix->rbuffer); + cffree(felix->rbuffer); waitpid(felix->pid, &status, 0); if ( status != 0 ) { ERROR("Felix either timed out, or is not working properly.\n"); - free(felix); + cffree(felix); return 0; } rval = read_felix(gp, image, gff_filename); - free(felix); + cffree(felix); return rval; } @@ -625,7 +625,7 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell, return NULL; } - gp = calloc(1, sizeof(*gp)); + gp = cfcalloc(1, sizeof(*gp)); if ( gp == NULL ) return NULL; /* Flags that Felix knows about */ @@ -640,7 +640,7 @@ void *felix_prepare(IndexingMethod *indm, UnitCell *cell, if ( gp->spacegroup == 0 ) { ERROR("Couldn't determine representative space group for your cell.\n"); ERROR("Try again with a more conventional cell.\n"); - free(gp); + cffree(gp); return NULL; } @@ -710,8 +710,8 @@ void felix_cleanup(IndexingPrivate *pp) struct felix_private *p; p = (struct felix_private *) pp; - free(p->readhkl_file); - free(p); + cffree(p->readhkl_file); + cffree(p); } @@ -812,7 +812,7 @@ int felix_default_options(struct felix_options **opts_ptr) { struct felix_options *opts; - opts = malloc(sizeof(struct felix_options)); + opts = cfmalloc(sizeof(struct felix_options)); if ( opts == NULL ) return ENOMEM; opts->ttmin = -1.0; diff --git a/libcrystfel/src/indexers/fromfile.c b/libcrystfel/src/indexers/fromfile.c index 1716dd66..30305b21 100644 --- a/libcrystfel/src/indexers/fromfile.c +++ b/libcrystfel/src/indexers/fromfile.c @@ -101,7 +101,7 @@ struct fromfile_entry *add_unique(struct fromfile_entry **phead, struct fromfile_entry *item; - item = malloc(sizeof(struct fromfile_entry)); + item = cfmalloc(sizeof(struct fromfile_entry)); if ( item == NULL ) return NULL; item->n_crystals = 0; @@ -197,12 +197,12 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) if ( opts->filename[0] == '/' ) { fh = fopen(opts->filename, "r"); } else { - char *prefixed_fn = malloc(4+strlen(opts->filename)); + char *prefixed_fn = cfmalloc(4+strlen(opts->filename)); if ( prefixed_fn == NULL ) return NULL; strcpy(prefixed_fn, "../"); strcat(prefixed_fn, opts->filename); fh = fopen(prefixed_fn, "r"); - free(prefixed_fn); + cffree(prefixed_fn); } if ( fh == NULL ) { @@ -210,7 +210,7 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) return NULL; } - dp = malloc(sizeof(struct fromfile_private)); + dp = cfmalloc(sizeof(struct fromfile_private)); if ( dp == NULL ) { fclose(fh); return NULL; @@ -305,8 +305,8 @@ void *fromfile_prepare(IndexingMethod *indm, struct fromfile_options *opts) } - for ( i=0; i<n; i++ ) free(bits[i]); - free(bits); + for ( i=0; i<n; i++ ) cffree(bits[i]); + cffree(bits); } while ( 1 ); @@ -337,7 +337,7 @@ int fromfile_index(struct image *image, void *mpriv) for ( i=0; i<p->n_crystals; i++ ) { Crystal *cr; - cr = crystal_copy_deep(p->crystals[i]); + cr = crystal_copy(p->crystals[i]); image_add_crystal(image, cr); } @@ -360,7 +360,7 @@ void fromfile_cleanup(void *mpriv) } } - free(dp); + cffree(dp); } @@ -376,7 +376,7 @@ static void fromfile_show_help() int fromfile_default_options(struct fromfile_options **opts_ptr) { struct fromfile_options *opts; - opts = malloc(sizeof(struct fromfile_options)); + opts = cfmalloc(sizeof(struct fromfile_options)); if ( opts == NULL ) return ENOMEM; opts->filename = NULL; *opts_ptr = opts; @@ -402,7 +402,7 @@ static error_t fromfile_parse_arg(int key, char *arg, return EINVAL; case 2 : - (*opts_ptr)->filename = strdup(arg); + (*opts_ptr)->filename = cfstrdup(arg); break; default : diff --git a/libcrystfel/src/indexers/mosflm.c b/libcrystfel/src/indexers/mosflm.c index 1bd53119..1cec0a35 100644 --- a/libcrystfel/src/indexers/mosflm.c +++ b/libcrystfel/src/indexers/mosflm.c @@ -162,13 +162,13 @@ static void mosflm_parseline(const char *line, struct image *image, char *copy; int i; - copy = strdup(line); + copy = cfstrdup(line); for ( i=0; i<strlen(copy); i++ ) { if ( copy[i] == '\r' ) copy[i]='r'; if ( copy[i] == '\n' ) copy[i]='\0'; } STATUS("MOSFLM: %s\n", copy); - free(copy); + cffree(copy); } } @@ -366,13 +366,13 @@ static void write_img(struct image *image, const char *filename) FILE *fh; unsigned short int *intimage; - intimage = malloc(sizeof(unsigned short int)); + intimage = cfmalloc(sizeof(unsigned short int)); intimage[0] = 1; fh = fopen(filename, "w"); if ( !fh ) { ERROR("Couldn't open temporary file '%s'\n", filename); - free(intimage); + cffree(intimage); return; } @@ -389,7 +389,7 @@ static void write_img(struct image *image, const char *filename) while ( ftell(fh) < 512 ) fprintf(fh," "); fwrite(intimage, sizeof(unsigned short int), 1, fh); - free(intimage); + cffree(intimage); fclose(fh); } @@ -400,13 +400,13 @@ static void mosflm_sendline(const char *line, struct mosflm_data *mosflm) char *copy; int i; - copy = strdup(line); + copy = cfstrdup(line); for ( i=0; i<strlen(copy); i++ ) { if ( copy[i] == '\r' ) copy[i]='\0'; if ( copy[i] == '\n' ) copy[i]='\0'; } STATUS("To MOSFLM: '%s'\n", copy); - free(copy); + cffree(copy); #endif if ( write(mosflm->pty, line, strlen(line)) == -1 ) { @@ -469,7 +469,7 @@ static char *mosflm_spacegroup_for_lattice(UnitCell *cell) } assert(g != NULL); - result = malloc(32); + result = cfmalloc(32); if ( result == NULL ) return NULL; snprintf(result, 31, "%c%s", centering, g); @@ -512,7 +512,7 @@ static void mosflm_send_next(struct image *image, struct mosflm_data *mosflm) symm = mosflm_spacegroup_for_lattice(mosflm->mp->template); snprintf(tmp, 255, "SYMM %s\n", symm); //STATUS("Asking MOSFLM for '%s'\n", symm); - free(symm); + cffree(symm); mosflm_sendline(tmp, mosflm); } else { @@ -629,7 +629,7 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) switch ( type ) { case MOSFLM_INPUT_LINE : - block_buffer = malloc(i+1); + block_buffer = cfmalloc(i+1); memcpy(block_buffer, mosflm->rbuffer, i); block_buffer[i] = '\0'; @@ -638,7 +638,7 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) } mosflm_parseline(block_buffer, image, mosflm); - free(block_buffer); + cffree(block_buffer); endbit_length = i+2; break; @@ -667,8 +667,8 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) - endbit_length; new_rbuflen = mosflm->rbuflen - endbit_length; if ( new_rbuflen == 0 ) new_rbuflen = 256; - mosflm->rbuffer = realloc(mosflm->rbuffer, - new_rbuflen); + mosflm->rbuffer = cfrealloc(mosflm->rbuffer, + new_rbuflen); mosflm->rbuflen = new_rbuflen; } else { @@ -676,9 +676,8 @@ static int mosflm_readable(struct image *image, struct mosflm_data *mosflm) if ( mosflm->rbufpos==mosflm->rbuflen ) { /* More buffer space is needed */ - mosflm->rbuffer = realloc( - mosflm->rbuffer, - mosflm->rbuflen + 256); + mosflm->rbuffer = cfrealloc(mosflm->rbuffer, + mosflm->rbuflen + 256); mosflm->rbuflen = mosflm->rbuflen + 256; /* The new space gets used at the next * read, shortly... */ @@ -701,7 +700,7 @@ int run_mosflm(struct image *image, void *ipriv) int status; int rval; - mosflm = malloc(sizeof(struct mosflm_data)); + mosflm = cfmalloc(sizeof(struct mosflm_data)); if ( mosflm == NULL ) { ERROR("Couldn't allocate memory for MOSFLM data.\n"); return 0; @@ -720,7 +719,7 @@ int run_mosflm(struct image *image, void *ipriv) if ( mosflm->pid == -1 ) { ERROR("Failed to fork for MOSFLM: %s\n", strerror(errno)); - free(mosflm); + cffree(mosflm); return 0; } if ( mosflm->pid == 0 ) { @@ -741,7 +740,7 @@ int run_mosflm(struct image *image, void *ipriv) } - mosflm->rbuffer = malloc(256); + mosflm->rbuffer = cfmalloc(256); mosflm->rbuflen = 256; mosflm->rbufpos = 0; @@ -796,7 +795,7 @@ int run_mosflm(struct image *image, void *ipriv) } while ( !rval ); close(mosflm->pty); - free(mosflm->rbuffer); + cffree(mosflm->rbuffer); waitpid(mosflm->pid, &status, 0); if ( mosflm->finished_ok == 0 ) { @@ -807,7 +806,7 @@ int run_mosflm(struct image *image, void *ipriv) } rval = mosflm->success; - free(mosflm); + cffree(mosflm); return rval; } @@ -835,7 +834,7 @@ void *mosflm_prepare(IndexingMethod *indm, UnitCell *cell) "monoclinic C cell choice.\n"); } - mp = malloc(sizeof(struct mosflm_private)); + mp = cfmalloc(sizeof(struct mosflm_private)); if ( mp == NULL ) return NULL; mp->template = cell; @@ -849,7 +848,7 @@ void mosflm_cleanup(void *pp) { struct mosflm_private *p; p = (struct mosflm_private *)pp; - free(p); + cffree(p); } diff --git a/libcrystfel/src/indexers/pinkindexer.c b/libcrystfel/src/indexers/pinkindexer.c index 929c209b..180246c2 100644 --- a/libcrystfel/src/indexers/pinkindexer.c +++ b/libcrystfel/src/indexers/pinkindexer.c @@ -83,7 +83,7 @@ int run_pinkIndexer(struct image *image, void *ipriv, int n_threads) } reciprocalPeaks_1_per_A.peakCount = 0; - intensities = malloc(npk*sizeof(float)); + intensities = cfmalloc(npk*sizeof(float)); allocReciprocalPeaks(&reciprocalPeaks_1_per_A); if ( intensities == NULL ) return 0; @@ -116,7 +116,7 @@ int run_pinkIndexer(struct image *image, void *ipriv, int n_threads) pinkIndexer_private_data->maxRefinementDisbalance, n_threads); - free(intensities); + cffree(intensities); freeReciprocalPeaks(reciprocalPeaks_1_per_A); if ( matchedPeaksCount == -1 ) { @@ -205,7 +205,7 @@ void *pinkIndexer_prepare(IndexingMethod *indm, return NULL; } - struct pinkIndexer_private_data* pinkIndexer_private_data = malloc(sizeof(struct pinkIndexer_private_data)); + struct pinkIndexer_private_data* pinkIndexer_private_data = cfmalloc(sizeof(struct pinkIndexer_private_data)); pinkIndexer_private_data->indm = *indm; pinkIndexer_private_data->cellTemplate = cell; pinkIndexer_private_data->maxRefinementDisbalance = pinkIndexer_opts->maxRefinementDisbalance; @@ -424,7 +424,7 @@ int pinkIndexer_default_options(struct pinkindexer_options **opts_ptr) { struct pinkindexer_options *opts; - opts = malloc(sizeof(struct pinkindexer_options)); + opts = cfmalloc(sizeof(struct pinkindexer_options)); if ( opts == NULL ) return ENOMEM; opts->considered_peaks_count = 4; diff --git a/libcrystfel/src/indexers/taketwo.c b/libcrystfel/src/indexers/taketwo.c index 0b652b9f..c87d6b3d 100644 --- a/libcrystfel/src/indexers/taketwo.c +++ b/libcrystfel/src/indexers/taketwo.c @@ -524,7 +524,7 @@ static double matrix_trace(gsl_matrix *a) static char *add_unique_axis(const char *inp, char ua) { - char *pg = malloc(64); + char *pg = cfmalloc(64); if ( pg == NULL ) return NULL; snprintf(pg, 63, "%s_ua%c", inp, ua); return pg; @@ -584,7 +584,7 @@ static char *get_chiral_holohedry(UnitCell *cell) if ( add_ua ) { return add_unique_axis(pg, cell_get_unique_axis(cell)); } else { - return strdup(pg); + return cfstrdup(pg); } } @@ -595,7 +595,7 @@ static SymOpList *sym_ops_for_cell(UnitCell *cell) char *pg = get_chiral_holohedry(cell); rawList = get_pointgroup(pg); - free(pg); + cffree(pg); return rawList; } @@ -845,7 +845,7 @@ static int obs_vecs_match_angles(int her, int his, new_size *= sizeof(struct Seed); /* Reallocate the array to fit in another match */ - struct Seed *tmp_seeds = realloc(*seeds, new_size); + struct Seed *tmp_seeds = cfrealloc(*seeds, new_size); if ( tmp_seeds == NULL ) { apologise(); @@ -878,8 +878,8 @@ static signed int finish_solution(gsl_matrix *rot, struct SpotVec *obs_vecs, gsl_matrix *sub = gsl_matrix_calloc(3, 3); gsl_matrix *mul = gsl_matrix_calloc(3, 3); - gsl_matrix **rotations = malloc(sizeof(*rotations)* pow(member_num, 2) - - member_num); + gsl_matrix **rotations = cfmalloc(sizeof(*rotations)* pow(member_num, 2) + - member_num); int i, j, count; @@ -929,7 +929,7 @@ static signed int finish_solution(gsl_matrix *rot, struct SpotVec *obs_vecs, gsl_matrix_free(rotations[i]); } - free(rotations); + cffree(rotations); gsl_matrix_free(sub); gsl_matrix_free(mul); @@ -1011,7 +1011,7 @@ static int weed_duplicate_matches(struct Seed **seeds, } } - free(old_mats); + cffree(old_mats); return 1; } @@ -1310,8 +1310,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, } /* indices of members of the self-consistent network of vectors */ - obs_members = malloc((cell->member_thresh+3)*sizeof(int)); - match_members = malloc((cell->member_thresh+3)*sizeof(int)); + obs_members = cfmalloc((cell->member_thresh+3)*sizeof(int)); + match_members = cfmalloc((cell->member_thresh+3)*sizeof(int)); if ( (obs_members == NULL) || (match_members == NULL) ) { apologise(); return 0; @@ -1334,8 +1334,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, while ( 1 ) { if (start > obs_vec_count) { - free(obs_members); - free(match_members); + cffree(obs_members); + cffree(match_members); return 0; } @@ -1347,8 +1347,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, &match_found, cell); if ( member_num < 2 ) { - free(obs_members); - free(match_members); + cffree(obs_members); + cffree(match_members); return 0; } @@ -1383,8 +1383,8 @@ static unsigned int grow_network(gsl_matrix *rot, int obs_idx1, int obs_idx2, finish_solution(rot, obs_vecs, obs_members, match_members, member_num, cell); - free(obs_members); - free(match_members); + cffree(obs_members); + cffree(match_members); return ( member_num ); } @@ -1519,7 +1519,7 @@ static int find_seeds(struct TakeTwoCell *cell, struct taketwo_private *tp) size_t new_size = cell->seed_count + seed_num; new_size *= sizeof(struct Seed); - struct Seed *tmp = realloc(cell->seeds, new_size); + struct Seed *tmp = cfrealloc(cell->seeds, new_size); if (tmp == NULL) { apologise(); @@ -1539,7 +1539,7 @@ static int find_seeds(struct TakeTwoCell *cell, struct taketwo_private *tp) cell->seed_count++; } - free(seeds); + cffree(seeds); } } @@ -1590,12 +1590,12 @@ static unsigned int start_seeds(gsl_matrix **rotation, struct TakeTwoCell *cell) } if (member_num >= NETWORK_MEMBER_THRESHOLD) { - free(seeds); + cffree(seeds); return max_members; } } - free(seeds); + cffree(seeds); return max_members; } @@ -1652,7 +1652,7 @@ static int generate_rotation_sym_ops(struct TakeTwoCell *ttCell) int i, j, k; int numOps = num_equivs(rawList, NULL); - ttCell->rotSymOps = malloc(numOps * sizeof(gsl_matrix *)); + ttCell->rotSymOps = cfmalloc(numOps * sizeof(gsl_matrix *)); ttCell->numOps = numOps; if (ttCell->rotSymOps == NULL) { @@ -1764,13 +1764,13 @@ static int match_obs_to_cell_vecs(struct TheoryVec *cell_vecs, int cell_vec_coun /* Sort in order to get most agreeable matches first */ qsort(for_sort, count, sizeof(struct sortme), sort_theory_distances); - *match_array = malloc(count*sizeof(struct TheoryVec)); + *match_array = cfmalloc(count*sizeof(struct TheoryVec)); *match_count = count; for ( j=0; j<count; j++ ) { (*match_array)[j] = for_sort[j].v; } - free(for_sort); + cffree(for_sort); } return 1; @@ -1806,8 +1806,8 @@ static int gen_observed_vecs(struct rvec *rlps, int rlp_count, count++; struct SpotVec *temp_obs_vecs; - temp_obs_vecs = realloc(cell->obs_vecs, - count*sizeof(struct SpotVec)); + temp_obs_vecs = cfrealloc(cell->obs_vecs, + count*sizeof(struct SpotVec)); if ( temp_obs_vecs == NULL ) { return 0; @@ -1899,8 +1899,8 @@ static int gen_theoretical_vecs(UnitCell *cell, struct TheoryVec **cell_vecs, count++; struct TheoryVec *temp_cell_vecs; - temp_cell_vecs = realloc(*cell_vecs, - count*sizeof(struct TheoryVec)); + temp_cell_vecs = cfrealloc(*cell_vecs, + count*sizeof(struct TheoryVec)); if ( temp_cell_vecs == NULL ) { return 0; @@ -1929,10 +1929,10 @@ static void cleanup_taketwo_obs_vecs(struct SpotVec *obs_vecs, { int i; for ( i=0; i<obs_vec_count; i++ ) { - free(obs_vecs[i].matches); + cffree(obs_vecs[i].matches); } - free(obs_vecs); + cffree(obs_vecs); } static void cleanup_taketwo_cell(struct TakeTwoCell *ttCell) @@ -1943,7 +1943,7 @@ static void cleanup_taketwo_cell(struct TakeTwoCell *ttCell) for ( i=0; i<ttCell->numOps; i++ ) { gsl_matrix_free(ttCell->rotSymOps[i]); } - free(ttCell->rotSymOps); + cffree(ttCell->rotSymOps); cleanup_taketwo_obs_vecs(ttCell->obs_vecs, ttCell->obs_vec_count); @@ -2056,12 +2056,12 @@ static UnitCell *run_taketwo(UnitCell *cell, const struct taketwo_options *opts, /* Add the current solution to the previous solutions list */ int new_size = (tp->numPrevs + 1) * sizeof(gsl_matrix *); - gsl_matrix **tmp = realloc(tp->prevSols, new_size); - double *tmpScores = realloc(tp->prevScores, + gsl_matrix **tmp = cfrealloc(tp->prevSols, new_size); + double *tmpScores = cfrealloc(tp->prevScores, (tp->numPrevs + 1) * sizeof(double)); unsigned int *tmpSuccesses; - tmpSuccesses = realloc(tp->membership, - (tp->numPrevs + 1) * sizeof(unsigned int)); + tmpSuccesses = cfrealloc(tp->membership, + (tp->numPrevs + 1) * sizeof(unsigned int)); if (!tmp) { apologise(); @@ -2096,11 +2096,11 @@ static void partial_taketwo_cleanup(struct taketwo_private *tp) gsl_matrix_free(tp->prevSols[i]); } - free(tp->prevSols); + cffree(tp->prevSols); } - free(tp->prevScores); - free(tp->membership); + cffree(tp->prevScores); + cffree(tp->membership); tp->prevScores = NULL; tp->membership = NULL; tp->xtal_num = 0; @@ -2143,7 +2143,7 @@ int taketwo_index(struct image *image, void *priv) tp->xtal_num = image->n_crystals; } - rlps = malloc((image_feature_count(image->features)+1)*sizeof(struct rvec)); + rlps = cfmalloc((image_feature_count(image->features)+1)*sizeof(struct rvec)); for ( i=0; i<image_feature_count(image->features); i++ ) { double r[3]; @@ -2164,7 +2164,7 @@ int taketwo_index(struct image *image, void *priv) rlps[n_rlps++].w = 0.0; cell = run_taketwo(tp->cell, tp->opts, rlps, n_rlps, tp); - free(rlps); + cffree(rlps); if ( cell == NULL ) return 0; cr = crystal_new(); @@ -2222,7 +2222,7 @@ void *taketwo_prepare(IndexingMethod *indm, struct taketwo_options *opts, STATUS("\n"); - tp = malloc(sizeof(struct taketwo_private)); + tp = cfmalloc(sizeof(struct taketwo_private)); if ( tp == NULL ) return NULL; tp->cell = cell; @@ -2248,9 +2248,9 @@ void taketwo_cleanup(IndexingPrivate *pp) struct taketwo_private *tp = (struct taketwo_private *)pp; partial_taketwo_cleanup(tp); - free(tp->theory_vecs); + cffree(tp->theory_vecs); - free(tp); + cffree(tp); } @@ -2280,7 +2280,7 @@ int taketwo_default_options(struct taketwo_options **opts_ptr) { struct taketwo_options *opts; - opts = malloc(sizeof(struct taketwo_options)); + opts = cfmalloc(sizeof(struct taketwo_options)); if ( opts == NULL ) return ENOMEM; opts->member_thresh = -1.0; opts->len_tol = -1.0; diff --git a/libcrystfel/src/indexers/xds.c b/libcrystfel/src/indexers/xds.c index 8ef496cf..23274dc4 100644 --- a/libcrystfel/src/indexers/xds.c +++ b/libcrystfel/src/indexers/xds.c @@ -468,7 +468,7 @@ void *xds_prepare(IndexingMethod *indm, UnitCell *cell) return NULL; } - xp = calloc(1, sizeof(*xp)); + xp = cfcalloc(1, sizeof(*xp)); if ( xp == NULL ) return NULL; /* Flags that XDS knows about */ @@ -487,7 +487,7 @@ void xds_cleanup(void *pp) struct xds_private *xp; xp = (struct xds_private *)pp; - free(xp); + cffree(xp); } diff --git a/libcrystfel/src/indexers/xgandalf.c b/libcrystfel/src/indexers/xgandalf.c index 6c50a38b..defef243 100644 --- a/libcrystfel/src/indexers/xgandalf.c +++ b/libcrystfel/src/indexers/xgandalf.c @@ -158,7 +158,7 @@ int run_xgandalf(struct image *image, void *ipriv) void *xgandalf_prepare(IndexingMethod *indm, UnitCell *cell, struct xgandalf_options *xgandalf_opts) { - struct xgandalf_private_data *xgandalf_private_data = malloc(sizeof(struct xgandalf_private_data)); + struct xgandalf_private_data *xgandalf_private_data = cfmalloc(sizeof(struct xgandalf_private_data)); allocReciprocalPeaks(&(xgandalf_private_data->reciprocalPeaks_1_per_A)); xgandalf_private_data->indm = *indm; xgandalf_private_data->cellTemplate = NULL; @@ -264,7 +264,7 @@ void xgandalf_cleanup(void *pp) if(xgandalf_private_data->centeringTransformation != NULL){ intmat_free(xgandalf_private_data->centeringTransformation); } - free(xgandalf_private_data); + cffree(xgandalf_private_data); } static void reduceCell(UnitCell *cell, LatticeTransform_t* appliedReductionTransform) @@ -382,7 +382,7 @@ int xgandalf_default_options(struct xgandalf_options **opts_ptr) { struct xgandalf_options *opts; - opts = malloc(sizeof(struct xgandalf_options)); + opts = cfmalloc(sizeof(struct xgandalf_options)); if ( opts == NULL ) return ENOMEM; opts->sampling_pitch = 6; diff --git a/libcrystfel/src/integer_matrix.c b/libcrystfel/src/integer_matrix.c index c6527d82..f7881d0a 100644 --- a/libcrystfel/src/integer_matrix.c +++ b/libcrystfel/src/integer_matrix.c @@ -62,12 +62,12 @@ IntegerMatrix *intmat_new(unsigned int rows, unsigned int cols) { IntegerMatrix *m; - m = malloc(sizeof(IntegerMatrix)); + m = cfmalloc(sizeof(IntegerMatrix)); if ( m == NULL ) return NULL; - m->v = calloc(rows*cols, sizeof(signed int)); + m->v = cfcalloc(rows*cols, sizeof(signed int)); if ( m->v == NULL ) { - free(m); + cffree(m); return NULL; } @@ -109,8 +109,8 @@ IntegerMatrix *intmat_copy(const IntegerMatrix *m) void intmat_free(IntegerMatrix *m) { if ( m == NULL ) return; - free(m->v); - free(m); + cffree(m->v); + cffree(m); } @@ -190,7 +190,7 @@ signed int *transform_indices(const IntegerMatrix *P, const signed int *hkl) signed int *ans; unsigned int j; - ans = malloc(P->rows * sizeof(signed int)); + ans = cfmalloc(P->rows * sizeof(signed int)); if ( ans == NULL ) return NULL; for ( j=0; j<P->cols; j++ ) { diff --git a/libcrystfel/src/integration.c b/libcrystfel/src/integration.c index 8b05efe7..d2c06db7 100644 --- a/libcrystfel/src/integration.c +++ b/libcrystfel/src/integration.c @@ -393,7 +393,7 @@ static int alloc_boxes(struct intcontext *ic, int new_max_boxes) { struct peak_box *boxes_new; - boxes_new = realloc(ic->boxes, sizeof(struct peak_box)*new_max_boxes); + boxes_new = cfrealloc(ic->boxes, sizeof(struct peak_box)*new_max_boxes); if ( boxes_new == NULL ) return 1; ic->boxes = boxes_new; @@ -467,7 +467,7 @@ struct intcontext *intcontext_new(struct image *image, int i; struct intcontext *ic; - ic = malloc(sizeof(struct intcontext)); + ic = cfmalloc(sizeof(struct intcontext)); if ( ic == NULL ) return NULL; ic->halfw = ir_out; @@ -481,36 +481,36 @@ struct intcontext *intcontext_new(struct image *image, ic->int_diag = INTDIAG_NONE; ic->w = 2*ic->halfw + 1; - ic->bm = malloc(ic->w * ic->w * sizeof(enum boxmask_val)); + ic->bm = cfmalloc(ic->w * ic->w * sizeof(enum boxmask_val)); if ( ic->bm == NULL ) { ERROR("Failed to allocate box mask.\n"); - free(ic); + cffree(ic); return NULL; } /* How many reference profiles? */ ic->n_reference_profiles = 1; - ic->reference_profiles = calloc(ic->n_reference_profiles, - sizeof(double *)); + ic->reference_profiles = cfcalloc(ic->n_reference_profiles, + sizeof(double *)); if ( ic->reference_profiles == NULL ) { - free(ic); + cffree(ic); return NULL; } - ic->reference_den = calloc(ic->n_reference_profiles, sizeof(double *)); + ic->reference_den = cfcalloc(ic->n_reference_profiles, sizeof(double *)); if ( ic->reference_den == NULL ) { - free(ic); + cffree(ic); return NULL; } - ic->n_profiles_in_reference = calloc(ic->n_reference_profiles, - sizeof(int)); + ic->n_profiles_in_reference = cfcalloc(ic->n_reference_profiles, + sizeof(int)); if ( ic->n_profiles_in_reference == NULL ) { - free(ic); + cffree(ic); return NULL; } for ( i=0; i<ic->n_reference_profiles; i++ ) { - ic->reference_profiles[i] = malloc(ic->w*ic->w*sizeof(double)); + ic->reference_profiles[i] = cfmalloc(ic->w*ic->w*sizeof(double)); if ( ic->reference_profiles[i] == NULL ) return NULL; - ic->reference_den[i] = malloc(ic->w*ic->w*sizeof(double)); + ic->reference_den[i] = cfmalloc(ic->w*ic->w*sizeof(double)); if ( ic->reference_den[i] == NULL ) return NULL; } zero_profiles(ic); @@ -519,7 +519,7 @@ struct intcontext *intcontext_new(struct image *image, ic->n_boxes = 0; ic->max_boxes = 0; if ( alloc_boxes(ic, 32) ) { - free(ic); + cffree(ic); return NULL; } @@ -534,20 +534,20 @@ void intcontext_free(struct intcontext *ic) int i; for ( i=0; i<ic->n_boxes; i++ ) { - free(ic->boxes[i].bm); + cffree(ic->boxes[i].bm); gsl_matrix_free(ic->boxes[i].bgm); } - free(ic->boxes); + cffree(ic->boxes); for ( i=0; i<ic->n_reference_profiles; i++ ) { - free(ic->reference_profiles[i]); - free(ic->reference_den[i]); - } - free(ic->reference_profiles); - free(ic->reference_den); - free(ic->n_profiles_in_reference); - free(ic->bm); - free(ic); + cffree(ic->reference_profiles[i]); + cffree(ic->reference_den[i]); + } + cffree(ic->reference_profiles); + cffree(ic->reference_den); + cffree(ic->n_profiles_in_reference); + cffree(ic->bm); + cffree(ic); } @@ -604,7 +604,7 @@ static void delete_box(struct intcontext *ic, struct peak_box *bx) return; } - free(bx->bm); + cffree(bx->bm); gsl_matrix_free(bx->bgm); memmove(&ic->boxes[i], &ic->boxes[i+1], @@ -803,7 +803,7 @@ static int check_box(struct intcontext *ic, struct peak_box *bx, int *sat) if ( sat != NULL ) *sat = 0; - bx->bm = malloc(ic->w*ic->w*sizeof(enum boxmask_val)); + bx->bm = cfmalloc(ic->w*ic->w*sizeof(enum boxmask_val)); if ( bx->bm == NULL ) { ERROR("Failed to allocate box mask\n"); return 1; @@ -980,7 +980,7 @@ static int center_and_check_box(struct intcontext *ic, struct peak_box *bx, t_offs_fs += ifs; t_offs_ss += iss; - free(bx->bm); + cffree(bx->bm); if ( check_box(ic, bx, sat) ) { return 1; } @@ -1342,17 +1342,16 @@ static void setup_profile_boxes(struct intcontext *ic, RefList *list) void integrate_prof2d(IntegrationMethod meth, - Crystal *cr, struct image *image, IntDiag int_diag, + Crystal *cr, RefList *list, + struct image *image, IntDiag int_diag, signed int idh, signed int idk, signed int idl, double ir_inn, double ir_mid, double ir_out, pthread_mutex_t *term_lock, int **masks) { - RefList *list; UnitCell *cell; struct intcontext *ic; int i; - list = crystal_get_reflections(cr); cell = crystal_get_cell(cr); ic = intcontext_new(image, cell, meth, @@ -1515,7 +1514,7 @@ static double estimate_resolution(Crystal *cr, struct image *image) UnitCell *cell; - acc = malloc(max_acc*sizeof(double)); + acc = cfmalloc(max_acc*sizeof(double)); if ( acc == NULL ) { ERROR("Allocation failed during estimate_resolution!\n"); return INFINITY; @@ -1577,7 +1576,7 @@ static double estimate_resolution(Crystal *cr, struct image *image) if ( n_acc < 3 ) { STATUS("WARNING: Too few peaks to estimate resolution.\n"); - free(acc); + cffree(acc); return 0.0; } @@ -1587,18 +1586,18 @@ static double estimate_resolution(Crystal *cr, struct image *image) if ( n < 2 ) n = 2; max_res = acc[(n_acc-1)-n]; - free(acc); + cffree(acc); return max_res; } static void integrate_rings(IntegrationMethod meth, - Crystal *cr, struct image *image, IntDiag int_diag, + Crystal *cr, RefList *list, + struct image *image, IntDiag int_diag, signed int idh, signed int idk, signed int idl, double ir_inn, double ir_mid, double ir_out, pthread_mutex_t *term_lock, int **masks) { - RefList *list; Reflection *refl; RefListIterator *iter; UnitCell *cell; @@ -1606,7 +1605,6 @@ static void integrate_rings(IntegrationMethod meth, int n_rej = 0; int n_refl = 0; - list = crystal_get_reflections(cr); cell = crystal_get_cell(cr); ic = intcontext_new(image, cell, meth, @@ -1653,23 +1651,21 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, /* Predict all reflections */ for ( i=0; i<image->n_crystals; i++ ) { - RefList *list; double res; - double saved_R = crystal_get_profile_radius(image->crystals[i]); + double saved_R = crystal_get_profile_radius(image->crystals[i].cr); if ( overpredict ) { - crystal_set_profile_radius(image->crystals[i], + crystal_set_profile_radius(image->crystals[i].cr, saved_R * 5); } - res = estimate_resolution(image->crystals[i], image); - crystal_set_resolution_limit(image->crystals[i], res); + res = estimate_resolution(image->crystals[i].cr, image); + crystal_set_resolution_limit(image->crystals[i].cr, res); - list = predict_to_res(image->crystals[i], res+push_res); - crystal_set_reflections(image->crystals[i], list); + image->crystals[i].refls = predict_to_res(image->crystals[i].cr, image, res+push_res); if ( overpredict ) { - crystal_set_profile_radius(image->crystals[i], saved_R); + crystal_set_profile_radius(image->crystals[i].cr, saved_R); } } @@ -1681,22 +1677,26 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, for ( i=0; i<image->n_crystals; i++ ) { - Crystal *cr = image->crystals[i]; - switch ( meth & INTEGRATION_METHOD_MASK ) { case INTEGRATION_NONE : break; case INTEGRATION_RINGS : - integrate_rings(meth, cr, image, + integrate_rings(meth, + image->crystals[i].cr, + image->crystals[i].refls, + image, int_diag, idh, idk, idl, ir_inn, ir_mid, ir_out, term_lock, masks); break; case INTEGRATION_PROF2D : - integrate_prof2d(meth, cr, image, + integrate_prof2d(meth, + image->crystals[i].cr, + image->crystals[i].refls, + image, int_diag, idh, idk, idl, ir_inn, ir_mid, ir_out, term_lock, masks); @@ -1711,7 +1711,7 @@ void integrate_all_5(struct image *image, IntegrationMethod meth, } for ( i=0; i<image->detgeom->n_panels; i++ ) { - free(masks[i]); + cffree(masks[i]); } } @@ -1794,7 +1794,7 @@ char *str_integration_method(IntegrationMethod m) strcat(tmp, "-grad"); } - return strdup(tmp); + return cfstrdup(tmp); } @@ -1854,10 +1854,10 @@ IntegrationMethod integration_method(const char *str, int *err) return INTEGRATION_NONE; } - free(methods[i]); + cffree(methods[i]); } - free(methods); + cffree(methods); return meth; diff --git a/libcrystfel/src/peakfinder8.c b/libcrystfel/src/peakfinder8.c index 80a219cb..1def35d3 100644 --- a/libcrystfel/src/peakfinder8.c +++ b/libcrystfel/src/peakfinder8.c @@ -119,26 +119,26 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma int i; struct radial_stats_pixels *rsp = NULL; - rsp = (struct radial_stats_pixels *)malloc(sizeof(struct radial_stats_pixels)); + rsp = (struct radial_stats_pixels *)cfmalloc(sizeof(struct radial_stats_pixels)); if ( rsp == NULL ) { return NULL; } - rsp->n_pixels = (int *)malloc(rmaps->n_rmaps * sizeof(int)); + rsp->n_pixels = (int *)cfmalloc(rmaps->n_rmaps * sizeof(int)); if ( rsp->n_pixels == NULL ) { - free(rsp); + cffree(rsp); return NULL; } - rsp->pidx = (int **)malloc(rmaps->n_rmaps * sizeof(int *)); + rsp->pidx = (int **)cfmalloc(rmaps->n_rmaps * sizeof(int *)); if ( rsp->pidx == NULL ) { - free(rsp->n_pixels); - free(rsp); + cffree(rsp->n_pixels); + cffree(rsp); return NULL; } - rsp->radius = (int **)malloc(rmaps->n_rmaps * sizeof(int *)); + rsp->radius = (int **)cfmalloc(rmaps->n_rmaps * sizeof(int *)); if ( rsp->radius == NULL ) { - free(rsp->n_pixels); - free(rsp->pidx); - free(rsp); + cffree(rsp->n_pixels); + cffree(rsp->pidx); + cffree(rsp); return NULL; } srand(0); @@ -147,16 +147,16 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma // Assuming 5000 is the maximum possible radius int n_bins = 5000; - int *n_pixels = (int *)malloc(n_bins * sizeof(int)); // selected pixels per bin - int *n_tot_pixels = (int *)malloc(n_bins * sizeof(int));; // total pixels per bin - int **panel = (int **)malloc(n_bins * sizeof(int *)); // panel ID of selected pixels - int **idx = (int **)malloc(n_bins * sizeof(int *)); // index of selected pixels + int *n_pixels = (int *)cfmalloc(n_bins * sizeof(int)); // selected pixels per bin + int *n_tot_pixels = (int *)cfmalloc(n_bins * sizeof(int));; // total pixels per bin + int **panel = (int **)cfmalloc(n_bins * sizeof(int *)); // panel ID of selected pixels + int **idx = (int **)cfmalloc(n_bins * sizeof(int *)); // index of selected pixels for ( i = 0; i < n_bins; i++ ) { n_pixels[i] = 0; n_tot_pixels[i] = 0; - panel[i] = (int *)malloc(n_pixels_per_bin * sizeof(int)); - idx[i] = (int *)malloc(n_pixels_per_bin * sizeof(int)); + panel[i] = (int *)cfmalloc(n_pixels_per_bin * sizeof(int)); + idx[i] = (int *)cfmalloc(n_pixels_per_bin * sizeof(int)); } int radius; @@ -186,40 +186,40 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma } } - int *sidx = (int *)malloc(rmaps->n_rmaps * sizeof(int)); + int *sidx = (int *)cfmalloc(rmaps->n_rmaps * sizeof(int)); if ( sidx == NULL ) { - free(rsp->n_pixels); - free(rsp->pidx); - free(rsp->radius); - free(rsp); + cffree(rsp->n_pixels); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp); return NULL; } for ( p = 0; p < rmaps->n_rmaps; p++ ) { - rsp->pidx[p] = (int *)malloc(rsp->n_pixels[p] * sizeof(int)); + rsp->pidx[p] = (int *)cfmalloc(rsp->n_pixels[p] * sizeof(int)); if ( rsp->pidx[p] == NULL ) { for ( i = 0; i < p; i++ ) { - free(rsp->pidx[i]); - free(rsp->radius[i]); + cffree(rsp->pidx[i]); + cffree(rsp->radius[i]); } - free(rsp->pidx); - free(rsp->radius); - free(rsp->n_pixels); - free(rsp); - free(sidx); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp->n_pixels); + cffree(rsp); + cffree(sidx); return NULL; } - rsp->radius[p] = (int *)malloc(rsp->n_pixels[p] * sizeof(int)); + rsp->radius[p] = (int *)cfmalloc(rsp->n_pixels[p] * sizeof(int)); if ( rsp->radius[p] == NULL ) { for ( i = 0; i < p; i++ ) { - free(rsp->pidx[i]); - free(rsp->radius[i]); + cffree(rsp->pidx[i]); + cffree(rsp->radius[i]); } - free(rsp->pidx[p]); - free(rsp->pidx); - free(rsp->radius); - free(rsp->n_pixels); - free(rsp); - free(sidx); + cffree(rsp->pidx[p]); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp->n_pixels); + cffree(rsp); + cffree(sidx); return NULL; } sidx[p] = 0; @@ -233,15 +233,15 @@ static struct radial_stats_pixels *compute_rstats_pixels(struct radius_maps *rma sidx[p] += 1; } } - free(sidx); + cffree(sidx); for ( i = 0; i < n_bins; i++ ) { - free(panel[i]); - free(idx[i]); + cffree(panel[i]); + cffree(idx[i]); } - free(panel); - free(idx); - free(n_pixels); - free(n_tot_pixels); + cffree(panel); + cffree(idx); + cffree(n_pixels); + cffree(n_tot_pixels); rsp->n_panels = rmaps->n_rmaps; return rsp; @@ -251,13 +251,13 @@ static void free_rstats_pixels(struct radial_stats_pixels *rsp) { int i; for ( i = 0; i < rsp->n_panels; i++ ) { - free(rsp->pidx[i]); - free(rsp->radius[i]); + cffree(rsp->pidx[i]); + cffree(rsp->radius[i]); } - free(rsp->pidx); - free(rsp->radius); - free(rsp->n_pixels); - free(rsp); + cffree(rsp->pidx); + cffree(rsp->radius); + cffree(rsp->n_pixels); + cffree(rsp); } @@ -267,20 +267,20 @@ static struct radius_maps *compute_radius_maps(struct detgeom *det) struct detgeom_panel p; struct radius_maps *rm = NULL; - rm = (struct radius_maps *)malloc(sizeof(struct radius_maps)); + rm = (struct radius_maps *)cfmalloc(sizeof(struct radius_maps)); if ( rm == NULL ) { return NULL; } - rm->r_maps = (float **)malloc(det->n_panels*sizeof(float*)); + rm->r_maps = (float **)cfmalloc(det->n_panels*sizeof(float*)); if ( rm->r_maps == NULL ) { - free(rm); + cffree(rm); return NULL; } - rm->n_pixels = (int *)malloc(det->n_panels*sizeof(int*)); + rm->n_pixels = (int *)cfmalloc(det->n_panels*sizeof(int*)); if ( rm->r_maps == NULL ) { - free(rm); + cffree(rm); return NULL; } @@ -289,13 +289,13 @@ static struct radius_maps *compute_radius_maps(struct detgeom *det) for( i=0 ; i<det->n_panels ; i++ ) { p = det->panels[i]; - rm->r_maps[i] = (float *)malloc(p.h*p.w*sizeof(float)); + rm->r_maps[i] = (float *)cfmalloc(p.h*p.w*sizeof(float)); if ( rm->r_maps[i] == NULL ) { for ( u = 0; u<i; u++ ) { - free(rm->r_maps[u]); + cffree(rm->r_maps[u]); } - free(rm); + cffree(rm); return NULL; } rm->n_pixels[i] = p.h * p.w; @@ -323,11 +323,11 @@ static void free_radius_maps(struct radius_maps *r_maps) int i; for ( i=0 ; i<r_maps->n_rmaps ; i++ ) { - free(r_maps->r_maps[i]); + cffree(r_maps->r_maps[i]); } - free(r_maps->r_maps); - free(r_maps->n_pixels); - free(r_maps); + cffree(r_maps->r_maps); + cffree(r_maps->n_pixels); + cffree(r_maps); } @@ -339,13 +339,13 @@ struct pf8_private_data *prepare_peakfinder8(struct detgeom *det, int fast_mode) return NULL; } - data = (struct pf8_private_data *)malloc(sizeof(struct pf8_private_data)); + data = (struct pf8_private_data *)cfmalloc(sizeof(struct pf8_private_data)); if ( data == NULL ) { return NULL; } data->rmaps = compute_radius_maps(det); if ( data->rmaps == NULL ) { - free(data); + cffree(data); return NULL; } if ( fast_mode ) { @@ -369,11 +369,11 @@ void free_pf8_private_data(struct pf8_private_data *data) if ( data->fast_mode ) { free_rstats_pixels(data->rpixels); } - free(data); + cffree(data); } -static struct peakfinder_mask *create_peakfinder_mask(struct image *img, +static struct peakfinder_mask *create_peakfinder_mask(const struct image *img, struct radius_maps *rmps, int min_res, int max_res) @@ -381,8 +381,8 @@ static struct peakfinder_mask *create_peakfinder_mask(struct image *img, int i; struct peakfinder_mask *msk; - msk = (struct peakfinder_mask *)malloc(sizeof(struct peakfinder_mask)); - msk->masks =(char **) malloc(img->detgeom->n_panels*sizeof(char*)); + msk = (struct peakfinder_mask *)cfmalloc(sizeof(struct peakfinder_mask)); + msk->masks =(char **) cfmalloc(img->detgeom->n_panels*sizeof(char*)); msk->n_masks = img->detgeom->n_panels; for ( i=0; i<img->detgeom->n_panels; i++) { @@ -391,7 +391,7 @@ static struct peakfinder_mask *create_peakfinder_mask(struct image *img, p = img->detgeom->panels[i]; - msk->masks[i] = (char *)calloc(p.w*p.h,sizeof(char)); + msk->masks[i] = (char *)cfcalloc(p.w*p.h,sizeof(char)); for ( iss=0 ; iss<p.h ; iss++ ) { for ( ifs=0 ; ifs<p.w ; ifs++ ) { @@ -422,10 +422,10 @@ static void free_peakfinder_mask(struct peakfinder_mask * pfmask) int i; for ( i=0 ; i<pfmask->n_masks ; i++ ) { - free(pfmask->masks[i]); + cffree(pfmask->masks[i]); } - free(pfmask->masks); - free(pfmask); + cffree(pfmask->masks); + cffree(pfmask); } @@ -434,29 +434,29 @@ static struct peakfinder_panel_data *allocate_panel_data(int num_panels) struct peakfinder_panel_data *pfdata; - pfdata = (struct peakfinder_panel_data *)malloc(sizeof(struct peakfinder_panel_data)); + pfdata = (struct peakfinder_panel_data *)cfmalloc(sizeof(struct peakfinder_panel_data)); if ( pfdata == NULL ) { return NULL; } - pfdata->panel_h = (int *)malloc(num_panels*sizeof(int)); + pfdata->panel_h = (int *)cfmalloc(num_panels*sizeof(int)); if ( pfdata->panel_h == NULL ) { - free(pfdata); + cffree(pfdata); return NULL; } - pfdata->panel_w = (int *)malloc(num_panels*sizeof(int)); + pfdata->panel_w = (int *)cfmalloc(num_panels*sizeof(int)); if ( pfdata->panel_w == NULL ) { - free(pfdata->panel_h); - free(pfdata); + cffree(pfdata->panel_h); + cffree(pfdata); return NULL; } - pfdata->panel_data = (float **)malloc(num_panels*sizeof(float*)); + pfdata->panel_data = (float **)cfmalloc(num_panels*sizeof(float*)); if ( pfdata->panel_data == NULL ) { - free(pfdata->panel_w); - free(pfdata->panel_h); - free(pfdata); + cffree(pfdata->panel_w); + cffree(pfdata->panel_h); + cffree(pfdata); return NULL; } @@ -468,10 +468,10 @@ static struct peakfinder_panel_data *allocate_panel_data(int num_panels) static void free_panel_data(struct peakfinder_panel_data *pfdata) { - free(pfdata->panel_data); - free(pfdata->panel_w); - free(pfdata->panel_h); - free(pfdata); + cffree(pfdata->panel_data); + cffree(pfdata->panel_w); + cffree(pfdata->panel_h); + cffree(pfdata); } @@ -496,48 +496,48 @@ static struct radial_stats* allocate_radial_stats(int num_rad_bins) { struct radial_stats* rstats; - rstats = (struct radial_stats *)malloc(sizeof(struct radial_stats)); + rstats = (struct radial_stats *)cfmalloc(sizeof(struct radial_stats)); if ( rstats == NULL ) { return NULL; } - rstats->roffset = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->roffset = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->roffset == NULL ) { - free(rstats); + cffree(rstats); return NULL; } - rstats->rthreshold = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->rthreshold = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->rthreshold == NULL ) { - free(rstats->roffset); - free(rstats); + cffree(rstats->roffset); + cffree(rstats); return NULL; } - rstats->lthreshold = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->lthreshold = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->lthreshold == NULL ) { - free(rstats->rthreshold); - free(rstats->roffset); - free(rstats); + cffree(rstats->rthreshold); + cffree(rstats->roffset); + cffree(rstats); return NULL; } - rstats->rsigma = (float *)malloc(num_rad_bins*sizeof(float)); + rstats->rsigma = (float *)cfmalloc(num_rad_bins*sizeof(float)); if ( rstats->rsigma == NULL ) { - free(rstats->roffset); - free(rstats->rthreshold); - free(rstats->lthreshold); - free(rstats); + cffree(rstats->roffset); + cffree(rstats->rthreshold); + cffree(rstats->lthreshold); + cffree(rstats); return NULL; } - rstats->rcount = (int *)malloc(num_rad_bins*sizeof(int)); + rstats->rcount = (int *)cfmalloc(num_rad_bins*sizeof(int)); if ( rstats->rcount == NULL ) { - free(rstats->roffset); - free(rstats->rthreshold); - free(rstats->lthreshold); - free(rstats->rsigma); - free(rstats); + cffree(rstats->roffset); + cffree(rstats->rthreshold); + cffree(rstats->lthreshold); + cffree(rstats->rsigma); + cffree(rstats); return NULL; } @@ -549,12 +549,12 @@ static struct radial_stats* allocate_radial_stats(int num_rad_bins) static void free_radial_stats(struct radial_stats *rstats) { - free(rstats->roffset); - free(rstats->rthreshold); - free(rstats->lthreshold); - free(rstats->rsigma); - free(rstats->rcount); - free(rstats); + cffree(rstats->roffset); + cffree(rstats->rthreshold); + cffree(rstats->lthreshold); + cffree(rstats->rsigma); + cffree(rstats->rcount); + cffree(rstats); } @@ -663,85 +663,85 @@ struct peakfinder_peak_data *allocate_peak_data(int max_num_peaks) { struct peakfinder_peak_data *pkdata; - pkdata = (struct peakfinder_peak_data*)malloc(sizeof(struct peakfinder_peak_data)); + pkdata = (struct peakfinder_peak_data*)cfmalloc(sizeof(struct peakfinder_peak_data)); if ( pkdata == NULL ) { return NULL; } - pkdata->npix = (int *)malloc(max_num_peaks*sizeof(int)); + pkdata->npix = (int *)cfmalloc(max_num_peaks*sizeof(int)); if ( pkdata->npix == NULL ) { - free(pkdata->npix); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata); return NULL; } - pkdata->com_fs = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->com_fs = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->com_fs == NULL ) { - free(pkdata->npix); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata); return NULL; } - pkdata->com_ss = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->com_ss = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->com_ss == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata); return NULL; } - pkdata->com_index = (int *)malloc(max_num_peaks*sizeof(int)); + pkdata->com_index = (int *)cfmalloc(max_num_peaks*sizeof(int)); if ( pkdata->com_ss == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata); return NULL; } - pkdata->tot_i = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->tot_i = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->tot_i == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata); return NULL; } - pkdata->max_i = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->max_i = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->max_i == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata); return NULL; } - pkdata->sigma = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->sigma = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->sigma == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata->max_i); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata->max_i); + cffree(pkdata); return NULL; } - pkdata->snr = (float *)malloc(max_num_peaks*sizeof(float)); + pkdata->snr = (float *)cfmalloc(max_num_peaks*sizeof(float)); if ( pkdata->snr == NULL ) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata->max_i); - free(pkdata->sigma); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata->max_i); + cffree(pkdata->sigma); + cffree(pkdata); return NULL; } @@ -750,15 +750,15 @@ struct peakfinder_peak_data *allocate_peak_data(int max_num_peaks) static void free_peak_data(struct peakfinder_peak_data *pkdata) { - free(pkdata->npix); - free(pkdata->com_fs); - free(pkdata->com_ss); - free(pkdata->com_index); - free(pkdata->tot_i); - free(pkdata->max_i); - free(pkdata->sigma); - free(pkdata->snr); - free(pkdata); + cffree(pkdata->npix); + cffree(pkdata->com_fs); + cffree(pkdata->com_ss); + cffree(pkdata->com_index); + cffree(pkdata->tot_i); + cffree(pkdata->max_i); + cffree(pkdata->sigma); + cffree(pkdata->snr); + cffree(pkdata); } @@ -768,38 +768,38 @@ static struct peakfinder_intern_data *allocate_peakfinder_intern_data(int data_s struct peakfinder_intern_data *intern_data; - intern_data = (struct peakfinder_intern_data *)malloc(sizeof(struct peakfinder_intern_data)); + intern_data = (struct peakfinder_intern_data *)cfmalloc(sizeof(struct peakfinder_intern_data)); if ( intern_data == NULL ) { return NULL; } - intern_data->pix_in_peak_map =(char *)calloc(data_size, sizeof(char)); + intern_data->pix_in_peak_map =(char *)cfcalloc(data_size, sizeof(char)); if ( intern_data->pix_in_peak_map == NULL ) { - free(intern_data); + cffree(intern_data); return NULL; } - intern_data->infs =(int *)calloc(data_size, sizeof(int)); + intern_data->infs =(int *)cfcalloc(data_size, sizeof(int)); if ( intern_data->infs == NULL ) { - free(intern_data->pix_in_peak_map); - free(intern_data); + cffree(intern_data->pix_in_peak_map); + cffree(intern_data); return NULL; } - intern_data->inss =(int *)calloc(data_size, sizeof(int)); + intern_data->inss =(int *)cfcalloc(data_size, sizeof(int)); if ( intern_data->inss == NULL ) { - free(intern_data->pix_in_peak_map); - free(intern_data->infs); - free(intern_data); + cffree(intern_data->pix_in_peak_map); + cffree(intern_data->infs); + cffree(intern_data); return NULL; } - intern_data->peak_pixels =(int *)calloc(max_pix_count, sizeof(int)); + intern_data->peak_pixels =(int *)cfcalloc(max_pix_count, sizeof(int)); if ( intern_data->peak_pixels == NULL ) { - free(intern_data->pix_in_peak_map); - free(intern_data->infs); - free(intern_data->inss); - free(intern_data); + cffree(intern_data->pix_in_peak_map); + cffree(intern_data->infs); + cffree(intern_data->inss); + cffree(intern_data); return NULL; } @@ -809,11 +809,11 @@ static struct peakfinder_intern_data *allocate_peakfinder_intern_data(int data_s static void free_peakfinder_intern_data(struct peakfinder_intern_data *pfid) { - free(pfid->peak_pixels); - free(pfid->pix_in_peak_map); - free(pfid->infs); - free(pfid->inss); - free(pfid); + cffree(pfid->peak_pixels); + cffree(pfid->pix_in_peak_map); + cffree(pfid->infs); + cffree(pfid->inss); + cffree(pfid); } @@ -1248,14 +1248,15 @@ static int peakfinder8_base(float *roffset, float *rthreshold, * \param max_res The maximum number of pixels out from the center * \param use_saturated Whether saturated peaks should be considered * - * Runs the peakfinder8 peak search algorithm + * Runs the peakfinder8 peak search algorithm, and returns an \ref ImageFeatureList, + * or NULL on error. */ -int peakfinder8(struct image *img, int max_n_peaks, - float threshold, float min_snr, - int min_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, struct pf8_private_data *private_data) +ImageFeatureList *peakfinder8(const struct image *img, int max_n_peaks, + float threshold, float min_snr, + int min_pix_count, int max_pix_count, + int local_bg_radius, int min_res, + int max_res, int use_saturated, + int fast_mode, struct pf8_private_data *private_data) { struct pf8_private_data *geomdata; struct radius_maps *rmaps; @@ -1272,10 +1273,11 @@ int peakfinder8(struct image *img, int max_n_peaks, int remaining_max_num_peaks; int iterations; float max_r; + ImageFeatureList *peaks; iterations = 5; - if ( img->detgeom == NULL) return 1; + if ( img->detgeom == NULL) return NULL; profile_start("pf8-rmaps"); if ( private_data == NULL ) { @@ -1286,21 +1288,21 @@ int peakfinder8(struct image *img, int max_n_peaks, rmaps = geomdata->rmaps; rspixels = geomdata->rpixels; profile_end("pf8-rmaps"); - if (geomdata == NULL) return 1; + if (geomdata == NULL) return NULL; profile_start("pf8-mask"); pfmask = create_peakfinder_mask(img, rmaps, min_res, max_res); profile_end("pf8-mask"); if ( pfmask == NULL ) { if ( private_data == NULL ) free_pf8_private_data(geomdata); - return 1; + return NULL; } pfdata = allocate_panel_data(img->detgeom->n_panels); if ( pfdata == NULL) { if ( private_data == NULL ) free_pf8_private_data(geomdata); free_peakfinder_mask(pfmask); - return 1; + return NULL; } for ( pi=0 ; pi<img->detgeom->n_panels ; pi++ ) { @@ -1327,7 +1329,7 @@ int peakfinder8(struct image *img, int max_n_peaks, if ( private_data == NULL ) free_pf8_private_data(geomdata); free_peakfinder_mask(pfmask); free_panel_data(pfdata); - return 1; + return NULL; } for ( i=0 ; i<rstats->n_rad_bins ; i++) { @@ -1389,10 +1391,11 @@ int peakfinder8(struct image *img, int max_n_peaks, free_peakfinder_mask(pfmask); free_panel_data(pfdata); free_radial_stats(rstats); - return 1; + return NULL; } remaining_max_num_peaks = max_n_peaks; + peaks = image_feature_list_new(); profile_start("pf8-search"); for ( pi=0 ; pi<img->detgeom->n_panels ; pi++) { @@ -1430,8 +1433,9 @@ int peakfinder8(struct image *img, int max_n_peaks, free_peakfinder_mask(pfmask); free_panel_data(pfdata); free_radial_stats(rstats); + image_feature_list_free(peaks); profile_end("pf8-search"); - return 1; + return NULL; } peaks_to_add = num_found_peaks; @@ -1454,11 +1458,10 @@ int peakfinder8(struct image *img, int max_n_peaks, } } - image_add_feature(img->features, + image_add_feature(peaks, pkdata->com_fs[pki]+0.5, pkdata->com_ss[pki]+0.5, - pi, img, pkdata->tot_i[pki], - NULL); + pi, pkdata->tot_i[pki], NULL); } } profile_end("pf8-search"); @@ -1468,5 +1471,5 @@ int peakfinder8(struct image *img, int max_n_peaks, free_panel_data(pfdata); free_radial_stats(rstats); free_peak_data(pkdata); - return 0; + return peaks; } diff --git a/libcrystfel/src/peakfinder8.h b/libcrystfel/src/peakfinder8.h index e5e86038..cf23bdbf 100644 --- a/libcrystfel/src/peakfinder8.h +++ b/libcrystfel/src/peakfinder8.h @@ -54,12 +54,13 @@ struct pf8_private_data *prepare_peakfinder8(struct detgeom *det, int fast_mode) void free_pf8_private_data(struct pf8_private_data *data); -extern int peakfinder8(struct image *img, int max_n_peaks, - float threshold, float min_snr, - int mix_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, struct pf8_private_data *private_data); +extern ImageFeatureList *peakfinder8(const struct image *img, int max_n_peaks, + float threshold, float min_snr, + int mix_pix_count, int max_pix_count, + int local_bg_radius, int min_res, + int max_res, int use_saturated, + int fast_mode, + struct pf8_private_data *private_data); #ifdef __cplusplus } diff --git a/libcrystfel/src/peaks.c b/libcrystfel/src/peaks.c index 837c00fc..cb438683 100644 --- a/libcrystfel/src/peaks.c +++ b/libcrystfel/src/peaks.c @@ -62,15 +62,15 @@ /** \file peaks.h */ -static void add_crystal_to_mask(struct image *image, - struct detgeom_panel *p, int pn, - double ir_inn, int *mask, Crystal *cr) +static void add_reflections_to_mask(struct image *image, + struct detgeom_panel *p, int pn, + double ir_inn, int *mask, RefList *list) { Reflection *refl; RefListIterator *iter; /* Loop over all reflections */ - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -115,14 +115,14 @@ int *make_BgMask(struct image *image, struct detgeom_panel *p, int *mask; int i; - mask = calloc(p->w*p->h, sizeof(int)); + mask = cfcalloc(p->w*p->h, sizeof(int)); if ( mask == NULL ) return NULL; if ( image->crystals == NULL ) return mask; for ( i=0; i<image->n_crystals; i++ ) { - add_crystal_to_mask(image, p, pn, ir_inn, - mask, image->crystals[i]); + add_reflections_to_mask(image, p, pn, ir_inn, + mask, image->crystals[i].refls); } return mask; @@ -131,7 +131,7 @@ int *make_BgMask(struct image *image, struct detgeom_panel *p, /* Returns non-zero if peak has been vetoed. * i.e. don't use result if return value is not zero. */ -int integrate_peak(struct image *image, +int integrate_peak(const struct image *image, int p_cfs, int p_css, int pn, double *pfs, double *pss, double *intensity, double *sigma, @@ -254,7 +254,8 @@ int integrate_peak(struct image *image, } -static void search_peaks_in_panel(struct image *image, float threshold, +static void search_peaks_in_panel(ImageFeatureList *peaklist, + const struct image *image, float threshold, float min_sq_gradient, float min_snr, int pn, double ir_inn, double ir_mid, double ir_out, int use_saturated) @@ -387,8 +388,7 @@ static void search_peaks_in_panel(struct image *image, float threshold, } /* Check for a nearby feature */ - image_feature_closest(image->features, f_fs, f_ss, pn, - &d, &idx); + image_feature_closest(peaklist, f_fs, f_ss, pn, &d, &idx); if ( d < 2.0*ir_inn ) { nrej_pro++; continue; @@ -400,8 +400,7 @@ static void search_peaks_in_panel(struct image *image, float threshold, } /* Add using "better" coordinates */ - image_add_feature(image->features, f_fs, f_ss, pn, - image, intensity, NULL); + image_add_feature(peaklist, f_fs, f_ss, pn, intensity, NULL); nacc++; if ( nacc > 10000 ) { @@ -422,69 +421,38 @@ static void search_peaks_in_panel(struct image *image, float threshold, } -void search_peaks(struct image *image, float threshold, float min_sq_gradient, - float min_snr, double ir_inn, double ir_mid, - double ir_out, int use_saturated) +ImageFeatureList *search_peaks(const struct image *image, + float threshold, float min_sq_gradient, + float min_snr, double ir_inn, double ir_mid, + double ir_out, int use_saturated) { int i; + ImageFeatureList *peaklist; - if ( image->features != NULL ) { - image_feature_list_free(image->features); - } - image->features = image_feature_list_new(); + peaklist = image_feature_list_new(); for ( i=0; i<image->detgeom->n_panels; i++ ) { - search_peaks_in_panel(image, threshold, min_sq_gradient, + search_peaks_in_panel(peaklist, image, + threshold, min_sq_gradient, min_snr, i, ir_inn, ir_mid, ir_out, use_saturated); } -} - - -/** - * \param image An \ref image structure - * \param max_n_peaks The maximum number of peaks to be searched for - * \param threshold The image threshold value, in detector units - * \param min_snr The minimum signal to noise ratio for a peak - * \param min_pix_count The minimum number of pixels in a peak - * \param max_pix_count The maximum number of pixels in a peak - * \param local_bg_radius The averaging radius for background calculation - * \param min_res The minimum number of pixels out from the center - * \param max_res The maximum number of pixels out from the center - * \param use_saturated Whether saturated peaks should be considered - * - * Runs the peakfinder8 peak search algorithm. This is a thin wrapper which - * creates an empty \ref ImageFeatureList for \p image, then calls - * the actual \ref peakfinder8 function, found in \ref peakfinder8.h. - */ -int search_peaks_peakfinder8(struct image *image, int max_n_peaks, - float threshold, float min_snr, - int min_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, void *private_data) -{ - if ( image->features != NULL ) { - image_feature_list_free(image->features); - } - image->features = image_feature_list_new(); - return peakfinder8(image, max_n_peaks, threshold, min_snr, - min_pix_count, max_pix_count, - local_bg_radius, min_res, - max_res, use_saturated, - fast_mode, private_data); + return peaklist; } #ifdef HAVE_FDIP -int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, - float min_snr_peak_pix, float min_snr_whole_peak, - float min_sig, float min_peak_over_neighbour, - int window_radius) +ImageFeatureList *search_peaks_peakfinder9(const struct image *image, + float min_snr_biggest_pix, + float min_snr_peak_pix, + float min_snr_whole_peak, + float min_sig, + float min_peak_over_neighbour, + int window_radius) { peakFinder9_accuracyConstants_t accuracy_consts; peakList_t peakList; @@ -492,11 +460,7 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, float *data_copy = NULL; float *data_copy_new; int panel_number; - - if ( image->features != NULL ) { - image_feature_list_free(image->features); - } - image->features = image_feature_list_new(); + ImageFeatureList *peaks; accuracy_consts.minSNR_biggestPixel = min_snr_biggest_pix; accuracy_consts.minSNR_peakPixel = min_snr_peak_pix; @@ -505,7 +469,9 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, accuracy_consts.minimumPeakOversizeOverNeighbours = min_peak_over_neighbour; accuracy_consts.windowRadius = window_radius; - if ( allocatePeakList(&peakList, NpeaksMax) ) return 1; + if ( allocatePeakList(&peakList, NpeaksMax) ) return NULL; + + peaks = image_feature_list_new(); for ( panel_number=0; panel_number<image->detgeom->n_panels; panel_number++ ) { @@ -524,13 +490,13 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, det_size_one_panel.pix_ny = h; det_size_one_panel.pix_nn = w * h; - data_copy_new = realloc(data_copy, w*h*sizeof(*data_copy)); + data_copy_new = cfrealloc(data_copy, w*h*sizeof(*data_copy)); if ( data_copy_new == NULL ) { if ( data_copy != NULL ) { - free(data_copy); + cffree(data_copy); } freePeakList(peakList); - return 1; + return NULL; } else { data_copy = data_copy_new; } @@ -544,10 +510,10 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, &det_size_one_panel, &peakList); for ( peak_number=0; peak_number<peakList.peakCount; peak_number++) { - image_add_feature(image->features, + image_add_feature(peaks, peakList.centerOfMass_rawX[peak_number], peakList.centerOfMass_rawY[peak_number], - panel_number, image, + panel_number, peakList.totalIntensity[peak_number], NULL); } @@ -555,19 +521,22 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, } freePeakList(peakList); - free(data_copy); - return 0; + cffree(data_copy); + return peaks; } #else -int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, - float min_snr_peak_pix, float min_snr_whole_peak, - float min_sig, float min_peak_over_neighbour, - int window_radius) +ImageFeatureList *search_peaks_peakfinder9(const struct image *image, + float min_snr_biggest_pix, + float min_snr_peak_pix, + float min_snr_whole_peak, + float min_sig, + float min_peak_over_neighbour, + int window_radius) { ERROR("This copy of CrystFEL was compiled without peakfinder9 support.\n"); - return 1; + return NULL; } #endif // HAVE_FDIP @@ -575,17 +544,20 @@ int search_peaks_peakfinder9(struct image *image, float min_snr_biggest_pix, /** * \param image An \ref image structure + * \param peaks An \ref ImageFeatureList * \param crystals Pointer to array of pointers to crystals * \param n_cryst The number of crystals * \param multi_mode Whether the thresholds should be set for multi-lattice indexing * - * Checks whether the peaks in \p image appear to be explained by the crystals + * Checks whether the peaks in \p peaks appear to be explained by the crystals * provided. * * Returns 1 if the peaks appear to be well-explained by the crystals. * Otherwise, if the indexing solutions appear to be "bad", returns 0. */ -int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, +int indexing_peak_check(const struct image *image, + ImageFeatureList *peaks, + Crystal **crystals, int n_cryst, int multi_mode) { int n_feat = 0; @@ -593,7 +565,7 @@ int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, int i; const double min_dist = 0.25; - for ( i=0; i<image_feature_count(image->features); i++ ) { + for ( i=0; i<image_feature_count(peaks); i++ ) { struct imagefeature *f; double q[3]; @@ -601,7 +573,7 @@ int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, int ok = 0; /* Assume all image "features" are genuine peaks */ - f = image_get_feature(image->features, i); + f = image_get_feature(peaks, i); if ( f == NULL ) continue; n_feat++; @@ -664,27 +636,21 @@ int indexing_peak_check(struct image *image, Crystal **crystals, int n_cryst, } -/** - * Deprecated: use indexing_peak_check instead - */ -int peak_sanity_check(struct image *image, Crystal **crystals, int n_cryst) -{ - return indexing_peak_check(image, crystals, n_cryst, 1); -} - - -void validate_peaks(struct image *image, double min_snr, - int ir_inn, int ir_mid, int ir_out, int use_saturated, - int check_snr) +ImageFeatureList *validate_peaks(const struct image *image, ImageFeatureList *peaks, + double min_snr, + int ir_inn, int ir_mid, int ir_out, int use_saturated, + int check_snr) { int i, n; ImageFeatureList *flist; int n_wtf, n_int, n_snr, n_sat; + if ( peaks == NULL ) return NULL; + flist = image_feature_list_new(); - if ( flist == NULL ) return; + if ( flist == NULL ) return NULL; - n = image_feature_count(image->features); + n = image_feature_count(peaks); /* Loop over peaks, putting each one through the integrator */ n_wtf = 0; n_int = 0; n_snr = 0; n_sat = 0; @@ -696,7 +662,7 @@ void validate_peaks(struct image *image, double min_snr, double intensity, sigma; int saturated; - f = image_get_feature(image->features, i); + f = image_get_feature(peaks, i); if ( f == NULL ) { n_wtf++; continue; @@ -723,16 +689,14 @@ void validate_peaks(struct image *image, double min_snr, } /* Add using "better" coordinates */ - image_add_feature(flist, f->fs, f->ss, f->pn, image, - intensity, NULL); + image_add_feature(flist, f->fs, f->ss, f->pn, intensity, NULL); } //STATUS("HDF5: %i peaks, validated: %i. WTF: %i, integration: %i, " // "SNR: %i, saturated: %i\n", // n, image_feature_count(flist), n_wtf, n_int, n_snr, n_sat); - image_feature_list_free(image->features); - image->features = flist; + return flist; } @@ -748,7 +712,7 @@ double estimate_peak_resolution(ImageFeatureList *peaks, double lambda, /* No peaks -> no resolution! */ if ( npk == 0 ) return 0.0; - rns = malloc(npk*sizeof(double)); + rns = cfmalloc(npk*sizeof(double)); if ( rns == NULL ) return -1.0; /* Get resolution values for all peaks */ @@ -772,7 +736,7 @@ double estimate_peak_resolution(ImageFeatureList *peaks, double lambda, if ( ncut < 2 ) ncut = 0; max_res = rns[(npk-1)-ncut]; - free(rns); + cffree(rns); return max_res; } diff --git a/libcrystfel/src/peaks.h b/libcrystfel/src/peaks.h index 89634269..5a20574d 100644 --- a/libcrystfel/src/peaks.h +++ b/libcrystfel/src/peaks.h @@ -97,33 +97,26 @@ extern enum peak_search_method parse_peaksearch(const char *arg); extern int *make_BgMask(struct image *image, struct detgeom_panel *p, int pn, double ir_inn); -extern void search_peaks(struct image *image, float threshold, - float min_gradient, float min_snr, double ir_inn, - double ir_mid, double ir_out, int use_saturated); - -extern int search_peaks_peakfinder8(struct image *image, int max_n_peaks, - float threshold, float min_snr, - int mix_pix_count, int max_pix_count, - int local_bg_radius, int min_res, - int max_res, int use_saturated, - int fast_mode, void *private_data); - -extern int search_peaks_peakfinder9(struct image *image, - float min_snr_biggest_pix, - float min_snr_peak_pix, - float min_snr_whole_peak, float min_sig, - float min_peak_over_neighbour, - int window_radius); - -extern int indexing_peak_check(struct image *image, Crystal **crystals, +extern ImageFeatureList *search_peaks(const struct image *image, float threshold, + float min_gradient, float min_snr, double ir_inn, + double ir_mid, double ir_out, int use_saturated); + +extern ImageFeatureList *search_peaks_peakfinder9(const struct image *image, + float min_snr_biggest_pix, + float min_snr_peak_pix, + float min_snr_whole_peak, float min_sig, + float min_peak_over_neighbour, + int window_radius); + +extern int indexing_peak_check(const struct image *image, ImageFeatureList *peaks, + Crystal **crystals, int n_cryst, int multi_mode); -extern int peak_sanity_check(struct image *image, Crystal **crystals, - int n_cryst); - -extern void validate_peaks(struct image *image, double min_snr, - int ir_inn, int ir_mid, int ir_out, - int use_saturated, int check_snr); +extern ImageFeatureList *validate_peaks(const struct image *image, + ImageFeatureList *peaks, + double min_snr, + int ir_inn, int ir_mid, int ir_out, + int use_saturated, int check_snr); extern double estimate_peak_resolution(ImageFeatureList *peaks, double lambda, diff --git a/libcrystfel/src/predict-refine.c b/libcrystfel/src/predict-refine.c index d5a3b403..6da0d3d1 100644 --- a/libcrystfel/src/predict-refine.c +++ b/libcrystfel/src/predict-refine.c @@ -46,7 +46,7 @@ /** \file predict-refine.h */ /* Weighting of excitation error term (m^-1) compared to position term (pixels) */ -#define EXC_WEIGHT (0.5e-7) +#define EXC_WEIGHT (1.0e-7) double r_dev(struct reflpeak *rp) @@ -488,8 +488,7 @@ static int pair_peaks(struct image *image, Crystal *cr, /* Get the excitation errors and detector positions for the candidate * reflections */ - crystal_set_reflections(cr, all_reflist); - update_predictions(cr); + update_predictions(all_reflist, cr, image); /* Pass over the peaks again, keeping only the ones which look like * good pairings */ @@ -529,7 +528,6 @@ static int pair_peaks(struct image *image, Crystal *cr, } reflist_free(all_reflist); - crystal_set_reflections(cr, NULL); /* Sort the pairings by excitation error and look for a transition * between good pairings and outliers */ @@ -558,20 +556,18 @@ int refine_radius(Crystal *cr, struct image *image) RefList *reflist; /* Maximum possible size */ - rps = malloc(image_feature_count(image->features) - * sizeof(struct reflpeak)); + rps = cfmalloc(image_feature_count(image->features) + * sizeof(struct reflpeak)); if ( rps == NULL ) return 1; reflist = reflist_new(); n_acc = pair_peaks(image, cr, reflist, rps); if ( n_acc < 3 ) { - free(rps); + cffree(rps); reflist_free(reflist); return 1; } - crystal_set_reflections(cr, reflist); - update_predictions(cr); - crystal_set_reflections(cr, NULL); + update_predictions(reflist, cr, image); qsort(rps, n_acc, sizeof(struct reflpeak), cmpd2); n = (n_acc-1) - n_acc/50; @@ -579,7 +575,7 @@ int refine_radius(Crystal *cr, struct image *image) crystal_set_profile_radius(cr, fabs(get_exerr(rps[n].refl))); reflist_free(reflist); - free(rps); + cffree(rps); return 0; } @@ -784,7 +780,7 @@ static double pred_residual(struct reflpeak *rps, int n, struct detgeom *det, /* NB Only for use when the list of reflpeaks was created without a RefList. - * If a RefList was used, then reflist_free the list then just free() the rps */ + * If a RefList was used, then reflist_free the list then just cffree() the rps */ static void free_rps_noreflist(struct reflpeak *rps, int n) { int i; @@ -792,7 +788,7 @@ static void free_rps_noreflist(struct reflpeak *rps, int n) for ( i=0; i<n; i++ ) { reflection_free(rps[i].refl); } - free(rps); + cffree(rps); } @@ -809,18 +805,17 @@ int refine_prediction(struct image *image, Crystal *cr, double total_shifts[12]; double res_r, res_fs, res_ss, res_overall; - rps = malloc(image_feature_count(image->features) - * sizeof(struct reflpeak)); + rps = cfmalloc(image_feature_count(image->features) + * sizeof(struct reflpeak)); if ( rps == NULL ) return 1; reflist = reflist_new(); n = pair_peaks(image, cr, reflist, rps); if ( n < 10 ) { - free(rps); + cffree(rps); reflist_free(reflist); return 1; } - crystal_set_reflections(cr, reflist); Minvs = make_panel_minvs(image->detgeom); @@ -832,8 +827,7 @@ int refine_prediction(struct image *image, Crystal *cr, } if ( max_I <= 0.0 ) { ERROR("All peaks negative?\n"); - free(rps); - crystal_set_reflections(cr, NULL); + cffree(rps); return 1; } for ( i=0; i<n; i++ ) { @@ -855,10 +849,9 @@ int refine_prediction(struct image *image, Crystal *cr, /* Refine (max 5 cycles) */ for ( i=0; i<5; i++ ) { - update_predictions(cr); + update_predictions(reflist, cr, image); if ( iterate(rps, n, crystal_get_cell(cr), image, Minvs, total_shifts) ) { - crystal_set_reflections(cr, NULL); return 1; } @@ -888,9 +881,8 @@ int refine_prediction(struct image *image, Crystal *cr, for ( i=0; i<image->detgeom->n_panels; i++ ) { gsl_matrix_free(Minvs[i]); } - free(Minvs); + cffree(Minvs); - crystal_set_reflections(cr, NULL); reflist_free(reflist); n = pair_peaks(image, cr, NULL, rps); diff --git a/libcrystfel/src/profile.c b/libcrystfel/src/profile.c index ac76b8fa..5ca18f17 100644 --- a/libcrystfel/src/profile.c +++ b/libcrystfel/src/profile.c @@ -36,6 +36,7 @@ #include <unistd.h> #include "profile.h" +#include "utils.h" #ifndef CLOCK_MONOTONIC_RAW #define CLOCK_MONOTONIC_RAW (CLOCK_MONOTONIC) @@ -70,12 +71,12 @@ static struct _profile_block *start_profile_block(const char *name) { struct _profile_block *b; - b = malloc(sizeof(struct _profile_block)); + b = cfmalloc(sizeof(struct _profile_block)); if ( b == NULL ) return NULL; - b->name = strdup(name); + b->name = cfstrdup(name); if ( b->name == NULL ) { - free(b); + cffree(b); return NULL; } b->n_children = 0; @@ -116,7 +117,7 @@ void profile_init() } if ( pd == NULL ) { - pd = malloc(sizeof(struct _profiledata)); + pd = cfmalloc(sizeof(struct _profiledata)); if ( pd == NULL ) return; } @@ -137,7 +138,7 @@ static char *format_profile_block(struct _profile_block *b) char **subbufs; char *full_buf; - subbufs = malloc(b->n_children * sizeof(char *)); + subbufs = cfmalloc(b->n_children * sizeof(char *)); if ( subbufs == NULL ) return NULL; total_len = 32 + strlen(b->name); @@ -147,16 +148,16 @@ static char *format_profile_block(struct _profile_block *b) total_len += 1 + strlen(subbufs[i]); } - full_buf = malloc(total_len); + full_buf = cfmalloc(total_len); snprintf(full_buf, 32, "(%s %.3f", b->name, b->total_time); for ( i=0; i<b->n_children; i++ ) { strcat(full_buf, " "); strcat(full_buf, subbufs[i]); - free(subbufs[i]); + cffree(subbufs[i]); } strcat(full_buf, ")"); - free(subbufs); + cffree(subbufs); return full_buf; } @@ -168,9 +169,9 @@ static void free_profile_block(struct _profile_block *b) for ( i=0; i<b->n_children; i++ ) { free_profile_block(b->children[i]); } - free(b->children); - free(b->name); - free(b); + cffree(b->children); + cffree(b->name); + cffree(b); } @@ -195,12 +196,12 @@ void profile_print_and_reset(int worker_id) stop_profile_block(pd->root); buf = format_profile_block(pd->root); - buf2 = malloc(8+strlen(buf)); + buf2 = cfmalloc(8+strlen(buf)); size_t len = 8+strlen(buf); snprintf(buf2, len, "%i %s\n", worker_id, buf); write(STDOUT_FILENO, buf2, strlen(buf2)); - free(buf); - free(buf2); + cffree(buf); + cffree(buf2); free_profile_block(pd->root); pd->root = start_profile_block("root"); @@ -218,7 +219,7 @@ void profile_start(const char *name) if ( pd->current->n_children >= pd->current->max_children ) { struct _profile_block **nblock; int nmax = pd->current->n_children + 64; - nblock = realloc(pd->current->children, nmax*sizeof(struct _profile_block *)); + nblock = cfrealloc(pd->current->children, nmax*sizeof(struct _profile_block *)); if ( nblock == NULL ) { fprintf(stderr, "Failed to allocate profiling record. " "Try again without --profile.\n"); diff --git a/libcrystfel/src/rational.c b/libcrystfel/src/rational.c index 800decf5..88294745 100644 --- a/libcrystfel/src/rational.c +++ b/libcrystfel/src/rational.c @@ -198,7 +198,7 @@ Rational rtnl_abs(Rational a) */ char *rtnl_format(Rational rt) { - char *v = malloc(32); + char *v = cfmalloc(32); if ( v == NULL ) return NULL; if ( rt.den == 1 ) { snprintf(v, 31, "%lli", rt.num); @@ -217,7 +217,7 @@ Rational *rtnl_list(signed int num_min, signed int num_max, Rational *list; int n = 0; - list = malloc((1+num_max-num_min)*(1+den_max-den_min)*sizeof(Rational)); + list = cfmalloc((1+num_max-num_min)*(1+den_max-den_min)*sizeof(Rational)); if ( list == NULL ) return NULL; for ( num=num_min; num<=num_max; num++ ) { @@ -263,12 +263,12 @@ RationalMatrix *rtnl_mtx_new(unsigned int rows, unsigned int cols) RationalMatrix *m; int i; - m = malloc(sizeof(RationalMatrix)); + m = cfmalloc(sizeof(RationalMatrix)); if ( m == NULL ) return NULL; - m->v = calloc(rows*cols, sizeof(Rational)); + m->v = cfcalloc(rows*cols, sizeof(Rational)); if ( m->v == NULL ) { - free(m); + cffree(m); return NULL; } @@ -372,8 +372,8 @@ IntegerMatrix *intmat_from_rtnl_mtx(const RationalMatrix *m) void rtnl_mtx_free(RationalMatrix *mtx) { if ( mtx == NULL ) return; - free(mtx->v); - free(mtx); + cffree(mtx->v); + cffree(mtx); } @@ -412,7 +412,7 @@ int transform_fractional_coords_rtnl(const RationalMatrix *P, cm = rtnl_mtx_copy(P); if ( cm == NULL ) return 1; - vec = malloc(cm->rows*sizeof(Rational)); + vec = cfmalloc(cm->rows*sizeof(Rational)); if ( vec == NULL ) return 1; for ( h=0; h<cm->rows; h++ ) vec[h] = ivec[h]; @@ -489,7 +489,7 @@ int transform_fractional_coords_rtnl(const RationalMatrix *P, ans[i] = rtnl_div(sum, rtnl_mtx_get(cm, i, i)); } - free(vec); + cffree(vec); rtnl_mtx_free(cm); return 0; @@ -517,7 +517,7 @@ void rtnl_mtx_print(const RationalMatrix *m) for ( j=0; j<m->cols; j++ ) { char *v = rtnl_format(rtnl_mtx_get(m, i, j)); fprintf(stderr, "%4s ", v); - free(v); + cffree(v); } fprintf(stderr, "]\n"); } diff --git a/libcrystfel/src/reflist-utils.c b/libcrystfel/src/reflist-utils.c index 66a4996c..14e99d01 100644 --- a/libcrystfel/src/reflist-utils.c +++ b/libcrystfel/src/reflist-utils.c @@ -399,7 +399,7 @@ static RefList *read_reflections_from_file(FILE *fh, char **sym) if ( strncmp(line, "Symmetry: ", 10) != 0 ) return NULL; if ( sym != NULL ) { - *sym = strdup(line+10); + *sym = cfstrdup(line+10); } /* Read (and ignore) the header */ @@ -780,9 +780,9 @@ void free_contribs(RefList *list) { struct reflection_contributions *c; c = get_contributions(refl); - free(c->contribs); - free(c->contrib_crystals); - free(c); + cffree(c->contribs); + cffree(c->contrib_crystals); + cffree(c); } } @@ -793,13 +793,13 @@ static char *full_command_line(int argc, char *argv[]) size_t len = 1; char *cl; - if ( argc == 0 ) return strdup(""); + if ( argc == 0 ) return cfstrdup(""); for ( i=0; i<argc; i++ ) { len += strlen(argv[i]) + 1; } - cl = malloc(len); - if ( cl == NULL ) return strdup(""); + cl = cfmalloc(len); + if ( cl == NULL ) return cfstrdup(""); cl[0] = '\0'; for ( i=0; i<argc; i++ ) { @@ -822,7 +822,7 @@ void reflist_add_command_and_version(RefList *list, int argc, char *argv[]) tmp = full_command_line(argc, argv); reflist_add_notes(list, tmp); - free(tmp); + cffree(tmp); } diff --git a/libcrystfel/src/reflist.c b/libcrystfel/src/reflist.c index 71eda6b2..7a66bf9f 100644 --- a/libcrystfel/src/reflist.c +++ b/libcrystfel/src/reflist.c @@ -125,7 +125,7 @@ static Reflection *new_node(unsigned int serial) { Reflection *new; - new = calloc(1, sizeof(struct _reflection)); + new = cfcalloc(1, sizeof(struct _reflection)); if ( new == NULL ) return NULL; new->in_list = 0; new->serial = serial; @@ -149,7 +149,7 @@ RefList *reflist_new() { RefList *new; - new = malloc(sizeof(struct _reflist)); + new = cfmalloc(sizeof(struct _reflist)); if ( new == NULL ) return NULL; new->head = NULL; @@ -184,7 +184,7 @@ Reflection *reflection_new(signed int h, signed int k, signed int l) void reflection_free(Reflection *refl) { pthread_mutex_destroy(&refl->lock); - free(refl); + cffree(refl); } @@ -212,8 +212,8 @@ void reflist_free(RefList *list) if ( list->head != NULL ) { recursive_free(list->head); } /* else empty list */ - if ( list->notes != NULL ) free(list->notes); - free(list); + if ( list->notes != NULL ) cffree(list->notes); + cffree(list); } @@ -994,9 +994,9 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) Reflection *refl; RefListIterator *iter; - iter = malloc(sizeof(struct _reflistiterator)); + iter = cfmalloc(sizeof(struct _reflistiterator)); iter->stack_size = 32; - iter->stack = malloc(iter->stack_size*sizeof(Reflection *)); + iter->stack = cfmalloc(iter->stack_size*sizeof(Reflection *)); iter->stack_ptr = 0; iter->is_const = 0; *piter = iter; @@ -1011,7 +1011,7 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) iter->stack[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack = realloc(iter->stack, + iter->stack = cfrealloc(iter->stack, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1019,8 +1019,8 @@ Reflection *first_refl(RefList *list, RefListIterator **piter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack); - free(iter); + cffree(iter->stack); + cffree(iter); return NULL; } @@ -1047,9 +1047,9 @@ const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) const Reflection *refl; RefListIterator *iter; - iter = malloc(sizeof(struct _reflistiterator)); + iter = cfmalloc(sizeof(struct _reflistiterator)); iter->stack_size = 32; - iter->stack_const = malloc(iter->stack_size*sizeof(Reflection *)); + iter->stack_const = cfmalloc(iter->stack_size*sizeof(Reflection *)); iter->stack_ptr = 0; iter->is_const = 1; *piter = iter; @@ -1064,7 +1064,7 @@ const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) iter->stack_const[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack_const = realloc(iter->stack_const, + iter->stack_const = cfrealloc(iter->stack_const, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1072,8 +1072,8 @@ const Reflection *first_refl_const(const RefList *list, RefListIterator **piter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack_const); - free(iter); + cffree(iter->stack_const); + cffree(iter); return NULL; } @@ -1119,7 +1119,7 @@ Reflection *next_refl(Reflection *refl, RefListIterator *iter) iter->stack[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack = realloc(iter->stack, + iter->stack = cfrealloc(iter->stack, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1127,8 +1127,8 @@ Reflection *next_refl(Reflection *refl, RefListIterator *iter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack); - free(iter); + cffree(iter->stack); + cffree(iter); return NULL; } @@ -1172,7 +1172,7 @@ const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) iter->stack_const[iter->stack_ptr++] = refl; if ( iter->stack_ptr == iter->stack_size ) { iter->stack_size += 32; - iter->stack_const = realloc(iter->stack_const, + iter->stack_const = cfrealloc(iter->stack_const, iter->stack_size*sizeof(Reflection *)); } refl = refl->child[0]; @@ -1180,8 +1180,7 @@ const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) } if ( iter->stack_ptr == 0 ) { - free(iter->stack_const); - free(iter); + free_reflistiterator(iter); return NULL; } @@ -1190,6 +1189,20 @@ const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter) } while ( 1 ); } + +void free_reflistiterator(RefListIterator *iter) +{ + if ( iter != NULL ) { + if ( iter->is_const ) { + cffree(iter->stack_const); + } else { + cffree(iter->stack); + } + cffree(iter); + } +} + + /*********************************** Voodoo ***********************************/ static int recursive_depth(Reflection *refl) @@ -1277,8 +1290,8 @@ void unlock_reflection(Reflection *refl) static void reflist_set_notes(RefList *reflist, const char *notes) { - free(reflist->notes); /* free(NULL) is OK */ - reflist->notes = strdup(notes); + cffree(reflist->notes); /* free(NULL) is OK */ + reflist->notes = cfstrdup(notes); } @@ -1315,7 +1328,7 @@ void reflist_add_notes(RefList *reflist, const char *notes_add) } len = strlen(notes_add) + strlen(reflist->notes) + 2; - nnotes = malloc(len); + nnotes = cfmalloc(len); if ( nnotes == NULL ) { ERROR("Failed to add notes to crystal.\n"); return; @@ -1324,6 +1337,6 @@ void reflist_add_notes(RefList *reflist, const char *notes_add) strcpy(nnotes, reflist->notes); strcat(nnotes, "\n"); strcat(nnotes, notes_add); - free(reflist->notes); + cffree(reflist->notes); reflist->notes = nnotes; } diff --git a/libcrystfel/src/reflist.h b/libcrystfel/src/reflist.h index 864e871d..5bba2e80 100644 --- a/libcrystfel/src/reflist.h +++ b/libcrystfel/src/reflist.h @@ -158,6 +158,7 @@ extern void add_refl_to_list(Reflection *refl, RefList *list); /* Iteration */ extern Reflection *first_refl(RefList *list, RefListIterator **piter); extern Reflection *next_refl(Reflection *refl, RefListIterator *iter); +extern void free_reflistiterator(RefListIterator *iter); extern const Reflection *first_refl_const(const RefList *list, RefListIterator **piter); extern const Reflection *next_refl_const(const Reflection *refl, RefListIterator *iter); diff --git a/libcrystfel/src/spectrum.c b/libcrystfel/src/spectrum.c index 5f126cf0..58b822f8 100644 --- a/libcrystfel/src/spectrum.c +++ b/libcrystfel/src/spectrum.c @@ -71,7 +71,7 @@ Spectrum *spectrum_new() { Spectrum *s; - s = malloc(sizeof(Spectrum)); + s = cfmalloc(sizeof(Spectrum)); if ( s == NULL ) return NULL; s->rep = SPEC_GAUSSIANS; @@ -95,10 +95,10 @@ Spectrum *spectrum_new() void spectrum_free(Spectrum *s) { if ( s == NULL ) return; - free(s->gaussians); - free(s->k); - free(s->pdf); - free(s); + cffree(s->gaussians); + cffree(s->k); + cffree(s->pdf); + cffree(s); } @@ -292,11 +292,11 @@ static void normalise_gaussians(struct gaussian *gauss, int n_gauss) void spectrum_set_gaussians(Spectrum *s, struct gaussian *gs, int n_gauss) { /* Free old contents (if any - may be NULL) */ - free(s->gaussians); - free(s->k); - free(s->pdf); + cffree(s->gaussians); + cffree(s->k); + cffree(s->pdf); - s->gaussians = malloc(n_gauss * sizeof(struct gaussian)); + s->gaussians = cfmalloc(n_gauss * sizeof(struct gaussian)); if ( s->gaussians == NULL ) return; memcpy(s->gaussians, gs, n_gauss*sizeof(struct gaussian)); @@ -348,17 +348,17 @@ void spectrum_set_pdf(Spectrum *s, double *kvals, double *heights, int n) int i; /* Free old contents (if any - may be NULL) */ - free(s->gaussians); - free(s->k); - free(s->pdf); + cffree(s->gaussians); + cffree(s->k); + cffree(s->pdf); - s->k = malloc(n * sizeof(double)); + s->k = cfmalloc(n * sizeof(double)); if ( s->k == NULL ) return; - s->pdf = malloc(n * sizeof(double)); + s->pdf = cfmalloc(n * sizeof(double)); if ( s->pdf == NULL ) return; - perm = malloc(n * sizeof(size_t)); + perm = cfmalloc(n * sizeof(size_t)); if ( perm == NULL ) return; gsl_sort_index(perm, kvals, 1, n); @@ -367,7 +367,7 @@ void spectrum_set_pdf(Spectrum *s, double *kvals, double *heights, int n) s->k[i] = kvals[perm[i]]; s->pdf[i] = heights[perm[i]]; } - free(perm); + cffree(perm); s->n_samples = n; s->rep = SPEC_HISTOGRAM; @@ -393,8 +393,8 @@ static int read_esrf_spectrum(FILE *fh, Spectrum *s) k = srealloc(k, max_bins*sizeof(double)); samp = srealloc(samp, max_bins*sizeof(double)); if ( (k==NULL) || (samp==NULL) ) { - free(k); - free(samp); + cffree(k); + cffree(samp); return 1; } } @@ -406,8 +406,8 @@ static int read_esrf_spectrum(FILE *fh, Spectrum *s) } spectrum_set_pdf(s, k, samp, n_bins); - free(k); - free(samp); + cffree(k); + cffree(samp); return 0; } diff --git a/libcrystfel/src/stream.c b/libcrystfel/src/stream.c index e767b59f..f1f2173c 100644 --- a/libcrystfel/src/stream.c +++ b/libcrystfel/src/stream.c @@ -148,8 +148,7 @@ static ImageFeatureList *read_peaks(Stream *st, struct image *image) ERROR("Failed to convert peak coords\n"); } else { image_add_feature(features, x, y, - pn, image, intensity, - NULL); + pn, intensity, NULL); } } @@ -200,7 +199,7 @@ static int write_peaks(const struct image *image, } -static RefList *read_stream_reflections_2_3(Stream *st) +static RefList *read_stream_reflections_2_3(Stream *st, double kpred) { char *rval = NULL; int first = 1; @@ -268,6 +267,7 @@ static RefList *read_stream_reflections_2_3(Stream *st) set_mean_bg(refl, bg); set_redundancy(refl, 1); set_symmetric_indices(refl, h, k, l); + set_kpred(refl, kpred); } } while ( rval != NULL ); @@ -339,11 +339,9 @@ static int num_integrated_reflections(RefList *list) } -static int write_crystal(Stream *st, Crystal *cr, - int include_reflections) +static int write_crystal(Stream *st, Crystal *cr, RefList *reflist) { UnitCell *cell; - RefList *reflist; double asx, asy, asz; double bsx, bsy, bsz; double csx, csy, csz; @@ -390,7 +388,6 @@ static int write_crystal(Stream *st, Crystal *cr, fprintf(st->fh, "predict_refine/det_shift x = %.3f y = %.3f mm\n", det_shift_x*1e3, det_shift_y*1e3); - reflist = crystal_get_reflections(cr); if ( reflist != NULL ) { fprintf(st->fh, "diffraction_resolution_limit" @@ -407,20 +404,17 @@ static int write_crystal(Stream *st, Crystal *cr, } - if ( include_reflections ) { - - if ( reflist != NULL ) { + if ( reflist != NULL ) { - fprintf(st->fh, STREAM_REFLECTION_START_MARKER"\n"); - ret = write_stream_reflections(st->fh, reflist, - st->dtempl_write); - fprintf(st->fh, STREAM_REFLECTION_END_MARKER"\n"); + fprintf(st->fh, STREAM_REFLECTION_START_MARKER"\n"); + ret = write_stream_reflections(st->fh, reflist, + st->dtempl_write); + fprintf(st->fh, STREAM_REFLECTION_END_MARKER"\n"); - } else { + } else { - fprintf(st->fh, "No integrated reflections.\n"); + fprintf(st->fh, "No integrated reflections.\n"); - } } fprintf(st->fh, STREAM_CRYSTAL_END_MARKER"\n"); @@ -454,7 +448,7 @@ int stream_write_chunk(Stream *st, const struct image *i, fprintf(st->fh, "hit = %i\n", i->hit); indexer = indexer_str(i->indexed_by); fprintf(st->fh, "indexed_by = %s\n", indexer); - free(indexer); + cffree(indexer); if ( i->indexed_by != INDEXING_NONE ) { fprintf(st->fh, "n_indexing_tries = %i\n", i->n_indexing_tries); } @@ -513,11 +507,11 @@ int stream_write_chunk(Stream *st, const struct image *i, } for ( j=0; j<i->n_crystals; j++ ) { - if ( crystal_get_user_flag(i->crystals[j]) ) { + if ( crystal_get_user_flag(i->crystals[j].cr) ) { continue; } - ret = write_crystal(st, i->crystals[j], - srf & STREAM_REFLECTIONS); + ret = write_crystal(st, i->crystals[j].cr, + srf & STREAM_REFLECTIONS ? i->crystals[j].refls : NULL); } fprintf(st->fh, STREAM_CHUNK_END_MARKER"\n"); @@ -565,8 +559,7 @@ static void read_crystal(Stream *st, struct image *image, char unique_axis = '*'; LatticeType lattice_type = L_TRICLINIC; Crystal *cr; - int n; - Crystal **crystals_new; + RefList *reflist = NULL; double shift_x, shift_y; as.u = 0.0; as.v = 0.0; as.w = 0.0; @@ -665,18 +658,13 @@ static void read_crystal(Stream *st, struct image *image, if ( (strcmp(line, STREAM_REFLECTION_START_MARKER) == 0) && (srf & STREAM_REFLECTIONS) ) { - - RefList *reflist; - reflist = read_stream_reflections_2_3(st); + reflist = read_stream_reflections_2_3(st, 1.0/image->lambda); if ( reflist == NULL ) { ERROR("Failed while reading reflections\n"); ERROR("Filename = %s\n", image->filename); ERROR("Event = %s\n", image->ev); break; } - - crystal_set_reflections(cr, reflist); - } if ( strcmp(line, STREAM_CRYSTAL_END_MARKER) == 0 ) break; @@ -714,17 +702,7 @@ static void read_crystal(Stream *st, struct image *image, /* Unused at the moment */ crystal_set_mosaicity(cr, 0.0); - /* Add crystal to the list for this image */ - n = image->n_crystals+1; - crystals_new = realloc(image->crystals, n*sizeof(Crystal *)); - - if ( crystals_new == NULL ) { - ERROR("Failed to expand crystal list!\n"); - } else { - image->crystals = crystals_new; - image->crystals[image->n_crystals++] = cr; - } - + image_add_crystal_refls(image, cr, reflist); } @@ -734,7 +712,7 @@ static void parse_header(const char *line_in, struct image *image, char *line; char *pos; - line = strdup(line_in); + line = cfstrdup(line_in); chomp(line); pos = strchr(line, ' '); @@ -817,12 +795,12 @@ struct image *stream_read_chunk(Stream *st, StreamFlags srf) chomp(line); if ( strncmp(line, "Image filename: ", 16) == 0 ) { - image->filename = strdup(line+16); + image->filename = cfstrdup(line+16); have_filename = 1; } if ( strncmp(line, "Event: ", 7) == 0 ) { - image->ev = strdup(line+7); + image->ev = cfstrdup(line+7); } if ( strncmp(line, "hdf5/", 5) == 0 ) { @@ -929,7 +907,7 @@ struct image *stream_read_chunk(Stream *st, StreamFlags srf) char *stream_audit_info(Stream *st) { if ( st->audit_info == NULL ) return NULL; - return strdup(st->audit_info); + return cfstrdup(st->audit_info); } @@ -946,7 +924,7 @@ static int read_geometry_file(Stream *st) const size_t max_geom_len = 1024*1024; char *geom; - geom = malloc(max_geom_len); + geom = cfmalloc(max_geom_len); if ( geom == NULL ) { ERROR("Failed to allocate memory for geometry file\n"); return 1; @@ -963,7 +941,7 @@ static int read_geometry_file(Stream *st) if ( rval == NULL ) { ERROR("Failed to read stream geometry file.\n"); stream_close(st); - free(geom); + cffree(geom); return 1; } @@ -976,7 +954,7 @@ static int read_geometry_file(Stream *st) if ( len > max_geom_len-1 ) { ERROR("Stream's geometry file is too long (%li > %i).\n", (long)len, (int)max_geom_len); - free(geom); + cffree(geom); return 1; } else { strcat(geom, line); @@ -995,7 +973,7 @@ static int read_headers(Stream *st) int done = 0; size_t len = 0; - st->audit_info = malloc(4096); + st->audit_info = cfmalloc(4096); if ( st->audit_info == NULL ) { ERROR("Failed to allocate memory for audit information\n"); return 1; @@ -1042,7 +1020,7 @@ Stream *stream_open_for_read(const char *filename) { Stream *st; - st = malloc(sizeof(struct _stream)); + st = cfmalloc(sizeof(struct _stream)); if ( st == NULL ) return NULL; st->old_indexers = 0; st->audit_info = NULL; @@ -1059,7 +1037,7 @@ Stream *stream_open_for_read(const char *filename) } if ( st->fh == NULL ) { - free(st); + cffree(st); return NULL; } @@ -1109,7 +1087,7 @@ Stream *stream_open_fd_for_write(int fd, const DataTemplate *dtempl) { Stream *st; - st = malloc(sizeof(struct _stream)); + st = cfmalloc(sizeof(struct _stream)); if ( st == NULL ) return NULL; st->old_indexers = 0; st->audit_info = NULL; @@ -1121,7 +1099,7 @@ Stream *stream_open_fd_for_write(int fd, const DataTemplate *dtempl) st->fh = fdopen(fd, "w"); if ( st->fh == NULL ) { - free(st); + cffree(st); return NULL; } @@ -1166,7 +1144,7 @@ Stream *stream_open_for_write(const char *filename, { Stream *st; - st = malloc(sizeof(struct _stream)); + st = cfmalloc(sizeof(struct _stream)); if ( st == NULL ) return NULL; st->old_indexers = 0; st->audit_info = NULL; @@ -1179,7 +1157,7 @@ Stream *stream_open_for_write(const char *filename, st->fh = fopen(filename, "w"); if ( st->fh == NULL ) { ERROR("Failed to open stream.\n"); - free(st); + cffree(st); return NULL; } @@ -1210,11 +1188,11 @@ int stream_get_fd(Stream *st) void stream_close(Stream *st) { if ( st == NULL ) return; - free(st->audit_info); - free(st->geometry_file); + cffree(st->audit_info); + cffree(st->geometry_file); data_template_free(st->dtempl_read); fclose(st->fh); - free(st); + cffree(st); } @@ -1339,9 +1317,9 @@ struct _streamindex void stream_index_free(StreamIndex *index) { if ( index == NULL ) return; - free(index->keys); - free(index->ptrs); - free(index); + cffree(index->keys); + cffree(index->ptrs); + cffree(index); } @@ -1352,7 +1330,7 @@ static char *make_key(const char *filename, if ( ev == NULL ) ev = "//"; - key = malloc(strlen(filename)+strlen(ev)+2); + key = cfmalloc(strlen(filename)+strlen(ev)+2); if ( key == NULL ) return NULL; strcpy(key, filename); @@ -1399,14 +1377,14 @@ static void add_index_record(StreamIndex *index, char **new_keys; long int *new_ptrs; - new_keys = realloc(index->keys, - new_max_keys*sizeof(char *)); + new_keys = cfrealloc(index->keys, + new_max_keys*sizeof(char *)); if ( new_keys == NULL ) return; - new_ptrs = realloc(index->ptrs, - new_max_keys*sizeof(long int)); + new_ptrs = cfrealloc(index->ptrs, + new_max_keys*sizeof(long int)); if ( new_ptrs == NULL ) { - free(new_keys); + cffree(new_keys); return; } @@ -1437,7 +1415,7 @@ StreamIndex *stream_make_index(const char *filename) fh = fopen(filename, "r"); if ( fh == NULL ) return NULL; - index = malloc(sizeof(StreamIndex)); + index = cfmalloc(sizeof(StreamIndex)); if ( index == NULL ) { fclose(fh); return NULL; @@ -1468,11 +1446,11 @@ StreamIndex *stream_make_index(const char *filename) } if ( strncmp(line, "Image filename: ", 16) == 0 ) { - last_filename = strdup(line+16); + last_filename = cfstrdup(line+16); } if ( strncmp(line, "Event: ", 7) == 0 ) { - last_ev = strdup(line+7); + last_ev = cfstrdup(line+7); } if ( strcmp(line, STREAM_CHUNK_END_MARKER) == 0 ) { @@ -1484,8 +1462,8 @@ StreamIndex *stream_make_index(const char *filename) last_filename, last_ev); } - free(last_filename); - free(last_ev); + cffree(last_filename); + cffree(last_ev); last_start_pos = 0; last_filename = NULL; last_ev = NULL; diff --git a/libcrystfel/src/symmetry.c b/libcrystfel/src/symmetry.c index 6cda54a2..8afe675d 100644 --- a/libcrystfel/src/symmetry.c +++ b/libcrystfel/src/symmetry.c @@ -66,7 +66,7 @@ struct _symopmask static void alloc_ops(SymOpList *ops) { - ops->ops = realloc(ops->ops, ops->max_ops*sizeof(IntegerMatrix *)); + ops->ops = cfrealloc(ops->ops, ops->max_ops*sizeof(IntegerMatrix *)); } @@ -82,13 +82,13 @@ SymOpMask *new_symopmask(const SymOpList *list) SymOpMask *m; int i; - m = malloc(sizeof(struct _symopmask)); + m = cfmalloc(sizeof(struct _symopmask)); if ( m == NULL ) return NULL; m->list = list; - m->mask = malloc(sizeof(int)*list->n_ops); + m->mask = cfmalloc(sizeof(int)*list->n_ops); if ( m->mask == NULL ) { - free(m); + cffree(m); return NULL; } @@ -104,7 +104,7 @@ SymOpMask *new_symopmask(const SymOpList *list) static SymOpList *new_symoplist() { SymOpList *new; - new = malloc(sizeof(SymOpList)); + new = cfmalloc(sizeof(SymOpList)); if ( new == NULL ) return NULL; new->max_ops = 16; new->n_ops = 0; @@ -129,9 +129,9 @@ void free_symoplist(SymOpList *ops) for ( i=0; i<ops->n_ops; i++ ) { intmat_free(ops->ops[i]); } - if ( ops->ops != NULL ) free(ops->ops); - if ( ops->name != NULL ) free(ops->name); - free(ops); + if ( ops->ops != NULL ) cffree(ops->ops); + if ( ops->name != NULL ) cffree(ops->name); + cffree(ops); } /** @@ -142,8 +142,8 @@ void free_symoplist(SymOpList *ops) void free_symopmask(SymOpMask *m) { if ( m == NULL ) return; - free(m->mask); - free(m); + cffree(m->mask); + cffree(m); } @@ -186,9 +186,9 @@ static void add_symop_v(SymOpList *ops, for ( i=0; i<3; i++ ) intmat_set(m, i, 1, k[i]); for ( i=0; i<3; i++ ) intmat_set(m, i, 2, l[i]); - free(h); - free(k); - free(l); + cffree(h); + cffree(k); + cffree(l); add_symop(ops, m); } @@ -248,7 +248,7 @@ IntegerMatrix *get_symop(const SymOpList *ops, const SymOpMask *m, int idx) static signed int *v(signed int h, signed int k, signed int i, signed int l) { - signed int *vec = malloc(3*sizeof(signed int)); + signed int *vec = cfmalloc(3*sizeof(signed int)); if ( vec == NULL ) return NULL; /* Convert back to 3-index form now */ vec[0] = h-i; vec[1] = k-i; vec[2] = l; @@ -411,7 +411,7 @@ static SymOpList *make_1bar() { SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("-1"); + new->name = cfstrdup("-1"); expand_ops(new); return new; } @@ -420,7 +420,7 @@ static SymOpList *make_1bar() static SymOpList *make_1() { SymOpList *new = new_symoplist(); - new->name = strdup("1"); + new->name = cfstrdup("1"); expand_ops(new); return new; } @@ -433,7 +433,7 @@ static SymOpList *make_2m() SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("2/m"); + new->name = cfstrdup("2/m"); expand_ops(new); return new; } @@ -443,7 +443,7 @@ static SymOpList *make_2() { SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ - new->name = strdup("2"); + new->name = cfstrdup("2"); expand_ops(new); return new; } @@ -453,7 +453,7 @@ static SymOpList *make_m() { SymOpList *new = new_symoplist(); add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("m"); + new->name = cfstrdup("m"); expand_ops(new); return new; } @@ -467,7 +467,7 @@ static SymOpList *make_mmm() add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* m -| k */ - new->name = strdup("mmm"); + new->name = cfstrdup("mmm"); expand_ops(new); return new; } @@ -478,7 +478,7 @@ static SymOpList *make_222() SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ - new->name = strdup("222"); + new->name = cfstrdup("222"); expand_ops(new); return new; } @@ -489,7 +489,7 @@ static SymOpList *make_mm2() SymOpList *new = new_symoplist(); add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* m -| k */ - new->name = strdup("mm2"); + new->name = cfstrdup("mm2"); expand_ops(new); return new; } @@ -502,7 +502,7 @@ static SymOpList *make_4m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("4/m"); + new->name = cfstrdup("4/m"); expand_ops(new); return new; } @@ -512,7 +512,7 @@ static SymOpList *make_4() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ - new->name = strdup("4"); + new->name = cfstrdup("4"); expand_ops(new); return new; } @@ -523,7 +523,7 @@ static SymOpList *make_4mm() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,1)); /* m -| l */ - new->name = strdup("4mm"); + new->name = cfstrdup("4mm"); expand_ops(new); return new; } @@ -534,7 +534,7 @@ static SymOpList *make_422() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ - new->name = strdup("422"); + new->name = cfstrdup("422"); expand_ops(new); return new; } @@ -544,7 +544,7 @@ static SymOpList *make_4bar() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ - new->name = strdup("-4"); + new->name = cfstrdup("-4"); expand_ops(new); return new; } @@ -555,7 +555,7 @@ static SymOpList *make_4bar2m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ - new->name = strdup("-42m"); + new->name = cfstrdup("-42m"); expand_ops(new); return new; } @@ -566,7 +566,7 @@ static SymOpList *make_4barm2() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h+k */ - new->name = strdup("-4m2"); + new->name = cfstrdup("-4m2"); expand_ops(new); return new; } @@ -578,7 +578,7 @@ static SymOpList *make_4mmm() add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,1)); /* m -| k */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("4/mmm"); + new->name = cfstrdup("4/mmm"); expand_ops(new); return new; } @@ -590,7 +590,7 @@ static SymOpList *make_3_R() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* 3 // h+k+l */ - new->name = strdup("3_R"); + new->name = cfstrdup("3_R"); expand_ops(new); return new; } @@ -601,7 +601,7 @@ static SymOpList *make_3bar_R() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* -3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("-3_R"); + new->name = cfstrdup("-3_R"); expand_ops(new); return new; } @@ -612,7 +612,7 @@ static SymOpList *make_32_R() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* 2 -| 3 */ - new->name = strdup("32_R"); + new->name = cfstrdup("32_R"); expand_ops(new); return new; } @@ -623,7 +623,7 @@ static SymOpList *make_3m_R() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m */ - new->name = strdup("3m_R"); + new->name = cfstrdup("3m_R"); expand_ops(new); return new; } @@ -635,7 +635,7 @@ static SymOpList *make_3barm_R() add_symop_v(new, v(0,0,0,1), v(1,0,0,0), v(0,1,0,0)); /* -3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m */ - new->name = strdup("-3m_R"); + new->name = cfstrdup("-3m_R"); expand_ops(new); return new; } @@ -647,7 +647,7 @@ static SymOpList *make_3_H() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ - new->name = strdup("3_H"); + new->name = cfstrdup("3_H"); expand_ops(new); return new; } @@ -658,7 +658,7 @@ static SymOpList *make_3bar_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("-3_H"); + new->name = cfstrdup("-3_H"); expand_ops(new); return new; } @@ -669,7 +669,7 @@ static SymOpList *make_321_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h */ - new->name = strdup("321_H"); + new->name = cfstrdup("321_H"); expand_ops(new); return new; } @@ -680,7 +680,7 @@ static SymOpList *make_312_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* 2 // h+k */ - new->name = strdup("312_H"); + new->name = cfstrdup("312_H"); expand_ops(new); return new; } @@ -691,7 +691,7 @@ static SymOpList *make_3m1_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ - new->name = strdup("3m1_H"); + new->name = cfstrdup("3m1_H"); expand_ops(new); return new; } @@ -702,7 +702,7 @@ static SymOpList *make_31m_H() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m -| (k+i) */ - new->name = strdup("31m_H"); + new->name = cfstrdup("31m_H"); expand_ops(new); return new; } @@ -714,7 +714,7 @@ static SymOpList *make_3barm1_H() add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h */ - new->name = strdup("-3m1_H"); + new->name = cfstrdup("-3m1_H"); expand_ops(new); return new; } @@ -726,7 +726,7 @@ static SymOpList *make_3bar1m_H() add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,1)); /* 3 // l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* 2 // h+k */ - new->name = strdup("-31m_H"); + new->name = cfstrdup("-31m_H"); expand_ops(new); return new; } @@ -738,7 +738,7 @@ static SymOpList *make_6() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ - new->name = strdup("6"); + new->name = cfstrdup("6"); expand_ops(new); return new; } @@ -748,7 +748,7 @@ static SymOpList *make_6bar() { SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ - new->name = strdup("-6"); + new->name = cfstrdup("-6"); expand_ops(new); return new; } @@ -759,7 +759,7 @@ static SymOpList *make_6m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ add_symop_v(new, v(1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* m -| l */ - new->name = strdup("6/m"); + new->name = cfstrdup("6/m"); expand_ops(new); return new; } @@ -770,7 +770,7 @@ static SymOpList *make_622() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,-1)); /* 2 // h */ - new->name = strdup("622"); + new->name = cfstrdup("622"); expand_ops(new); return new; } @@ -781,7 +781,7 @@ static SymOpList *make_6mm() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,-1,0), v(-1,0,0,0), v(0,0,0,1)); /* 6 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ - new->name = strdup("6mm"); + new->name = cfstrdup("6mm"); expand_ops(new); return new; } @@ -792,7 +792,7 @@ static SymOpList *make_6barm2() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ - new->name = strdup("-6m2"); + new->name = cfstrdup("-6m2"); expand_ops(new); return new; } @@ -803,7 +803,7 @@ static SymOpList *make_6bar2m() SymOpList *new = new_symoplist(); add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ add_symop_v(new, v(0,1,0,0), v(1,0,0,0), v(0,0,0,1)); /* m -| (k+i) */ - new->name = strdup("-62m"); + new->name = cfstrdup("-62m"); expand_ops(new); return new; } @@ -815,7 +815,7 @@ static SymOpList *make_6mmm() add_symop_v(new, v(0,0,1,0), v(1,0,0,0), v(0,0,0,-1)); /* -6 // l */ add_symop_v(new, v(0,-1,0,0), v(-1,0,0,0), v(0,0,0,1)); /* m -| i */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("6/mmm"); + new->name = cfstrdup("6/mmm"); expand_ops(new); return new; } @@ -829,7 +829,7 @@ static SymOpList *make_23() add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,1)); /* 2 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ - new->name = strdup("23"); + new->name = cfstrdup("23"); expand_ops(new); return new; } @@ -842,7 +842,7 @@ static SymOpList *make_m3bar() add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("m-3"); + new->name = cfstrdup("m-3"); expand_ops(new); return new; } @@ -854,7 +854,7 @@ static SymOpList *make_432() add_symop_v(new, v(0,-1,0,0), v(1,0,0,0), v(0,0,0,1)); /* 4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1));/* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ - new->name = strdup("432"); + new->name = cfstrdup("432"); expand_ops(new); return new; } @@ -866,7 +866,7 @@ static SymOpList *make_4bar3m() add_symop_v(new, v(0,1,0,0), v(-1,0,0,0), v(0,0,0,-1)); /* -4 // l */ add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1)); /* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ - new->name = strdup("-43m"); + new->name = cfstrdup("-43m"); expand_ops(new); return new; } @@ -879,7 +879,7 @@ static SymOpList *make_m3barm() add_symop_v(new, v(-1,0,0,0), v(0,1,0,0), v(0,0,0,-1));/* 2 // k */ add_symop_v(new, v(0,1,0,0), v(0,0,0,1), v(1,0,0,0)); /* 3 // h+k+l */ add_symop_v(new, v(-1,0,0,0), v(0,-1,0,0), v(0,0,0,-1)); /* -I */ - new->name = strdup("m-3m"); + new->name = cfstrdup("m-3m"); expand_ops(new); return new; } @@ -979,7 +979,7 @@ static SymOpList *getpg_arbitrary_ua(const char *sym, size_t s) return NULL; } - pg_type = strndup(sym, s-1); + pg_type = cfstrndup(sym, s-1); if ( pg_type == NULL ) { ERROR("Couldn't allocate string.\n"); return NULL; @@ -991,7 +991,7 @@ static SymOpList *getpg_arbitrary_ua(const char *sym, size_t s) pg_type); return NULL; } - free(pg_type); + cffree(pg_type); t = intmat_new(3, 3); if ( t == NULL ) return NULL; @@ -1027,14 +1027,14 @@ static SymOpList *getpg_arbitrary_ua(const char *sym, size_t s) transform_ops(pg, t); intmat_free(t); - new_name = malloc(64); + new_name = cfmalloc(64); if ( new_name == NULL ) { ERROR("Couldn't allocate space for PG name\n"); return NULL; } snprintf(new_name, 64, "%s_ua%c", pg->name, ua); - free(pg->name); + cffree(pg->name); pg->name = new_name; return pg; @@ -1115,7 +1115,7 @@ static void do_op(const IntegerMatrix *op, assert(ans != NULL); *he = ans[0]; *ke = ans[1]; *le = ans[2]; - free(ans); + cffree(ans); } @@ -1175,9 +1175,9 @@ void special_position(const SymOpList *ops, SymOpMask *m, assert(m->list == ops); n = num_equivs(ops, NULL); - htest = malloc(n*sizeof(signed int)); - ktest = malloc(n*sizeof(signed int)); - ltest = malloc(n*sizeof(signed int)); + htest = cfmalloc(n*sizeof(signed int)); + ktest = cfmalloc(n*sizeof(signed int)); + ltest = cfmalloc(n*sizeof(signed int)); for ( i=0; i<n; i++ ) { @@ -1202,9 +1202,9 @@ void special_position(const SymOpList *ops, SymOpMask *m, } - free(htest); - free(ktest); - free(ltest); + cffree(htest); + cffree(ktest); + cffree(ltest); } @@ -1609,7 +1609,7 @@ SymOpList *get_ambiguities(const SymOpList *source, const SymOpList *target) free_symoplist(src_reordered); free_symoplist(tgt_reordered); - name = malloc(64); + name = cfmalloc(64); snprintf(name, 63, "%s -> %s", symmetry_name(source), symmetry_name(target)); twins->name = name; @@ -1716,7 +1716,7 @@ char *get_matrix_name(const IntegerMatrix *m, int col) int i; int printed = 0; - text = malloc(max_len+1); + text = cfmalloc(max_len+1); text[0] = '\0'; for ( i=0; i<3; i++ ) { @@ -1755,7 +1755,7 @@ char *get_matrix_name(const IntegerMatrix *m, int col) } -static char *name_equiv(const IntegerMatrix *op) +char *name_equiv(const IntegerMatrix *op) { char *h, *k, *l; char *name; @@ -1763,7 +1763,7 @@ static char *name_equiv(const IntegerMatrix *op) h = get_matrix_name(op, 0); k = get_matrix_name(op, 1); l = get_matrix_name(op, 2); - name = malloc(32); + name = cfmalloc(32); if ( strlen(h)+strlen(k)+strlen(l) == 3 ) { snprintf(name, 31, "%s%s%s", h, k, l); @@ -1794,7 +1794,7 @@ void describe_symmetry(const SymOpList *s) char *name = name_equiv(s->ops[i]); len = strlen(name); if ( len > max_len ) max_len = len; - free(name); + cffree(name); } if ( max_len < 8 ) max_len = 8; @@ -1810,7 +1810,7 @@ void describe_symmetry(const SymOpList *s) for ( j=0; j<m; j++ ) { STATUS(" "); } - free(name); + cffree(name); if ( (i!=0) && (i%8==0) ) STATUS("\n%15s ", ""); } @@ -1839,5 +1839,5 @@ const char *symmetry_name(const SymOpList *ops) */ void set_symmetry_name(SymOpList *ops, const char *name) { - ops->name = strdup(name); + ops->name = cfstrdup(name); } diff --git a/libcrystfel/src/symmetry.h b/libcrystfel/src/symmetry.h index b8780735..ba2c3742 100644 --- a/libcrystfel/src/symmetry.h +++ b/libcrystfel/src/symmetry.h @@ -83,6 +83,7 @@ extern int is_centrosymmetric(const SymOpList *s); extern const char *symmetry_name(const SymOpList *ops); extern void set_symmetry_name(SymOpList *ops, const char *name); extern void describe_symmetry(const SymOpList *s); +extern char *name_equiv(const IntegerMatrix *op); extern int is_centric(signed int h, signed int k, signed int l, const SymOpList *ops); diff --git a/libcrystfel/src/thread-pool.c b/libcrystfel/src/thread-pool.c index 0951fcc6..fb17e7e4 100644 --- a/libcrystfel/src/thread-pool.c +++ b/libcrystfel/src/thread-pool.c @@ -88,11 +88,11 @@ static void *task_worker(void *pargsv) struct task_queue *q = w->tq; int *cookie_slot; - cookie_slot = malloc(sizeof(int)); + cookie_slot = cfmalloc(sizeof(int)); *cookie_slot = w->id; pthread_setspecific(status_label_key, cookie_slot); - free(w); + cffree(w); do { @@ -129,7 +129,7 @@ static void *task_worker(void *pargsv) } while ( 1 ); - free(cookie_slot); + cffree(cookie_slot); return NULL; } @@ -173,7 +173,7 @@ int run_threads(int n_threads, TPWorkFunc work, pthread_key_create(&status_label_key, NULL); - workers = malloc(n_threads * sizeof(pthread_t)); + workers = cfmalloc(n_threads * sizeof(pthread_t)); pthread_mutex_init(&q.lock, NULL); q.work = work; @@ -192,7 +192,7 @@ int run_threads(int n_threads, TPWorkFunc work, struct worker_args *w; - w = malloc(sizeof(struct worker_args)); + w = cfmalloc(sizeof(struct worker_args)); w->tq = &q; w->tqr = NULL; @@ -214,7 +214,7 @@ int run_threads(int n_threads, TPWorkFunc work, use_status_labels = 0; - free(workers); + cffree(workers); return q.n_completed; } diff --git a/libcrystfel/src/utils.c b/libcrystfel/src/utils.c index 44faa7ee..7bfac487 100644 --- a/libcrystfel/src/utils.c +++ b/libcrystfel/src/utils.c @@ -375,6 +375,83 @@ void ERROR(const char *format, ...) } +/* ---------------------------- Memory management --------------------------- */ + +struct _mmconf { + void *(*malloc)(size_t size); + void (*free)(void *ptr); + void *(*calloc)(size_t nmemb, size_t size); + void *(*realloc)(void *ptr, size_t size); +} mm_conf = { malloc, free, calloc, realloc }; + +void *cfmalloc(size_t size) +{ + return mm_conf.malloc(size); +} + +void cffree(void *ptr) +{ + mm_conf.free(ptr); +} + +void *cfcalloc(size_t nmemb, size_t size) +{ + return mm_conf.calloc(nmemb, size); +} + +void *cfrealloc(void *ptr, size_t size) +{ + return mm_conf.realloc(ptr, size); +} + +int set_mm_funcs(void *(*cfmalloc)(size_t size), + void (*cffree)(void *ptr), + void *(*cfcalloc)(size_t nmemb, size_t size), + void *(*cfrealloc)(void *ptr, size_t size)) +{ + mm_conf.malloc = cfmalloc; + mm_conf.free = cffree; + mm_conf.calloc = cfcalloc; + mm_conf.realloc = cfrealloc; + return 0; +} + +char *cfstrdup(const char *s) +{ + size_t l = strlen(s); + char *r = cfmalloc(l+1); + if ( r == NULL ) return NULL; + strcpy(r, s); + return r; +} + +char *cfstrndup(const char *s, size_t n) +{ + char *r = cfmalloc(n+1); + if ( r == NULL ) return NULL; + strncpy(r, s, n); + r[n] = '\0'; + return r; +} + +void *srealloc(void *arr, size_t new_size) +{ + void *new_arr = cfrealloc(arr, new_size); + if ( new_arr == NULL ) { + cffree(arr); + return NULL; + } else { + return new_arr; + } +} + +char *safe_strdup(const char *in) +{ + if ( in == NULL ) return NULL; + return cfstrdup(in); +} + + /* ------------------------------ Useful functions ---------------------------- */ int convert_int(const char *str, int *pval) @@ -555,9 +632,9 @@ static int assplode_extract(char ***pbits, int n, size_t n_captured, size_t start, const char *a) { char **bits = *pbits; - bits = realloc(bits, sizeof(char *)*(n+1)); + bits = cfrealloc(bits, sizeof(char *)*(n+1)); assert(bits != NULL); - bits[n] = malloc(n_captured+1); + bits[n] = cfmalloc(n_captured+1); assert(bits[n] != NULL); memcpy(bits[n], a+start, n_captured); bits[n][n_captured] = '\0'; @@ -572,8 +649,8 @@ static int assplode_extract(char ***pbits, int n, size_t n_captured, * deliminators. * Store each segment in bits[0...n] where n is the number of segments and is * the return value. pbits = &bits - * Each segment needs to be freed with free() when finished with. - * The array of bits also needs to be freed with free() when finished with, + * Each segment needs to be freed with cffree() when finished with. + * The array of bits also needs to be freed with cffree() when finished with, * unless n=0 in which case bits==NULL */ int assplode(const char *a, const char *delims, char ***pbits, @@ -665,27 +742,20 @@ char *check_prefix(char *prefix) " with a slash. I'm going to add it for you.\n", prefix); STATUS("If this isn't what you want, run with --no-check-prefix.\n"); len = strlen(prefix)+2; - new = malloc(len); + new = cfmalloc(len); snprintf(new, len, "%s/", prefix); - free(prefix); + cffree(prefix); return new; } -char *safe_strdup(const char *in) -{ - if ( in == NULL ) return NULL; - return strdup(in); -} - - char *safe_basename(const char *in) { int i; char *cpy; char *res; - cpy = strdup(in); + cpy = cfstrdup(in); /* Get rid of any trailing slashes */ for ( i=strlen(cpy)-1; i>0; i-- ) { @@ -704,10 +774,10 @@ char *safe_basename(const char *in) } } - res = strdup(cpy+i); + res = cfstrdup(cpy+i); /* If we didn't find a previous slash, i==0 so res==cpy */ - free(cpy); + cffree(cpy); return res; } @@ -892,7 +962,7 @@ char *load_entire_file(const char *filename) return NULL; } - contents = malloc(statbuf.st_size+1); + contents = cfmalloc(statbuf.st_size+1); if ( contents == NULL ) { ERROR("Failed to allocate memory for file\n"); return NULL; @@ -901,14 +971,14 @@ char *load_entire_file(const char *filename) fh = fopen(filename, "r"); if ( fh == NULL ) { ERROR("Failed to open file '%s'\n", filename); - free(contents); + cffree(contents); return NULL; } if ( fread(contents, 1, statbuf.st_size, fh) != statbuf.st_size ) { ERROR("Failed to read file '%s'\n", filename); fclose(fh); - free(contents); + cffree(contents); return NULL; } contents[statbuf.st_size] = '\0'; @@ -957,18 +1027,6 @@ int compare_double(const void *av, const void *bv) } -void *srealloc(void *arr, size_t new_size) -{ - void *new_arr = realloc(arr, new_size); - if ( new_arr == NULL ) { - free(arr); - return NULL; - } else { - return new_arr; - } -} - - /* -------------------------- libcrystfel features ------------------------ */ int crystfel_has_peakfinder9() diff --git a/libcrystfel/src/utils.h b/libcrystfel/src/utils.h index cb68069e..30a7c4ef 100644 --- a/libcrystfel/src/utils.h +++ b/libcrystfel/src/utils.h @@ -239,6 +239,20 @@ extern void set_log_message_func(LogMsgFunc new_log_msg_func, void *vp); +/* ---------------------------- Memory management --------------------------- */ + +extern void *cfmalloc(size_t size); +extern void cffree(void *ptr); +extern void *cfcalloc(size_t nmemb, size_t size); +extern void *cfrealloc(void *ptr, size_t size); +extern char *cfstrdup(const char *s); +extern char *cfstrndup(const char *s, size_t n); +extern int set_mm_funcs(void *(*cfmalloc)(size_t size), + void (*cffree)(void *ptr), + void *(*cfcalloc)(size_t nmemb, size_t size), + void *(*cfrealloc)(void *ptr, size_t size)); + + /* ------------------------------ File handling ----------------------------- */ extern char *check_prefix(char *prefix); diff --git a/src/ambigator.c b/src/ambigator.c index 3777cf0a..91e621ac 100644 --- a/src/ambigator.c +++ b/src/ambigator.c @@ -1287,7 +1287,8 @@ int main(int argc, char *argv[]) RefList *list; UnitCell *cell; - cr = image->crystals[i]; + cr = image->crystals[i].cr; + list = image->crystals[i].refls; cell = crystal_get_cell(cr); if ( n_crystals == max_crystals ) { @@ -1308,7 +1309,6 @@ int main(int argc, char *argv[]) } - list = crystal_get_reflections(cr); crystals[n_crystals] = asymm_and_merge(list, s_sym, cell, rmin, rmax, diff --git a/src/cell_explorer.c b/src/cell_explorer.c index 99cb284f..a92de347 100644 --- a/src/cell_explorer.c +++ b/src/cell_explorer.c @@ -2002,9 +2002,7 @@ static int add_stream(CellWindow *w, const char *stream_filename, for ( i=0; i<image->n_crystals; i++ ) { - Crystal *cr; - - cr = image->crystals[i]; + Crystal *cr = image->crystals[i].cr; if ( w->n_cells == max_cells ) { diff --git a/src/crystfelimageview.c b/src/crystfelimageview.c index 03350204..1659ae4f 100644 --- a/src/crystfelimageview.c +++ b/src/crystfelimageview.c @@ -707,9 +707,8 @@ static gint draw_sig(GtkWidget *window, cairo_t *cr, CrystFELImageView *iv) if ( iv->show_refls ) { int i; for ( i=0; i<iv->image->n_crystals; i++ ) { - Crystal *cry = iv->image->crystals[i]; draw_refls(cr, iv, - crystal_get_reflections(cry), + iv->image->crystals[i].refls, iv->label_refls, crystal_cols[i % n_crystal_cols]); } diff --git a/src/gui_index.c b/src/gui_index.c index 2cc8e8db..218331eb 100644 --- a/src/gui_index.c +++ b/src/gui_index.c @@ -636,19 +636,19 @@ static void run_indexing_once(struct crystfelproject *proj) index_pattern(proj->cur_image, ipriv); for ( i=0; i<proj->cur_image->n_crystals; i++ ) { - crystal_set_mosaicity(proj->cur_image->crystals[i], 0.0); + crystal_set_mosaicity(proj->cur_image->crystals[i].cr, 0.0); if ( proj->indexing_params.use_fix_profile_radius ) { /* Manual radius */ - crystal_set_profile_radius(proj->cur_image->crystals[i], + crystal_set_profile_radius(proj->cur_image->crystals[i].cr, proj->indexing_params.fix_profile_radius); } else { /* Auto radius determination */ - crystal_set_profile_radius(proj->cur_image->crystals[i], + crystal_set_profile_radius(proj->cur_image->crystals[i].cr, 0.02e9); - if ( refine_radius(proj->cur_image->crystals[i], + if ( refine_radius(proj->cur_image->crystals[i].cr, proj->cur_image) ) { ERROR("WARNING: Radius determination failed\n"); @@ -682,7 +682,7 @@ static void run_indexing_once(struct crystfelproject *proj) STATUS("Number of crystals: %i\n", proj->cur_image->n_crystals); for ( i=0; i<proj->cur_image->n_crystals; i++ ) { - cell_print(crystal_get_cell(proj->cur_image->crystals[i])); + cell_print(crystal_get_cell(proj->cur_image->crystals[i].cr)); } } diff --git a/src/gui_peaksearch.c b/src/gui_peaksearch.c index 976e08ec..314fd5d4 100644 --- a/src/gui_peaksearch.c +++ b/src/gui_peaksearch.c @@ -41,6 +41,7 @@ #include <datatemplate.h> #include <peaks.h> +#include <peakfinder8.h> #include "crystfelimageview.h" #include "gui_project.h" @@ -60,52 +61,55 @@ void update_peaks(struct crystfelproject *proj) switch ( proj->peak_search_params.method ) { + ImageFeatureList *peaks; + case PEAK_ZAEF: - search_peaks(proj->cur_image, - proj->peak_search_params.threshold, - proj->peak_search_params.min_sq_gradient, - proj->peak_search_params.min_snr, - proj->peak_search_params.pk_inn, - proj->peak_search_params.pk_mid, - proj->peak_search_params.pk_out, - 1); + proj->cur_image->features = search_peaks(proj->cur_image, + proj->peak_search_params.threshold, + proj->peak_search_params.min_sq_gradient, + proj->peak_search_params.min_snr, + proj->peak_search_params.pk_inn, + proj->peak_search_params.pk_mid, + proj->peak_search_params.pk_out, + 1); break; case PEAK_PEAKFINDER8: - search_peaks_peakfinder8(proj->cur_image, 2048, - proj->peak_search_params.threshold, - proj->peak_search_params.min_snr, - proj->peak_search_params.min_pix_count, - proj->peak_search_params.max_pix_count, - proj->peak_search_params.local_bg_radius, - proj->peak_search_params.min_res, - proj->peak_search_params.max_res, - 1, 0, NULL); + proj->cur_image->features = peakfinder8(proj->cur_image, 2048, + proj->peak_search_params.threshold, + proj->peak_search_params.min_snr, + proj->peak_search_params.min_pix_count, + proj->peak_search_params.max_pix_count, + proj->peak_search_params.local_bg_radius, + proj->peak_search_params.min_res, + proj->peak_search_params.max_res, + 1, 0, NULL); break; case PEAK_PEAKFINDER9: - search_peaks_peakfinder9(proj->cur_image, - proj->peak_search_params.min_snr_biggest_pix, - proj->peak_search_params.min_snr_peak_pix, - proj->peak_search_params.min_snr, - proj->peak_search_params.min_sig, - proj->peak_search_params.min_peak_over_neighbour, - proj->peak_search_params.local_bg_radius); + proj->cur_image->features = search_peaks_peakfinder9(proj->cur_image, + proj->peak_search_params.min_snr_biggest_pix, + proj->peak_search_params.min_snr_peak_pix, + proj->peak_search_params.min_snr, + proj->peak_search_params.min_sig, + proj->peak_search_params.min_peak_over_neighbour, + proj->peak_search_params.local_bg_radius); break; case PEAK_HDF5: case PEAK_CXI: - proj->cur_image->features = image_read_peaks(proj->dtempl, - proj->cur_image->filename, - proj->cur_image->ev, - proj->peak_search_params.half_pixel_shift); + peaks = image_read_peaks(proj->dtempl, + proj->cur_image->filename, + proj->cur_image->ev, + proj->peak_search_params.half_pixel_shift); if ( proj->peak_search_params.revalidate ) { - validate_peaks(proj->cur_image, - proj->peak_search_params.min_snr, - proj->peak_search_params.pk_inn, - proj->peak_search_params.pk_mid, - proj->peak_search_params.pk_out, - 1, 0); + proj->cur_image->features = validate_peaks(proj->cur_image, peaks, + proj->peak_search_params.min_snr, + proj->peak_search_params.pk_inn, + proj->peak_search_params.pk_mid, + proj->peak_search_params.pk_out, + 1, 0); + image_feature_list_free(peaks); } break; diff --git a/src/merge.c b/src/merge.c index 0a5c5f14..4a2dae66 100644 --- a/src/merge.c +++ b/src/merge.c @@ -55,7 +55,7 @@ struct merge_queue_args { RefList *full; pthread_rwlock_t full_lock; - Crystal **crystals; + struct crystal_refls *crystals; int n_started; double push_res; int use_weak; @@ -68,6 +68,7 @@ struct merge_worker_args { struct merge_queue_args *qargs; Crystal *crystal; + RefList *refls; int crystal_number; int n_reflections; }; @@ -81,7 +82,9 @@ static void *create_merge_job(void *vqargs) wargs = malloc(sizeof(struct merge_worker_args)); wargs->qargs = qargs; wargs->crystal_number = qargs->n_started; - wargs->crystal = qargs->crystals[qargs->n_started++]; + wargs->crystal = qargs->crystals[qargs->n_started].cr; + wargs->refls = qargs->crystals[qargs->n_started].refls; + qargs->n_started++; return wargs; } @@ -180,7 +183,7 @@ static void run_merge_job(void *vwargs, int cookie) G = crystal_get_osf(cr); B = crystal_get_Bfac(cr); - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(wargs->refls, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -262,8 +265,8 @@ static void finalise_merge_job(void *vqargs, void *vwargs) } -RefList *merge_intensities(Crystal **crystals, int n, int n_threads, - int min_meas, +RefList *merge_intensities(struct crystal_refls *crystals, int n, + int n_threads, int min_meas, double push_res, int use_weak, int ln_merge) { RefList *full; @@ -364,7 +367,7 @@ double correct_reflection(double val, Reflection *refl, double osf, double Bfac, } -double residual(Crystal *cr, const RefList *full, int free, +double residual(RefList *list, Crystal *cr, const RefList *full, int free, int *pn_used, const char *filename) { Reflection *refl; @@ -376,7 +379,7 @@ double residual(Crystal *cr, const RefList *full, int free, double B = crystal_get_Bfac(cr); UnitCell *cell = crystal_get_cell(cr); - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -420,7 +423,8 @@ double residual(Crystal *cr, const RefList *full, int free, } -double log_residual(Crystal *cr, const RefList *full, int free, +double log_residual(RefList *list, Crystal *cr, + const RefList *full, int free, int *pn_used, const char *filename) { double dev = 0.0; @@ -439,7 +443,7 @@ double log_residual(Crystal *cr, const RefList *full, int free, } } - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -487,7 +491,7 @@ double log_residual(Crystal *cr, const RefList *full, int free, /* Has to match run_merge_job to be useful */ -void write_unmerged(const char *fn, Crystal **crystals, int n_crystals) +void write_unmerged(const char *fn, struct crystal_refls *crystals, int n_crystals) { FILE *fh; int i; @@ -506,17 +510,17 @@ void write_unmerged(const char *fn, Crystal **crystals, int n_crystals) UnitCell *cell; fprintf(fh, "Crystal %i\n", i); - if ( crystal_get_user_flag(crystals[i]) ) { + if ( crystal_get_user_flag(crystals[i].cr) ) { fprintf(fh, "Flagged: yes\n"); } else { fprintf(fh, "Flagged: no\n"); } - G = crystal_get_osf(crystals[i]); - B = crystal_get_Bfac(crystals[i]); - cell = crystal_get_cell(crystals[i]); + G = crystal_get_osf(crystals[i].cr); + B = crystal_get_Bfac(crystals[i].cr); + cell = crystal_get_cell(crystals[i].cr); - for ( refl = first_refl(crystal_get_reflections(crystals[i]), &iter); + for ( refl = first_refl(crystals[i].refls, &iter); refl != NULL; refl = next_refl(refl, iter) ) { diff --git a/src/merge.h b/src/merge.h index 5f7e0e64..e304db78 100644 --- a/src/merge.h +++ b/src/merge.h @@ -43,7 +43,7 @@ #define MIN_PART_MERGE (0.3) -extern RefList *merge_intensities(Crystal **crystals, int n, int n_threads, +extern RefList *merge_intensities(struct crystal_refls *crystals, int n, int n_threads, int min_meas, double push_res, int use_weak, int ln_merge); @@ -53,12 +53,12 @@ extern double correct_reflection_nopart(double val, Reflection *refl, extern double correct_reflection(double val, Reflection *refl, double osf, double Bfac, double res); -extern double residual(Crystal *cr, const RefList *full, int free, +extern double residual(RefList *list, Crystal *cr, const RefList *full, int free, int *pn_used, const char *filename); -extern double log_residual(Crystal *cr, const RefList *full, int free, +extern double log_residual(RefList *list, Crystal *cr, const RefList *full, int free, int *pn_used, const char *filename); -extern void write_unmerged(const char *fn, Crystal **crystals, int n_crystals); +extern void write_unmerged(const char *fn, struct crystal_refls *crystals, int n_crystals); #endif /* MERGE */ diff --git a/src/partialator.c b/src/partialator.c index 9b1803b0..7d3f19f6 100644 --- a/src/partialator.c +++ b/src/partialator.c @@ -169,14 +169,14 @@ static void add_to_csplit(struct custom_split *csplit, const char *id, /* Write two-way split results (i.e. for CC1/2 etc) for this list of crystals */ -static void write_split(Crystal **crystals, int n_crystals, const char *outfile, - int nthreads, PartialityModel pmodel, +static void write_split(struct crystal_refls *crystals, int n_crystals, + const char *outfile, int nthreads, PartialityModel pmodel, int min_measurements, SymOpList *sym, double push_res) { char tmp[1024]; RefList *split; - Crystal **crystals1; - Crystal **crystals2; + struct crystal_refls *crystals1; + struct crystal_refls *crystals2; int n_crystals1 = 0; int n_crystals2 = 0; int i; @@ -186,13 +186,12 @@ static void write_split(Crystal **crystals, int n_crystals, const char *outfile, return; } - crystals1 = malloc(n_crystals * sizeof(Crystal *)); + crystals1 = malloc(n_crystals * sizeof(struct crystal_refls)); if ( crystals1 == NULL ) return; - crystals2 = malloc(n_crystals * sizeof(Crystal *)); + crystals2 = malloc(n_crystals * sizeof(struct crystal_refls)); if ( crystals2 == NULL ) return; - for ( i=0; i<n_crystals; i++ ) { if ( i % 2 ) { crystals1[n_crystals1] = crystals[i]; @@ -259,14 +258,15 @@ static char *insert_into_filename(const char *fn, const char *add) /* Write custom split results (including a two-way split) */ static void write_custom_split(struct custom_split *csplit, int dsn, - Crystal **crystals, int n_crystals, + struct crystal_refls *crystals, + struct image **images, int n_crystals, PartialityModel pmodel, int min_measurements, double push_res, SymOpList *sym, int nthreads, const char *outfile) { char *tmp; RefList *split; - Crystal *crystalsn[n_crystals]; + struct crystal_refls crystalsn[n_crystals]; int n_crystalsn = 0; int i; @@ -277,8 +277,8 @@ static void write_custom_split(struct custom_split *csplit, int dsn, char *id; int dsn_crystal; - fn = crystal_get_image(crystals[i])->filename; - evs = crystal_get_image(crystals[i])->ev; + fn = images[i]->filename; + evs = images[i]->ev; if ( evs == NULL ) evs = "//"; id = malloc(strlen(evs)+strlen(fn)+2); @@ -362,7 +362,7 @@ static void show_help(const char *s) } -static signed int find_first_crystal(Crystal **crystals, int n_crystals, +static signed int find_first_crystal(struct image **images, int n_crystals, struct custom_split *csplit, int dsn) { int i; @@ -373,8 +373,8 @@ static signed int find_first_crystal(Crystal **crystals, int n_crystals, char *id; int dsn_crystal; - fn = crystal_get_image(crystals[i])->filename; - evs = crystal_get_image(crystals[i])->ev; + fn = images[i]->filename; + evs = images[i]->ev; if ( evs == NULL ) evs = "//"; id = malloc(strlen(evs)+strlen(fn)+2); @@ -394,8 +394,8 @@ static signed int find_first_crystal(Crystal **crystals, int n_crystals, } -static void check_csplit(Crystal **crystals, int n_crystals, - struct custom_split *csplit) +static void check_csplit(struct crystal_refls *crystals, struct image **images, + int n_crystals, struct custom_split *csplit) { int i; int n_nosplit = 0; @@ -412,8 +412,8 @@ static void check_csplit(Crystal **crystals, int n_crystals, char *id; int dsn_crystal; - fn = crystal_get_image(crystals[i])->filename; - evs = crystal_get_image(crystals[i])->ev; + fn = images[i]->filename; + evs = images[i]->ev; if ( evs == NULL ) evs = "//"; id = malloc(strlen(evs)+strlen(fn)+2); @@ -437,7 +437,7 @@ static void check_csplit(Crystal **crystals, int n_crystals, for ( i=0; i<csplit->n_datasets; i++ ) { /* Try to find a crystal with dsn = i */ - if ( find_first_crystal(crystals, n_crystals, csplit, i) != -1 ) + if ( find_first_crystal(images, n_crystals, csplit, i) != -1 ) { n_cry++; } else { @@ -621,11 +621,10 @@ static void skip_to_end(FILE *fh) } -static int set_initial_params(Crystal *cr, FILE *fh, double force_bandwidth, - double force_radius, double force_lambda) +static int set_initial_params(Crystal *cr, struct image *image, FILE *fh, + double force_bandwidth, double force_radius, + double force_lambda) { - struct image *image = crystal_get_image(cr); - if ( fh != NULL ) { int err; @@ -736,7 +735,7 @@ static void write_to_pgraph(FILE *fh, RefList *list, RefList *full, Crystal *cr, } -static void write_pgraph(RefList *full, Crystal **crystals, int n_crystals, +static void write_pgraph(RefList *full, struct crystal_refls *crystals, int n_crystals, signed int iter, const char *suff, const char *log_folder) { @@ -762,16 +761,16 @@ static void write_pgraph(RefList *full, Crystal **crystals, int n_crystals, } for ( i=0; i<n_crystals; i++ ) { - if ( crystal_get_user_flag(crystals[i]) != 0 ) continue; - write_to_pgraph(fh, crystal_get_reflections(crystals[i]), full, - crystals[i], i, iter); + if ( crystal_get_user_flag(crystals[i].cr) != 0 ) continue; + write_to_pgraph(fh, crystals[i].refls, full, + crystals[i].cr, i, iter); } fclose(fh); } -static void all_residuals(Crystal **crystals, int n_crystals, RefList *full, +static void all_residuals(struct crystal_refls *crystals, int n_crystals, RefList *full, int no_free, double *presidual, double *pfree_residual, double *plog_residual, double *pfree_log_residual, @@ -798,28 +797,28 @@ static void all_residuals(Crystal **crystals, int n_crystals, RefList *full, double r, free_r, log_r, free_log_r; int n; - if ( crystal_get_user_flag(crystals[i]) ) continue; + if ( crystal_get_user_flag(crystals[i].cr) ) continue; /* Scaling should have been done right before calling this */ - r = residual(crystals[i], full, 0, &n, NULL); + r = residual(crystals[i].refls, crystals[i].cr, full, 0, &n, NULL); if ( n == 0 ) { n_non_linear++; } else if ( isnan(r) ) { n_nan_linear++; } - free_r = residual(crystals[i], full, 1, &n, NULL); + free_r = residual(crystals[i].refls, crystals[i].cr, full, 1, &n, NULL); if ( n == 0 ) { n_non_linear_free++; } else if ( isnan(free_r) ) { n_nan_linear_free++; } - log_r = log_residual(crystals[i], full, 0, &n, NULL); + log_r = log_residual(crystals[i].refls, crystals[i].cr, full, 0, &n, NULL); if ( n == 0 ) { n_non_log++; } else if ( isnan(log_r) ) { n_nan_log++; } - free_log_r = log_residual(crystals[i], full, 1, &n, NULL); + free_log_r = log_residual(crystals[i].refls, crystals[i].cr, full, 1, &n, NULL); if ( n == 0 ) { n_non_log_free++; } else if ( isnan(free_log_r) ) { @@ -876,7 +875,7 @@ static void all_residuals(Crystal **crystals, int n_crystals, RefList *full, } -static void show_all_residuals(Crystal **crystals, int n_crystals, +static void show_all_residuals(struct crystal_refls *crystals, int n_crystals, RefList *full, int no_free) { double dev, free_dev, log_dev, free_log_dev; @@ -896,7 +895,8 @@ struct log_qargs { int iter; int next; - Crystal **crystals; + struct crystal_refls *crystals; + struct image **images; int n_crystals; RefList *full; int scaleflags; @@ -909,6 +909,8 @@ struct log_qargs struct log_args { Crystal *cr; + RefList *refls; + struct image *image; RefList *full; int scaleflags; PartialityModel pmodel; @@ -928,7 +930,9 @@ static void *get_log_task(void *vp) task = malloc(sizeof(struct log_args)); if ( task == NULL ) return NULL; - task->cr = qargs->crystals[qargs->next]; + task->cr = qargs->crystals[qargs->next].cr; + task->refls = qargs->crystals[qargs->next].refls; + task->image = qargs->images[qargs->next]; task->full = qargs->full; task->iter = qargs->iter; task->cnum = qargs->next; @@ -944,12 +948,13 @@ static void *get_log_task(void *vp) static void write_logs(void *vp, int cookie) { struct log_args *args = vp; - write_specgraph(args->cr, args->full, args->iter, args->cnum, - args->log_folder); - write_gridscan(args->cr, args->full, args->iter, args->cnum, - args->scaleflags, args->pmodel, args->log_folder); - write_test_logs(args->cr, args->full, args->iter, args->cnum, - args->log_folder); + write_specgraph(args->refls, args->cr, args->image, args->full, + args->iter, args->cnum, args->log_folder); + write_gridscan(args->refls, args->cr, args->image, args->full, + args->iter, args->cnum, args->scaleflags, args->pmodel, + args->log_folder); + write_test_logs(args->cr, args->image, args->full, args->iter, + args->cnum, args->log_folder); } @@ -963,7 +968,8 @@ static void done_log(void *vqargs, void *vp) } -static void write_logs_parallel(Crystal **crystals, int n_crystals, +static void write_logs_parallel(struct crystal_refls *crystals, struct image **images, + int n_crystals, RefList *full, int iter, int n_threads, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -974,6 +980,7 @@ static void write_logs_parallel(Crystal **crystals, int n_crystals, qargs.next = 0; qargs.full = full; qargs.crystals = crystals; + qargs.images = images; qargs.n_done = 0; qargs.n_crystals = n_crystals; qargs.scaleflags = scaleflags; @@ -1084,7 +1091,8 @@ int main(int argc, char *argv[]) int no_scale = 0; int no_Bscale = 0; int no_pr = 0; - Crystal **crystals; + struct crystal_refls *crystals; + struct image **images; char *pmodel_str = NULL; PartialityModel pmodel = PMODEL_XSPHERE; int min_measurements = 2; @@ -1526,6 +1534,7 @@ int main(int argc, char *argv[]) n_crystals = 0; n_crystals_seen = 0; crystals = NULL; + images = NULL; if ( sparams_fn != NULL ) { char line[1024]; sparams_fh = fopen(sparams_fn, "r"); @@ -1560,7 +1569,6 @@ int main(int argc, char *argv[]) do { struct image *image; - RefList *as; int i; image = stream_read_chunk(st, STREAM_REFLECTIONS); @@ -1574,37 +1582,44 @@ int main(int argc, char *argv[]) for ( i=0; i<image->n_crystals; i++ ) { Crystal *cr; - Crystal **crystals_new; + struct crystal_refls *crystals_new; + struct image **images_new; RefList *cr_refl; - RefList *cr_refl_raw; struct image *image_for_crystal; double lowest_r; n_crystals_seen++; if ( n_crystals_seen <= start_after ) continue; - if ( crystal_get_resolution_limit(image->crystals[i]) < min_res ) continue; + if ( crystal_get_resolution_limit(image->crystals[i].cr) < min_res ) continue; - lowest_r = lowest_reflection(crystal_get_cell(image->crystals[i])); - if ( crystal_get_profile_radius(image->crystals[i]) > 0.5*lowest_r ) { + lowest_r = lowest_reflection(crystal_get_cell(image->crystals[i].cr)); + if ( crystal_get_profile_radius(image->crystals[i].cr) > 0.5*lowest_r ) { ERROR("Rejecting %s %s crystal %i because " "profile radius is obviously too big (%e %e).\n", image->filename, image->ev, i, - crystal_get_profile_radius(image->crystals[i]), + crystal_get_profile_radius(image->crystals[i].cr), lowest_r); continue; } crystals_new = realloc(crystals, - (n_crystals+1)*sizeof(Crystal *)); + (n_crystals+1)*sizeof(struct crystal_refls)); if ( crystals_new == NULL ) { ERROR("Failed to allocate memory for crystal " "list.\n"); return 1; } crystals = crystals_new; - crystals[n_crystals] = crystal_copy_deep(image->crystals[i]); - cr = crystals[n_crystals]; + cr = crystal_copy(image->crystals[i].cr); + crystals[n_crystals].cr = cr; + + images_new = realloc(images, (n_crystals+1)*sizeof(struct image *)); + if ( images_new == NULL ) { + ERROR("Failed to allocate memory for image list\n"); + return 1; + } + images = images_new; /* Create a completely new, separate image * structure for this crystal. */ @@ -1614,11 +1629,10 @@ int main(int argc, char *argv[]) return 1; } - crystal_set_image(cr, image_for_crystal); *image_for_crystal = *image; - image_for_crystal->n_crystals = 1; - image_for_crystal->crystals = malloc(sizeof(Crystal *)); - image_for_crystal->crystals[0] = cr; + images[n_crystals] = image_for_crystal; + image_for_crystal->n_crystals = 0; + image_for_crystal->crystals = NULL; image_for_crystal->filename = strdup(image->filename); image_for_crystal->ev = safe_strdup(image->ev); image_for_crystal->detgeom = NULL; @@ -1629,20 +1643,18 @@ int main(int argc, char *argv[]) image_for_crystal->bad = NULL; image_for_crystal->sat = NULL; - /* This is the raw list of reflections */ - cr_refl_raw = crystal_get_reflections(cr); - - cr_refl = apply_max_adu(cr_refl_raw, max_adu); - reflist_free(cr_refl_raw); - + cr_refl = apply_max_adu(image->crystals[i].refls, max_adu); if ( !no_free ) select_free_reflections(cr_refl, rng); - - as = asymmetric_indices(cr_refl, sym); - crystal_set_reflections(cr, as); - crystal_set_user_flag(cr, PRFLAG_OK); + image_add_crystal_refls(image_for_crystal, cr, + asymmetric_indices(cr_refl, sym)); reflist_free(cr_refl); - if ( set_initial_params(cr, sparams_fh, force_bandwidth, + crystals[n_crystals].cr = image_for_crystal->crystals[0].cr; + crystals[n_crystals].refls = image_for_crystal->crystals[0].refls; + + crystal_set_user_flag(cr, PRFLAG_OK); + if ( set_initial_params(cr, image_for_crystal, + sparams_fh, force_bandwidth, force_radius, force_lambda) ) { ERROR("Failed to set initial parameters\n"); @@ -1681,17 +1693,16 @@ int main(int argc, char *argv[]) STATUS("Initial partiality calculation...\n"); for ( icryst=0; icryst<n_crystals; icryst++ ) { - Crystal *cr = crystals[icryst]; - update_predictions(cr); + Crystal *cr = crystals[icryst].cr; + RefList *refls = crystals[icryst].refls; + update_predictions(refls, cr, images[icryst]); /* Polarisation correction requires kpred values */ - polarisation_correction(crystal_get_reflections(cr), - crystal_get_cell(cr), polarisation); - - calculate_partialities(cr, pmodel); + polarisation_correction(refls, crystal_get_cell(cr), polarisation); + calculate_partialities(refls, cr, images[icryst], pmodel); } - if (csplit != NULL) check_csplit(crystals, n_crystals, csplit); + if (csplit != NULL) check_csplit(crystals, images, n_crystals, csplit); /* Make a first pass at cutting out crap */ //STATUS("Early rejection...\n"); @@ -1716,7 +1727,7 @@ int main(int argc, char *argv[]) if ( do_write_logs ) { write_pgraph(full, crystals, n_crystals, 0, "", log_folder); - write_logs_parallel(crystals, n_crystals, full, 0, nthreads, + write_logs_parallel(crystals, images, n_crystals, full, 0, nthreads, scaleflags, pmodel, log_folder); } @@ -1726,7 +1737,7 @@ int main(int argc, char *argv[]) STATUS("Scaling and refinement cycle %i of %i\n", itn+1, n_iter); if ( !no_pr ) { - refine_all(crystals, n_crystals, full, nthreads, pmodel, + refine_all(crystals, images, n_crystals, full, nthreads, pmodel, itn+1, no_logs, sym, amb, scaleflags, log_folder); } @@ -1771,7 +1782,7 @@ int main(int argc, char *argv[]) int j; for ( j=0; j<csplit->n_datasets; j++ ) { write_custom_split(csplit, j, crystals, - n_crystals, pmodel, + images, n_crystals, pmodel, min_measurements, push_res, sym, nthreads, tmp); @@ -1805,7 +1816,7 @@ int main(int argc, char *argv[]) show_all_residuals(crystals, n_crystals, full, no_free); if ( do_write_logs ) { write_pgraph(full, crystals, n_crystals, -1, "", log_folder); - write_logs_parallel(crystals, n_crystals, full, -1, nthreads, + write_logs_parallel(crystals, images, n_crystals, full, -1, nthreads, scaleflags, pmodel, log_folder); } @@ -1827,7 +1838,7 @@ int main(int argc, char *argv[]) if ( csplit != NULL ) { int i; for ( i=0; i<csplit->n_datasets; i++ ) { - write_custom_split(csplit, i, crystals, n_crystals, + write_custom_split(csplit, i, crystals, images, n_crystals, pmodel, min_measurements, push_res, sym, nthreads, outfile); } @@ -1835,10 +1846,6 @@ int main(int argc, char *argv[]) /* Clean up */ gsl_rng_free(rng); - for ( icryst=0; icryst<n_crystals; icryst++ ) { - struct image *image = crystal_get_image(crystals[icryst]); - image_free(image); - } free_contribs(full); reflist_free(full); free_symoplist(sym); diff --git a/src/post-refinement.c b/src/post-refinement.c index 70b14a0f..4a02ed08 100644 --- a/src/post-refinement.c +++ b/src/post-refinement.c @@ -56,14 +56,16 @@ struct rf_alteration struct rf_priv { - Crystal *cr; /**< Original crystal (before any refinement) */ + Crystal *cr; /**< Original crystal (before any refinement) */ + struct image *image; /**< Original image (before any refinement) */ const RefList *full; int serial; int scaleflags; PartialityModel pmodel; - Crystal *cr_tgt; /**< Crystal to use for testing modifications */ - struct image image_tgt; /**< Image structure to go with cr_tgt */ + Crystal *cr_tgt; /**< Crystal to use for testing modifications */ + struct image image_tgt; /**< Image structure to go with cr_tgt */ + RefList *refls; /**< The reflections to use */ }; @@ -151,32 +153,30 @@ static void rotate_cell_xy(UnitCell *source, UnitCell *tgt, static void apply_parameters(Crystal *cr_orig, Crystal *cr_tgt, + struct image *im_orig, struct image *im_tgt, struct rf_alteration alter) { - double R, lambda; + double R; struct gaussian g; - struct image *image; - image = crystal_get_image(cr_tgt); R = crystal_get_profile_radius(cr_orig); - lambda = crystal_get_image_const(cr_orig)->lambda; rotate_cell_xy(crystal_get_cell(cr_orig), crystal_get_cell(cr_tgt), alter.rot_x, alter.rot_y); crystal_set_profile_radius(cr_tgt, R+alter.delta_R); - image->lambda = lambda+alter.delta_wave; + im_tgt->lambda = im_orig->lambda+alter.delta_wave; - g.kcen = 1.0/image->lambda; - g.sigma = image->bw/image->lambda; + g.kcen = 1.0/im_tgt->lambda; + g.sigma = im_tgt->bw/im_tgt->lambda; g.area = 1; - spectrum_set_gaussians(image->spectrum, &g, 1); + spectrum_set_gaussians(im_tgt->spectrum, &g, 1); } static double calc_residual(struct rf_priv *pv, struct rf_alteration alter, int free) { - apply_parameters(pv->cr, pv->cr_tgt, alter); + apply_parameters(pv->cr, pv->cr_tgt, pv->image, &pv->image_tgt, alter); if ( fabs(crystal_get_profile_radius(pv->cr_tgt)) > 5e9 ) { STATUS("radius > 5e9\n"); @@ -189,16 +189,16 @@ static double calc_residual(struct rf_priv *pv, struct rf_alteration alter, return NAN; } - if ( crystal_get_image(pv->cr_tgt)->lambda <= 0.0 ) { + if ( pv->image_tgt.lambda <= 0.0 ) { STATUS("lambda < 0\n"); return NAN; } - update_predictions(pv->cr_tgt); - calculate_partialities(pv->cr_tgt, pv->pmodel); + update_predictions(pv->refls, pv->cr_tgt, &pv->image_tgt); + calculate_partialities(pv->refls, pv->cr_tgt, &pv->image_tgt, pv->pmodel); - return residual(pv->cr_tgt, pv->full, free, NULL, NULL); + return residual(pv->refls, pv->cr_tgt, pv->full, free, NULL, NULL); } @@ -264,64 +264,58 @@ static void reindex_cell(UnitCell *cell, SymOpList *amb, int idx) } -static void try_reindex(Crystal *crin, const RefList *full, - SymOpList *sym, SymOpList *amb, int scaleflags, - PartialityModel pmodel) +static void try_reindex(RefList **prefls, Crystal *crin, struct image *image, + const RefList *full, SymOpList *sym, SymOpList *amb, + int scaleflags, PartialityModel pmodel) { - Crystal *cr; double residual_original; int idx, n; if ( sym == NULL || amb == NULL ) return; - if ( scale_one_crystal(crin, full, scaleflags) ) return; - residual_original = residual(crin, full, 0, NULL, NULL); - - cr = crystal_copy(crin); + if ( scale_one_crystal(*prefls, crin, full, scaleflags) ) return; + residual_original = residual(*prefls, crin, full, 0, NULL, NULL); n = num_equivs(amb, NULL); for ( idx=0; idx<n; idx++ ) { RefList *list; - UnitCell *cell; - double residual_flipped; - - cell = cell_new_from_cell(crystal_get_cell(crin)); - if ( cell == NULL ) return; - reindex_cell(cell, amb, idx); - crystal_set_cell(cr, cell); - - list = reindex_reflections(crystal_get_reflections(crin), - amb, sym, idx); - crystal_set_reflections(cr, list); - - update_predictions(cr); - calculate_partialities(cr, pmodel); - - if ( scale_one_crystal(cr, full, scaleflags) ) return; - residual_flipped = residual(cr, full, 0, NULL, NULL); - - if ( residual_flipped < residual_original ) { - crystal_set_cell(crin, cell); - crystal_set_reflections(crin, list); - residual_original = residual_flipped; - } else { - cell_free(crystal_get_cell(cr)); - reflist_free(crystal_get_reflections(cr)); + Crystal *cr; + + cr = crystal_copy(crin); + + reindex_cell(crystal_get_cell(cr), amb, idx); + list = reindex_reflections(*prefls, amb, sym, idx); + + update_predictions(list, cr, image); + calculate_partialities(list, cr, image, pmodel); + if ( scale_one_crystal(list, cr, full, scaleflags) == 0 ) { + + double residual_flipped; + residual_flipped = residual(list, cr, full, 0, NULL, NULL); + + if ( residual_flipped < residual_original ) { + crystal_set_cell(crin, crystal_relinquish_cell(cr)); + reflist_free(*prefls); + *prefls = list; + residual_original = residual_flipped; + } else { + reflist_free(list); + } } + + crystal_free(cr); } - crystal_free(cr); } -void write_test_logs(Crystal *crystal, const RefList *full, +void write_test_logs(Crystal *crystal, struct image *image, const RefList *full, signed int cycle, int serial, const char *log_folder) { FILE *fh; - struct image *image = crystal_get_image(crystal); char tmp[256]; char ins[16]; @@ -367,7 +361,7 @@ void write_test_logs(Crystal *crystal, const RefList *full, } -void write_specgraph(Crystal *crystal, const RefList *full, +void write_specgraph(RefList *list, Crystal *crystal, struct image *image, const RefList *full, signed int cycle, int serial, const char *log_folder) { @@ -378,7 +372,6 @@ void write_specgraph(Crystal *crystal, const RefList *full, double G = crystal_get_osf(crystal); double B = crystal_get_Bfac(crystal); UnitCell *cell; - struct image *image = crystal_get_image(crystal); char ins[16]; snprintf(tmp, 256, "%s/specgraph-crystal%i.dat", log_folder, serial); @@ -408,7 +401,7 @@ void write_specgraph(Crystal *crystal, const RefList *full, ins[1] = '\0'; } - for ( refl = first_refl(crystal_get_reflections(crystal), &iter); + for ( refl = first_refl(list, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -443,7 +436,8 @@ void write_specgraph(Crystal *crystal, const RefList *full, } -static void write_angle_grid(Crystal *cr, const RefList *full, +static void write_angle_grid(RefList *list_in, Crystal *cr, struct image *image, + const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -452,7 +446,6 @@ static void write_angle_grid(Crystal *cr, const RefList *full, char fn[64]; char ins[16]; struct rf_priv priv; - RefList *list; UnitCell *cell; Spectrum *spectrum; @@ -462,12 +455,11 @@ static void write_angle_grid(Crystal *cr, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); - priv.image_tgt = *crystal_get_image(cr); + priv.image = image; + priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - crystal_set_image(priv.cr_tgt, &priv.image_tgt); - list = copy_reflist(crystal_get_reflections(cr)); - crystal_set_reflections(priv.cr_tgt, list); + priv.refls = copy_reflist(list_in); cell = cell_new_from_cell(crystal_get_cell(cr)); crystal_set_cell(priv.cr_tgt, cell); @@ -504,13 +496,14 @@ static void write_angle_grid(Crystal *cr, const RefList *full, fclose(fh); } - reflist_free(crystal_get_reflections(priv.cr_tgt)); + reflist_free(priv.refls); crystal_free(priv.cr_tgt); spectrum_free(spectrum); } -static void write_radius_grid(Crystal *cr, const RefList *full, +static void write_radius_grid(RefList *list_in, Crystal *cr, struct image *image, + const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) @@ -519,7 +512,6 @@ static void write_radius_grid(Crystal *cr, const RefList *full, char fn[64]; char ins[16]; struct rf_priv priv; - RefList *list; UnitCell *cell; Spectrum *spectrum; @@ -529,12 +521,11 @@ static void write_radius_grid(Crystal *cr, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); - priv.image_tgt = *crystal_get_image(cr); + priv.image = image; + priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - crystal_set_image(priv.cr_tgt, &priv.image_tgt); - list = copy_reflist(crystal_get_reflections(cr)); - crystal_set_reflections(priv.cr_tgt, list); + priv.refls = copy_reflist(list_in); cell = cell_new_from_cell(crystal_get_cell(cr)); crystal_set_cell(priv.cr_tgt, cell); @@ -571,19 +562,20 @@ static void write_radius_grid(Crystal *cr, const RefList *full, fclose(fh); } - reflist_free(crystal_get_reflections(priv.cr_tgt)); + reflist_free(priv.refls); crystal_free(priv.cr_tgt); spectrum_free(spectrum); } -void write_gridscan(Crystal *cr, const RefList *full, +void write_gridscan(RefList *list, + Crystal *cr, struct image *image, const RefList *full, signed int cycle, int serial, int scaleflags, PartialityModel pmodel, const char *log_folder) { - write_angle_grid(cr, full, cycle, serial, scaleflags, pmodel, log_folder); - write_radius_grid(cr, full, cycle, serial, scaleflags, pmodel, log_folder); + write_angle_grid(list, cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); + write_radius_grid(list, cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); } @@ -631,7 +623,7 @@ static int refine_loop(struct rf_alteration *cur, struct rf_alteration *dirns, *total_iter, lowest_fom, freefom, cur->rot_x, cur->rot_y, crystal_get_profile_radius(priv->cr)+cur->delta_R, - crystal_get_image_const(priv->cr)->lambda+cur->delta_wave); + priv->image->lambda+cur->delta_wave); } } while ( (best != 0) && (n_iter < 10) ); @@ -649,7 +641,8 @@ static void zero_alter(struct rf_alteration *alter) } -static void do_pr_refine(Crystal *cr, const RefList *full, +static void do_pr_refine(RefList **plist_in, Crystal *cr, struct image *image, + const RefList *full, PartialityModel pmodel, int serial, int cycle, int write_logs, SymOpList *sym, SymOpList *amb, int scaleflags, @@ -659,12 +652,11 @@ static void do_pr_refine(Crystal *cr, const RefList *full, struct rf_alteration alter; int n_iter = 0; double fom, freefom; - RefList *list; FILE *fh = NULL; UnitCell *cell; Spectrum *spectrum; - try_reindex(cr, full, sym, amb, scaleflags, pmodel); + try_reindex(plist_in, cr, image, full, sym, amb, scaleflags, pmodel); zero_alter(&alter); @@ -674,12 +666,11 @@ static void do_pr_refine(Crystal *cr, const RefList *full, priv.scaleflags = scaleflags; priv.pmodel = pmodel; priv.cr_tgt = crystal_copy(cr); - priv.image_tgt = *crystal_get_image(cr); + priv.image = image; + priv.image_tgt = *image; spectrum = spectrum_new(); priv.image_tgt.spectrum = spectrum; - crystal_set_image(priv.cr_tgt, &priv.image_tgt); - list = copy_reflist(crystal_get_reflections(cr)); - crystal_set_reflections(priv.cr_tgt, list); + priv.refls = copy_reflist(*plist_in); cell = cell_new_from_cell(crystal_get_cell(cr)); crystal_set_cell(priv.cr_tgt, cell); @@ -700,7 +691,7 @@ static void do_pr_refine(Crystal *cr, const RefList *full, n_iter, fom, freefom, alter.rot_x, alter.rot_y, crystal_get_profile_radius(cr)+alter.delta_R, - crystal_get_image(cr)->lambda+alter.delta_wave); + image->lambda+alter.delta_wave); } } @@ -724,15 +715,15 @@ static void do_pr_refine(Crystal *cr, const RefList *full, refine_loop(&alter, dirns, 2, &priv, &n_iter, fh); /* Apply the final shifts */ - apply_parameters(cr, cr, alter); - update_predictions(cr); - calculate_partialities(cr, pmodel); + apply_parameters(cr, cr, image, image, alter); + update_predictions(*plist_in, cr, image); + calculate_partialities(*plist_in, cr, image, pmodel); if ( write_logs ) { - write_gridscan(cr, full, cycle, serial, scaleflags, + write_gridscan(*plist_in, cr, image, full, cycle, serial, scaleflags, pmodel, log_folder); - write_specgraph(cr, full, cycle, serial, log_folder); - write_test_logs(cr, full, cycle, serial, log_folder); + write_specgraph(*plist_in, cr, image, full, cycle, serial, log_folder); + write_test_logs(cr, image, full, cycle, serial, log_folder); } if ( crystal_get_profile_radius(cr) > 5e9 ) { @@ -743,7 +734,7 @@ static void do_pr_refine(Crystal *cr, const RefList *full, fclose(fh); } - reflist_free(crystal_get_reflections(priv.cr_tgt)); + reflist_free(priv.refls); crystal_free(priv.cr_tgt); spectrum_free(spectrum); } @@ -753,6 +744,8 @@ struct refine_args { RefList *full; Crystal *crystal; + RefList **prefls; + struct image *image; PartialityModel pmodel; int serial; int cycle; @@ -768,7 +761,8 @@ struct pr_queue_args { int n_started; int n_done; - Crystal **crystals; + struct crystal_refls *crystals; + struct image **images; int n_crystals; struct refine_args task_defaults; }; @@ -777,12 +771,12 @@ struct pr_queue_args static void refine_image(void *task, int id) { struct refine_args *pargs = task; - Crystal *cr = pargs->crystal; int write_logs = 0; write_logs = !pargs->no_logs && (pargs->serial % 20 == 0); - do_pr_refine(cr, pargs->full, pargs->pmodel, + do_pr_refine(pargs->prefls, pargs->crystal, pargs->image, + pargs->full, pargs->pmodel, pargs->serial, pargs->cycle, write_logs, pargs->sym, pargs->amb, pargs->scaleflags, pargs->log_folder); @@ -797,7 +791,9 @@ static void *get_image(void *vqargs) task = malloc(sizeof(struct refine_args)); memcpy(task, &qargs->task_defaults, sizeof(struct refine_args)); - task->crystal = qargs->crystals[qargs->n_started]; + task->crystal = qargs->crystals[qargs->n_started].cr; + task->prefls = &qargs->crystals[qargs->n_started].refls; + task->image = qargs->images[qargs->n_started]; task->serial = qargs->n_started; qargs->n_started++; @@ -817,7 +813,7 @@ static void done_image(void *vqargs, void *task) } -void refine_all(Crystal **crystals, int n_crystals, +void refine_all(struct crystal_refls *crystals, struct image **images, int n_crystals, RefList *full, int nthreads, PartialityModel pmodel, int cycle, int no_logs, SymOpList *sym, SymOpList *amb, int scaleflags, @@ -828,6 +824,8 @@ void refine_all(Crystal **crystals, int n_crystals, task_defaults.full = full; task_defaults.crystal = NULL; + task_defaults.prefls = NULL; + task_defaults.image = NULL; task_defaults.pmodel = pmodel; task_defaults.cycle = cycle; task_defaults.no_logs = no_logs; @@ -842,6 +840,7 @@ void refine_all(Crystal **crystals, int n_crystals, qargs.n_done = 0; qargs.n_crystals = n_crystals; qargs.crystals = crystals; + qargs.images = images; /* Don't have threads which are doing nothing */ if ( n_crystals < nthreads ) nthreads = n_crystals; diff --git a/src/post-refinement.h b/src/post-refinement.h index 546050a4..91c0f4f8 100644 --- a/src/post-refinement.h +++ b/src/post-refinement.h @@ -58,18 +58,21 @@ enum prflag extern const char *str_prflag(enum prflag flag); -extern void refine_all(Crystal **crystals, int n_crystals, +extern void refine_all(struct crystal_refls *crystals, struct image **images, + int n_crystals, RefList *full, int nthreads, PartialityModel pmodel, int cycle, int no_logs, SymOpList *sym, SymOpList *amb, int scaleflags, const char *log_folder); -extern void write_gridscan(Crystal *cr, const RefList *full, +extern void write_gridscan(RefList *list, Crystal *cr, struct image *image, + const RefList *full, int cycle, int serial, int scaleflags, PartialityModel model, const char *log_folder); -extern void write_specgraph(Crystal *crystal, const RefList *full, +extern void write_specgraph(RefList *list, Crystal *crystal, struct image *image, + const RefList *full, signed int cycle, int serial, const char *log_folder); @@ -77,7 +80,8 @@ extern void write_specgraph(Crystal *crystal, const RefList *full, extern double gradient(Crystal *cr, int k, Reflection *refl, PartialityModel pmodel); -extern void write_test_logs(Crystal *crystal, const RefList *full, +extern void write_test_logs(Crystal *crystal, struct image *image, + const RefList *full, signed int cycle, int serial, const char *log_folder); diff --git a/src/process_hkl.c b/src/process_hkl.c index be1c95d4..31e4b1fc 100644 --- a/src/process_hkl.c +++ b/src/process_hkl.c @@ -271,7 +271,7 @@ static void apply_kpred(double k, RefList *list) static int merge_crystal(RefList *model, struct image *image, Crystal *cr, - RefList *reference, const SymOpList *sym, + RefList *new_refl, RefList *reference, const SymOpList *sym, double **hist_vals, signed int hist_h, signed int hist_k, signed int hist_l, int *hist_n, struct polarisation p, double min_snr, double max_adu, @@ -280,11 +280,8 @@ static int merge_crystal(RefList *model, struct image *image, Crystal *cr, { Reflection *refl; RefListIterator *iter; - RefList *new_refl; double scale; - new_refl = crystal_get_reflections(cr); - /* First, correct for polarisation */ apply_kpred(1.0/image->lambda, new_refl); polarisation_correction(new_refl, crystal_get_cell(cr), p); @@ -309,7 +306,7 @@ static int merge_crystal(RefList *model, struct image *image, Crystal *cr, scale = 1.0; } - for ( refl = first_refl(crystal_get_reflections(cr), &iter); + for ( refl = first_refl(new_refl, &iter); refl != NULL; refl = next_refl(refl, iter) ) { @@ -431,7 +428,8 @@ static int merge_stream(Stream *st, for ( i=0; i<image->n_crystals; i++ ) { - Crystal *cr = image->crystals[i]; + Crystal *cr = image->crystals[i].cr; + RefList *refls = image->crystals[i].refls; n_crystals_seen++; if ( (n_crystals_seen > start_after) @@ -440,8 +438,8 @@ static int merge_stream(Stream *st, { int r; n_crystals++; - r = merge_crystal(model, image, cr, reference, - sym, hist_vals, + r = merge_crystal(model, image, cr, refls, + reference, sym, hist_vals, hist_h, hist_k, hist_l, hist_i, p, min_snr, max_adu, push_res, diff --git a/src/process_image.c b/src/process_image.c index 2f856594..c26842c3 100644 --- a/src/process_image.c +++ b/src/process_image.c @@ -57,6 +57,8 @@ #include "im-sandbox.h" #include "im-zmq.h" #include "im-asapo.h" +#include "peaks.h" +#include "peakfinder8.h" static float **backup_image_data(float **dp, struct detgeom *det) { @@ -292,35 +294,42 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, profile_start("peak-search"); switch ( iargs->peak_search.method ) { + ImageFeatureList *peaks; + case PEAK_HDF5: case PEAK_CXI: set_last_task(last_task, "peaksearch:hdf5orcxi"); - image->features = image_read_peaks(iargs->dtempl, - pargs->filename, - pargs->event, - iargs->peak_search.half_pixel_shift); - if ( image->features == NULL ) { - ERROR("Failed to get peaks from HDF5 file.\n"); - } + peaks = image_read_peaks(iargs->dtempl, + pargs->filename, + pargs->event, + iargs->peak_search.half_pixel_shift); if ( iargs->peak_search.revalidate ) { - validate_peaks(image, iargs->peak_search.min_snr, - iargs->peak_search.pk_inn, iargs->peak_search.pk_mid, - iargs->peak_search.pk_out, iargs->peak_search.use_saturated, - iargs->peak_search.check_hdf5_snr); + ImageFeatureList *npeaks = validate_peaks(image, peaks, + iargs->peak_search.min_snr, + iargs->peak_search.pk_inn, + iargs->peak_search.pk_mid, + iargs->peak_search.pk_out, + iargs->peak_search.use_saturated, + iargs->peak_search.check_hdf5_snr); + image_feature_list_free(peaks); + image->features = npeaks; } break; case PEAK_ZAEF: set_last_task(last_task, "peaksearch:zaef"); - search_peaks(image, iargs->peak_search.threshold, - iargs->peak_search.min_sq_gradient, iargs->peak_search.min_snr, - iargs->peak_search.pk_inn, iargs->peak_search.pk_mid, iargs->peak_search.pk_out, - iargs->peak_search.use_saturated); + image->features = search_peaks(image, iargs->peak_search.threshold, + iargs->peak_search.min_sq_gradient, + iargs->peak_search.min_snr, + iargs->peak_search.pk_inn, + iargs->peak_search.pk_mid, + iargs->peak_search.pk_out, + iargs->peak_search.use_saturated); break; case PEAK_PEAKFINDER8: set_last_task(last_task, "peaksearch:pf8"); - if ( search_peaks_peakfinder8(image, 2048, + image->features = peakfinder8(image, 2048, iargs->peak_search.threshold, iargs->peak_search.min_snr, iargs->peak_search.min_pix_count, @@ -329,40 +338,36 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, iargs->peak_search.min_res, iargs->peak_search.max_res, iargs->peak_search.use_saturated, - iargs->peak_search.peakfinder8_fast, - iargs->pf_private) ) { - ERROR("Failed to find peaks in image %s" - "(event %s).\n", - image->filename, image->ev); - } + iargs->peak_search.peakfinder8_fast, + iargs->pf_private); break; case PEAK_PEAKFINDER9: set_last_task(last_task, "peaksearch:pf9"); - if ( search_peaks_peakfinder9(image, - iargs->peak_search.min_snr_biggest_pix, - iargs->peak_search.min_snr_peak_pix, - iargs->peak_search.min_snr, - iargs->peak_search.min_sig, - iargs->peak_search.min_peak_over_neighbour, - iargs->peak_search.local_bg_radius) ) - { - ERROR("Failed to find peaks in image %s" - "(event %s).\n", - image->filename, image->ev); - } + image->features = search_peaks_peakfinder9(image, + iargs->peak_search.min_snr_biggest_pix, + iargs->peak_search.min_snr_peak_pix, + iargs->peak_search.min_snr, + iargs->peak_search.min_sig, + iargs->peak_search.min_peak_over_neighbour, + iargs->peak_search.local_bg_radius); break; case PEAK_MSGPACK: - image->features = image_msgpack_read_peaks(iargs->dtempl, - pargs->zmq_data, - pargs->zmq_data_size, - iargs->peak_search.half_pixel_shift); + peaks = image_msgpack_read_peaks(iargs->dtempl, + pargs->zmq_data, + pargs->zmq_data_size, + iargs->peak_search.half_pixel_shift); if ( iargs->peak_search.revalidate ) { - validate_peaks(image, iargs->peak_search.min_snr, - iargs->peak_search.pk_inn, iargs->peak_search.pk_mid, - iargs->peak_search.pk_out, iargs->peak_search.use_saturated, - iargs->peak_search.check_hdf5_snr); + ImageFeatureList *npeaks = validate_peaks(image, peaks, + iargs->peak_search.min_snr, + iargs->peak_search.pk_inn, + iargs->peak_search.pk_mid, + iargs->peak_search.pk_out, + iargs->peak_search.use_saturated, + iargs->peak_search.check_hdf5_snr); + image_feature_list_free(peaks); + image->features = npeaks; } break; @@ -371,6 +376,10 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, break; } + if ( image->features == NULL ) { + ERROR("Peaksearch failed for image %s" "(event %s).\n", + image->filename, image->ev); + } profile_end("peak-search"); image->peak_resolution = estimate_peak_resolution(image->features, @@ -434,20 +443,20 @@ void process_image(const struct index_args *iargs, struct pattern_args *pargs, set_last_task(last_task, "prediction params"); if ( iargs->fix_profile_r >= 0.0 ) { for ( i=0; i<image->n_crystals; i++ ) { - crystal_set_profile_radius(image->crystals[i], + crystal_set_profile_radius(image->crystals[i].cr, iargs->fix_profile_r); - crystal_set_mosaicity(image->crystals[i], 0.0); + crystal_set_mosaicity(image->crystals[i].cr, 0.0); } } else { for ( i=0; i<image->n_crystals; i++ ) { - crystal_set_profile_radius(image->crystals[i], 0.02e9); - crystal_set_mosaicity(image->crystals[i], 0.0); + crystal_set_profile_radius(image->crystals[i].cr, 0.02e9); + crystal_set_mosaicity(image->crystals[i].cr, 0.0); } } if ( iargs->fix_profile_r < 0.0 ) { for ( i=0; i<image->n_crystals; i++ ) { - if ( refine_radius(image->crystals[i], image) ) { + if ( refine_radius(image->crystals[i].cr, image) ) { ERROR("WARNING: Radius determination failed\n"); } } @@ -479,7 +488,7 @@ streamwrite: int n = 0; for ( i=0; i<image->n_crystals; i++ ) { - n += crystal_get_num_implausible_reflections(image->crystals[i]); + n += crystal_get_num_implausible_reflections(image->crystals[i].cr); } if ( n > 0 ) { STATUS("WARNING: %i implausibly negative reflection%s in %s " @@ -495,7 +504,7 @@ out: pthread_mutex_lock(&sb_shared->totals_lock); any_crystals = 0; for ( i=0; i<image->n_crystals; i++ ) { - if ( crystal_get_user_flag(image->crystals[i]) == 0 ) { + if ( crystal_get_user_flag(image->crystals[i].cr) == 0 ) { sb_shared->n_crystals++; any_crystals = 1; } diff --git a/src/rejection.c b/src/rejection.c index 4e3ff6ba..d3aa9b1f 100644 --- a/src/rejection.c +++ b/src/rejection.c @@ -63,7 +63,7 @@ static double mean_intensity(RefList *list) /* Reject really obvious outliers */ -void early_rejection(Crystal **crystals, int n) +void early_rejection(struct crystal_refls *crystals, int n) { int i; double m = 0.0; @@ -73,18 +73,16 @@ void early_rejection(Crystal **crystals, int n) for ( i=0; i<n; i++ ) { double u; - RefList *list = crystal_get_reflections(crystals[i]); - u = mean_intensity(list); + u = mean_intensity(crystals[i].refls); m += u; fprintf(fh, "%i %f\n", i, u); } mean_m = m/n; for ( i=0; i<n; i++ ) { double u; - RefList *list = crystal_get_reflections(crystals[i]); - u = mean_intensity(list); + u = mean_intensity(crystals[i].refls); if ( u/mean_m < 0.2 ) { - crystal_set_user_flag(crystals[i], 5); + crystal_set_user_flag(crystals[i].cr, 5); n_flag++; } } @@ -219,7 +217,7 @@ static double calculate_cchalf(RefList *template, RefList *full, * If the crystal is marked as bad, we should not remove it * because it did not contribute in the first place. */ if ( exclude != NULL && !crystal_get_user_flag(exclude) ) { - exrefl = find_refl(crystal_get_reflections(exclude), h, k, l); + exrefl = find_refl(template, h, k, l); } else { exrefl = NULL; } @@ -275,7 +273,7 @@ static double calculate_cchalf(RefList *template, RefList *full, struct deltacchalf_queue_args { RefList *full; - Crystal **crystals; + struct crystal_refls *crystals; int n_crystals; int n_done; int n_started; @@ -289,6 +287,7 @@ struct deltacchalf_worker_args { RefList *full; Crystal *crystal; + RefList *refls; int crystal_number; int non; int nan; @@ -304,7 +303,8 @@ static void *create_deltacchalf_job(void *vqargs) wargs = malloc(sizeof(struct deltacchalf_worker_args)); wargs->full = qargs->full; - wargs->crystal = qargs->crystals[qargs->n_started]; + wargs->crystal = qargs->crystals[qargs->n_started].cr; + wargs->refls = qargs->crystals[qargs->n_started].refls; wargs->crystal_number = qargs->n_started; wargs->non = 0; wargs->nan = 0; @@ -320,9 +320,8 @@ static void run_deltacchalf_job(void *vwargs, int cookie) double cchalf, cchalfi; struct deltacchalf_worker_args *wargs = vwargs; int nref = 0; - RefList *template = crystal_get_reflections(wargs->crystal); - cchalf = calculate_cchalf(template, wargs->full, NULL, &nref); - cchalfi = calculate_cchalf(template, wargs->full, wargs->crystal, &nref); + cchalf = calculate_cchalf(wargs->refls, wargs->full, NULL, &nref); + cchalfi = calculate_cchalf(wargs->refls, wargs->full, wargs->crystal, &nref); //STATUS("Frame %i:", i); //STATUS(" With = %f ", cchalf*100.0); //STATUS("Without = %f", cchalfi*100.0); @@ -355,8 +354,8 @@ static void finalise_deltacchalf_job(void *vqargs, void *vwargs) } -static void check_deltacchalf(Crystal **crystals, int n, RefList *full, - int n_threads) +static void check_deltacchalf(struct crystal_refls *crystals, int n, + RefList *full, int n_threads) { double cchalf; int i; @@ -409,7 +408,7 @@ static void check_deltacchalf(Crystal **crystals, int n, RefList *full, if ( isnan(vals[i]) || isinf(vals[i]) || ((vals[i]<0.0) && (vals[i] < mean-2.0*sd)) ) { - crystal_set_user_flag(crystals[i], PRFLAG_DELTACCHALF); + crystal_set_user_flag(crystals[i].cr, PRFLAG_DELTACCHALF); } } @@ -417,7 +416,7 @@ static void check_deltacchalf(Crystal **crystals, int n, RefList *full, } -static void show_duds(Crystal **crystals, int n_crystals) +static void show_duds(struct crystal_refls *crystals, int n_crystals) { int j; int bads[32]; @@ -427,7 +426,7 @@ static void show_duds(Crystal **crystals, int n_crystals) for ( j=0; j<n_crystals; j++ ) { int flag; - flag = crystal_get_user_flag(crystals[j]); + flag = crystal_get_user_flag(crystals[j].cr); assert(flag < 32); bads[flag]++; if ( flag != PRFLAG_OK ) any_bad++; @@ -444,8 +443,8 @@ static void show_duds(Crystal **crystals, int n_crystals) } -void check_rejection(Crystal **crystals, int n, RefList *full, double max_B, - int no_deltacchalf, int n_threads) +void check_rejection(struct crystal_refls *crystals, int n, RefList *full, + double max_B, int no_deltacchalf, int n_threads) { int i; int n_acc = 0; @@ -456,10 +455,10 @@ void check_rejection(Crystal **crystals, int n, RefList *full, double max_B, } for ( i=0; i<n; i++ ) { - if ( fabs(crystal_get_Bfac(crystals[i])) > max_B ) { - crystal_set_user_flag(crystals[i], PRFLAG_BIGB); + if ( fabs(crystal_get_Bfac(crystals[i].cr)) > max_B ) { + crystal_set_user_flag(crystals[i].cr, PRFLAG_BIGB); } - if ( crystal_get_user_flag(crystals[i]) == 0 ) n_acc++; + if ( crystal_get_user_flag(crystals[i].cr) == 0 ) n_acc++; } show_duds(crystals, n); diff --git a/src/rejection.h b/src/rejection.h index 7dc2c92b..152c004e 100644 --- a/src/rejection.h +++ b/src/rejection.h @@ -35,10 +35,10 @@ #endif -#include "crystal.h" +#include "image.h" -extern void early_rejection(Crystal **crystals, int n); -extern void check_rejection(Crystal **crystals, int n, RefList *full, +extern void early_rejection(struct crystal_refls *crystals, int n); +extern void check_rejection(struct crystal_refls *crystals, int n, RefList *full, double max_B, int no_deltacchalf, int n_threads); #endif /* REJECTION_H */ diff --git a/src/scaling.c b/src/scaling.c index f007b757..52954f9a 100644 --- a/src/scaling.c +++ b/src/scaling.c @@ -53,6 +53,7 @@ struct scale_args { RefList *full; Crystal *crystal; + RefList *refls; int flags; }; @@ -61,7 +62,7 @@ struct scale_queue_args { int n_started; int n_done; - Crystal **crystals; + struct crystal_refls *crystals; int n_crystals; struct scale_args task_defaults; }; @@ -70,7 +71,7 @@ struct scale_queue_args static void scale_crystal(void *task, int id) { struct scale_args *pargs = task; - scale_one_crystal(pargs->crystal, pargs->full, pargs->flags); + scale_one_crystal(pargs->refls, pargs->crystal, pargs->full, pargs->flags); } @@ -82,7 +83,8 @@ static void *get_crystal(void *vqargs) task = malloc(sizeof(struct scale_args)); memcpy(task, &qargs->task_defaults, sizeof(struct scale_args)); - task->crystal = qargs->crystals[qargs->n_started]; + task->crystal = qargs->crystals[qargs->n_started].cr; + task->refls = qargs->crystals[qargs->n_started].refls; qargs->n_started++; @@ -99,8 +101,8 @@ static void done_crystal(void *vqargs, void *task) } -static double total_log_r(Crystal **crystals, int n_crystals, RefList *full, - int *ninc) +static double total_log_r(struct crystal_refls *crystals, int n_crystals, + RefList *full, int *ninc) { int i; double total = 0.0; @@ -108,8 +110,9 @@ static double total_log_r(Crystal **crystals, int n_crystals, RefList *full, for ( i=0; i<n_crystals; i++ ) { double r; - if ( crystal_get_user_flag(crystals[i]) ) continue; - r = log_residual(crystals[i], full, 0, NULL, NULL); + if ( crystal_get_user_flag(crystals[i].cr) ) continue; + r = log_residual(crystals[i].refls, crystals[i].cr, + full, 0, NULL, NULL); if ( isnan(r) ) continue; total += r; n++; @@ -121,7 +124,7 @@ static double total_log_r(Crystal **crystals, int n_crystals, RefList *full, /* Perform iterative scaling, all the way to convergence */ -void scale_all(Crystal **crystals, int n_crystals, int nthreads, int scaleflags) +void scale_all(struct crystal_refls *crystals, int n_crystals, int nthreads, int scaleflags) { struct scale_args task_defaults; struct scale_queue_args qargs; @@ -163,7 +166,7 @@ void scale_all(Crystal **crystals, int n_crystals, int nthreads, int scaleflags) int i; double meanB = 0.0; for ( i=0; i<n_crystals; i++ ) { - meanB += crystal_get_Bfac(crystals[i]); + meanB += crystal_get_Bfac(crystals[i].cr); } meanB /= n_crystals; STATUS("Mean B = %e\n", meanB); @@ -181,7 +184,8 @@ void scale_all(Crystal **crystals, int n_crystals, int nthreads, int scaleflags) /* Calculates G and B, by which cr's reflections should be multiplied to fit reference */ -int scale_one_crystal(Crystal *cr, const RefList *listR, int flags) +int scale_one_crystal(const RefList *listS, Crystal *cr, + const RefList *listR, int flags) { const Reflection *reflS; RefListIterator *iter; @@ -202,7 +206,6 @@ int scale_one_crystal(Crystal *cr, const RefList *listR, int flags) int n_part = 0; int n_nom = 0; int n_red = 0; - RefList *listS = crystal_get_reflections(cr); UnitCell *cell = crystal_get_cell(cr); double G, B; diff --git a/src/scaling.h b/src/scaling.h index e47a845d..27ace6b7 100644 --- a/src/scaling.h +++ b/src/scaling.h @@ -45,9 +45,10 @@ enum ScaleFlags SCALE_VERBOSE_ERRORS = 1<<1, }; -extern int scale_one_crystal(Crystal *cr, const RefList *reference, int flags); +extern int scale_one_crystal(const RefList *listS, Crystal *cr, + const RefList *reference, int flags); -extern void scale_all(Crystal **crystals, int n_crystals, int nthreads, - int flags); +extern void scale_all(struct crystal_refls *crystals, int n_crystals, + int nthreads, int flags); #endif /* SCALING_H */ diff --git a/src/whirligig.c b/src/whirligig.c index 20fcfa40..aa2cf090 100644 --- a/src/whirligig.c +++ b/src/whirligig.c @@ -175,12 +175,11 @@ static void process_series(struct image *images, signed int *ser, fprintf(fh, "%i frames in series\n\n", len); fprintf(fh, " # Serial Filename EventID Crystal\n"); for ( i=0; i<len; i++ ) { - Crystal *cr = images[i].crystals[ser[i]]; fprintf(fh, "%4i %5i %s %s %i\n", i, images[i].serial, images[i].filename, images[i].ev, ser[i]); - p[i] = transform_reflections(crystal_get_reflections(cr), + p[i] = transform_reflections(images[i].crystals[ser[i]].refls, mat[i]); } @@ -316,8 +315,8 @@ static IntegerMatrix *try_all(struct window *win, int n1, int n2, for ( i=0; i<i1->n_crystals; i++ ) { for ( j=0; j<i2->n_crystals; j++ ) { - if ( compare_permuted_cell_parameters_and_orientation(crystal_get_cell(i1->crystals[i]), - crystal_get_cell(i2->crystals[j]), + if ( compare_permuted_cell_parameters_and_orientation(crystal_get_cell(i1->crystals[i].cr), + crystal_get_cell(i2->crystals[j].cr), tols, &m) ) { if ( !crystal_used(win, n1, i) @@ -377,12 +376,12 @@ static int try_join(struct window *win, int sn) /* Get the appropriately transformed cell from the last crystal in this * series */ - cr = win->img[sp].crystals[win->ser[sn][sp]]; + cr = win->img[sp].crystals[win->ser[sn][sp]].cr; ref = cell_transform_intmat(crystal_get_cell(cr), win->mat[sn][sp]); for ( j=0; j<win->img[win->join_ptr].n_crystals; j++ ) { Crystal *cr2; - cr2 = win->img[win->join_ptr].crystals[j]; + cr2 = win->img[win->join_ptr].crystals[j].cr; if ( compare_permuted_cell_parameters_and_orientation(ref, crystal_get_cell(cr2), tols, &win->mat[sn][win->join_ptr]) ) diff --git a/tests/gradient_check.c b/tests/gradient_check.c index 001bff7a..0722b849 100644 --- a/tests/gradient_check.c +++ b/tests/gradient_check.c @@ -98,7 +98,7 @@ int main(int argc, char *argv[]) #ifdef CHANGE_CELL double asx, asy, asz, bsx, bsy, bsz, csx, csy, csz; - UnitCell *cell = crystal_get_cell(image.crystals[0]); + UnitCell *cell = crystal_get_cell(image.crystals[0].cr); step = 0.5e5; cell_get_reciprocal(cell, &asx, &asy, &asz, &bsx, &bsy, &bsz, @@ -115,7 +115,7 @@ int main(int argc, char *argv[]) return 1; } - update_predictions(image.crystals[0]); + update_predictions(image.crystals[0].refls, image.crystals[0].cr, &image); after = make_dev_list(rps, n_refls, image.detgeom); for ( i=0; i<n_refls; i++ ) { @@ -124,11 +124,11 @@ int main(int argc, char *argv[]) double obs[3]; calc[0] = r_gradient(TEST_GPARAM, rps[i].refl, - crystal_get_cell(image.crystals[0]), + crystal_get_cell(image.crystals[0].cr), image.lambda); fs_ss_gradient(TEST_GPARAM, rps[i].refl, - crystal_get_cell(image.crystals[0]), + crystal_get_cell(image.crystals[0].cr), &image.detgeom->panels[rps[i].peak->pn], panel_matrices[rps[i].peak->pn], cx, cy, cz, &calc[1], &calc[2]); diff --git a/tests/gradient_check_utils.c b/tests/gradient_check_utils.c index 67ba255e..8b9191cf 100644 --- a/tests/gradient_check_utils.c +++ b/tests/gradient_check_utils.c @@ -141,11 +141,9 @@ struct reflpeak *make_test_image(int *pn_refls, struct image *image) } crystal_set_mosaicity(cr, 0.0); crystal_set_profile_radius(cr, 0.005e9); - crystal_set_image(cr, image); crystal_set_cell(cr, random_rotated_cell(rng)); - refls = predict_to_res(cr, detgeom_max_resolution(image->detgeom, image->lambda)); - crystal_set_reflections(cr, refls); + refls = predict_to_res(cr, image, detgeom_max_resolution(image->detgeom, image->lambda)); n_refls = num_reflections(refls); /* Associate a peak with every reflection */ @@ -175,7 +173,7 @@ struct reflpeak *make_test_image(int *pn_refls, struct image *image) i++; } - image_add_crystal(image, cr); + image_add_crystal_refls(image, cr, refls); gsl_rng_free(rng); diff --git a/tests/prof2d_check.c b/tests/prof2d_check.c index 28ecd67c..4ea3cee5 100644 --- a/tests/prof2d_check.c +++ b/tests/prof2d_check.c @@ -38,11 +38,12 @@ #include "histogram.h" -extern void integrate_prof2d(IntegrationMethod meth, - Crystal *cr, struct image *image, IntDiag int_diag, - signed int idh, signed int idk, signed int idl, - double ir_inn, double ir_mid, double ir_out, - pthread_mutex_t *term_lock, int **masks); +void integrate_prof2d(IntegrationMethod meth, + Crystal *cr, RefList *list, + struct image *image, IntDiag int_diag, + signed int idh, signed int idk, signed int idl, + double ir_inn, double ir_mid, double ir_out, + pthread_mutex_t *term_lock, int **masks); #define ADD_PX(fs, ss, val) \ @@ -125,15 +126,14 @@ int main(int argc, char *argv[]) cr = crystal_new(); crystal_set_profile_radius(cr, 0.001e9); crystal_set_mosaicity(cr, 0.0); /* radians */ - crystal_set_image(cr, &image); crystal_set_cell(cr, cell); - image.n_crystals = 1; - image.crystals = &cr; + image.crystals = NULL; + image.n_crystals = 0; + list = predict_to_res(cr, &image, detgeom_max_resolution(image.detgeom, + image.lambda)); - list = predict_to_res(cr, detgeom_max_resolution(image.detgeom, - image.lambda)); - crystal_set_reflections(cr, list); + image_add_crystal_refls(&image, cr, list); for ( fs=0; fs<w; fs++ ) { for ( ss=0; ss<h; ss++ ) { @@ -169,7 +169,7 @@ int main(int argc, char *argv[]) STATUS("%i strong, %i weak\n", n_strong, n_weak); - integrate_prof2d(INTEGRATION_PROF2D, cr, &image, + integrate_prof2d(INTEGRATION_PROF2D, cr, list, &image, INTDIAG_NONE, 0, 0, 0, ir_inn, ir_mid, ir_out, 0, NULL); diff --git a/tests/stream_roundtrip.c b/tests/stream_roundtrip.c index d36191bb..79231b62 100644 --- a/tests/stream_roundtrip.c +++ b/tests/stream_roundtrip.c @@ -78,7 +78,7 @@ int main(int argc, char *argv[]) image->features = image_feature_list_new(); for ( i=0; i<N_PEAKS; i++ ) { image_add_feature(image->features, peak_fs[i], peak_ss[i], - peak_pn[i], image, peak_i[i], NULL); + peak_pn[i], peak_i[i], NULL); } st = stream_open_for_write("stream_roundtrip.stream", dtempl); |