Ejemplo n.º 1
0
def write_source_table(source_dicts, out_stream):
    """
    Write tables of cases and their respective sources.

    Parameters
    ----------
    source_dicts : dict or list of dicts
        Dict of source and cases.
    out_stream : file-like object
        Where to send human readable output.
    """
    if out_stream is None:
        return

    # use tabulate if we are in a notebook, have tabulate and are using the default out_stream
    if notebook and tabulate and out_stream is _DEFAULT_OUT_STREAM:
        use_tabulate = True
    else:
        use_tabulate = False

    if out_stream is _DEFAULT_OUT_STREAM:
        out_stream = sys.stdout
    elif not isinstance(out_stream, TextIOBase):
        raise TypeError("Invalid output stream specified for 'out_stream'.")

    if not source_dicts:
        out_stream.write('No data found.\n')
        return

    if not isinstance(source_dicts, list):
        source_dicts = [source_dicts]

    for source_dict in source_dicts:
        if use_tabulate:
            display(
                HTML(
                    tabulate(source_dict,
                             disable_numparse=True,
                             colalign=["center"] * len(source_dict),
                             headers="keys",
                             tablefmt='html')))
        else:
            for key, value in source_dict.items():
                if value:
                    out_stream.write(f'{key}\n')
                    for val in value:
                        out_stream.write(f'    {val}\n')
