Skip to content

Commit 5132b77

Browse files
authored
Merge branch 'develop' into add-spin
2 parents 8e7751d + e3a640a commit 5132b77

74 files changed

Lines changed: 6674 additions & 1542 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

‎.github/workflows/test.yml‎

Lines changed: 72 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,72 @@
1+
# Runs the pytest suite on every supported OS and Python version.
2+
#
3+
# Modelled on reflectometry-lib's test.yml (same triggers, concurrency and OS
4+
# matrix), but installed with pip: the app has no pixi environment. The suite
5+
# is fast enough (~1-2 min) that there is no fast/slow split.
6+
7+
name: Code tests
8+
9+
on:
10+
# Trigger the workflow on push
11+
push:
12+
branches-ignore: [master, main] # Already verified in PR
13+
# But do not run this workflow on creating a new tag starting with 'v'
14+
tags-ignore: ['v*']
15+
# Trigger the workflow on pull request
16+
pull_request:
17+
branches: ['**']
18+
# Allows you to run this workflow manually from the Actions tab
19+
workflow_dispatch:
20+
21+
permissions:
22+
contents: read
23+
24+
# Allow only one concurrent workflow, skipping runs queued between the run
25+
# in-progress and latest queued. And cancel in-progress runs.
26+
concurrency:
27+
group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.ref }}
28+
cancel-in-progress: true
29+
30+
jobs:
31+
source-test:
32+
timeout-minutes: 30
33+
34+
strategy:
35+
fail-fast: false
36+
matrix:
37+
os: [ubuntu-24.04, macos-15, windows-2022]
38+
python-version: ['3.12', '3.13']
39+
40+
runs-on: ${{ matrix.os }}
41+
42+
env:
43+
# No display on the runners. Only test_qml_close_behaviour.py starts a
44+
# QGuiApplication (in a subprocess), and it needs this too.
45+
QT_QPA_PLATFORM: offscreen
46+
QT_QUICK_BACKEND: software
47+
48+
steps:
49+
- name: Checkout repository
50+
uses: actions/checkout@v4
51+
52+
- name: Set up Python ${{ matrix.python-version }}
53+
uses: actions/setup-python@v5
54+
with:
55+
python-version: ${{ matrix.python-version }}
56+
cache: pip
57+
cache-dependency-path: pyproject.toml
58+
59+
# Shared libraries the Qt offscreen platform plugin loads on Linux.
60+
- name: Install Qt runtime libraries (Linux)
61+
if: runner.os == 'Linux'
62+
run: |
63+
sudo apt-get update
64+
sudo apt-get install -y libegl1 libgl1 libxkbcommon0 libfontconfig1 libdbus-1-3
65+
66+
- name: Install the app with test dependencies
67+
run: |
68+
python -m pip install --upgrade pip
69+
python -m pip install -e ".[test]"
70+
71+
- name: Run tests
72+
run: python -m pytest tests --color=yes -v

