Files
uLib/CLAUDE.md

5.3 KiB

CLAUDE.md

This file provides guidance to Claude Code (claude.ai/code) when working with code in this repository.

Build Commands

# Activate the conda environment (required before any build/run)
export MAMBA_EXE="/home/share/micromamba/bin/micromamba"
export MAMBA_ROOT_PREFIX="/home/share/micromamba"
eval "$(/home/share/micromamba/bin/micromamba shell hook --shell bash)"
micromamba activate uLib

# Configure (from repo root, using Conan preset — uses Ninja + ccache)
cmake --preset conan-release

# Build everything
cmake --build build -j$(nproc)

# Build a specific target
cmake --build build --target gcompose -j$(nproc)

# Run tests
cmake --build build --target test
# or
ctest --test-dir build

# Run a single test binary (example)
./build/src/Core/testing/CoreTest

# Run the gcompose GUI app
./build/app/gcompose/gcompose

First-time setup (if build/ does not exist):

conan profile detect
conan install . --output-folder=build --build=missing
cmake --preset conan-release

Build acceleration (already configured)

  • Ninja generator — used automatically via the conan default profile (~/.conan2/profiles/default)
  • ccache — enabled via CMAKE_CXX_COMPILER_LAUNCHER=ccache; cached rebuilds are nearly instant (~0.3s vs ~25s cold)
  • Clang 22 + lld profile available (~/.conan2/profiles/fast) but blocked by template overload ambiguities in src/Core/Archives.h that need fixing for full compatibility

To reconfigure with the fast profile once Archives.h is fixed:

conan install . --output-folder=build --build=missing --profile=fast
cmake -B build -G Ninja -DCMAKE_TOOLCHAIN_FILE=build/conan_toolchain.cmake -DCMAKE_BUILD_TYPE=Release
cmake --build build -j$(nproc)

Architecture

uLib is a C++ framework for Cosmic Muon Tomography (CMT), structured as layered shared libraries:

mutomCore  →  mutomMath  →  mutomDetectors  →  mutomGeant
                                              ↘
                                           mutomVtk  →  gcompose (Qt6 GUI app)
                                           mutomRoot

Core Object Model (src/Core/)

  • All framework objects inherit from uLib::Object
  • Property system: Property<T> wraps member pointers with change notification via PropertyChanged signal
  • Signal/slot: uLib::Object::connect(sender, &Sender::Signal, callback) — resembles Qt but works for non-QObject classes
  • Serialization: Boost archives (xml_oarchive, text_oarchive, hrt_oarchive); hrp<T> marks fields as "human-readable properties"
  • ObjectsContext is a container owning a list of Object* pointers; signals ObjectAdded/ObjectRemoved

VTK Layer (src/Vtk/)

  • Prop3D (inherits uLib::Object): wraps a VTK vtkProp for rendering. Has GetContent() returning the underlying domain object. Display-only properties are registered via ULIB_ACTIVATE_DISPLAY_PROPERTIES macro.
  • Viewport: base class managing the VTK renderer, picking, selection logic. Maintains m_Prop3Ds vector and m_ObjectToProp3D map.
  • QViewport (inherits QWidget + Viewport): Qt-embedded VTK widget. Emits Qt signal prop3dSelected(Prop3D*) on click-selection via OnSelectionChanged.
  • vtkObjectsContext: wraps ObjectsContext, creating/destroying Prop3Ds as objects come/go. Emits Prop3DAdded/Prop3DRemoved.
  • Display properties: serialize_display() + display_properties_archive registers selected hrp<T> fields as PropertyBase* in the prop3d's m_DisplayProperties. PropertyEditor::setObject(obj, displayOnly=true) shows only those.

gcompose GUI App (app/gcompose/src/)

  • MainPanel: top-level widget. Owns ContextPanel (left) and ViewportPane (right). Wires together viewport↔context selection via signals.
  • ContextPanel: tree view of ObjectsContext. Emits objectSelected(Object*). Contains an embedded PropertiesPanel.
  • PropertiesPanel: shows uLib::Object properties via PropertyEditor.
  • ViewportPane: embeds QViewport + a slide-out "Display Properties" panel (PropertyEditor in display-only mode).
  • PropertyEditor: populates widgets from Object::GetProperties() (all) or Prop3D::GetDisplayProperties() (display-only mode).

Selection Sync Flow

Viewport click  →  Viewport::SelectProp3D()  →  QViewport::OnSelectionChanged()
                →  emit prop3dSelected(p)
                →  MainPanel: contextPanel->selectObject(p->GetContent())  [updates tree + PropertiesPanel]
                →  MainPanel: firstPane->setObject(p)  [updates Display Properties panel]

ContextPanel tree click  →  emit objectSelected(obj)
                →  MainPanel: viewport->SelectProp3D(prop3d)  [visual selection in VTK]
                →  MainPanel: firstPane->setObject(prop3d)  [updates Display Properties panel]

Key Patterns

  • Two signal systems coexist: Qt signals (Q_OBJECT, connect(...)) for GUI; uLib::Object::connect(...) for domain signals.
  • Display properties flow: Prop3D::serialize_display()display_properties_archiveRegisterDisplayProperty()PropertyEditor(displayOnly=true). Must call ULIB_ACTIVATE_DISPLAY_PROPERTIES in the prop3d constructor.
  • Prop3D ↔ Object map: Viewport::m_ObjectToProp3D allows lookup by domain object; vtkObjectsContext::GetProp3D(obj) does the same.