Ejemplo n.º 2
0
def write_var_table(pathname, var_list, var_type, var_dict,
                    hierarchical=True, top_name='model', print_arrays=False,
                    out_stream=_DEFAULT_OUT_STREAM):
    """
    Write table of variable names, values, residuals, and metadata to out_stream.

    Parameters
    ----------
    pathname : str
        Pathname to be printed. If None, defaults to 'model'.
    var_list : list of str
        List of variable names in the order they are to be written.
    var_type : 'input', 'explicit' or 'implicit'
        Indicates type of variables, input or explicit/implicit output.
    var_dict : dict
        Dict storing vals and metadata for each var name.
    hierarchical : bool
        When True, human readable output shows variables in hierarchical format.
    top_name : str
        The name of the top level group when using hierarchical format.
    print_arrays : bool
        When False, in the columnar display, just display norm of any ndarrays with size > 1.
        The norm is surrounded by vertical bars to indicate that it is a norm.
        When True, also display full values of the ndarray below the row. Format  is affected
        by the values set with numpy.set_printoptions.
    out_stream : file-like object
        Where to send human readable output.
    """
    if out_stream is None:
        return

    if notebook and tabulate and not hierarchical and out_stream is _DEFAULT_OUT_STREAM:
        use_tabulate = True
    else:
        use_tabulate = False

    if out_stream is _DEFAULT_OUT_STREAM:
        out_stream = sys.stdout
    elif not isinstance(out_stream, TextIOBase):
        raise TypeError("Invalid output stream specified for 'out_stream'.")

    count = len(var_dict)

    # Write header
    rel_idx = len(pathname) + 1 if pathname else 0
    pathname = pathname if pathname else 'model'

    if var_type == 'input':
        header = "%d Input(s) in '%s'" % (count, pathname)
    else:
        header = "%d %s Output(s) in '%s'" % (count, var_type.capitalize(), pathname)

    out_stream.write(header + '\n')

    if not count:
        out_stream.write('\n\n')
        return

    # Need an ordered list of possible output values for the two cases: inputs and outputs
    #  so that we do the column output in the correct order
    if var_type == 'input':
        out_types = ('val', 'units', 'shape', 'global_shape', 'prom_name', 'desc', 'min', 'max')
    else:
        out_types = ('val', 'resids', 'units', 'shape', 'global_shape', 'lower', 'upper',
                     'ref', 'ref0', 'res_ref', 'prom_name', 'desc', 'min', 'max')

    # Figure out which columns will be displayed
    # Look at any one of the outputs, they should all be the same, so just look at first one
    for outputs in var_dict.values():
        column_names = [out_type for out_type in out_types if out_type in outputs]
        break

    if use_tabulate and var_list:
        rows = []
        for name in var_list:
            rows.append([name] + [var_dict[name][field] for field in column_names])

        hdrs = ['varname'] + column_names
        algn = ["center"] * len(hdrs)  # colalign "left" is currently broken
        display(HTML(tabulate(rows, headers=hdrs, colalign=algn, tablefmt='html')))
        return

    # Find with width of the first column in the table
    #    Need to look through all the possible varnames to find the max width
    max_varname_len = len('varname')
    if hierarchical:
        for name, outs in var_dict.items():
            for i, name_part in enumerate(name[rel_idx:].split('.')):
                total_len = i * indent_inc + len(name_part)
                max_varname_len = max(max_varname_len, total_len)
    else:
        for name, outs in var_dict.items():
            max_varname_len = max(max_varname_len, len(name[rel_idx:]))

    # Determine the column widths of the data fields by finding the max width for all rows
    for column_name in column_names:
        column_widths[column_name] = len(column_name)  # has to be able to display name!

    for name in var_list:
        for column_name in column_names:
            column_value = var_dict[name][column_name]
            if isinstance(column_value, np.ndarray) and column_value.size > 1:
                out = '|{}|'.format(str(np.linalg.norm(column_value)))
            else:
                out = str(column_value)
            column_widths[column_name] = max(column_widths[column_name], len(str(out)))

    # Write out the column headers
    column_header = '{:{align}{width}}'.format('varname', align=align,
                                               width=max_varname_len)
    column_dashes = max_varname_len * '-'
    for column_name in column_names:
        column_header += column_spacing * ' '
        column_header += '{:{align}{width}}'.format(column_name, align=align,
                                                    width=column_widths[column_name])
        column_dashes += column_spacing * ' ' + column_widths[column_name] * '-'

    out_stream.write('\n')
    out_stream.write(column_header + '\n')
    out_stream.write(column_dashes + '\n')

    # Write out the variable names and optional values and metadata
    if hierarchical:

        cur_sys_names = []

        for abs_name in var_list:
            rel_name = abs_name[rel_idx:]

            # For hierarchical, need to display system levels in the rows above the
            #   actual row containing the var name and values. Want to make use
            #   of the hierarchies that have been written about this.
            existing_sys_names = []
            sys_names = rel_name.split('.')[:-1]
            for i, sys_name in enumerate(sys_names):
                if sys_names[:i + 1] != cur_sys_names[:i + 1]:
                    break
                else:
                    existing_sys_names = cur_sys_names[:i + 1]

            # What parts of the hierarchy for this varname need to be written that
            #   were not already written above this
            remaining_sys_path_parts = sys_names[len(existing_sys_names):]

            # Write the Systems in the var name path
            indent = len(existing_sys_names) * indent_inc
            for i, sys_name in enumerate(remaining_sys_path_parts):
                out_stream.write(indent * ' ' + sys_name + '\n')
                indent += indent_inc
            cur_sys_names = sys_names

            row = '{:{align}{width}}'.format(indent * ' ' + abs_name.split('.')[-1],
                                             align=align, width=max_varname_len)
            _write_variable(out_stream, row, column_names, var_dict[abs_name], print_arrays)
    else:
        for name in var_list:
            row = '{:{align}{width}}'.format(name[rel_idx:], align=align, width=max_varname_len)
            _write_variable(out_stream, row, column_names, var_dict[name], print_arrays)

    out_stream.write('\n\n')
