From 626ea361675f9107e61a6576b443a36477e19c5c Mon Sep 17 00:00:00 2001 From: Thomas White Date: Mon, 17 Jun 2024 15:17:36 +0200 Subject: Julia: Expose DetGeom panel hierarchy --- julia/CrystFEL/src/CrystFEL.jl | 2 +- julia/CrystFEL/src/detgeom.jl | 91 ++++++++++++++++++++++++++++++++++++++---- 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/julia/CrystFEL/src/CrystFEL.jl b/julia/CrystFEL/src/CrystFEL.jl index 9ab5d15f..bb1f1534 100644 --- a/julia/CrystFEL/src/CrystFEL.jl +++ b/julia/CrystFEL/src/CrystFEL.jl @@ -38,7 +38,7 @@ export rotatecell, compare_reindexed_cell_parameters include("detgeom.jl") using .DetGeoms -export Panel, DetGeom +export Panel, DetGeom, DetGeomPanel, DetGeomGroup, findgroup include("symmetry.jl") using .Symmetry diff --git a/julia/CrystFEL/src/detgeom.jl b/julia/CrystFEL/src/detgeom.jl index b662e79d..6f57b167 100644 --- a/julia/CrystFEL/src/detgeom.jl +++ b/julia/CrystFEL/src/detgeom.jl @@ -1,5 +1,6 @@ module DetGeoms -export DetGeom, DetGeomPanel, InternalDetGeom, copydetgeom +export DetGeom, DetGeomPanel, DetGeomGroup, InternalDetGeom, copydetgeom +export findgroup mutable struct InternalPanel name::Cstring @@ -21,10 +22,23 @@ mutable struct InternalPanel end +mutable struct InternalDetGeomPanelGroup + name::Cstring + n_children::Cint + parent::Ptr{InternalDetGeomPanelGroup} + serial::Cint + cx::Cdouble + cy::Cdouble + cz::Cdouble + children::Ptr{Ptr{InternalDetGeomPanelGroup}} + panel::Ptr{InternalPanel} +end + + mutable struct InternalDetGeom panels::Ptr{InternalPanel} n_panels::Cint - top_group::Ptr{Cvoid} + top_group::Ptr{InternalDetGeomPanelGroup} end @@ -46,14 +60,20 @@ mutable struct DetGeomPanel h end +struct DetGeomGroup + serial + name + children + center # For rotation +end + mutable struct DetGeom panels::Vector{DetGeomPanel} + topgroup::DetGeomGroup end - - function copy_dg_panel(p::InternalPanel) DetGeomPanel(unsafe_string(p.name), p.cx, p.cy, p.cz, @@ -64,14 +84,56 @@ function copy_dg_panel(p::InternalPanel) end +function copydggroup(panels, grp) + grpdata = unsafe_load(grp, 1) + name = unsafe_string(grpdata.name) + children = DetGeomGroup[] + if grpdata.n_children > 1 + for i in 1:grpdata.n_children + cdata = unsafe_load(grpdata.children, i) + push!(children, copydggroup(panels, cdata)) + end + DetGeomGroup(grpdata.serial, name, children, + [grpdata.cx, grpdata.cy, grpdata.cz]) + else + name = unsafe_string(grpdata.name) + pn = findfirst(x->x.name==name, panels) + DetGeomGroup(grpdata.serial, name, [panels[pn]], + [grpdata.cx, grpdata.cy, grpdata.cz]) + end +end + + function copydetgeom(dg::Ptr{InternalDetGeom}) dgdata = unsafe_load(dg, 1) - detgeom = DetGeom(DetGeomPanel[]) + panels = DetGeomPanel[] for i in 1:dgdata.n_panels paneldata = unsafe_load(dgdata.panels, i) - push!(detgeom.panels, copy_dg_panel(paneldata)) + push!(panels, copy_dg_panel(paneldata)) + end + topgroup = copydggroup(panels, dgdata.top_group) + DetGeom(panels, topgroup) +end + + +function seq100(ser, head) + if ser == 0 + () + elseif ser < 100 + (head...,ser % 100) + else + seq100(ser ÷ 100, (head..., ser % 100)) end - detgeom +end + +findgroup(dg::DetGeom, ser) = findgroup(dg.topgroup, ser, seq100(ser÷100, ())) + +function findgroup(group::DetGeomGroup, ser, path) + if length(path) == 0 + @assert(group.serial == ser) + return group + end + findgroup(group.children[path[1]], ser, path[2:end]) end @@ -90,5 +152,20 @@ function Base.show(io::IO, p::DetGeomPanel) write(io, "))") end +function showgroup(io, p::DetGeomPanel, prefix) + println(io, prefix, "Panel ", p.name, " (",p.w,"×",p.h,")") +end + +function showgroup(io, grp::DetGeomGroup, prefix) + println(io, prefix, "Group ", grp.name, " (serial number ", grp.serial, ")") + for child in grp.children + showgroup(io, child, prefix*" ") + end +end + +function Base.show(io::IO, ::MIME"text/plain", dg::DetGeom) + println(io, "Detector geometry structure with ", length(dg.panels), " panels") + showgroup(io, dg.topgroup, " ") +end end # of module -- cgit v1.2.3