Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
36 changes: 18 additions & 18 deletions .github/workflows/installer.yml
Original file line number Diff line number Diff line change
Expand Up @@ -111,26 +111,26 @@ jobs:
# ${{ secrets.APPLE_CERT_DATA }} ${{ secrets.APPLE_CERT_PASSWORD }}
# ${{ secrets.APPLE_NOTARY_USER }} ${{ secrets.APPLE_NOTARY_PASSWORD }}

- name: Setup SM_CLIENT_CERT_FILE from base64 secret data
if: runner.os == 'Windows'
run: |
echo "${{ secrets.KEYLOCKER_CERT_DATA }}" | base64 --decode > /d/Certificate_pkcs12.p12
shell: bash
# - name: Setup SM_CLIENT_CERT_FILE from base64 secret data
# if: runner.os == 'Windows'
# run: |
# echo "${{ secrets.KEYLOCKER_CERT_DATA }}" | base64 --decode > /d/Certificate_pkcs12.p12
# shell: bash


- name: Setup Software Trust Manager
if: runner.os == 'Windows'
uses: digicert/code-signing-software-trust-action@v1
with:
simple-signing-mode: true
# If the below 2 parameters are supplied, then smctl executable is invoked to attempt the signing.
input: ${{ env.SETUP_EXE_PATH }}
keypair-alias: ${{ secrets.KEYLOCKER_KEYPAIR_ALIAS }}
env:
SM_HOST: ${{ secrets.KEYLOCKER_HOST }}
SM_API_KEY: ${{ secrets.KEYLOCKER_API_KEY }}
SM_CLIENT_CERT_FILE: D:\\Certificate_pkcs12.p12
SM_CLIENT_CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }}
# - name: Setup Software Trust Manager
# if: runner.os == 'Windows'
# uses: digicert/code-signing-software-trust-action@v1
# with:
# simple-signing-mode: true
# # If the below 2 parameters are supplied, then smctl executable is invoked to attempt the signing.
# input: ${{ env.SETUP_EXE_PATH }}
# keypair-alias: ${{ secrets.KEYLOCKER_KEYPAIR_ALIAS }}
# env:
# SM_HOST: ${{ secrets.KEYLOCKER_HOST }}
# SM_API_KEY: ${{ secrets.KEYLOCKER_API_KEY }}
# SM_CLIENT_CERT_FILE: D:\\Certificate_pkcs12.p12
# SM_CLIENT_CERT_PASSWORD: ${{ secrets.WINDOWS_CERT_PASSWORD }}

- name: Create zip archive of offline app installer for distribution
run: >
Expand Down
3 changes: 3 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -50,3 +50,6 @@ settings.ini*

#Snap
*.snap

# Claude Code personal settings
.claude/settings.local.json
13 changes: 13 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
@@ -1,3 +1,16 @@
# Version 1.4.0 (3 Aug 2026)

- Added Bayesian analysis: run MCMC sampling alongside classical fitting, with posterior median and credibility intervals on the main chart, trace/corner-style plots per parameter, a dedicated status display with cancellation support, and plot export.
- Bayesian results are now cleared whenever they become stale: on project create/load/reset, when a classical fit starts, and when a new sampling run starts. Previously the posterior overlays, plots and the "Bayesian Sampling Results" dialog could show results from a superseded run or a different project.
- Cancelling a fit now keeps the UI locked until the worker thread actually exits, and late signals from a superseded worker are ignored. This prevents two fits from mutating the shared parameters concurrently when the minimizer cannot abort mid-run (lmfit, DFO).
- Bayesian sampling no longer fails for data files without uncertainty/resolution columns: missing `ye` falls back to zero variances (reported by the sampler with a clear message) and the unused `xe` is no longer attached to the Q coordinate.
- Fixed wrong parameter group/display names for the first and last layers of each assembly: the parameter-tree walker now prefers the canonical `layers` container over the `front_layer`/`back_layer` alias properties.
- Removed the unused `corner` dependency.
- Migrated to the new `easyscience` core API surface exposed by `reflectometry-lib`:
- Layer removal now calls `remove_at(index)`; the lib's index-based `remove` was replaced by standard `MutableSequence.remove(value)` semantics.
- Parameter discovery uses `get_all_parameters()`.
- **Breaking:** project files saved by earlier versions (predating `file_format=2`) can no longer be opened. Opening one now shows a clear error dialog instead of failing uncaught; affected projects must be recreated.

