reports Package#

What is the reports package?#

The report package offers versatile and powerful tools for generating detailed and insightful reports for both standard simulations and design of experiments (DOE) analyses.

Two main classes are available within the package: Report and ReportDOE, each tailored for specific use cases within the domain of simulation analysis and reporting.

The Report class provides a convenient way of post-processing simulation results and is intended for regular simulations. It handles the generation and presentation of reports based on simulation data. Taking advantage of Jupyter Notebook and the numerous plotting libraries of python, the results of one or multiple MotionSolve runs can be formatted and visualized in an automatically generated Jupyter Notebook.

The generated report contains pages, plots and curves, which are configured according to your preferred template. The template can be a pltpy configuration file, or you can interactively build a custom template using the functionalities illustrated in the following section.

You can choose the plotting library that fits your work best and your results will be visualized accordingly. Due to the dynamic nature of Jupyter Notebooks, further customization of the report is feasible. We encourage you to modify the code in order to adjust the report to your preferences or perform additional post-processing and signal processing on the simulation run data.

The functionality of this package is not restricted to the Jupyter Notebook only. You can use it to create standalone plots interactively while coding in msolve. To utilize the package in this manner, the only thing you have to do is not specify the Report.output attribute.

The ReportDOE is tailored for DOE analyses. It extends the reporting capabilities to suit the specific requirements of DOE methodologies, including handling complex data structures and providing specialized visualizations and statistical tools such as ANOVA table and Pareto Chart. It is an ideal solution for extracting and presenting insights from DOE data, making it a valuable asset for researchers and analysts in various fields. In addition, it makes available the entire experiment data structure so that you can use, manipulate it and perform post-processing operations.

Together, these classes within the report subpackage form a cohesive and dynamic toolkit, allowing users to transform complex simulation data and DOE analyses into accessible, insightful, and visually engaging reports.

Classes#

class Report(**kwds)#

Creates a Jupyter Notebook and populates it with model information and visualized simulation results.

The generated simulation report is a collection of pages, which are collections of plots. Plots contain one or multiple curves. The Report class is an easy and flexible tool to post-process a simulation or a series of simulations.

Parameters:
  • run (SimulationResults/SimulationResultsHistory/path object) –

    supported types are

    • SimulationResults or SimulationResultsHistory: runData attribute will be set to the content of this run(s) object and proper accessor methods are called (getObject, getComponents) to obtain the data to plot.

    • dict: runData will be set to the content of the dict and accessed directly.

    • JSON byte stream: runData will be deserialized to a dict

    • pickle byte stream: runData will be deserialized via pickle.loads() to reconstruct the original object.

    • JSON file: runData will be deserialized to a dict

    • pickle file: runData will be deserialized via pickle.load() to reconstruct the original object.

  • plt_py (path object, optional) – A plot config file in the style of Inspire Motion. The file defines a report template that contains pages, plots, and curves.

  • output (str, optional) – The output file name (.ipynb). If not specified, standalone plots will be interactively created instead.

  • plotting_package (str, default='matplotlib') – The name of the plotting package that is to be used. Choose between ‘matplotlib’, ‘bokeh’, ‘plotly’.

  • image (path object, optional) – Path to an image file that is to be used in the Jupyter Notebook report.

  • subtitle (str, optional) – A title for the analysis that is to be post-processed in the report.

Raises:

ValueError – If the provided ‘run’ object is not a valid SimulationResults (or SimulationResultsHistory) instance or pickle file, or if an error occurs during setup.

__call__()#

Allows an instance of the class to be callable. It generates a report tailored to the specified attributes.

page(*args, **kwargs)#

Creates a Page instance and adds it to the Report.

Parameters:

**kwargs – See Page for valid keyword arguments.

Returns:

The Page instance.

plot(*args, **kwargs)#

Creates a Plot instance and adds it to the specified page.

Parameters:

**kwargs – See Plot for valid keyword arguments.

Returns:

The Plot instance.

class ReportDOE(**kwds)#

Class for reporting Design of Experiments (DOE).

This class handles the generation of reports for DOE. It can take either an instance of DesignExperiment or a path to a CSV file containing experiment data. It utilizes a plotting package (default ‘matplotlib’) for generating visual representations of the experiments.

design_experiment#

