Skip to content

Commit 24de5bd

Browse files
committed
update docstrings and docs files
1 parent 46ab222 commit 24de5bd

9 files changed

Lines changed: 109 additions & 44 deletions

File tree

docs/source/api.rst

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,10 +15,20 @@ Classes
1515
.. autoclass:: prms_python.Parameters
1616
:members:
1717

18+
.. _data:
19+
.. autoclass:: prms_python.Data
20+
21+
.. _optimizer:
22+
.. autoclass:: prms_python.Optimizer
23+
24+
.. _optimizationresult:
25+
.. autoclass:: prms_python.OptimizationResult
1826

1927
Data, Parameter, Statsvar helper functions
2028
------------------------------------------
2129

30+
31+
2232
.. _load-data:
2333
.. autofunction:: prms_python.load_data_file
2434

docs/source/conf.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -62,7 +62,7 @@
6262
# built documents.
6363
#
6464
# The short X.Y version.
65-
version = u'0.1'
65+
version = u'1.0.0'
6666
# The full version, including alpha/beta/rc tags.
6767
release = u'0.1'
6868

@@ -140,7 +140,7 @@
140140

141141
# The name for this set of Sphinx documents.
142142
# "<project> v<release> documentation" by default.
143-
html_title = u'PRMS-Python v0.1'
143+
html_title = u'PRMS-Python v1.0.0'
144144

145145
# A shorter title for the navigation bar. Default is the same as html_title.
146146
#html_short_title = None

docs/source/index.rst

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ analysis.
1717
Questions or comments? Contact `John Volk <mailto:jmvolk@unr.edu>`_
1818

1919

20-
Install (out of date version on PyPI, for new version use method below)
20+
Install
2121
-------
2222

2323
``pip install prms-python``
@@ -29,7 +29,8 @@ First, clone from GitHub
2929

3030
.. code-block:: sh
3131
32-
git clone https://github.com/JohnVolk/PRMS-Python && cd PRMS-Python
32+
git clone https://github.com/PRMS-Python/PRMS-Python.git
33+
cd PRMS-Python
3334
3435
Then install dependencies and executable
3536

@@ -41,17 +42,13 @@ Then install dependencies and executable
4142
Usage
4243
-----
4344

44-
If you want to dive right in, modify some parameters and run some scenarios,
45-
go on to the :doc:`cli` page. There you'll learn how to run `prmspy`, the
46-
command-line interface to the PRMS-Python tools.
45+
..
46+
If you want to dive right in, modify some parameters and run some scenarios,
47+
go on to the :doc:`cli` page. There you'll learn how to run `prmspy`, the
48+
command-line interface to the PRMS-Python tools.
4749
48-
If instead you would rather get acquainted with the Python API for direct use,
49-
see the :doc:`tutorial` page for usage recipes and examples, and consult the
50-
:doc:`api` for more details. More examples and in depth documentation can be
51-
found in the Jupyter notebooks found in the notebooks directory in the PRMS-Python
52-
package.
50+
We recommend getting acquainted with the Python API by reading and applying some examples and recipes found in the :doc:`tutorial` page, and consult the :doc:`api` for more details. More examples, basic and advanced workflows, and in depth documentation can be found in the Jupyter notebooks found in the `notebooks directory <https://github.com/PRMS-Python/PRMS-Python/tree/master/notebooks>`_ in the PRMS-Python package.
5351

54-
Happy coding, y'all!
5552

5653

5754
.. toctree::

docs/source/tutorial.rst

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -286,7 +286,7 @@ then use the parallelized ``ScenarioSeries.run()`` method to execute all
286286
requested scenarios.
287287

288288
This is adapted from the `scenario_series.ipynb, viewable on GitHub
289-
<https://github.com/mtpain/PRMS-Python/blob/master/notebooks/scenario_series.ipynb>`_.
289+
<https://github.com/PRMS-Python/PRMS-Python/blob/master/notebooks/scenario_series.ipynb>`_.
290290
There are some details on customizing the plots that can be viewed there.
291291

