Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
37 commits
Select commit Hold shift + click to select a range
dde7f2b
Add csv post process for time series variables
genevievestarke Jan 8, 2026
7e9c7d5
Rename and move to postprocesss folder
genevievestarke Jan 8, 2026
329160a
Clean up function file
genevievestarke Jan 8, 2026
b9c6d73
Fis ruff formatting
genevievestarke Jan 8, 2026
b0f65bf
added alternative approach to saving timeseries data
elenya-grant Jan 8, 2026
5e307b5
added docstrings and comments to new methods
elenya-grant Jan 8, 2026
cc36149
Add column renaming ability
genevievestarke Jan 8, 2026
47408a1
Merge remote-tracking branch 'refs/remotes/personal/feature/post_proc…
genevievestarke Jan 8, 2026
2759697
Add alternative varibale name capability
genevievestarke Jan 8, 2026
e8b4538
bugfix in set_recorders
elenya-grant Jan 8, 2026
86bef92
added timeseries saving to example 2 and removed post_process
elenya-grant Jan 8, 2026
d1b300a
removed post_process
elenya-grant Jan 8, 2026
286249f
Fix ruff issue, delete old code
genevievestarke Jan 8, 2026
68c5bd5
Sort import statements
genevievestarke Jan 8, 2026
138daf3
Unsort import statements
genevievestarke Jan 8, 2026
dcbd69c
Add line
genevievestarke Jan 8, 2026
ab79788
added basic tests for saving timeseries results
elenya-grant Jan 8, 2026
3540f77
Merge remote-tracking branch 'gen/feature/post_process_csv' into feat…
elenya-grant Jan 8, 2026
bf8119c
Add test for alternative column names and adjust alternative column n…
genevievestarke Jan 9, 2026
0690fc9
fix formatting
genevievestarke Jan 9, 2026
ac3a91e
update test name
genevievestarke Jan 9, 2026
78a9b22
Add unit and alternative name test
genevievestarke Jan 9, 2026
3276716
updated CHANGELOG
elenya-grant Jan 9, 2026
cb26f81
renamed new files and updated import statements
elenya-grant Jan 9, 2026
6726c44
Minor comment updates
johnjasa Jan 9, 2026
4603508
Merge branch 'develop' into feature/post_process_csv
johnjasa Jan 10, 2026
3bb1066
minor updates based on feedback
elenya-grant Jan 12, 2026
c1c9a64
Merge branch 'develop' into feature/post_process_csv
johnjasa Jan 13, 2026
b5f0f92
Merge branch 'develop' into feature/post_process_csv
johnjasa Jan 13, 2026
2f3c3e7
Merge branch 'develop' into feature/post_process_csv
johnjasa Jan 16, 2026
9607521
Add to docs
genevievestarke Jan 16, 2026
38084aa
Update Ex 2 and docs
genevievestarke Jan 16, 2026
32d5106
minor updates to doc page for formatting
elenya-grant Jan 20, 2026
4a5dc35
updated test since merged in develop
elenya-grant Jan 20, 2026
5ce318c
Added doc content to address review feedback
johnjasa Jan 21, 2026
255e9b5
Merge branch 'develop' into feature/post_process_csv
johnjasa Jan 21, 2026
6fb4e6c
updated tests for changes to example
elenya-grant Jan 21, 2026
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
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
- Added capability to have transport models that require user input parameters
- Add geologic hydrogen surface processing converter
- Add baseclass for caching functionality
- Added postprocessing function to save timeseries
- Minor reorg for profast tools
- Removed hydrogen tank cost and performance models that were unused

Expand Down
84 changes: 84 additions & 0 deletions docs/user_guide/postprocessing_results.md
Original file line number Diff line number Diff line change
Expand Up @@ -88,3 +88,87 @@ print(model.prob.get_val("electrolyzer.total_hydrogen_produced", units='kg'))
This will print the total hydrogen produced by the electrolyzer in kg.
The `get_val` method is used to access the value of the variable in the `prob` object.
The `units` argument is used to specify the units of the value to be returned.

### Saving outputs

The time series outputs can be saved to a csv output using the `save_case_timeseries_as_csv` function. If no variables are specified, then the function saves all time series variables in the simulation. Otherwise, the specified variables are saved.

The `vars_to_save` argument supports three different input formats:

1. **List of variable names** - saves variables with their default units
2. **Dictionary with units** - keys are variable names, values are the desired units
3. **Dictionary with options** - keys are variable names, values are dictionaries with `"units"` and/or `"alternative_name"` keys

#### Example 1: Save all timeseries data

```python
from h2integrate.core.h2integrate_model import H2IntegrateModel
from h2integrate.postprocess.sql_timeseries_to_csv import save_case_timeseries_as_csv

# Create and run a H2Integrate model
model = H2IntegrateModel("top_level_config.yaml")
model.run()
model.post_process()

# Save all timeseries data to a csv file
timeseries_data = save_case_timeseries_as_csv(model.recorder_path)
```

#### Example 2: Specify variables as a list

When providing a list of variable names, the function uses the default units for each variable.