Ejemplo n.º 3
0
def n2(data_source, outfile='n2.html', case_id=None, show_browser=True, embeddable=False,
       title=None, use_declare_partial_info=False):
    """
    Generate an HTML file containing a tree viewer.

    Optionally opens a web browser to view the file.

    Parameters
    ----------
    data_source : <Problem> or str
        The Problem or case recorder database containing the model or model data.

    case_id : int, str, or None
        Case name or index of case in SQL file if data_source is a database.

    outfile : str, optional
        The name of the final output file

    show_browser : bool, optional
        If True, pop up the system default web browser to view the generated html file.
        Defaults to True.

    embeddable : bool, optional
        If True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>, <body>
        and <head> tags. If False, gives a single, standalone HTML file for viewing.

    title : str, optional
        The title for the diagram. Used in the HTML title.

    use_declare_partial_info : ignored
        This option is no longer used because it is now always true.
        Still present for backwards compatibility.

    """
    # grab the model viewer data
    model_data = _get_viewer_data(data_source, case_id=case_id)

    # if MPI is active only display one copy of the viewer
    if MPI and MPI.COMM_WORLD.rank != 0:
        return

    options = {}
    model_data['options'] = options

    if use_declare_partial_info:
        warn_deprecation("'use_declare_partial_info' is now the"
                         " default and the option is ignored.")

    raw_data = json.dumps(model_data, default=default_noraise).encode('utf8')
    b64_data = str(base64.b64encode(zlib.compress(raw_data)).decode("ascii"))
    model_data = 'var compressedModel = "%s";' % b64_data

    import openmdao
    openmdao_dir = os.path.dirname(inspect.getfile(openmdao))
    vis_dir = os.path.join(openmdao_dir, "visualization/n2_viewer")
    libs_dir = os.path.join(vis_dir, "libs")
    src_dir = os.path.join(vis_dir, "src")
    style_dir = os.path.join(vis_dir, "style")
    assets_dir = os.path.join(vis_dir, "assets")

    # grab the libraries, src and style
    lib_dct = {
        'd3': 'd3.v5.min',
        'awesomplete': 'awesomplete',
        'vk_beautify': 'vkBeautify',
        'pako_inflate': 'pako_inflate.min',
        'json5': 'json5_2.2.0.min'
    }
    libs = read_files(lib_dct.values(), libs_dir, 'js')
    src_names = \
        'utils', \
        'SymbolType', \
        'N2TreeNode', \
        'ModelData', \
        'N2Style', \
        'N2Window', \
        'N2Layout', \
        'N2MatrixCell', \
        'N2Legend', \
        'N2Matrix', \
        'N2Arrow', \
        'N2Search', \
        'N2Toolbar', \
        'N2Diagram', \
        'NodeInfo', \
        'N2UserInterface', \
        'defaults', \
        'ptN2'

    srcs = read_files(src_names, src_dir, 'js')

    style_names = \
        'window', \
        'partition_tree', \
        'n2toolbar-icons', \
        'toolbar', \
        'legend', \
        'awesomplete'

    styles = read_files((style_names), style_dir, 'css')

    with open(os.path.join(style_dir, "n2toolbar-icons-font.woff"), "rb") as f:
        encoded_font = str(base64.b64encode(f.read()).decode("ascii"))

    with open(os.path.join(style_dir, "logo_png.b64"), "r") as f:
        logo_png = str(f.read())

    with open(os.path.join(assets_dir, "spinner.png"), "rb") as f:
        waiting_icon = str(base64.b64encode(f.read()).decode("ascii"))

    with open(os.path.join(assets_dir, "n2toolbar_screenshot_png.b64"), "r") as f:
        n2toolbar_png = str(f.read())

    if title:
        title = "OpenMDAO Model Hierarchy and N2 diagram: %s" % title
    else:
        title = "OpenMDAO Model Hierarchy and N2 diagram"

    src_names = ('N2ErrorHandling',)
    head_srcs = read_files(src_names, src_dir, 'js')

    h = DiagramWriter(filename=os.path.join(vis_dir, "index.html"),
                      title=title,
                      styles=styles, embeddable=embeddable, head_srcs=head_srcs)

    if (embeddable):
        h.insert("non-embedded-n2", "embedded-n2")

    # put all style and JS into index
    h.insert('{{n2toolbar-icons}}', encoded_font)
    h.insert('{{logo_png}}', logo_png)
    h.insert('{{waiting_icon}}', waiting_icon)
    h.insert('{{n2toolbar_png}}', n2toolbar_png)
    h.insert('{{om_version}}', openmdao_version)

    for k, v in lib_dct.items():
        h.insert('{{{}_lib}}'.format(k), write_script(libs[v], indent=_IND))

    for name, code in srcs.items():
        h.insert('{{{}_lib}}'.format(name.lower()),
                 write_script(code, indent=_IND))

    h.insert('{{model_data}}', write_script(model_data, indent=_IND))

    # Write output file
    h.write(outfile)

    if notebook:
        # display in Jupyter Notebook
        outfile = os.path.relpath(outfile)
        if not colab:
            display(IFrame(src=outfile, width="100%", height=700))
        else:
            display(HTML(outfile))
    elif show_browser:
        # open it up in the browser
        from openmdao.utils.webview import webview
        webview(outfile)
