Skip to content

(I002) setInputsCSV()#447

Draft
syntron wants to merge 14 commits into
OpenModelica:masterfrom
syntron:I002-setInputsCSV
Draft

(I002) setInputsCSV()#447
syntron wants to merge 14 commits into
OpenModelica:masterfrom
syntron:I002-setInputsCSV

Conversation

@syntron
Copy link
Copy Markdown
Contributor

@syntron syntron commented Mar 6, 2026

Read content from a CSV file and use it to define the time based input data.

See issue #353 - currently completly untested from my side!

@FaBiasch could you please tests?

@syntron
Copy link
Copy Markdown
Contributor Author

syntron commented Mar 18, 2026

from PR #404:

But what against the following code:

    mod = ModelicaSystemRunner(work_directory='.')
    mod.setup(model_name=modelName)
    mod.setInputsCSV(csvfile=csvfile)
    mod.simulate(resultfile=resfilepathname)

So this creates a CSV file (as input for the model executable) from a CSV file (for setInputsCSV) that the user needs to provide. I would try to avoid this workflow if possible.

  • it adds unnecessary overhead (which may become relevant when calling ModelicaSystemRunner in huge batches)
  • we need means to customize the location of the intermediate CSV file and users may need to take care about this.
  • users will end up checking two input files in case some things go wrong
  • users will need to take care for additional cleaning & deleting input files

So I would currently prefer setting csvInput in simargs as you proposed above @syntron . At least for ModelicaSystemRunner there shouldn't be a problem with WSL, Docker, k8s & co.

On the other hand, I also like the idea of having a simple pythonic interface for timeseries inputs in OMPython. What do you think about

  • mod.setInputsSeries(series=dict or list of dicts). E.g. series=
    [{'time': 0.0, 'col1': 1, 'col2': 0.5}, {'time': 0.25, 'col1': 2, 'col2': 0.75}, {'time': 0.5, 'col1': 2.1, 'col2': 0.8}]
  • or mod.setInputsDataframe(dataframe=dataframe)

I think this would fit the current workflow of OMPython well. And in case the interfaces to the model executables is changed again in a future version, the users wouldn't need to worry about it.

I would not do it via a pandas dataframe as this would add the dependency to OMPython; but using the dictionary would work - at the end, the current code just converts the CSV file to a dictionary to apply it to the existing data.

@joewa would this work for you?

@joewa
Copy link
Copy Markdown

joewa commented Mar 20, 2026

Yes, that would work for me @syntron .

When using tables / DataFrames this helper function proved to be useful too:

def toInputs(data: dict[str, list[float]]) -> dict[str, list[tuple[float, float]]]:
    """
    Converts a dictionary of lists (from pandas DataFrame.to_dict(orient='list'))
    into the OMPython setInputs input format.

    Example: mod.setInputs(**toInputs(pdf.to_dict(orient='list')))
    
    Assumes the dictionary contains a key named 'time'.
    """
    if "time" not in data:
        raise ValueError("The provided data must contain a 'time' key.")

    time_series = data["time"]

    inputs = {
        var_name: list(zip(time_series, values))
        for var_name, values in data.items()
        if var_name != "time"
    }

    return inputs

Shall we add it as well?

@syntron
Copy link
Copy Markdown
Contributor Author

syntron commented Apr 1, 2026

Yes, that would work for me @syntron .

When using tables / DataFrames this helper function proved to be useful too:

def toInputs(data: dict[str, list[float]]) -> dict[str, list[tuple[float, float]]]:
    """
    Converts a dictionary of lists (from pandas DataFrame.to_dict(orient='list'))
    into the OMPython setInputs input format.

    Example: mod.setInputs(**toInputs(pdf.to_dict(orient='list')))
    
    Assumes the dictionary contains a key named 'time'.
    """
    if "time" not in data:
        raise ValueError("The provided data must contain a 'time' key.")

    time_series = data["time"]

    inputs = {
        var_name: list(zip(time_series, values))
        for var_name, values in data.items()
        if var_name != "time"
    }

    return inputs

Shall we add it as well?

Looks good to me! This can be added as a staticmethod to ModelicaSystemABC. The check for numeric values is done in setInputs() ...