```python
# Get a subset of timeseries data using a list of variable names
output_vars = [
"electrolyzer.hydrogen_out",
"hopp.electricity_out",
"ammonia.ammonia_out",
"h2_storage.hydrogen_out",
]

# Don't save subset of timeseries to a csv file using save_to_file=False
timeseries_data = save_case_timeseries_as_csv(
model.recorder_path, vars_to_save=output_vars, save_to_file=False
)
```

#### Example 3: Specify variables with custom units

When providing a dictionary with variable names as keys and unit strings as values, the function converts each variable to the specified units.

```python
# Specify variables with custom units
vars_with_units = {
"ammonia.hydrogen_in": "kg/h",
"h2_storage.hydrogen_in": "kg/h",
"electrolyzer.electricity_in": "kW",
}

timeseries_data = save_case_timeseries_as_csv(
model.recorder_path, vars_to_save=vars_with_units, save_to_file=False
)
```

#### Example 4: Specify variables with alternative column names

When providing a dictionary with variable names as keys and dictionaries as values, you can specify both custom units and alternative column names for the output DataFrame.

```python
# Specify variables with alternative names and/or units
vars_with_options = {
"electrolyzer.hydrogen_out": {"alternative_name": "Electrolyzer Hydrogen Output"},
"hopp.electricity_out": {"units": "kW", "alternative_name": "Plant Electricity Output"},
"ammonia.ammonia_out": {"alternative_name": None}, # Uses default variable name
"h2_storage.hydrogen_out": {"alternative_name": "H2 Storage Hydrogen Output"},
}

timeseries_data = save_case_timeseries_as_csv(
model.recorder_path, vars_to_save=vars_with_options, save_to_file=False
)
# Resulting columns: "Electrolyzer Hydrogen Output (kg/h)", "Plant Electricity Output (kW)", etc.
```

```{note}
The `electricity_base_unit` argument (default: `"MW"`) controls the units used for electricity-based variables when no specific units are provided. Valid options are `"W"`, `"kW"`, `"MW"`, or `"GW"`.
```
17 changes: 17 additions & 0 deletions examples/02_texas_ammonia/driver_config.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -3,3 +3,20 @@ description: "This analysis runs a hybrid plant to match the first example in H2

general:
folder_output: outputs

recorder:
# required inputs
flag: True #record outputs
file: "cases.sql" #this file will be written to the folder `outputs`

# optional but recommended inputs
overwrite_recorder: True #If True, do not create a unique recorder file for subsequent runs. Defaults to False.
recorder_attachment: "model" #"driver" or "model", defaults to "model". Use "driver" if running a parallel simulation.
includes: ["*"] #include everything
excludes: ["*resource_data*"] #exclude resource data

# below are optional and defaulted to the OpenMDAO default
# record_inputs: True #defaults to True
# record_outputs: True #defaults to True
# record_residuals: True #defaults to True
# options_excludes: #this is only used if recorder_attachment is "model"
19 changes: 19 additions & 0 deletions examples/02_texas_ammonia/run_texas_ammonia_plant.py
Original file line number Diff line number Diff line change
@@ -1,16 +1,35 @@
import numpy as np

from h2integrate.core.h2integrate_model import H2IntegrateModel
from h2integrate.postprocess.sql_timeseries_to_csv import save_case_timeseries_as_csv


# Create a H2Integrate model
model = H2IntegrateModel("02_texas_ammonia.yaml")

# Set battery demand profile to electrolyzer capacity
# TODO: Update with demand module once it is developed
demand_profile = np.ones(8760) * 640.0
model.setup()
model.prob.set_val("battery.electricity_demand", demand_profile, units="MW")

# Run the model
model.run()

model.post_process()

# Save all timeseries data to a csv file
timeseries_data = save_case_timeseries_as_csv(model.recorder_path)

# Get a subset of timeseries data
vars_to_save = [
"electrolyzer.hydrogen_out",
"hopp.electricity_out",
"ammonia.ammonia_out",
"h2_storage.hydrogen_out",
]

# Don't save subset of timeseries to a csv file using save_to_file=False
timeseries_data = save_case_timeseries_as_csv(
model.recorder_path, vars_to_save=vars_to_save, save_to_file=False
)
7 changes: 4 additions & 3 deletions h2integrate/core/pose_optimization.py
Original file line number Diff line number Diff line change
Expand Up @@ -448,8 +448,8 @@ def set_recorders(self, opt_prob):
for current optimization problem

Returns:
opt_prob (openmdao problem instance): openmdao problem instance for
current optimization problem edited to include a set up recorder
recorder_path (Path or None): Path to the recorder file if recorder is enabled,
None otherwise
"""
folder_output = self.config["general"]["folder_output"]

Expand Down Expand Up @@ -525,7 +525,7 @@ def set_recorders(self, opt_prob):
opt_prob.model.recording_options["excludes"] = self.config["recorder"].get(
"excludes", ["*resource_data"]
)
return
return recorder_path

if recorder_attachment == "driver":
recorder_options += [
Expand All @@ -550,6 +550,7 @@ def set_recorders(self, opt_prob):
"excludes", ["*resource_data"]
)
return recorder_path

return None

def set_restart(self, opt_prob):
Expand Down
Loading