# Version 1.3.0 (1 May 2026)

- Migrated the application to the new `EasyApplication` module and removed the old `EasyApp` footer dependency.
Expand Down
34 changes: 34 additions & 0 deletions EasyReflectometryApp/Backends/Mock/Analysis.qml
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,28 @@ QtObject {
readonly property var fitPreviewParameterValues: ({})
readonly property var fitResults: ({ success: true, nvarys: 3, chi2: 1.2345 })

// Bayesian sampling
readonly property bool isBayesianSelected: false
readonly property int bayesianSamples: 10000
readonly property int bayesianBurnIn: 2000
readonly property int bayesianPopulation: 10
readonly property int bayesianThinning: 1
readonly property var bayesianPosterior: null
readonly property bool bayesianResultAvailable: false
readonly property var bayesianMarginals: []

// Phase 2: corner/trace/distribution plots (HTML), diagnostics, heatmap
readonly property string bayesianCornerPlotUrl: ''
readonly property string bayesianTracePlotUrl: ''
readonly property string bayesianDistributionPlotUrl: ''
readonly property var bayesianDiagnostics: ({})
readonly property var bayesianParamNames: []
readonly property var bayesianHeatmapData: null
readonly property string bayesianHeatmapPlotUrl: ''
function bayesianComputeHeatmap(x, y) {
console.debug(`bayesianComputeHeatmap ${x}, ${y}`)
}

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

Expand Down Expand Up @@ -123,4 +145,16 @@ QtObject {
showFitResultsDialog = value
console.debug(`setShowFitResultsDialog ${value}`)
}
function setBayesianSamples(value) {
console.debug(`setBayesianSamples ${value}`)
}
function setBayesianBurnIn(value) {
console.debug(`setBayesianBurnIn ${value}`)
}
function setBayesianPopulation(value) {
console.debug(`setBayesianPopulation ${value}`)
}
function setBayesianThinning(value) {
console.debug(`setBayesianThinning ${value}`)
}
}
4 changes: 2 additions & 2 deletions EasyReflectometryApp/Backends/Mock/Home.qml
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,8 @@ QtObject {
property bool created: false

readonly property var version: {
'number': '1.3.1',
'date': '1 May 2026',
'number': '1.4.0',
'date': '3 Aug 2026',
}

readonly property var urls: {
Expand Down
14 changes: 14 additions & 0 deletions EasyReflectometryApp/Backends/Mock/Plotting.qml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,20 @@ QtObject {
property bool scaleShown: false
property bool bkgShown: false

// Posterior predictive (Bayesian) overlay data
readonly property var posteriorPredictiveQ: []
readonly property var posteriorPredictiveMedian: []
readonly property var posteriorPredictiveLower: []
readonly property var posteriorPredictiveUpper: []
signal posteriorPredictiveDataChanged()

// Phase 2: SLD posterior predictive (Bayesian) overlay
readonly property var posteriorPredictiveSldZ: []
readonly property var posteriorPredictiveSldMedian: []
readonly property var posteriorPredictiveSldLower: []
readonly property var posteriorPredictiveSldUpper: []
signal posteriorPredictiveSldDataChanged()

// Signals for plot mode changes
signal plotModeChanged()
signal axisTypeChanged()
Expand Down
2 changes: 1 addition & 1 deletion EasyReflectometryApp/Backends/Mock/Status.qml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ import QtQuick
QtObject {

readonly property string project: 'Undefined'
readonly property string phaseCount: '1'
readonly property string modelsCount: '1'
readonly property string experimentsCount: '1'
readonly property string calculator: 'CrysPy'
readonly property string minimizer: 'Lmfit (leastsq)'
Expand Down
Loading
Loading