Source code for pyretis.inout.report.report_path

# -*- coding: utf-8 -*-
# Copyright (c) 2021, PyRETIS Development Team.
# Distributed under the LGPLv2.1+ License. See LICENSE for more info.
"""Method for generating reports from path sampling simulations.

The reports are useful for displaying results from the analysis.

Important methods defined here
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~

generate_report_tis (:py:func:`.generate_report_tis`)
    Generate a report for the overall results from a TIS simulation.

generate_report_tis_path (:py:func:`.generate_report_tis_path`)
    Generate a report for a single TIS simulation.

generate_report_retis (:py:func:`.generate_report_retis`)
    Generate a report for the overall results from a RETIS simulation.
"""
import logging
from pyretis.inout.report.markup import (generate_rst_table,
                                         generate_latex_table)
from pyretis.inout.formats.formatter import apply_format, format_number
logger = logging.getLogger(__name__)  # pylint: disable=invalid-name
logger.addHandler(logging.NullHandler())


__all__ = ['generate_report_tis', 'generate_report_tis_path',
           'generate_report_retis']


[docs]def generate_report_tis_path(analysis, output='rst'): """Generate a report for a single TIS simulation. Parameters ---------- analysis : dict This is the output from the analysis. output : string, optional This is the desired output format. It must match one of the formats defined in :py:const:`pyretis.inout.report.report._TEMPLATES`. Default is 'rst' (reStructuredText). Returns ------- out[0] : string The generated report in the desired format. out[1] : string The file extension (i.e. file type) for the generated report. """ result = analysis['pathensemble'] report = {'ensemble': result['out']['ensemble'], 'figures': _get_path_figures(result['figures']), 'tables': {'interfaces': None, 'probability': None, 'path': None, 'efficiency': None}} # Create tables results = [result] tables = report['tables'] tables['interfaces'] = _table_interface(results, fmt=output)[1] tables['probability'] = _table_probability(results, fmt=output)[1] tables['path'] = _table_path(results, fmt=output)[1] tables['efficiency'] = _table_efficiencies(results, fmt=output)[1] return report
[docs]def generate_report_tis(analysis, output='rst'): """Generate a report for the over-all results from a TIS simulation. Parameters ---------- analysis : dict This is the output from the analysis. output : string, optional This is the desired output format. It must match one of the formats defined in :py:const:`pyretis.inout.report.report._TEMPLATES`. Default is 'rst' (reStructuredText). Returns ------- out[0] : string The generated report in the desired format. out[1] : string The file extension (i.e. file type) for the generated report. """ report = {'figures': {'tis': [], 'matched': None}, 'tables': {'interfaces': None, 'probability': None, 'path': None, 'efficiency': None}, 'numbers': {'pcross': None, 'perr': None, 'simt': None, 'teff': None, 'opteff': None}} results = analysis['pathensemble'] figures = report['figures'] # Add figures: for result in results: figures['tis'].append(_get_path_figures(result['figures'])) # Get matched result: matched_fig = analysis['matched']['figures'] matched_out = analysis['matched']['out'] figures['matched'] = matched_fig.get('matched-probability', None) figures['total'] = matched_fig.get('total-probability', None) figures['progress'] = matched_fig.get('overall-prun', None) figures['error'] = matched_fig.get('overall-err', None) # Get numbers: report['numbers']['pcross'] = format_number(matched_out['prob'], 0.1, 1) report['numbers']['perr'] = format_number(matched_out['relerror'] * 100, 0.1, 100) report['numbers']['simt'] = format_number(matched_out['simtime'], 0.1, 100) report['numbers']['teff'] = format_number(matched_out['eff'], 0.1, 100) report['numbers']['opteff'] = format_number(matched_out['opteff'], 0.1, 100) # Get tables: tables = report['tables'] tables['interfaces'] = _table_interface(results, fmt=output)[1] tables['probability'] = _table_probability(results, fmt=output)[1] tables['path'] = _table_path(results, fmt=output)[1] tables['efficiency'] = _table_efficiencies(results, fmt=output)[1] return report
[docs]def generate_report_retis(analysis, output='rst'): """Generate a report for the over-all results from a RETIS simulation. Parameters ---------- analysis : dict This is the output from the analysis. output : string, optional This is the desired output format. It must match one of the formats defined in :py:const:`pyretis.inout.report.report._TEMPLATES`. Default is 'rst' (reStructuredText). Returns ------- out[0] : string The generated report in the desired format. out[1] : string The file extension (i.e. file type) for the generated report. """ report = {'figures': {'tis': [], 'matched': None}, 'tables': {'interfaces': None, 'interfaces0': None, 'path0': None, 'probability': None, 'path': None, 'efficiency': None, 'summary': None}, 'numbers': {'pcross': None, 'perr': None, 'simt': None, 'teff': None, 'opteff': None, 'flux': None, 'flux-err': None}, 'text': {'flux-unit': None}} results = analysis['pathensemble'] result0 = analysis['pathensemble0'] figures = report['figures'] # Add figures: for result in results: figures['tis'].append(_get_path_figures(result['figures'])) figures['path0'] = _get_path_figures(result0['figures']) # Get matched result: matched_fig = analysis['matched']['figures'] matched_out = analysis['matched']['out'] figures['matched'] = matched_fig.get('matched-probability', None) figures['total'] = matched_fig.get('total-probability', None) figures['progress'] = matched_fig.get('overall-rrun', None) figures['error'] = matched_fig.get('overall-err', None) # Get numbers: numbers = report['numbers'] numbers['pcross'] = format_number(matched_out['prob'], 0.1, 1) numbers['perr'] = format_number(matched_out['relerror'] * 100, 0.1, 100) numbers['flux'] = format_number(analysis['flux']['value'], 0.1, 100) numbers['flux-err'] = format_number(analysis['flux']['error'] * 100, 0.1, 100) numbers['rate'] = format_number(analysis['rate']['value'], 0.1, 100) numbers['rate-err'] = format_number(analysis['rate']['error'] * 100, 0.1, 100) numbers['simt'] = format_number(matched_out['simtime'], 0.1, 100) numbers['teff'] = format_number(matched_out['eff'], 0.1, 100) numbers['opteff'] = format_number(matched_out['opteff'], 0.1, 100) report['text']['flux-unit'] = analysis['flux']['unit'] # Get tables: tables = report['tables'] tables['interfaces0'] = _table_interface0([result0], fmt=output)[1] tables['path0'] = _table_path([result0], fmt=output)[1] tables['interfaces'] = _table_interface(results, fmt=output)[1] tables['probability'] = _table_probability(results, fmt=output)[1] tables['path'] = _table_path(results, fmt=output)[1] tables['efficiency'] = _table_efficiencies(results, fmt=output)[1] tables['summary'] = _table_summary(report, fmt=output)[1] return report
def generate_report_retis0(analysis, output='txt'): """Generate a report for [0^-] in a RETIS simulation. This method is primarily intended for displaying results on the screen during the analysis. Parameters ---------- analysis : dict This is the output of the analysis. output : string, optional This is the desired output format. It must match one of the formats defined in :py:const:`pyretis.inout.report.report._TEMPLATES`. Default is 'rst' (reStructuredText). Returns ------- out[0] : string The generated report in the desired format. out[1] : string The file extension (i.e. file type) for the generated report. """ if output != 'txt': output = 'txt' logger.warning('Report for [0^-] is only indended as "txt"' '\nOutput format "%s" ignored', output) result = analysis['pathensemble'] flux = result['out']['fluxlength'] report = { 'ensemble': result['out']['ensemble'], 'numbers': {'fluxlength': format_number(flux[0], 0, 10000), 'fluxlengtherror': format_number(flux[1] * 100, 0, 100)}, 'tables': {'interfaces0': _table_interface0([result], fmt=output)[1], 'path0': _table_path([result], fmt=output)[1]}, } return report
[docs]def _table_interface(results, fmt='rst'): """Generate the table for the interfaces. This table will display the location of the different interfaces. Parameters ---------- results : list of dicts These are the results of the analysis. fmt : string, optional Determines if we create reStructuredText ('rst') or latex ('tex'). Returns ------- out[0] : list of strings These are the rows of the table. out[1] : string This is a string in the desired format which represents the table. """ table = [] for result in results: interf = result['out']['interfaces'] row = [ '{:^8s}'.format(result['out']['ensemble']), apply_format(interf[0], '{:^8.4f}'), apply_format(interf[1], '{:^8.4f}'), apply_format(interf[2], '{:^8.4f}'), ] detect = result['out']['detect'] if detect is None: row.append('') else: row.append(apply_format(detect, '{:^8.4f}')) table.append(row) if fmt in ['tex', 'latex']: table_str = generate_latex_table(table, 'Interfaces', ['Ensemble', 'Left', 'Middle', 'Right', 'Detect'], fixnum={0, 1, 2, 3, 4}) else: table_str = generate_rst_table(table, 'Interfaces', ['Ensemble', 'Left', 'Middle', 'Right', 'Detect']) table_txt = '\n'.join(table_str) return table, table_txt
[docs]def _table_interface0(results, fmt='rst'): """Generate the table for the [0^-] ensemble. This table will display the location of the different interfaces. Parameters ---------- results : list of dicts These are the results of the analysis. fmt : string, optional Determines if we create reStructuredText ('rst') or latex ('tex'). Returns ------- out[0] : list of strings These are the rows of the table. out[1] : string This is a string in the desired format which represents the table. """ table = [] for result in results: row = ['{:^8s}'.format(result['out']['ensemble'])] interf = result['out']['interfaces'] row.append(apply_format(interf[0], '{:^8.4f}')) row.append(apply_format(interf[1], '{:^8.4f}')) row.append(apply_format(interf[2], '{:^8.4f}')) table.append(row) if fmt in ['tex', 'latex']: table_str = generate_latex_table(table, 'Interfaces', ['Ensemble', 'Left', 'Middle', 'Right'], fixnum={0, 1, 2, 3}) else: table_str = generate_rst_table(table, 'Interfaces', ['Ensemble', 'Left', 'Middle', 'Right']) table_txt = '\n'.join(table_str) return table, table_txt
[docs]def _table_probability(results, fmt='rst'): """Generate the table for the probabilities. This table will display the crossing probabilities with uncertainties. Parameters ---------- results : list of dicts The dictionaries are the results obtained from the analysis. fmt : string, optional Determines if we create reStructuredText ('rst') or latex ('tex'). Returns ------- out[0] : list of strings These are the rows of the table. out[1] : string This is a string in reStructuredText format which represents the table. """ table = [] for result in results: row = [ '{:^8s}'.format(result['out']['ensemble']), apply_format(result['out']['prun'][-1], '{:^10.6f}'), apply_format(result['out']['blockerror'][2], '{:^10.6f}'), apply_format(result['out']['blockerror'][4] * 100, '{:^10.6f}'), ] table.append(row) if fmt in ['tex', 'latex']: table_str = generate_latex_table(table, r'Probabilities', [r'Ensemble', r'$P_\text{cross}$', r'Error', r'Rel. error (\%)'], fixnum={0, 1, 2, 3}) else: table_str = generate_rst_table(table, r'Probabilities', [r'Ensemble', r'Pcross', r'Error', r'Rel. error (%)']) table_txt = '\n'.join(table_str) return table, table_txt
[docs]def _table_path(results, fmt='rst'): """Generate the table for the path lengths. This table will display the path lengths and also show the ratio of path lengths for all paths and accepted paths. Parameters ---------- results : list of dicts The dictionaries are the results obtained from the analysis. fmt : string, optional Determines if we create reStructuredText ('rst') or latex ('tex'). Returns ------- out[0] : list of strings These are the rows of the table. out[1] : string This is a string in reStructuredText format which represents the table. """ table = [] for result in results: row = ['{:^8s}'.format(result['out']['ensemble'])] hist1 = result['out']['pathlength'][0] hist2 = result['out']['pathlength'][1] row.append(apply_format(hist1[2][0], '{:^10.6f}')) row.append(apply_format(hist2[2][0], '{:^10.6f}')) row.append(apply_format(hist2[2][0] / hist1[2][0], '{:^10.6f}')) table.append(row) if fmt in ['tex', 'latex']: table_str = generate_latex_table(table, 'Path lengths', ['Ensemble', 'Accepted', 'All', 'All/Accepted'], fixnum={0, 1, 2, 3}) else: table_str = generate_rst_table(table, 'Path lengths', ['Ensemble', 'Accepted', 'All', 'All/Accepted']) table_txt = '\n'.join(table_str) return table, table_txt
[docs]def _table_efficiencies(results, fmt='rst'): """Generate table for efficiencies. This table will display results for the efficiencies, acceptance ratios and correlation. Parameters ---------- results : list of dicts The dictionaries are the results obtained from the analysis. fmt : string, optional Determines if we create reStructuredText ('rst') or latex ('tex'). Returns ------- out[0] : list of strings These are the rows of the table. out[1] : string This is a string in reStructuredText format which represents the table. """ table = [] for result in results: row = [ '{:^8s}'.format(result['out']['ensemble']), apply_format(result['out']['tis-cycles'], '{:^10.0f}'), apply_format(result['out']['efficiency'][1], '{:^10.6f}'), apply_format(result['out']['efficiency'][0], '{:^10.6f}'), apply_format(result['out']['blockerror'][6], '{:^10.6f}'), apply_format(result['out']['efficiency'][2], '{:^10.6f}'), ] table.append(row) if fmt in ['tex', 'latex']: table_str = generate_latex_table(table, 'Efficiency', ['Ensemble', 'TIS cycles', 'Tot sim.', 'Acceptance ratio', 'Correlation', 'Efficiency'], fixnum={0, 1, 2, 3, 4, 5}) else: table_str = generate_rst_table(table, 'Efficiency', ['Ensemble', 'TIS cycles', 'Tot sim.', 'Acceptance ratio', 'Correlation', 'Efficiency']) table_txt = '\n'.join(table_str) return table, table_txt
[docs]def _table_summary(report, fmt='rst'): """Generate table with summary of main results. This table will display results for the crossing probability, the initial flux and rate constant. Parameters ---------- report : dict Dict with current report. We use the information in this dictionary to generate the table. fmt : string, optional Determines if we create reStructuredText ('rst') or latex ('tex'). Returns ------- out[0] : list of strings These are the rows of the table. out[1] : string This is a string in reStructuredText format which represents the table. """ numbers = report['numbers'] text = report['text'] table = [['Crossing probability', numbers['pcross'], numbers['perr']], ['Flux (1/{})'.format(text['flux-unit']), numbers['flux'], numbers['flux-err']], ['Rate constant (1/{})'.format(text['flux-unit']), numbers['rate'], numbers['rate-err']]] if fmt in ['tex', 'latex']: table_str = generate_latex_table(table, 'Summary of main results', ['Property', 'Value', r'Relative error ($\%$)'], fixnum={1, 2}) else: table_str = generate_rst_table(table, 'Summary of main results', ['Property', 'Value', 'Relative error (%)']) table_txt = '\n'.join(table_str) return table, table_txt
[docs]def _get_path_figures(figures): """Return path figures from a dict of figures. This method extracts figures from results and makes them available to the report. Parameters ---------- figures : dict The figures generated by the analysis. Returns ------- path_figures : dict A dict which can be used in the report. """ path_figures = {} for fig in {'pcross', 'prun', 'perror', 'lpath', 'shoots', 'shoots_scaled'}: for key in figures: if key.endswith(fig): path_figures[fig] = figures[key] return path_figures