Skip to content

Commit

Permalink
Merge pull request #215 from mgcooper/feat/configuration-module
Browse files Browse the repository at this point in the history
Feat/configuration module
  • Loading branch information
changliao1025 committed May 6, 2024
2 parents 2af7bc4 + 2730164 commit 1ad9acb
Show file tree
Hide file tree
Showing 17 changed files with 805 additions and 269 deletions.
5 changes: 5 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
# pyflowline
data/**/output/
examples/**/output/
examples/**/*.png

# Byte-compiled / optimized / DLL files
__pycache__/
*.py[cod]
Expand Down
8 changes: 4 additions & 4 deletions docs/source/application/application.rst
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,9 @@ The example `run_simulation_mpas.py` script import a few packages and functions.
import os, sys
from pathlib import Path
from os.path import realpath
from pyflowline.pyflowline_read_model_configuration_file import pyflowline_read_model_configuration_file
from pyflowline.configuration.read_configuration_file import pyflowline_read_configuration_file

The `pyflowline_read_model_configuration_file` function reads in a JSON configuration file and loads all the necessary model parameters.
The `pyflowline_read_configuration_file` function reads in a JSON configuration file and loads all the necessary model parameters.


================
Expand Down Expand Up @@ -55,7 +55,7 @@ Check the configuration file:
if os.path.isfile(sFilename_configuration_in):
pass
else:
print('This configuration does not exist: ', sFilename_configuration_in )
print('The domain configuration file does not exist: ',sFilename_configuration_in )

================
Step 4
Expand All @@ -70,7 +70,7 @@ Set up case information and read the configuration file.
Date='20220901'


