Reports System
Contents
Reports System¶
Default Usage¶
OpenMDAO has a reports system which will generate reports when you run your model. To see a list of the reports that are run by default, along with a brief description of each, use the command:
openmdao list_reports -d
Running the same command without the -d
will list all reports that are available.
Here is a table with more info about these default commands.
Report Name |
Description |
When Run |
Doc link |
|
---|---|---|---|---|
|
Interactive, graphical view of the model |
after |
||
|
Information on design variables, objectives, and constraints |
after |
||
|
Metadata associated with the creation of the coloring |
after |
||
|
Summary of results of an optimization run |
after |
Note that the reports are only run the first time the method is called on a given instance. For example, the scaling report is only run after the first call to Driver._compute_totals
.
These reports will, by default, be put into a subfolder of reports
named after the Problem
name.
For example, if your model has a single Problem and its default name, problem1
, was not changed by the user, the reports will be placed in a directory named reports/problem1
.
The user has control over the reports system by setting some environment variables which are described below.
Controlling which reports are generated¶
There are two ways to control which reports are generated on which models.
Controlling reporting using an environment variable¶
To turn off OpenMDAO’s default report generation, the user should set the OPENMDAO_REPORTS
environment variable to any one of these four values: ‘0’, ‘false’, ‘off’, or ‘none’.
The user can also have more fine-grained control over what reports are generated by setting this environment variable to a string that lists the reports to run. For example
OPENMDAO_REPORTS=n2
OPENMDAO_REPORTS=n2,scaling
OPENMDAO_REPORTS=none
If OPENMDAO_REPORTS
is not set, or is set to ‘1’, ‘true’, or ‘on’, the default reports will be generated.
The user can also explicitly turn on all available reports by setting OPENMDAO_REPORTS
to ‘all’.
Controlling reporting using the Problem reports argument¶
The user can also control what reports are generated using the reports
argument to Problem
.
If reports
is the default of _UNDEFINED
or True
, the OPENMDAO_REPORTS
environment variable determines reporting.
If the value for reports
is None
or False
, it will disable all reports on that Problem
.
Otherwise, reports
may be a list of names or a single comma-delimited string of the names of the reports to run for that Problem.
Overall, OPENMDAO_REPORTS
represents the global default list of reports, and individual Problems can either use that default list or override it by specifying their own list explicitly.
Setting the directory for the reports¶
If the user wishes to have the reports directory placed into a different directory other than the default current working
directory, the user can set the environment variable, OPENMDAO_REPORTS_DIR
to the name of that directory. The
directory does not have to exist beforehand. It will be created by the reporting system. As an example, if OPENMDAO_REPORTS_DIR
is set to “my_reports”, then, if the Problem
name is problem1
, then the reports will be written to the “my_reports/problem1” directory.
Support for subproblems¶
The reporting system supports subproblems. For example, if a model has two Problems and they have the default names of
problem1
and problem2
, the reporting system will put the reports into the subfolders, problem1
and problem2
under the top level reports directory, which defaults to ./reports
or is specified by the value of OPENMDAO_REPORTS_DIR
.
Adding user defined reports¶
The user can register a user defined report using the register_report
function.
- openmdao.utils.reports_system.register_report(name, func, desc, class_name, method, pre_or_post, filename=None, inst_id=None)[source]
Register a report with the reporting system.
- Parameters
- namestr
Name of report. Report names must be unique across all reports.
- funcfunction
A function to do the reporting. Expects the first argument to be an instance of class_name.
- descstr
A description of the report.
- class_namestr
The name of the class owning the method where the report will be run.
- methodstr
In which method of class_name should this be run.
- pre_or_poststr
Valid values are ‘pre’ and ‘post’. Indicates when to run the report in the method.
- filenamestr or None
Name of file to use when saving the report.
- inst_idstr or None
Either the instance ID of an OpenMDAO object (e.g. Problem, Driver) or None. If None, then this report will be run for all objects of type class_name.
Here is a script to show how this is done. Note that the function that is called to generate the actual report must have
as its first argument the class name of the OpenMDAO object owning the method where the report will be run. Currently, the only options are Problem
and Driver
. The second argument to the report function is the local filename of the report. The full file path of the report will be determined based on OPENMDAO_REPORTS_DIR
and the name of the enclosing Problem
instance. The directory where the report will be written can
be obtained by calling the get_reports_dir
method on the Problem
or Driver
instance passed into the reporting function.
Note that register_report
only adds a report type to the global reports registry. In order to activate the report so that it actually generates output, it must appear in either OPENMDAO_REPORTS
or must be passed in the Problem
reports arg as shown below.
After this script is run, there will be a file named user_report.txt
in the directory problem1
.
import pathlib
import openmdao.api as om
from openmdao.test_suite.components.paraboloid import Paraboloid
user_report_filename = 'user_report.txt'
def user_defined_report(prob, report_filename):
path = pathlib.Path(prob.get_reports_dir()).joinpath(report_filename)
with open(path, "w") as f:
f.write(f"Do some reporting on the Problem, {prob._name}\n")
# Run the report before the call to Problem.setup
om.register_report("user_report", user_defined_report, "This report is user defined",
'Problem', 'setup', 'pre', user_report_filename)
prob = om.Problem(reports='user_report')
model = prob.model
model.add_subsystem('p1', om.IndepVarComp('x', 0.0), promotes=['x'])
model.add_subsystem('p2', om.IndepVarComp('y', 0.0), promotes=['y'])
model.add_subsystem('comp', Paraboloid(), promotes=['x', 'y', 'f_xy'])
model.add_design_var('x', lower=0.0, upper=1.0)
model.add_design_var('y', lower=0.0, upper=1.0)
model.add_objective('f_xy')
prob.driver = om.ScipyOptimizeDriver()
prob.setup()
prob.run_driver()
prob.cleanup()
Optimization terminated successfully (Exit mode 0)
Current function value: [17.]
Iterations: 2
Function evaluations: 2
Gradient evaluations: 2
Optimization Complete
-----------------------------------
Creating a report plugin¶
What if you’ve developed an OpenMDAO-related python package and would like anyone using that package
to have access to a new report type that you’ve defined within that package? You can do this by
creating an openmdao_report
plugin using the steps outlined below. This example will use the
existing summary
report plugin as an example.
Create the function that generates your report. For example:
def _summary_report(prob): path = str(pathlib.Path(prob.get_reports_dir()).joinpath('summary.html')) s = StringIO() config_summary(prob, s) with open(path, 'w') as f: f.write(text2html(s.getvalue()))
Note that your report function must take as an argument an instance of the type that contains the method where your report is registered to run. For example, in the
register_report
call below, it refers to thefinal_setup
method ofProblem
, so our instance in this case must be an instance ofProblem
. Also, note that the function callsprob.get_reports_dir()
to get the location of the reports directory where the report shouild be written. In addition, the string generated from callingconfig_summary
is plain text, so it is wrapped in html using thetext2html
function to make it easily viewable in a browser, and therefore accessible using theopenmdao view_reports
command.Create a function that will register your new report type. For example:
def _summary_report_register(): register_report('summary', _summary_report, 'Model summary', 'Problem', 'final_setup', 'post')
The call above will result in a report type called
summary
that triggers at the end ofProblem.final_setup
.Create an entry point in your package’s
setup.py
file. In this example, our report registry function is found in theopenmdao.devtools.debug.py
file, so we’ll update theentry_point
arg in the call tosetup
in oursetup.py
file as follows:entry_points = { # other entry point groups here... 'openmdao_report': [ # other report entry points here... 'summary=openmdao.devtools.debug:_summary_report_register', ], }
As shown above, report entry points are part of the
openmdao_report
entry point group.
Viewing existing reports¶
As mentioned earlier, the openmdao view_reports
command provides an easy way to view all of the
reports that have been generated, either for an entire script or just for a specific Problem
instance. To view only reports for a specific problem, use
openmdao view_reports probname
where probname
is the name of the problem of interest.
Listing available reports¶
As mentioned before, the user can list available reports using the openmdao list_reports
command.
It can also be done programmatically, using the list_reports
function.
- openmdao.utils.reports_system.list_reports(default=False, out_stream=None)[source]
Write table of information about reports currently registered in the reporting system.
- Parameters
- defaultbool
If True, list only the default reports.
- out_streamfile-like object
Where to send report info.
om.list_reports()
name description class name method pre or post
-------------- --------------------------- ---------- --------------- -----------
user_report This report is user defined Problem setup pre
checks Config checks Problem final_setup post
connections Connections viewer Problem final_setup post
n2 N2 diagram Problem final_setup post
optimizer Summary of optimization Problem run_driver post
scaling Driver scaling report Driver _compute_totals post
summary Model summary Problem final_setup post
total_coloring Total coloring Driver _get_coloring post