An instance of DesignExperiment.

Type:

DesignExperiment

serialized_design_experiment#

Serialized version of the design_experiment. Can be used to perform additional post-processing, visualization and manipulation of the design space in the report.

Type:

bytes

plotting_package#

Name of the plotting package to be used for generating plots.

Type:

str

csv_file#

Path to the CSV file containing the experiment data.

Type:

str

Raises:
  • ValueError – If both or neither design_experiment and csv_file are provided.

  • ValueError – If the provided design_experiment is not an instance of DesignExperiment or if the csv_file is not a string.

Parameters:
  • design_experiment (DesignExperiment, optional) – An instance of DesignExperiment.

  • csv_file (str, optional) – Path to a CSV file containing experiment data.

  • output (str, optional) – Output destination for the plots. If None, plots will be pop-ups.

  • plotting_package (str, optional) – The plotting package to use. Defaults to ‘matplotlib’.

__call__()#

Allows an instance of the class to be callable. It generates the notebook.

addSummaryTable()#
class Page(**kwds)#

Creates a Page instance that will be part of a Report.

Parameters:
  • name (str, optional) – A name for the page.

  • layout (str, default='1x1') – The layout of the page. Valid options are ‘1’, ‘1x1’, ‘1x2’, ‘2x1’, ‘2x2’.

Warning

The Page class should not be instantiated by the user. Use Report.page instead.

class Plot(**kwds)#

Creates a Plot instance that will be part of a Page.

Parameters:
  • report (Report) – The Report instance that the plot will be in.

  • page (Page) – The Page instance that the plot will be in.

  • legend (str, optional) – The plot legend.

  • grid (bool, default=True) – Dictates if the plot will have grid.

  • xlabel (str, optional) – The x-axis label.

  • ylabel (str, optional) – The y-axis label.

  • name (str, optional) – A name for the plot.

  • curves (list [Curve], optional) – A list of the Curve instances that will be plotted.

Warning

The Plot class should not be instantiated by the user. Use Report.plot instead.

addCurve(*args, **kwargs)#

Adds a curve to the plot.

Parameters:

**kwargs – Pass in a curve instance using the keyword ‘curve’, or pass in keyword arguments of the Curve class to automatically create a Curve instance.

class Curve(**kwds)

Creates a Curve instance that is to be plotted in the Report.

Parameters:
  • x (iterable/str) – An iterable containing the numerical values for the x component of the curve, or a string referencing time (eg. ‘TIME’, ‘time’), or a string containing a valid entity name and entity component, separated by a dot (eg.: x = “request_1.F3”).

  • y (iterable/str) – The same as ‘x’ for the y component of the curve. If no name is provided for the curve, then curve will inherit the component name (clabel)

  • z (iterable/str) – The same as ‘x’ for the z component of the curve. If no name is provided for the curve, then curve will inherit the component name (clabel). A valid z will generate a 3D plot but only for Plotly package.

  • color (str/hex color code/tuple, optional) – The curve color.

  • name (str, optional) – A name for the curve. It will be used if specified.

  • style (str, default='-') – The line-style.

  • x_axis_scaling (Enum) –

    The increment type for the independent axis. Valid choices are:

    • ”LOG”

    • ”LINEAR”

  • y_axis_scaling (Enum) –

    The increment type for the dependent axis. Valid choices are:

    • ”LOG”

    • ”LINEAR”

  • **kwargs – Customization keyword arguments that are valid argument to the specific plotting package.

Note

You can find more about Curve customization in the following links: Matplotlib, Bokeh, Plotly

extract_data_from_csv(csv_file)#
Reads a CSV file.

Categorizes columns into parameters (DV) and responses (RV), returns a pandas DataFrame as well as the names of the design and response variables.

Args:
csv_file (str):

A fully specified filename pointing to the CSV file generated during the DOE.

Returns:
pandas.DataFrame:

DataFrame containing the data from the CSV file, with columns categorized as DV or RV.

parameter_columns (list):

A list of strings describing the design variables in the CSV file.

response_columns (list):

A list of strings describing the response variables in the CSV file.

Usage:

df, dvs, rvs = extract_data_from_csv(r"C:\workspaces\doe\exp1\fracfact_design_matrix.csv")

The CSV file must conform to the following format:

DV

DV

DV

RV

part_mass

spring_k

spring_c

response

1.0

10.0

0.2

0.345

15.0

10.0

0.1

235.1

1.0

200.0

0.1

435.61

15.0

200.0

0.2

-34.325

Note

This function only reads CSV files formatted according to the specific layout shown above. Ensure your CSV file matches this format to avoid any parsing errors.

Usage Information#

There are numerous ways you can use the reports package, depending on the Report attributes that you will specify. A brief summary is given below:

  • Depending on the run data

    1. You can pass in a SimulationResults/SimulationResultsHistory object.

    2. You can pass in a pickle or json file containing serialized run data.

    3. You can pass in a pickle or json byte stream object containing serialized run data.

    4. You can pass in a simple dictionary.

  • Depending on the template

    1. You can pass in a pltpy config file. The pltpy file will be used to create pages, plots and curves.

    2. You can create your own plot template interactively.

  • Depending on the output name

    1. Generate a Jupyter notebook by specifying an output name.

    2. Create plots interactively by neglecting the output name (matplotlib only).

Examples

In the first example, we illustrate how to generate a report, using run data in the form of a SimulationResults object. The format of the report is interactively built. This example uses the Report class. An example for the ReportDOE class can be found in DOE analysis documentation.

from msolve import *
from msolve.reports import *

def getModel():
  """Create a simple model"""
  model = Model (output="report_example")
  Units(system="mmks")
  Accgrav(kgrav=-9810)

  ground = Part (ground=True)
  global_ref = Marker (body=ground)
  ground_mar = Marker(body=ground, qp=Point(), zp=[0, 100, 0], xp=[100, 0, 0])

  part = Part (mass=2, ip=[1e3,1e3,1e3], cm=Marker(qp=[100,0,0], zp=[200,100,0], xp=[200,0,0]), name="part_1")
  sphere = Sphere(cm=part.cm, radius=20)
  wire = Outline(markers=[sphere.cm, ground_mar])
  joint = Joint(type="REVOLUTE", i=ground_mar, j=Marker(body=part, xp=[100, 0, 0], zp=[0, 100, 0]))

  ke_req    = Request(type="EXPRESSION", f2=f"KE({part.id})", name="part_ke")
  force_req = Request(type="FORCE", i=joint.i, j=joint.j, rm=joint.i, name="force")
  angle_req = Request(f1=f"RTOD*AX({joint.i.id}, {joint.j.id})",
                      f2=f"RTOD*AY({joint.i.id}, {joint.j.id})",
                      f3=f"RTOD*AZ({joint.i.id}, {joint.j.id})", name="angle")

  return model

def simulate(model):
  """Run a simulation"""
  run = model.simulate (type="DYNAMIC", end=2, dtout=.01, returnResults=True)
  return run

if __name__ == "__main__":

  # Initialize the Report
  report = Report(plotting_package = "matplotlib",
                  output           = "report_example.ipynb",
                  run              = simulate(getModel()),
                  subtitle         = "Report Example"
                  )
  # Page 1: ONE plot, TWO curves
  page1  = report.page(name="page_1", layout='1x1')
  # Plot1
  plot1 = report.plot(page=page1, name="plot_1", legend="force",
                      grid=True, xlabel='TIME (s)', ylabel="FORCE (N)")
  # Curve1.1
  plot1.addCurve (name="Fx", x='TIME', y="force.FX", color='green')
  # Curve1.2
  plot1.addCurve (name="Fy", x='TIME', y="force.FY", color='red')

  # Page 2: TWO plots, one curve each
  page2  = report.page(name="page_2", layout='1x2')
  # Plot2
  plot2 = report.plot(page=page2, name="plot_2", legend="Kinetic Energy",
                      grid=True, xlabel='Time (s)', ylabel="KE")
  # Curve2.1
  plot2.addCurve (name="part KE", x='TIME', y="part_ke.F2", color='green')
  # Plot3
  plot3 = report.plot(page=page2, name="plot_3", legend="angle_az",
                      grid=True, xlabel='TIME', ylabel="angle")
  # Curve23.1
  plot3.addCurve (name="angle AZ", x='TIME', y="angle.F3", color='green')

  # Call the execute method to generate a Jupyter Notebook
  report()