syntron added a commit to syntron/OMPython that referenced this pull request Apr 1, 2026
@joewa
Copy link
Copy Markdown

joewa commented Apr 6, 2026

Perfect!

syntron added 14 commits May 11, 2026 20:15
[test_*] reorder imports

[tests_ModelicaDoE*] fix pylint hint

* use .items()

[tests_*] use OMSessionABC.get_version()

[test_ModelicaSystemCmd] use get_model_name() instead of access to private variable _model_name

[test_ModelicaSystemOMC] read file using utf-8 encoding / linter fix

[test_ModelicaSystemRunner] update test case

* ModelicaSystemRunner & OMCPath
* ModelicaSystemRunner & OMPathRunnerLocal
* ModelicaSystemRunner & OMPathRunnerBash
* ModelicaSystemRunner & OMPathRunnerBash using docker
* ModelicaSystemRunner & OMPathRunnerBash using WSL (not tested!)

[test_OMCPath] update test case

* OMCPath & OMCSessionZMQ
* OMCPath & OMCSessionLocal
* OMCPath & OMCSessionDocker
* OMCPath & OMCSessionWSL (not tested!)
* OMPathLocal & OMCSessionRunner
* OMPathBash & OMCSessionRunner
* OMPathBash & OMCSessionRunner in docker
* OMPathBash & OMCSessionRunner in WSL (not tested!)

add workflow to run unittests in ./tests

[test_OMParser] use only the public interface => om_parser_basic()

[test_OMTypedParser] rename file / use om_parser_typed()

update tests - do NOT run test_FMIRegression.py

reason:
* it is only a test for OMC / not OMPython specific
* furthermore, it is run automatically via cron job (= FMITest)

[test_ModelExecutionCmd] rename from test_ModelicaSystemCmd
[ModelicaSystemCmd] add missing docstring

[OMCSession] spelling fixes

[OMCSessionCmd] add warning about depreciated class

[OMCSessionABC] remove duplicated code; see OMSessionABC

[OMSessionRunnerABC] define class

[OMCSessionZMQ] call super()__init__()

[OMCPath] fix forward dependency on OMCSessionLocal

[OMSessionException] rename from OMCSessionException

[__init__] fix imports
[README.md] small updates

[__init__] small updates
[pylint] fix 'R1729: Use a generator instead 'all(isinstance(item, tuple) for item in val_evaluated)' (use-a-generator)'

[pylint] fix 'W0237: Parameter 'expr' has been renamed to 'command' in overriding 'OMCSessionZMQ.sendExpression' method (arguments-renamed)'

[pylint] [OM*Path*] fix pylint messags about incompatible definitions
[ModelExecutionException] catch exception if ModelExecutionCmd.run() is used

[bugfix] [ModelicaSystem] fix exception; use ModelicaSystemError (instead of wrong ModelExecutionException)

[bugfix] [ModelicaSystemABC] fix _prepare_input_data() - ensure returned data is dict[str, str]
[compatibility] add class wrapper to provide the depreciation message

[ModelicaSystem] fix / improve wrapper functions for v4.0.0 compatibility

[ModelicaSystemABC] additional checks for setInputs()

[test_ModelicaSystemOMC] add tests for setInputs()

[__init__] define ModelicaSystemDoE at the right point (=> compatibility layer)

[__init__] remove duplicate 'OMCSessionABC' in __all__
[ModelicaSystemABC] remove code for (depreciated) arguments in set*() methods

* define code in the compatibility layer in class ModelicaSystem

[test_ModelicaSystem(OMC)] update tests

* for new version: remove usage of old definition
* for compatibility version: test old definition
[OMCSessionABC] remove execute(); still available in compatibility v4.0.0

[ModelicaSystem] define _set_compatibility_helper() as static

[ModelExecutionCmd] remove depreciated simflags

[test_ModelSystemCmd/ModelExecutionCmd] fix test due to changes

[ModelicaSystemCmd] cleanup - do not define (unused / not useable) class
@syntron syntron force-pushed the I002-setInputsCSV branch from 03a50ab to 7822295 Compare May 11, 2026 18:53
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