Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
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
2 changes: 1 addition & 1 deletion src/dementpy.py
Original file line number Diff line number Diff line change
Expand Up @@ -101,6 +101,6 @@ def main():

#...export the Output_init object to the output_folder using the export() funtion in the utility module
os.chdir('../'+output_folder)
export(Output_init, site, outname)
Output_init.export(outname)

main()
52 changes: 51 additions & 1 deletion src/initialization.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,10 @@
import pandas as pd
import numpy as np

import warnings
import numbers
from pathlib import Path

from substrate import Substrate
from monomer import Monomer
from enzyme import Enzyme
Expand Down Expand Up @@ -163,4 +167,50 @@ def initialize_data(runtime_parameters, site):
'Psi': daily_psi # water potential
}

return Data_Dictionary
return Data_Dictionary


def export_initialization_dict(base_path: Path | str, d: dict) -> None:
"""Export contents of the initialisation directory to a folder.

Writes each of the items of a type below to a separate CSV file
- pandas.DataFrame
- pandas.Series
- numpy.ndarray of rank below 2
All scalar numbers are grouped in a single CSV 'scalars.csv' file.

Note:
All other items are ignored following a warning!
If you need them written you need to add extra entry.
"""

# Create space for output
base_path = Path(base_path)
base_path.mkdir(parents=True, exist_ok=True)

# Collect all scalar numbers
scalar_numbers = dict()

for name, member in d.items():
if isinstance(member, (pd.DataFrame, pd.Series)):
fname = name + ".csv"
member.to_csv(base_path / fname)
elif isinstance(member, np.ndarray):
if len(member.shape) <= 2:
fname = name + ".csv"
np.savetxt(fname, member, delimiter=",")
else:
warnings.warn(
f"Member '{name}' of initialisation dictionary could not be saved since "
f"it is an array of rank higher than 2 (rank: {len(member.shape)})."
)
elif isinstance(member, numbers.Number):
scalar_numbers[name] = member
else:
warnings.warn(
f"Initialisation member '{name}' has unsupported type '{type(member)}'. "
f"It has not been exported to the output directory '{base_path}'."
)

# Print numbers
pd.Series(scalar_numbers).to_csv(base_path / "scalars.csv")
55 changes: 55 additions & 0 deletions src/output.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,12 @@
# output.py module dealing with outputs of DEMENTpy.
# Bin Wang, January, 2020

from pathlib import Path
import warnings
import numbers

from initialization import export_initialization_dict

import numpy as np
import pandas as pd

Expand Down Expand Up @@ -293,3 +299,52 @@ def microbes_tradeoff(self, ecosystem, year, day):
GY_grid = ecosystem.Microbe_C_Gain.groupby(level=0,sort=False).sum()
GY_grid.name = self.cycle*year + (day+1)
self.Growth_yield = pd.concat([self.Growth_yield,GY_grid],axis=1,sort=False)


def export(self, base_path: Path | str) -> None:
"""Export contents of the output file to a directory.

Exports each class member of type pandas.DataFrame to a separate CSV file.
All pandas.Series members are combined in a DataFrame and printed dto 'series.csv' file.
Similarly all scalar numerical members are grouped in 'scalars.csv'.

Parameters:
base_path : Path
A path that names the root directory where contents will be exported.
If the directory does not exist it will be created.
"""
# Create space for output
base_path = Path(base_path)
base_path.mkdir(parents=True, exist_ok=True)

# Collect all series and scalar data
# We will dump them at the end
series_data = dict()
scalar_numbers = dict()

for name, member in vars(self).items():
if isinstance(member, pd.DataFrame):
fname = name + ".csv"
member.to_csv(base_path / fname)
elif isinstance(member, pd.Series):
series_data[name] = member
elif isinstance(member, numbers.Number):
scalar_numbers[name] = member
elif name == "Initialization":
# Special case - Initialization dictionary
# Serialise it to a subfolder
path = base_path / name
export_initialization_dict(path, member)
else:
warnings.warn(
f"Output member '{name}' has unsupported type '{type(member)}'. "
f"It has not been exported to the output directory '{base_path}'."
)

# If it happens that Series have different lengths they will be padded
# with missing data labels (NaNs)
series_data = pd.concat(series_data, axis=1)
series_data.to_csv(base_path / "series.csv")

# Print numbers
pd.Series(scalar_numbers).to_csv(base_path / "scalars.csv")