oPyflowline = pyflowline_read_model_configuration_file(sFilename_configuration_in, \
oPyflowline = pyflowline_read_configuration_file(sFilename_configuration_in, \
iCase_index_in=iCase_index, sDate_in=sDate)
oPyflowline.aBasin[0].dLatitude_outlet_degree=39.462000
oPyflowline.aBasin[0].dLongitude_outlet_degree=-76.009300
Expand Down
2 changes: 1 addition & 1 deletion docs/source/data/data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ PyFlowline uses two JSON-format configuration files to manage all input informat

These files serve as the entry point for setting up and running a PyFlowline case. They can exist wherever the user prefers, but PyFlowline uses the paths specified in these files to locate model inputs and write outputs. Model inputs, outputs, and a recommended directory structure are described in the following two sections.

To create a new PyFlowline case, pass the full path to the parent configuration file to the `pyflowline_read_model_configuration_file` function. This will return a PyFlowline object configured with the values from the file, and it can be used to run the model. See the example notebooks for a demonstration.
To create a new PyFlowline case, pass the full path to the parent configuration file to the `pyflowline_read_configuration_file` function. This will return a PyFlowline object configured with the values from the file, and it can be used to run the model. See the example notebooks for a demonstration.

Note that the "parent" configuration file contains one block of parameter-value pairs that apply to the entire domain. In contrast, the "child" configuration file contains one block of parameter-value pairs for each watershed. A domain with a single watershed will have a single block in the "child" configuration file, while a domain with multiple watersheds will have multiple blocks.

Expand Down
25 changes: 8 additions & 17 deletions examples/susquehanna/run_simulation_hexagon.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,42 +2,33 @@
from pathlib import Path
from os.path import realpath



#===================================
#set up workspace path
#===================================
#%% set up workspace path
sPath_parent = str(Path(__file__).parents[2]) # data is located two dir's up
import sys
sys.path.append(sPath_parent)
from pyflowline.configuration.pyflowline_read_configuration_file import pyflowline_read_model_configuration_file

from pyflowline.configuration.read_configuration_file import pyflowline_read_configuration_file


sPath_data = realpath( sPath_parent + '/data/susquehanna' )
sWorkspace_input = str(Path(sPath_data) / 'input')
sWorkspace_output= str(Path(sPath_data) / 'output')

#===================================
#you need to update this file based on your own case study
#===================================
#%% you need to update this file based on your own case study
sFilename_configuration_in = realpath( sPath_parent + '/data/susquehanna/input/pyflowline_susquehanna_hexagon.json' )
if os.path.isfile(sFilename_configuration_in):
pass
else:
print('This configuration does not exist: ', sFilename_configuration_in )

#===================================
#setup case information
#===================================
#%% setup case information
iCase_index = 1
dResolution_meter = 50000

sMesh = 'hexagon'
sDate='20230101'




oPyflowline = pyflowline_read_model_configuration_file(sFilename_configuration_in, \
oPyflowline = pyflowline_read_configuration_file(sFilename_configuration_in, \
iCase_index_in=iCase_index, dResolution_meter_in=dResolution_meter, sDate_in=sDate)
oPyflowline.aBasin[0].dLatitude_outlet_degree=39.462000
oPyflowline.aBasin[0].dLongitude_outlet_degree=-76.009300
Expand All @@ -50,4 +41,4 @@

print('Finished')


# %%
24 changes: 10 additions & 14 deletions examples/susquehanna/run_simulation_latlon.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,40 +2,36 @@
from pathlib import Path
from os.path import realpath

#===================================
#set up workspace path
#===================================
#%% set up workspace path
sPath_parent = str(Path(__file__).parents[2]) # data is located two dir's up
sPath_parent = str(Path(__file__).parents[2]) # data is located two dir's up
import sys
sys.path.append(sPath_parent)
from pyflowline.configuration.pyflowline_read_configuration_file import pyflowline_read_model_configuration_file

from pyflowline.configuration.pyflowline_read_configuration_file import pyflowline_read_configuration_file

sPath_data = realpath( sPath_parent + '/data/susquehanna' )
sWorkspace_input = str(Path(sPath_data) / 'input')
sWorkspace_output= str(Path(sPath_data) / 'output')

#===================================
#you need to update this file based on your own case study
#===================================
sFilename_configuration_in = realpath( sPath_parent + '//data/susquehanna/input//pyflowline_susquehanna_latlon.json' )
#%% you need to update this file based on your own case study
sFilename_configuration_in = realpath( sPath_parent + '//data/susquehanna/input//pyflowline_susquehanna_latlon.json' )
if os.path.isfile(sFilename_configuration_in):
pass
else:
print('This configuration does not exist: ', sFilename_configuration_in )

#===================================
#setup case information
#===================================
#%% setup case information
iCase_index = 3
dResolution_meter = 50000

sMesh = 'latlon'
sDate='20230101'



oPyflowline = pyflowline_read_model_configuration_file(sFilename_configuration_in, \
oPyflowline = pyflowline_read_configuration_file(sFilename_configuration_in, \
iCase_index_in=iCase_index, dResolution_meter_in=dResolution_meter, sDate_in=sDate)

#%%
oPyflowline.aBasin[0].dLatitude_outlet_degree=39.462000
oPyflowline.aBasin[0].dLongitude_outlet_degree=-76.009300
oPyflowline.setup()
Expand Down
189 changes: 133 additions & 56 deletions examples/susquehanna/run_simulation_mpas.py
Original file line number Diff line number Diff line change
@@ -1,98 +1,175 @@
import os, sys
from pathlib import Path
from os.path import realpath
#===================================
#set up workspace path
#===================================
sPath_parent = str(Path(__file__).parents[2]) # data is located two dir's up

sys.path.append(sPath_parent)
from pyflowline.configuration.change_json_key_value import change_json_key_value
from pyflowline.configuration.pyflowline_read_configuration_file import pyflowline_read_model_configuration_file

sPath_data = realpath( sPath_parent + '/data/susquehanna' )
sWorkspace_input = str(Path(sPath_data) / 'input')
sWorkspace_output= str(Path(sPath_data) / 'output')


#===================================
#you need to update this file based on your own case study
#===================================
sFilename_configuration_in = realpath( sPath_parent + '/data/susquehanna/input/pyflowline_susquehanna_mpas.json' )
if os.path.isfile(sFilename_configuration_in):
pass
else:
print('This configuration does not exist: ', sFilename_configuration_in )

#===================================
#setup case information
#===================================

from pyflowline.configuration.read_configuration_file import pyflowline_read_configuration_file
from pyflowline.configuration.change_json_key_value import pyflowline_change_json_key_value
from pyflowline.configuration import path_manager as pyflowline_path_manager


#%% Define the case information (configuration file parameters)
sDomainName = 'susquehanna'
iCase_index = 1
iFlag_simulation = 0
iFlag_visualization = 1
sMesh = 'mpas'
sDate='20230701'
sDate = '20230701'

#%% Define workspace paths and configuration file path parameters
oPath_parent = pyflowline_path_manager.pyflowline_project_root()
sys.path.append(str(oPath_parent))

# Define the full path to the input and output folders.
oFolder_input = oPath_parent.joinpath(
'data', sDomainName, 'input')
oFolder_output = oPath_parent.joinpath(
'data', sDomainName, 'output')

# Define the full path to the domain ("parent") configuration file.
oFilename_domain_config = oFolder_input.joinpath(
'pyflowline_susquehanna_mpas.json')

sFolder_data = os.path.join(sPath_parent, 'data')
sFolder_data_susquehanna = os.path.join(sFolder_data, 'susquehanna')
sFolder_input = os.path.join(sFolder_data_susquehanna, 'input')
sFilename_flowline = realpath( os.path.join(sFolder_input, 'flowline.geojson') )
sFilename_basins = realpath( os.path.join(sFolder_input , 'pyflowline_susquehanna_basins.json' ))
change_json_key_value(sFilename_basins, 'sFilename_flowline_filter', sFilename_flowline, iFlag_basin_in=1)
# Define the full path to the individual basin ("child") configuration file.
oFilename_basins_config = oFolder_input.joinpath(
'pyflowline_susquehanna_basins.json')

oPyflowline = pyflowline_read_model_configuration_file(sFilename_configuration_in,
iCase_index_in=iCase_index, sDate_in=sDate)
# Define the full path to the MPAS mesh file
oFilename_mesh_netcdf = oFolder_input.joinpath(
'lnd_cull_mesh.nc')

#take a look at the model parameters
# Define the full path to the input flowline file.
oFilename_flowline = oFolder_input.joinpath(
'flowline.geojson')

# Define the full path to the boundary file used to clip the mesh.
oFilename_mesh_boundary = oFolder_input.joinpath(
'boundary_wgs.geojson')

# Confirm that the domain configuration file exists.
if os.path.isfile(oFilename_domain_config):
pass
else:
print('The domain configuration file does not exist: ', oFilename_domain_config)

#%% Update the domain (parent) configuration file

# The following parameters need to be set in the configuration file:
# sWorkspace_output: full/path/to/output
# sFilename_mesh_netcdf: full/path/to/lnd_cull_mesh.nc
# sFilename_mesh_boundary: full/path/to/boundary_wgs.geojson
# sFilename_basins: full/path/to/pyflowline_susquehanna_basins.json.

# The json file will be overwritten, you may want to make a copy of it first.

# Set the path to the output folder
# Pass the configuration filename followed by a single key-value pair.
pyflowline_change_json_key_value(
oFilename_domain_config,
'sWorkspace_output', str(oFolder_output))

# Set the path to the mpas mesh file
pyflowline_change_json_key_value(
oFilename_domain_config,
'sFilename_mesh_netcdf', str(oFilename_mesh_netcdf))

# Set the path to the boundary file used to clip the mesh
pyflowline_change_json_key_value(
oFilename_domain_config,
'sFilename_mesh_boundary', str(oFilename_mesh_boundary))

# Set the path to the basin ("child") configuration file
pyflowline_change_json_key_value(
oFilename_domain_config,
'sFilename_basins', str(oFilename_basins_config))

# These parameters are not strictly necessary, but will reduce the potential for errors or confusion.
pyflowline_change_json_key_value(
oFilename_domain_config,
'sFilename_model_configuration', str(oFilename_domain_config))

pyflowline_change_json_key_value(
oFilename_domain_config,
'sWorkspace_data', str(oPath_parent.joinpath('data')))

#%% Update the basin ("child") configuration file

# Set the path to the flowline file.
pyflowline_change_json_key_value(
oFilename_basins_config,
'sFilename_flowline_filter', str(oFilename_flowline),
iFlag_basin_in=1) # Set iFlag_basin_in=1 when changing the basin configuration file.

#%% Read the configuration file
oPyflowline = pyflowline_read_configuration_file(
oFilename_domain_config,
iCase_index_in=iCase_index,
sDate_in=sDate)

#%% Check the model parameters
oPyflowline.pyflowline_print()

#now we can change the following model parameters
#there are two ways to change the model parameters
#use a function or assign a value directly
#%% Now we can change some model parameters

oPyflowline.pyflowline_change_model_parameter(sVariable_in='sWorkspace_output', sValue_in=sWorkspace_output)
# There are two ways to change the model parameters: 1) use a function, or 2) assign a value directly. Use the function:
oPyflowline.pyflowline_change_model_parameter(
'sWorkspace_output', str(oFolder_output))

#if you need to change a parameter for a basin instead of the whole model domain, use the iFlag_basin_in option, this will change all the basins
oPyflowline.pyflowline_change_model_parameter(sVariable_in='dLatitude_outlet_degree', sValue_in=39.462000, iFlag_basin_in=1)
oPyflowline.pyflowline_change_model_parameter(sVariable_in='dLongitude_outlet_degree', sValue_in=-76.009300, iFlag_basin_in=1)
# To change a parameter for a basin instead of the whole model domain, use the iFlag_basin_in option, this will change the value for all of the basins in the basin configuration file.
oPyflowline.pyflowline_change_model_parameter(
'dLatitude_outlet_degree', 39.462000,
iFlag_basin_in=1)

oPyflowline.pyflowline_change_model_parameter(
'dLongitude_outlet_degree', -76.009300,
iFlag_basin_in=1)

#the second way is to assign a value directly
# The second way is to assign a value directly
oPyflowline.aBasin[0].dLatitude_outlet_degree=39.462000
oPyflowline.aBasin[0].dLongitude_outlet_degree=-76.009300

#oPyflowline.setup()
if iFlag_visualization ==1:
#oPyflowline.plot(sVariable_in = 'flowline_filter', sFilename_output_in = 'filter_flowline.png' )
#%%
oPyflowline.pyflowline_setup()

#%%
if iFlag_visualization == 1:
oPyflowline.plot(sVariable_in='flowline_filter', sFilename_output_in='filter_flowline.png')
pass

#%%
if iFlag_simulation == 1:
#oPyflowline.pyflowline_flowline_simplification()
oPyflowline.pyflowline_flowline_simplification()
pass

#%%
if iFlag_visualization == 1:

aExtent_meander = [-76.5,-76.2, 41.6,41.9]
#oPyflowline.plot( sVariable_in='flowline_simplified' , sFilename_output_in = 'flowline_simplified.png' )
#oPyflowline.plot( sVariable_in='flowline_simplified' , sFilename_output_in = 'flowline_simplified_zoom.png', aExtent_in =aExtent_meander )

aExtent_meander = [-76.5, -76.2, 41.6, 41.9]
# oPyflowline.plot(sVariable_in='flowline_simplified', sFilename_output_in='flowline_simplified.png')
# oPyflowline.plot(sVariable_in='flowline_simplified',
# sFilename_output_in='flowline_simplified_zoom.png',
# aExtent_in=aExtent_meander)
pass

#%%
if iFlag_simulation == 1:
aCell = oPyflowline.pyflowline_mesh_generation()

#%%
if iFlag_visualization == 1:
oPyflowline.plot( sVariable_in='mesh', sFilename_output_in = 'mesh.png' )
# This will fail unless iFlag_simulation is true or has been run
# oPyflowline.plot(sVariable_in='mesh', sFilename_output_in='mesh.png' )
pass

#%%
if iFlag_simulation == 1:
oPyflowline.pyflowline_reconstruct_topological_relationship(aCell)

#%%
if iFlag_visualization == 1:
oPyflowline.plot( sVariable_in='overlap', sFilename_output_in = 'mesh_w_flowline.png',)
# oPyflowline.plot(sVariable_in='overlap', sFilename_output_in='mesh_w_flowline.png')
pass

oPyflowline.export()
# oPyflowline.pyflowline_export()

print('Finished')

# %%
Loading

0 comments on commit 1ad9acb

Please sign in to comment.