Skip to content

add_variables: DataArray bounds with missing dimensions yield wrong dimension order #706

@FBumann

Description

@FBumann

Issue Description

Follow-up to #450 (partially fixed by #614).

After #614, add_variables correctly applies the full dimensionality from coords even when the lower/upper bounds are DataArrays missing some of those dimensions. However, the dimension order of the resulting variable depends on the type of the bounds rather than on coords:

  • If at least one bound is a scalar (int/float), the variable follows the coords order.
  • If both bounds are DataArrays missing the same dimension, that dimension gets prepended instead of placed in coords order.

This is inconsistent and surprising — the variable's dimension order should always match coords.

Reproducible Example

import xarray as xr
import numpy as np
import linopy

m = linopy.Model()
test = xr.DataArray(np.random.rand(3, 2), [("x", ["a", "b", "c"]), ("y", ["X", "Y"])])

# Scalar lower bound -> dims follow coords order: ('x', 'y')
foo = m.add_variables(lower=0, upper=test.sum("y"), coords=test.coords, name="foo")
print("foo:", foo.dims)   # ('x', 'y')

# Both bounds are DataArrays missing 'y' -> 'y' is prepended: ('y', 'x')
bar = m.add_variables(lower=-test.sum("y"), upper=test.sum("y"), coords=test.coords, name="bar")
print("bar:", bar.dims)   # ('y', 'x')  <-- wrong

Output:

foo: ('x', 'y')
bar: ('y', 'x')

Expected Behavior

Both foo and bar should have dimensions in the order given by coords, i.e. ('x', 'y').

Root Cause

In linopy/model.py, _validate_dataarray_bounds expands missing dimensions with arr.expand_dims(expand). DataArray.expand_dims prepends new dimensions by default, so a bound with dims ('x',) becomes ('y', 'x') instead of ('x', 'y'). When only one bound is a scalar, as_dataarray/xr.broadcast happens to recover the coords order, which masks the bug — hence the type-dependent inconsistency.

A fix would transpose the expanded array back to the coords dimension order after expand_dims.

Installed Versions

linopy 0.7.0.post1.dev18+ged594d7fb (current master, commit ed594d7).

Metadata

Metadata

Assignees

No one assigned

    Labels

    bugSomething isn't working

    Type

    No type
    No fields configured for issues without a type.

    Projects

    No projects

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions