Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Meta Model Visualization #1052

Merged
merged 68 commits into from
Sep 27, 2019
Merged
Show file tree
Hide file tree
Changes from 63 commits
Commits
Show all changes
68 commits
Select commit Hold shift + click to select a range
f91cd65
inital commit of MetaModel Visualization suite
DKilkenny Aug 29, 2019
a59ab75
Added formatted docstrings
DKilkenny Aug 30, 2019
e7abcf0
added init files
DKilkenny Aug 30, 2019
b1fa748
Added module to setup.py file
DKilkenny Aug 30, 2019
6c994b6
renamed MetaModelVisualization to meta_model_viewer and updated test_…
DKilkenny Aug 30, 2019
04f2b0c
fixed missing comma in setup.py
DKilkenny Aug 30, 2019
f7ebe04
Fixed PEP8 and PEP257
DKilkenny Aug 30, 2019
2a90499
Added bokeh dependency
DKilkenny Aug 30, 2019
a3eae8e
fixed python 2.7 error with *sliders
DKilkenny Aug 30, 2019
8b9f47e
Addressing first round of comments
DKilkenny Sep 3, 2019
6b4b680
fixed pep error
DKilkenny Sep 3, 2019
c7e9dde
Addressing second round of comments
DKilkenny Sep 4, 2019
93efd56
Added command line functionality to display plots
DKilkenny Sep 4, 2019
6587eca
PEP8 fix
DKilkenny Sep 4, 2019
a8c0dbb
Removed the need for user to pass Problem reference
DKilkenny Sep 4, 2019
f3487f8
added unit tests for make_predictions, and training_point functions. …
DKilkenny Sep 5, 2019
0d1fdc2
Fixed command line functionality and made edits to lint checks to ski…
DKilkenny Sep 11, 2019
48cf70d
Complete refactor of contour_data
DKilkenny Sep 11, 2019
b81e9db
Added checks for meta_model command line
DKilkenny Sep 11, 2019
ec5bdad
improved performance of sliders making a slice
DKilkenny Sep 12, 2019
d03840d
checkpoint
swryan Sep 13, 2019
629de8e
add view_metamodel function, remove _hidden_func_cmd
swryan Sep 13, 2019
3fb09e4
remove assignment
swryan Sep 13, 2019
734e8ff
remove extra '
swryan Sep 13, 2019
0e7ca57
Added support for visualization of slinear structured meta models
DKilkenny Sep 16, 2019
4a180c0
added example cases and commiting to pull latest
DKilkenny Sep 17, 2019
3930f59
Merge branch 'master' of github.com:OpenMDAO/OpenMDAO into mybug1
DKilkenny Sep 17, 2019
d17f35d
Built unit tests for structured meta models
DKilkenny Sep 17, 2019
ef09987
Merge pull request #1045 from swryan/bokeh
DKilkenny Sep 18, 2019
f29592d
added docs
DKilkenny Sep 18, 2019
73154e5
Added raise errors, fixed code logic for multi-dimention inputs
DKilkenny Sep 18, 2019
f927c99
Fixed training data not showing
DKilkenny Sep 18, 2019
9e35fb0
Added new function to calculate structured metamodels training points
DKilkenny Sep 19, 2019
b60a016
Slider bar performace enhancements
DKilkenny Sep 19, 2019
72cbb9d
Error check for training point distance
DKilkenny Sep 19, 2019
940ef17
Bret's comment changes
DKilkenny Sep 23, 2019
33ff8c0
Ken's comment changes
DKilkenny Sep 23, 2019
0955a53
Cleanup
DKilkenny Sep 23, 2019
393bf7c
cleaned up example code
DKilkenny Sep 23, 2019
d44dcdb
fix for when kdtree doesn't find all requested points
Kenneth-T-Moore Sep 23, 2019
562214c
Merge branch 'mybug1' of github.com:DKilkenny/OpenMDAO into HEAD
Kenneth-T-Moore Sep 23, 2019
aeb82ea
fixed indexing issue for subplots
DKilkenny Sep 23, 2019
33f594f
Merge branch 'mybug1' of github.com:DKilkenny/OpenMDAO into danny_meta
Kenneth-T-Moore Sep 23, 2019
73a896d
added 2D prediction code for slinear
DKilkenny Sep 24, 2019
ac23217
added multi dimention
DKilkenny Sep 24, 2019
2657bb7
conflict resolve
Kenneth-T-Moore Sep 24, 2019
ec7350c
some changes
Kenneth-T-Moore Sep 24, 2019
8d6a98b
latest changes
DKilkenny Sep 24, 2019
f13989e
Merge branch 'mybug1' of github.com:DKilkenny/OpenMDAO into danny_meta
Kenneth-T-Moore Sep 24, 2019
e669b4c
some cleanup
Kenneth-T-Moore Sep 24, 2019
128e25c
major changes
Kenneth-T-Moore Sep 24, 2019
e97bcda
more changes, closer
Kenneth-T-Moore Sep 24, 2019
243ac74
works for all cases
Kenneth-T-Moore Sep 25, 2019
e286ea3
works for all cases
Kenneth-T-Moore Sep 25, 2019
480b207
Ken's refactor and the first half of code comments
DKilkenny Sep 25, 2019
6f1a280
Part 2 of code comments
DKilkenny Sep 25, 2019
5523f89
Part 3/3 of code comments
DKilkenny Sep 26, 2019
92c7320
Updated docs and renamed 'meta_model' to 'view_mm' in the command line
DKilkenny Sep 26, 2019
4bccb2d
Addressed Bret's comments
DKilkenny Sep 26, 2019
6fa87a9
pep error fix
DKilkenny Sep 26, 2019
61191c4
Updated docsand removed unneeded function
DKilkenny Sep 26, 2019
f6b7331
Another update of docs
DKilkenny Sep 26, 2019
def5d84
Docs fix...again
DKilkenny Sep 26, 2019
8f484a0
Addressed Steve's comment
DKilkenny Sep 27, 2019
7f146b0
You already know what it is, doc changes and code changes...
DKilkenny Sep 27, 2019
c33cd89
unneeded atribute
DKilkenny Sep 27, 2019
ea2efd1
Added tests for command line failures
DKilkenny Sep 27, 2019
e76bb71
removed tests
DKilkenny Sep 27, 2019
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 openmdao/code_review/test_lint_attributes.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,7 @@ def test_attributes(self):

# Loop over files
for file_name in os.listdir(dirpath):
if file_name != '__init__.py' and file_name[-3:] == '.py':
if not file_name.startswith('_') and file_name[-3:] == '.py':
if print_info:
print('File: {}'.format(file_name))

Expand Down
2 changes: 1 addition & 1 deletion openmdao/code_review/test_lint_docstrings.py
Original file line number Diff line number Diff line change
Expand Up @@ -527,7 +527,7 @@ def test_docstrings(self):

# Loop over files
for file_name in os.listdir(dirpath):
if file_name != '__init__.py' and file_name[-3:] == '.py' and not os.path.isdir(file_name):
if not file_name.startswith("_") and file_name[-3:] == '.py' and not os.path.isdir(file_name):
if print_info:
print(file_name)

Expand Down
2 changes: 1 addition & 1 deletion openmdao/code_review/test_lint_peps.py
Original file line number Diff line number Diff line change
Expand Up @@ -27,7 +27,7 @@

file_excludes = [
'test_*',
'__init__.py',
'_*.py',
]

ignores = {
Expand Down
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
1 change: 1 addition & 0 deletions openmdao/docs/features/model_visualization/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -15,3 +15,4 @@ a model.
view_connections.rst
n2_basics.rst
n2_details.rst
meta_model_basics.rst
62 changes: 62 additions & 0 deletions openmdao/docs/features/model_visualization/meta_model_basics.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,62 @@
.. _meta_model_basics:

*************************
Metamodel Visualization
*************************

When evaluating surrogate models, it can be useful to determine their fit of the training data, graphically.
OpenMDAO has a visualization package to view the training data and surrogate models generated from it.
DKilkenny marked this conversation as resolved.
Show resolved Hide resolved
This page explains how to use `view_mm` in the command line.

The metamodel viewer allows a user the ability of reducing a high dimentional input space down
to three dimensions to enable the user to determine the fit of a surrogate model to the given
training data.

-----------------------
Running the Visualizer
-----------------------

.. image:: images/view_mm.png
:width: 900

.. note::
This tool is accessible through the OpenMDAO command line tools which can be found
:ref:`here <om-command>`.

Running :code:`openmdao view_mm structured_meta_model_example.py` will open the metamodel generated
from the script in the browser and generate a metamodel viewer like the one below. The user can adjust
sliders to make slices in the graph, change X and Y inputs, and change the scatter distance value to
fine tune the distance a point can be from the surrogate line.

To recreate the viewer above, copy the first script given below and paste it into a file named :code:`structured_meta_model_example.py`.
Next, run :code:`openmdao view_mm structured_meta_model_example.py` in the command line.

Structred MetaModel Example Script
-----------------------------------
.. embed-code::
../test_suite/test_examples/meta_model_examples/structured_meta_model_example.py



Unstructred MetaModel Example Script
-------------------------------------
To view this example metamodel, copy the following script into a file named :code:`unstructured_meta_model_example.py` and then
run :code:`openmdao view_mm unstructured_meta_model_example.py` in the command line.

.. embed-code::
../test_suite/test_examples/meta_model_examples/unstructured_meta_model_example.py

.. note::
OpenMDAO supports structured and unstructured metamodels. Please refer to the documentation for a more
in depth overview of what :ref:`Unstructured <feature_MetaModelUnStructuredComp>` and :ref:`Structured <feature_MetaModelStructuredComp>`
metamodels are.

Command Line Interface
----------------------

The command, :code:`openmdao view_mm` requires a file path, the name of the surrogate model which you
want to visualize if there is more than one, and optionally a port number:

.. embed-shell-cmd::
:cmd: openmdao view_mm -h

Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
import numpy as np
import openmdao.api as om

num_train = 10

x0_min, x0_max = -5.0, 10.0
x1_min, x1_max = 0.0, 15.0
train_x0 = np.linspace(x0_min, x0_max, num_train)
train_x1 = np.linspace(x1_min, x1_max, num_train)
t_data = np.array([[308.12909601, 253.61567418, 204.6578079, 161.25549718, 123.40874201, 91.1175424, 64.38189835, 43.20180985, 27.5772769, 17.50829952],
[162.89542418, 123.20470795, 89.06954726, 60.48994214, 37.46589257, 19.99739855, 8.08446009, 1.72707719, 0.92524984, 5.67897804,],
[ 90.2866907, 63.02637433, 41.32161352, 25.17240826, 14.57875856, 9.54066442, 10.05812583, 16.13114279, 27.75971531, 44.94384339,],
[ 55.60211264, 38.37989042, 26.71322375, 20.60211264, 20.04655709, 25.04655709, 35.60211264, 51.71322375, 73.37989042, 100.60211264],
[ 22.81724065, 13.24080685, 9.2199286, 10.75460591, 17.84483877, 30.49062719, 48.69197117, 72.4488707, 101.76132579, 136.62933643],
[ 5.11168719, 0.78873608, 2.02134053, 8.80950054, 21.1532161, 39.05248721, 62.50731389, 91.51769611, 126.0836339, 166.20512723],
[ 14.3413983, 12.87962416, 16.97340558, 26.62274256, 41.82763509, 62.58808317, 88.90408682, 120.77564601, 158.20276077, 201.18543108],
[ 20.18431209, 19.1914092, 23.75406186, 33.87227009, 49.54603386, 70.77535319, 97.56022808, 129.90065853, 167.79664453, 211.24818608],
[ 8.48953212, 5.57319475, 8.21241294, 16.40718668, 30.15751598, 49.46340083, 74.32484124, 104.74183721, 140.71438873, 182.2424958 ],
[ 10.96088904, 3.72881146, 2.05228945, 5.93132298, 15.36591208, 30.35605673, 50.90175693, 77.00301269, 108.65982401, 145.87219088]])

prob = om.Problem()
ivc = om.IndepVarComp()
ivc.add_output('x0', 0.0)
ivc.add_output('x1', 0.0)

prob.model.add_subsystem('p', ivc, promotes=['*'])
mm = prob.model.add_subsystem('mm', om.MetaModelStructuredComp(method='slinear'),
promotes=['x0', 'x1'])
mm.add_input('x0', 0.0, train_x0)
mm.add_input('x1', 0.0, train_x1)
mm.add_output('f', 0.0, t_data)

prob.setup()
prob.final_setup()
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
import numpy as np
from math import pi
import openmdao.api as om

# Model
interp = om.MetaModelUnStructuredComp()

# Training Data
x_train1 = np.random.uniform(0, pi, 100)
x_train2 = np.random.uniform(0, pi, 100)
x_train3 = np.random.uniform(0, pi, 100)
y = np.sin(x_train1 * x_train2 * x_train3)

# Inputs
interp.add_input('input_1', 0., training_data=x_train1)
interp.add_input('input_2', 0., training_data=x_train2)
interp.add_input('input_3', 0., training_data=x_train3)

# Outputs
interp.add_output('output_1', 0., training_data=y)

# Surrogate Model
interp.options['default_surrogate'] = om.KrigingSurrogate()

prob = om.Problem()
prob.model.add_subsystem('interp', interp)
prob.setup()
prob.final_setup()
78 changes: 77 additions & 1 deletion openmdao/utils/om.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,9 @@
from openmdao.core.problem import Problem
from openmdao.visualization.n2_viewer.n2_viewer import n2
from openmdao.visualization.connection_viewer.viewconns import view_connections
from openmdao.components.meta_model_unstructured_comp import MetaModelUnStructuredComp
from openmdao.components.meta_model_structured_comp import MetaModelStructuredComp
from openmdao.visualization.meta_model_viewer.meta_model_visualization import view_metamodel
from openmdao.devtools.debug import config_summary, tree, dump_dist_idxs
from openmdao.devtools.itrace import _itrace_exec, _itrace_setup_parser
from openmdao.devtools.iprofile_app.iprofile_app import _iprof_exec, _iprof_setup_parser
Expand Down Expand Up @@ -236,6 +239,78 @@ def _viewconns(prob):
return _viewconns


def _meta_model_parser(parser):
"""
Set up the openmdao subparser for the 'openmdao meta_model' command.

Parameters
----------
parser : argparse subparser
The parser we're adding options to.
"""
parser.add_argument('file', nargs=1, help='Python file containing the model.')
parser.add_argument('-m', '--metamodel_pathname', action='store', dest='pathname',
help='pathname of the metamodel component.')
parser.add_argument('-p', '--port_number', default=5007, action='store', dest='port_number',
help='Port number to open viewer')


def _meta_model_cmd(options):
"""
Return the post_setup hook function for 'openmdao meta_model'.

Parameters
----------
options : argparse Namespace
Command line options.

Returns
-------
function
The post-setup hook function.
"""
def _view_metamodel(prob):
DKilkenny marked this conversation as resolved.
Show resolved Hide resolved
Problem._post_setup_func = None

mm_types = (MetaModelStructuredComp, MetaModelUnStructuredComp)

pathname = options.pathname
port_number = options.port_number

if pathname:
comp = prob.model._get_subsystem(pathname)
if comp and isinstance(comp, mm_types):
view_metamodel(comp, port_number)
return
else:
comp = None

metamodels = {mm.pathname: mm for
mm in prob.model.system_iter(include_self=True, typ=mm_types)}

mm_names = list(metamodels.keys())
mm_count = len(mm_names)

if mm_count == 0:
print("No Metamodel components found in model.")

elif mm_count == 1 and not pathname:
comp = metamodels[mm_names[0]]
view_metamodel(comp, port_number)

else:
try_str = "Try one of the following: {}.".format(mm_names)

if not pathname:
raise AttributeError("Metamodel not specified.\n {}".format(try_str))
elif not comp:
raise AttributeError("Metamodel '{}' not found.\n {}".format(pathname, try_str))
else:
raise AttributeError("'{}' is not a Metamodel.\n {}".format(pathname, try_str))

DKilkenny marked this conversation as resolved.
Show resolved Hide resolved
return _view_metamodel


def _config_summary_setup_parser(parser):
"""
Set up the openmdao subparser for the 'openmdao summary' command.
Expand Down Expand Up @@ -504,6 +579,7 @@ def _post_setup_exec(options):
'Print citations referenced by problem'),
'check': (_check_config_setup_parser, _check_config_cmd,
'Perform a number of configuration checks on the problem.'),
'view_mm': (_meta_model_parser, _meta_model_cmd, "Meta Model Viewer.")
}


Expand All @@ -527,7 +603,7 @@ def _post_setup_exec(options):
'Colored jacobian viewer.'),
'xdsm': (_xdsm_setup_parser, _xdsm_cmd, 'XDSM viewer.'),
'scaffold': (_scaffold_setup_parser, _scaffold_exec,
'Generate a simple scaffold for a component.')
'Generate a simple scaffold for a component.'),
}


Expand Down
Empty file.
Loading