Skip to content

Use om.Constraints throughout.#86

Merged
hmgaudecker merged 69 commits intomainfrom
om.Constraints
Mar 18, 2026
Merged

Use om.Constraints throughout.#86
hmgaudecker merged 69 commits intomainfrom
om.Constraints

Conversation

@hmgaudecker
Copy link
Member

@hmgaudecker hmgaudecker commented Mar 14, 2026

We still had the dict-based constraints from estimagic in here and converted to modern constraints only in the very last step. This PR switches to the optimagic constraints.

Main realisation: optimagic just picks whatever start value there is; but skillmodels needs to set the start value for fixed constraints. Hence we introduce a simple wrapper class:

@dataclass(frozen=True)
class FixedConstraintWithValue(om.FixedConstraint):
    """Fixed constraint that carries the target value and parameter location.

    `om.FixedConstraint` fixes parameters at their start values but does not carry a
    target value. This wrapper adds `loc` (the parameter location in the params
    DataFrame) and `value` (the value to set before optimization).
    """

    loc: pd.MultiIndex | tuple | str | None = None
    """Parameter location in the params DataFrame."""
    value: float | None = None
    """Value to enforce on the parameter."""

    def __post_init__(self) -> None:
        """Validate that `loc` and `value` are not None and derive `selector`."""
        if self.loc is None:
            msg = "loc must not be None"
            raise TypeError(msg)
        if self.value is None:
            msg = "value must not be None"
            raise TypeError(msg)
        object.__setattr__(
            self,
            "selector",
            functools.partial(select_by_loc, loc=self.loc),
        )

hmgaudecker and others added 30 commits January 8, 2026 18:53
Introduce strongly-typed dataclasses for model configuration:
- Dimensions, Labels, Anchoring, EstimationOptions, TransitionInfo
- FactorEndogenousInfo, EndogenousFactorsInfo

This improves type safety and enables IDE autocompletion while keeping
user-facing model_dict as a plain dictionary.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Replace dict fields with frozendict in frozen dataclasses to ensure
true immutability:
- Labels.aug_periods_to_periods
- Labels.aug_stages_to_stages
- Anchoring.outcomes
- TransitionInfo.param_names, individual_functions, function_names
- EndogenousFactorsInfo.aug_periods_to_aug_period_meas_types, factor_info

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Update process_model() to return a ProcessedModel frozen dataclass
and update all consumers to use attribute access instead of dict access.

This provides:
- Better type safety with explicit typed fields
- Immutability via frozen dataclass
- IDE autocomplete support
- Clear documentation of the model structure

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
…c so that config.TEST_DATA_DIR is valid also for skillmodels the package (as opposed to the project).
The filtered_states DataFrame and params index both use aug_period as the
period identifier, not period. This fixes KeyError when calling
decompose_measurement_variance.

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
@codecov
Copy link

codecov bot commented Mar 14, 2026

Codecov Report

❌ Patch coverage is 94.47853% with 9 lines in your changes missing coverage. Please review.
✅ Project coverage is 96.86%. Comparing base (e965395) to head (da915d5).
⚠️ Report is 1 commits behind head on main.

Files with missing lines Patch % Lines
src/skillmodels/constraints.py 93.24% 5 Missing ⚠️
tests/test_constraints.py 93.61% 3 Missing ⚠️
src/skillmodels/transition_functions.py 95.23% 1 Missing ⚠️
Additional details and impacted files
@@            Coverage Diff             @@
##             main      #86      +/-   ##
==========================================
- Coverage   97.04%   96.86%   -0.19%     
==========================================
  Files          57       57              
  Lines        4845     4809      -36     
==========================================
- Hits         4702     4658      -44     
- Misses        143      151       +8     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

hmgaudecker and others added 5 commits March 15, 2026 14:47
Remove list from loc type union, convert callers to tuple().
Update anchoring test expectations from list to tuple.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
@hmgaudecker hmgaudecker marked this pull request as ready for review March 15, 2026 13:50
@hmgaudecker hmgaudecker requested a review from janosg March 15, 2026 13:50
hmgaudecker and others added 9 commits March 15, 2026 16:59
The viz code assumed states DataFrames always have `aug_period` as a
column, but pre-computed states (e.g. from health-cognition) may carry
`period` in the index instead. Add `_normalize_states_columns` to
promote index levels and rename `period` → `aug_period` when needed.

Also document the period vs aug_period convention in CLAUDE.md.

Co-Authored-By: Claude Opus 4.6 (1M context) <noreply@anthropic.com>
Base automatically changed from output-formatting to main March 18, 2026 13:02
@hmgaudecker hmgaudecker merged commit 023775e into main Mar 18, 2026
4 checks passed
@hmgaudecker hmgaudecker deleted the om.Constraints branch March 18, 2026 13:03
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants