source: sasmodels/doc/genmodel.py @ a5b8477

core_shell_microgelscostrafo411magnetic_modelrelease_v0.94release_v0.95ticket-1257-vesicle-productticket_1156ticket_1265_superballticket_822_more_unit_tests
Last change on this file since a5b8477 was a5b8477, checked in by Paul Kienzle <pkienzle@…>, 8 years ago

update docs to work with the new ModelInfo/ParameterTable? classes

  • Property mode set to 100644
File size: 5.8 KB
Line 
1from __future__ import print_function
2
3import sys, os, math, re
4import numpy as np
5import matplotlib.pyplot as plt
6sys.path.insert(0, os.path.abspath('..'))
7from sasmodels import generate, core
8from sasmodels.direct_model import DirectModel
9from sasmodels.data import empty_data1D, empty_data2D
10
11try:
12    from typing import Dict, Any
13except ImportError:
14    pass
15else:
16    from matplotlib.axes import Axes
17    from sasmodels.kernel import KernelModel
18    from sasmodels.modelinfo import ModelInfo
19
20def plot_1d(model, opts, ax):
21    # type: (KernelModel, Dict[str, Any], Axes) -> None
22    """
23    Create a 1-D image.
24    """
25    q_min, q_max, nq = opts['q_min'], opts['q_max'], opts['nq']
26    q_min = math.log10(q_min)
27    q_max = math.log10(q_max)
28    q = np.logspace(q_min, q_max, nq)
29    data = empty_data1D(q)
30    calculator = DirectModel(data, model)
31    Iq1D = calculator()
32
33    ax.plot(q, Iq1D, color='blue', lw=2, label=model.info.name)
34    ax.set_xlabel(r'$Q \/(\AA^{-1})$')
35    ax.set_ylabel(r'$I(Q) \/(\mathrm{cm}^{-1})$')
36    ax.set_xscale(opts['xscale'])
37    ax.set_yscale(opts['yscale'])
38    #ax.legend(loc='best')
39
40def plot_2d(model, opts, ax):
41    # type: (KernelModel, Dict[str, Any], Axes) -> None
42    """
43    Create a 2-D image.
44    """
45    qx_max, nq2d = opts['qx_max'], opts['nq2d']
46    q = np.linspace(-qx_max, qx_max, nq2d) # type: np.ndarray
47    data2d = empty_data2D(q, resolution=0.0)
48    calculator = DirectModel(data2d, model)
49    Iq2D = calculator() #background=0)
50    Iq2D = Iq2D.reshape(nq2d, nq2d)
51    if opts['zscale'] == 'log':
52        Iq2D = np.log(np.clip(Iq2D, opts['vmin'], np.inf))
53    ax.imshow(Iq2D, interpolation='nearest', aspect=1, origin='lower',
54              extent=[-qx_max, qx_max, -qx_max, qx_max], cmap=opts['colormap'])
55    ax.set_xlabel(r'$Q_x \/(\AA^{-1})$')
56    ax.set_ylabel(r'$Q_y \/(\AA^{-1})$')
57
58def figfile(model_info):
59    # type: (ModelInfo) -> str
60    return model_info.id + '_autogenfig.png'
61
62def make_figure(model_info, opts):
63    # type: (ModelInfo, Dict[str, Any]) -> None
64    """
65    Generate the figure file to include in the docs.
66    """
67    model = core.build_model(model_info)
68
69    fig_height = 3.0 # in
70    fig_left = 0.6 # in
71    fig_right = 0.5 # in
72    fig_top = 0.6*0.25 # in
73    fig_bottom = 0.6*0.75
74    if model_info.parameters.has_2d:
75        plot_height = fig_height - (fig_top+fig_bottom)
76        plot_width = plot_height
77        fig_width = 2*(plot_width + fig_left + fig_right)
78        aspect = (fig_width, fig_height)
79        ratio = aspect[0]/aspect[1]
80        ax_left = fig_left/fig_width
81        ax_bottom = fig_bottom/fig_height
82        ax_height = plot_height/fig_height
83        ax_width = ax_height/ratio # square axes
84        fig = plt.figure(figsize=aspect)
85        ax2d = fig.add_axes([0.5+ax_left, ax_bottom, ax_width, ax_height])
86        plot_2d(model, opts, ax2d)
87        ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height])
88        plot_1d(model, opts, ax1d)
89        #ax.set_aspect('square')
90    else:
91        plot_height = fig_height - (fig_top+fig_bottom)
92        plot_width = (1+np.sqrt(5))/2*fig_height
93        fig_width = plot_width + fig_left + fig_right
94        ax_left = fig_left/fig_width
95        ax_bottom = fig_bottom/fig_height
96        ax_width = plot_width/fig_width
97        ax_height = plot_height/fig_height
98        aspect = (fig_width, fig_height)
99        fig = plt.figure(figsize=aspect)
100        ax1d = fig.add_axes([ax_left, ax_bottom, ax_width, ax_height])
101        plot_1d(model, opts, ax1d)
102
103    # Save image in model/img
104    path = os.path.join('model', 'img', figfile(model_info))
105    plt.savefig(path, bbox_inches='tight')
106    #print("figure saved in",path)
107
108def gen_docs(model_info):
109    # type: (ModelInfo) -> None
110    """
111    Generate the doc string with the figure inserted before the references.
112    """
113
114    # Load the doc string from the module definition file and store it in rst
115    docstr = generate.make_doc(model_info)
116
117    # Auto caption for figure
118    captionstr = '\n'
119    captionstr += '.. figure:: img/' + figfile(model_info) + '\n'
120    captionstr += '\n'
121    if model_info.parameters.has_2d:
122        captionstr += '    1D and 2D plots corresponding to the default parameters of the model.\n'
123    else:
124        captionstr += '    1D plot corresponding to the default parameters of the model.\n'
125    captionstr += '\n'
126
127    # Add figure reference and caption to documentation (at end, before References)
128    pattern = '\*\*REFERENCE'
129    match = re.search(pattern, docstr.upper())
130
131    if match:
132        docstr1 = docstr[:match.start()]
133        docstr2 = docstr[match.start():]
134        docstr = docstr1 + captionstr + docstr2
135    else:
136        print('------------------------------------------------------------------')
137        print('References NOT FOUND for model: ', model_info.id)
138        print('------------------------------------------------------------------')
139        docstr += captionstr
140
141    open(sys.argv[2],'w').write(docstr)
142
143def process_model(path):
144    # type: (str) -> None
145    """
146    Generate doc file and image file for the given model definition file.
147    """
148
149    # Load the model file
150    model_name = os.path.basename(path)[:-3]
151    model_info = core.load_model_info(model_name)
152
153    # Plotting ranges and options
154    opts = {
155        'xscale'    : 'log',
156        'yscale'    : 'log' if not model_info.structure_factor else 'linear',
157        'zscale'    : 'log' if not model_info.structure_factor else 'linear',
158        'q_min'     : 0.001,
159        'q_max'     : 1.0,
160        'nq'        : 1000,
161        'nq2d'      : 1000,
162        'vmin'      : 1e-3,  # floor for the 2D data results
163        'qx_max'    : 0.5,
164        #'colormap'  : 'gist_ncar',
165        'colormap'  : 'nipy_spectral',
166        #'colormap'  : 'jet',
167    }
168
169    # Generate the RST file and the figure.  Order doesn't matter.
170    gen_docs(model_info)
171    make_figure(model_info, opts)
172
173if __name__ == "__main__":
174    process_model(sys.argv[1])
Note: See TracBrowser for help on using the repository browser.