Repository navigation
calibrate SSP parameters against reference data - #1675
Merged
Merged
Conversation
Add OMSimulator.calibration: fits the parameters of a Calibration activity of the OpenSCALING UQ layered standard to the reference data of a CSV file by bounded nonlinear least squares (scipy.optimize.least_squares). The UQ file is the one the SSD references by ssc:MetaData of type application/x-uncertainty-quantification. * each evaluation resets the instantiated model, sets the parameters, initializes and steps through the reference time points, no result file * the model starts at its own start time; a calibration window only selects the compared samples * RMSE per observed variable as ErrorMetric in the ResultSet, calibrated values as <activity>_calibrated.ssv next to the UQ file * column mapping, weights, time window, scaling and optimizer settings, not yet in the standard, from a KeyValues element of type org.openmodelica.omsimulator.calibration in the SimulationSetting * command line: OMSimulator --calibrate [ACTIVITY] [--calibrationOutput] [--uqFile] model.ssp * pip extra OMSimulator[calibration] for numpy and scipy * test calibration/HelloWorldCalibration.py fits a and x_start of HelloWorld to exp(-t), over all samples and over t >= 0.5 Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
A wrong activity id, a missing UQ file or an unknown observed variable made `OMSimulator --calibrate` print a Python traceback. They are user errors, so print them as a single "error:" line on stderr and exit with status 1. OMEdit shows that line in its calibration dialog. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This was referenced Oct 20, 2026
calibration.HelloWorldCalibration failed in the coverage workflow with "No module named 'numpy'": the bare GitHub runner only had what the workflow installed with apt, and the calibration needs the optional OMSimulator[calibration] dependencies. Run the job in docker.openmodelica.org/build-deps:ubuntu-24.04-omsimulator instead, the image the linux64-noble Jenkins stage already uses. It has the compilers, flex, ccache, gcovr and the testsuite's Python packages (numpy and scipy included), so the apt step goes away and the coverage runs see the same environment as Jenkins. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
adrpo
force-pushed
the
ssp-calibration
branch
from
October 20, 2026 13:15
9935e55 to
cba3cee
Compare
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## master #1675 +/- ##
==========================================
+ Coverage 27.69% 28.35% +0.65%
==========================================
Files 72 72
Lines 13976 13976
Branches 9020 9020
==========================================
+ Hits 3871 3963 +92
+ Misses 8876 8775 -101
- Partials 1229 1238 +9
Flags with carried forward coverage won't be shown. Click here to find out more. ☔ View full report in Codecov by Harness. 🚀 New features to boost your workflow:
|
This was referenced Oct 20, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Fixes #1674.
Adds
OMSimulator.calibration. It fits the parameters of aCalibrationactivity of the OpenSCALING UQ layered standard to the reference data in a CSV file, on an SSP. The fit is bounded nonlinear least squares (scipy.optimize.least_squares). The UQ file is the one the SSD references byssc:MetaDataof typeapplication/x-uncertainty-quantification.How it works
reset, sets the fixedParameterSetvalues and the targets, runsinitialize, thenstepUntileach reference time point andgetValueon the observed variables. No result file is written.ResultSetgets anErrorMetric type="RMSE"per observed variable and refers to<activity>_calibrated.ssv, an SSP parameter set with the calibrated values written next to the UQ file. Both validate against their schemas (UQ specification-v1, SSP 2.0).<uq:KeyValues type="org.openmodelica.omsimulator.calibration">in theSimulationSetting, which the schema allows:dataName:<var>,weight:<var>,startTime,stopTime,scaling,relativeTolerance,maxEvaluations,diffStep. By default an observed variable maps to the CSV column with its name, optionally followed by|unit.pip install OMSimulator[calibration]. Theomsimulatorbuild-deps images already have scipy.Tests
calibration/HelloWorldCalibration.pyfitsaandx_startofHelloWorld(der(x) = a*x) toexp(-t).cal_01uses all samples;cal_02uses only t ≥ 0.5 while the model still starts at 0. Both recovera = -1,x_start = 1. Checked thatcal_02fails (x_start = 0.6065) if the simulation starts at the first compared sample. Run withruntest.pyagainst an installed OMSimulator (pin ffc28b1) plus this branch's Python sources.Validation on the OpenSCALING DC-motor use case
This is the OpenSCALING DC-motor calibration (
d2.1-uq-layered-standard,use_cases/dc_motor, activitycal_01): 6 parameters, 502 noisy samples of speed and current at 13 V / 0.25 N·m. The SSP was rebuilt from three FMUs exported by omc 1.28 as model exchange (one CVODE integrates the whole system), and it matches the omc simulation ofDCMotor_L3to six digits. The run takes 485 evaluations and 15 s:Using the use case needed three changes, which were made in the test SSP, not in this PR:
ParameterSetnamesconstantVoltage.V/constantTorque.tau_constantare calculated parameters in an FMU;Vbattideal/Tmechloadwere used instead.level_3_dc_motor.Iis the negative of the CSV columndc_motor_electric1.I, sodc_motor.dc_motor_electric1.Iis observed.uq:Settingselement is no longer in the schema and was dropped.With co-simulation (the default for
me_csFMUs) the fit is off (c_gat its upper bound), because the electrical time constant of 1 ms is no larger than the communication step.Not in this PR
info:lines (step size, final statistics), since info messages cannot be silenced from Python.Error reporting
An invalid calibration problem (unknown activity id, no UQ file, unknown observed variable, ...) is reported as a single
error:line on stderr with exit status 1, not a Python traceback.Coverage workflow
The calibration test needs numpy and scipy, which the bare GitHub runner of the coverage workflow did not have. The job now runs in
docker.openmodelica.org/build-deps:ubuntu-24.04-omsimulator, the image the linux64-noble Jenkins stage uses, so coverage and Jenkins test in the same environment. OpenModelica/build-deps#101 also adds numpy and scipy to every apt image, not only the omsimulator add-on.OMEdit
The OMEdit front end is OpenModelica/OpenModelica#17360 (issue OpenModelica/OpenModelica#17359): a Calibrate dialog for SSP models that runs
OMSimulator --calibrate. It needs an OMSimulator submodule bump after this PR is merged.Generated by Claude Code
🤖 Generated with Claude Code