292292
See inline comments for more details.

prms_python/data.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,5 @@
11
'''
2-
data.py -- holds Data class for PRMS standard climate input.
2+
data.py -- holds ``Data`` class for standard PRMS climate input data.
33
'''
44

55
import pandas as pd

prms_python/optimizer.py

Lines changed: 68 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'''
2-
optimizer.py -- Optimization routines for PRMS parameters.
2+
optimizer.py -- holds ``Optimizer`` and ``OptimizationResult`` classes for
3+
optimization routines and management conducted on PRMS parameters.
34
'''
45
from __future__ import print_function
56
import pandas as pd
@@ -21,9 +22,11 @@
2122

2223
class Optimizer:
2324
'''
24-
Container for a PRMS parameter optimization routine consisting of
25-
stages similar to what is described in Hay, et al, 2006
25+
Container for PRMS parameter optimization routines that are
26+
defined as stages similar to what is described in Hay, et al, 2006
2627
(ftp://brrftp.cr.usgs.gov/pub/mows/software/luca_s/jawraHay.pdf).
28+
Currently the ``monte_carlo`` method provides random parameter
29+
resampling routines using uniform and normal random variables.
2730
2831
Example:
2932
@@ -33,10 +36,10 @@ class Optimizer:
3336
>>> control = 'path/to/control'
3437
>>> work_directory = 'path/to/create/simulations'
3538
>>> optr = Optimizer(params, data, control, work_directory, \
36-
title='the title', description='desc')
39+
title='the title', description='desc')
3740
>>> measured = 'path/to/measured/csv'
3841
>>> statvar_name = 'basin_cfs' # or any other valid statvar
39-
>>> params_to_resample = ['dday_intcp', 'dday_slope'] # list
42+
>>> params_to_resample = ['dday_intcp', 'dday_slope'] # list of params
4043
>>> optr.monte_carlo(measured, params_to_resample, statvar_name)
4144
4245
'''
@@ -97,9 +100,9 @@ def monte_carlo(self, reference_path, param_names, statvar_name, \
97100
stage, n_sims=10, method='uniform', mu_factor=1,\
98101
noise_factor=0.1, nproc=None):
99102
'''
100-
Optimize the monthly dday_intcp and dday_slope parameters
101-
(two key parameters in the ddsolrad module in PRMS) by one of
102-
multiple methods (in development): Monte Carlo default method
103+
The ``monte_carlo`` method of ``Optimizer`` performs parameter
104+
random resampling techniques to a set of PRMS parameters and
105+
executes and manages the corresponding simulations.
103106
104107
Args:
105108
reference_path (str): path to measured data for optimization
@@ -381,17 +384,17 @@ def resample_param(params, param_name, how='uniform', mu_factor=1,\
381384
taken from a uniform distribution, where the range of the uniform
382385
values is equal to the difference between the min and max of the allowable
383386
range from PRMS. The parameter min and max are set in Optimizer.param_ranges
384-
If the resampling method ("how" argument) is set to 'normal', randomly
385-
sample a normal distribution with mean = mean(parameter) X mu_factor and
386-
sigma = param allowable range multiplied by noise_factor. If parameters have
387+
If the resampling method (``how`` argument) is set to 'normal', randomly
388+
sample a normal distribution with mean = mean(parameter) X ``mu_factor`` and
389+
sigma = param allowable range multiplied by ``noise_factor``. If parameters have
387390
array length <= 366 then individual parameter values are resampled otherwise
388391
resample all param values at once, e.g. by taking a single random value
389392
from the uniform distribution. If they are taking all at once using the
390393
normal method then the original values are scaled by mu_factor and a normal
391-
random variable with mean=0 and std dev = parameter range X noise_factor.
394+
random variable with mean=0 and std dev = parameter range X ``noise_factor``.
392395
393396
Args:
394-
params (parameters.Parameters): parameter object
397+
params (parameters.Parameters): ``Parameters`` object
395398
param_name (str): name of PRMS parameter to resample
396399
Kwargs:
397400
how (str): distribution to resample parameters from in the case
@@ -400,10 +403,9 @@ def resample_param(params, param_name, how='uniform', mu_factor=1,\
400403
noise_factor (float): factor to multiply parameter range by,
401404
use the result as the standard deviation for the normal rand.
402405
variable used to add element wise noise. i.e. higher
403-
noise facter will result in higher variance. Must be > 0.
406+
noise_factor will result in higher variance. Must be > 0.
404407
Returns:
405-
ret (numpy.ndarry): ndarray of param after uniform random mean
406-
shift or element-wise noise addition (normal r.v.)
408+
ret (numpy.ndarry): ndarray of param after resampling
407409
"""
408410
p_min, p_max = Optimizer.param_ranges.get(param_name,(-1,-1))
409411

@@ -501,8 +503,57 @@ def _mod_params(parameters, params, param_names):
501503

502504

503505
class OptimizationResult:
504-
506+
"""
507+
The ``OptimizationResult`` object serves to collect and manage output
508+
from an ``Optimizer`` method. Upon initialization and a given optimization
509+
stage that was used when running the Optimizer method, e.g. ``monte_carlo``,
510+
the class gathers all JSON metadata that was produced for the given stage.
511+
The ``OptimizationResult`` has three main user methods: first ``result_table``
512+
which returns the top n simulations according to four model performance
513+
metrics (Nash-Sutcliffe efficiency (NSE), root-mean squared-error (RMSE),
514+
percent bias (PBIAS), and the coefficient of determination (COEF_DET) as
515+
calculated against measured data. For example the table may look like:
516+
517+
>>> ddsolrad_res = OptimizationResult(work_directory, stage=stage)
518+
>>> top10 = ddsolrad_res.result_table(freq='monthly',top_n=10)
519+
>>> top10
520+
======================== ======== ======= ========= ========
521+
ddsolrad parameters NSE RMSE PBIAS COEF_DET
522+
======================== ======== ======= ========= ========
523+
orig_params 0.956267 39.4725 -0.885715 0.963116
524+
tmax_index_54.2224631748 0.921626 47.6092 -0.849256 0.94402
525+
tmax_index_44.8823940703 0.879965 58.9194 5.79603 0.922021
526+
tmax_index_47.6835387480 0.764133 82.5918 -4.78896 0.837582
527+
======================== ======== ======= ========= ========
528+
529+
Second, the ``get_top_ranked_sims`` which returns a dictionary that map
530+
key information about the top n ranked simulations, an example returned
531+
dictionary may look like:
532+
533+
>>> {
534+
'dir_name' : ['pathToSim1', 'pathToSim2'],
535+
'param_path' : ['pathToSim1/input/parameters', 'pathToSim2/input/parameters'],
536+
'statvar_path' : ['pathToSim1/output/statvar.dat', 'pathToSim2/output/statvar.dat'],
537+
'params_adjusted' : [[param_names_sim1], [param_names_sim2]]
538+
}
539+
540+
The third method of ``OptimizationResult`` is ``archive`` which essentially
541+
opens all parameter and statvar files from each simulation of the given
542+
stage and archives the parameters that were modified and their modified values
543+
and the statistical variable (PRMS time series output) that is associated with
544+
the optimization stage. Other ``Optimizer`` simulation metadata is also gathered
545+
and new JSON metadata containing only this information is created and written
546+
within a newly created "archived" subdirectory within the same directory that
547+
the ``Optimizer`` routine managed simulations. The ``OptimizationResult.archive``
548+
method then recursively deletes the simulation data for each of the given stage.
549+
"""
550+
505551
def __init__(self, working_dir, stage):
552+
"""
553+
Create an ``OptimizationResult`` instance to manage output and analyse parameter-
554+
output relationships as produced by the use of an ``Optimizer`` method of a user
555+
defined optimization stage.
556+
"""
506557
self.working_dir = working_dir
507558
self.stage = stage
508559
self.metadata_json_paths = self._get_optr_jsons(working_dir, stage)

prms_python/parameters.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
'''
2-
parameters.py -- holds Parameter class for PRMS standard parameters input file.
2+
parameters.py -- holds ``Parameter`` class with multiple functionality for
3+
the standard PRMS parameters input file.
34
'''
45

56
import datetime, calendar
@@ -143,7 +144,7 @@ def plot(self, nrows, which='all', out_dir=None, xlabel=None,\
143144
os.mkdir(out_dir)
144145

145146
nhru = params.dimensions['nhru']
146-
ncols = nhru//nrows
147+
ncols = nhru // nrows
147148

148149
if not mpl_style:
149150
mpl_style = 'classic'
@@ -153,7 +154,7 @@ def plot(self, nrows, which='all', out_dir=None, xlabel=None,\
153154
if which == 'all':
154155
## spatial parameters with dimension of length nhru
155156
p_names = [param['name'] for param in params.base_params if\
156-
param['length'] == nhru and len(param['dimnames'])==1 ]
157+
param['length'] == nhru and len(param['dimnames'])==1]
157158
with PdfPages(OPJ(out_dir,'nhru_param_maps.pdf')) as pdf:
158159
for p in p_names:
159160
try:
@@ -165,7 +166,7 @@ def plot(self, nrows, which='all', out_dir=None, xlabel=None,\
165166
cax = divider.append_axes("right", size="5%", pad=0.05)
166167
plt.colorbar(im, cax=cax)
167168
ax.set_title('{}'.format(p))
168-
ax.tick_params(left='off', bottom='off', labelleft='off', labelbottom='off')
169+
ax.tick_params(left='off', bottom='off', labelleft='off',labelbottom='off')
169170
pdf.savefig()
170171
plt.close()
171172
except:

prms_python/scenario.py

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
'''
2-
scenario.py -- holds Scenario and ScenarioSeries class for PRMS managing parameter-based
3-
model scenarios.
2+
scenario.py -- holds ``Scenario`` and ``ScenarioSeries`` classes for PRMS
3+
managing parameter-based model scenarios that may be used for hypotheses
4+
testing.
45
'''
56

67
import inspect

prms_python/simulation.py

Lines changed: 11 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
"""
2-
simulation.py -- Contains Simulation and SimulationSeries classes and associated functions for
3-
managing PRMS simulations at a low level.
2+
simulation.py -- Contains ``Simulation`` and ``SimulationSeries`` classes and
3+
associated functions for managing PRMS simulations at a low level.
44
"""
55

66
from __future__ import print_function
@@ -19,7 +19,12 @@
1919

2020
class SimulationSeries(object):
2121
'''
22-
Series of simulations all to be run through a common interface
22+
Series of simulations all to be run through a common interface.
23+
Utilizes ``multiprocessing.Pool`` class to parallelize the
24+
execution of series of PRMS simulations. SimulationSeries also
25+
allows the user to define the PRMS executable command which is
26+
set to "prms" as default. It is best to add the prms executable to
27+
your PATH environment variable.
2328
'''
2429

2530
def __init__(self, simulations):
@@ -30,7 +35,7 @@ def __init__(self, simulations):
3035
def run(self, prms_exec='prms', nproc=None):
3136

3237
if not nproc:
33-
nproc = mp.cpu_count()//2
38+
nproc = mp.cpu_count() // 2
3439

3540
pool = mp.Pool(processes=nproc)
3641
pool.map(_simulation_runner, self.series)
@@ -41,8 +46,8 @@ def run(self, prms_exec='prms', nproc=None):
4146
def outputs_iter(self):
4247
'''
4348
Return an iterator of directories with the path to the simulation_dir
44-
as well as paths to the statvar output, the data and
45-
parameter files used in the simulation.
49+
as well as paths to the statvar output, the data and parameter files
50+
used in the simulation.
4651
4752
Example:
4853
>>> ser = SimulationSeries(simulations)

0 commit comments

Comments
 (0)