‎CHANGELOG.md‎

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,45 @@
1818
- An "H →" reference is on screen wherever an arrow is.
1919
- A project with no magnetic layer is unchanged: no arrows, no slider, and the
2020
same Structure and SLD layout as before.
21+
- Multiple contrasts ([#425](https://github.com/easyscience/reflectometry-lib/issues/425)):
22+
- New demo files `examples/datasets/film_contrasts.ort` (a film on silicon in
23+
D2O, H2O and CMSi, with its slab model in the header) and `dppc_contrasts.ort`
24+
(three contrasts of a DPPC monolayer) for trying Add contrast and a joint fit
25+
(see the datasets README).
26+
- "Add contrast of the selected model…" on the Sample page creates a model
27+
sharing the selected one's structure, with chosen materials replaced (e.g.
28+
D2O by H2O, which also changes every hydrated layer) or re-formulated
29+
(isotopic substitution). Its scale, background and resolution are its own.
30+
A shared assembly is marked ⇄ in the model editor: editing it edits every
31+
model sharing it.
32+
- "Model constraints" is now "Link contrasts": it ties the selected models'
33+
corresponding parameters, but no longer their scale and background, and
34+
their material SLDs only on request. Layouts that do not correspond are
35+
reported instead of being tied partially. Removing a tie restores the
36+
parameter's value and bounds from before the link.
37+
- The parameters table lists a parameter shared by several models once,
38+
marked ⇄ with the models in its tooltip; a shared layer parameter can be
39+
detached for one model.
40+
- Each experiment's model is chosen per row on the Experiment and Analysis
41+
pages and shows the stored pairing (the combo used to reset to the first
42+
model and could change another experiment).
43+
- A "Fit" checkbox per experiment chooses what the next fit, or Bayesian
44+
sampling, includes; a parameter that an included model follows stays
45+
fitted even when its own model is left out. The pre-fit bound checks look
46+
only at the parameters the fit varies. The results dialog lists each
47+
dataset's χ² per point and share of the total; the statistics come from
48+
the library's record of the last completed run, so they survive switching
49+
the current model and are not replaced by a failed or cancelled run.
50+
- The Analysis chart has the staggered view too (not in the R·q⁴ view).
51+
- Linking several models links all of them or, when one cannot be linked,
52+
none.
53+
- Removing a model that experiments use asks whether to remove them or fit
54+
them with another model; experiments are no longer removed by position.
55+
- A data file that cannot be read is reported in a dialog.
56+
- The HTML report lists all models, with the model each contrast was derived
57+
from.
58+
- The legacy synchronous fit path (`Fitting.start_stop`) was removed; the GUI
59+
always fitted in a worker thread.
2160

2261
- Added a **Structure** tab on the Model page: a schematic view of the layer stack with one
2362
colored box per layer (colors per material, heights following thickness, "× N" badges for

‎EasyReflectometryApp/Backends/Mock/Analysis.qml‎

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,11 @@ QtObject {
1818
// Minimizer
1919
readonly property double minimizerTolerance: 1.0
2020
readonly property int minimizerMaxIterations: 2
21+
readonly property var fitObjectives: ['hybrid', 'mighell', 'legacy_mask']
22+
readonly property string fitObjective: 'hybrid'
23+
readonly property var minimizerOptions: []
24+
readonly property bool minimizerRequiresFiniteBounds: false
25+
readonly property int unboundedFreeParametersCount: 0
2126

2227
// Fitting
2328
readonly property string fittingStatus: ''//undefined //'Success'
@@ -61,10 +66,21 @@ QtObject {
6166
function bayesianComputeHeatmap(x, y) {
6267
console.debug(`bayesianComputeHeatmap ${x}, ${y}`)
6368
}
69+
function saveBayesianPlot(sourceUrl, destinationUrl) {
70+
console.debug(`saveBayesianPlot ${sourceUrl} -> ${destinationUrl}`)
71+
return true
72+
}
73+
function bayesianPlotSuggestedFileUrl(sourceUrl) {
74+
console.debug(`bayesianPlotSuggestedFileUrl ${sourceUrl}`)
75+
return ''
76+
}
6477

6578
// Fit failure signal (mirrors Python backend)
6679
signal fitFailed(string message)
6780

81+
// Pre-fit check failure signal (mirrors Python backend)
82+
signal prefitCheckFailed(string title, string message)
83+
6884
// Stop fit signal (mirrors Python backend)
6985
signal stopFit()
7086

@@ -139,6 +155,21 @@ QtObject {
139155
function setMinimizerTolerance(value) {
140156
console.debug(`setMinimizerTolerance ${value}`)
141157
}
158+
function resetMinimizerTolerance() {
159+
console.debug('resetMinimizerTolerance')
160+
}
161+
function resetMinimizerMaxIterations() {
162+
console.debug('resetMinimizerMaxIterations')
163+
}
164+
function setFitObjective(value) {
165+
console.debug(`setFitObjective ${value}`)
166+
}
167+
function setMinimizerOption(name, text) {
168+
console.debug(`setMinimizerOption ${name} ${text}`)
169+
}
170+
function showFreeParameters() {
171+
console.debug('showFreeParameters')
172+
}
142173
function setMinimizerMaxIterations(value) {
143174
console.debug(`setMinimizerMaxIterations ${value}`)
144175
}

0 commit comments

Comments
 (0)