Ejemplo n.º 4
0
def n2(data_source,
       outfile=_default_n2_filename,
       case_id=None,
       show_browser=True,
       embeddable=False,
       title=None,
       use_declare_partial_info=False,
       display_in_notebook=True):
    """
    Generate an HTML file containing a tree viewer.

    Optionally opens a web browser to view the file.

    Parameters
    ----------
    data_source : <Problem> or str
        The Problem or case recorder database containing the model or model data.
    outfile : str, optional
        The name of the final output file.
    case_id : int, str, or None
        Case name or index of case in SQL file if data_source is a database.
    show_browser : bool, optional
        If True, pop up the system default web browser to view the generated html file.
        Defaults to True.
    embeddable : bool, optional
        If True, gives a single HTML file that doesn't have the <html>, <DOCTYPE>, <body>
        and <head> tags. If False, gives a single, standalone HTML file for viewing.
    title : str, optional
        The title for the diagram. Used in the HTML title.
    use_declare_partial_info : ignored
        This option is no longer used because it is now always true.
        Still present for backwards compatibility.
    display_in_notebook : bool, optional
        If True, display the N2 diagram in the notebook, if this is called from a notebook.
        Defaults to True.
    """
    # grab the model viewer data
    model_data = _get_viewer_data(data_source, case_id=case_id)
    # if MPI is active only display one copy of the viewer
    if MPI and MPI.COMM_WORLD.rank != 0:
        return

    options = {}
    model_data['options'] = options

    if use_declare_partial_info:
        warn_deprecation("'use_declare_partial_info' is now the"
                         " default and the option is ignored.")

    import openmdao
    openmdao_dir = os.path.dirname(inspect.getfile(openmdao))
    vis_dir = os.path.join(openmdao_dir, "visualization/n2_viewer")

    if title:
        title = f"OpenMDAO Model Hierarchy and N2 diagram: {title}"
    else:
        title = "OpenMDAO Model Hierarchy and N2 diagram"

    html_vars = {
        'title': title,
        'embeddable': "embedded-n2" if embeddable else "non-embedded-n2",
        'openmdao_version': openmdao_version,
        'model_data': model_data
    }

    HtmlPreprocessor(os.path.join(vis_dir, "index.html"),
                     outfile,
                     allow_overwrite=True,
                     var_dict=html_vars,
                     json_dumps_default=default_noraise,
                     verbose=False).run()

    if notebook:
        if display_in_notebook:
            # display in Jupyter Notebook
            outfile = os.path.relpath(outfile)
            if not colab:
                display(IFrame(src=outfile, width="100%", height=700))
            else:
                display(HTML(outfile))
    elif show_browser:
        # open it up in the browser
        from openmdao.utils.webview import webview
        webview(outfile)