File: render.py

package info (click to toggle)
openmm 8.1.2%2Bdfsg-12
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 119,192 kB
  • sloc: xml: 377,325; cpp: 226,673; ansic: 42,767; python: 32,634; lisp: 2,441; sh: 440; makefile: 254; f90: 233; csh: 19
file content (142 lines) | stat: -rw-r--r-- 4,582 bytes parent folder | download | duplicates (3)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
"""
The function of this script is to render the Jinja2 templates in the current
directory into input files for sphinx. It introspects the OpenMM Python module
to find all of the classes and formats them for inclusion into the templates.
"""
from os.path import dirname, join, splitext, basename
from glob import glob
import inspect

import jinja2
import openmm
import openmm.app



def fullname(klass):
    return klass.__module__ + '.' + klass.__name__


def library_template_variables():
    """Create the data structure available to the Jinja2 renderer when
    filling in the templates.

    This function extracts all of classes in ``openmm.openmm`` and returns
    a dictionary with them grouped into three lists, the integrators, the forces,
    and the remainder (library_extras).

    A couple core classes are skipped, because they're included manually in the
    template.
    """
    data = {
        'integrators': [],
        'forces': [],
        'library_extras': [],
        'units': [],
    }

    mm_klasses = inspect.getmembers(openmm, predicate=inspect.isclass)


    # gather all Force subclasses
    for name, klass in mm_klasses:
        if issubclass(klass, openmm.openmm.Force):
            data['forces'].append(fullname(klass))

    # gather all Integrator subclasses
    for _, klass in mm_klasses:
        if issubclass(klass, openmm.openmm.Integrator):
            data['integrators'].append(fullname(klass))

    # gather all extra subclasses in openmm.openmm

    # core classes that are already included in library.rst.jinja2
    exclude = ['openmm.openmm.Platform', 'openmm.openmm.Context',
              'openmm.openmm.System', 'openmm.openmm.State']
    exclude.extend(data['forces'])
    exclude.extend(data['integrators'])

    # these classes are useless and not worth documenting.
    exclude.extend([
        'openmm.openmm.SwigPyIterator',
        'openmm.openmm.OpenMMException'])

    for _, klass in mm_klasses:
        full = fullname(klass)
        if full not in exclude and not klass.__name__[0].islower():
            data['library_extras'].append(full)

    # gather units related classes
    unit_klasses = inspect.getmembers(openmm.unit, predicate=inspect.isclass)
    for name, klass in unit_klasses:
        data['units'].append(fullname(klass))

    return data


def app_template_variables():
    """Create the data structure available to the Jinja2 renderer when
    filling in the templates.

    This function extracts all of classes in ``openmm.app`` and returns
    a dictionary with them grouped into three lists, the reporters, the
    classes with the word "File" in the name, and the remainder.

    Four classes are skipped (see exclude), because they're included manually
    in the template.
    """
    data = {
        'reporters': [],
        'fileclasses': [],
        'app_extras': [],
    }
    app_klasses = inspect.getmembers(openmm.app, predicate=inspect.isclass)

    # gather all Reporters
    for name, klass in app_klasses:
        if name.endswith('Reporter'):
            data['reporters'].append(fullname(klass))

    # gather all classes with "File" in the name
    for name, klass in app_klasses:
        if 'File' in name or 'CharmmParameterSet' in name:
            data['fileclasses'].append(fullname(klass))

    # gather all extra subclasses in openmm.app
    exclude = ['openmm.app.topology.Topology',
               'openmm.app.topology.Chain',
               'openmm.app.topology.Residue',
               'openmm.app.topology.Atom',
               'openmm.app.modeller.Modeller',
               'openmm.app.forcefield.ForceField',
               'openmm.app.simulation.Simulation']
    exclude.extend(data['reporters'])
    exclude.extend(data['fileclasses'])

    for _, klass in app_klasses:
        full = fullname(klass)
        if full not in exclude and not klass.__name__[0].islower():
            data['app_extras'].append(full)

    return data


def main():
    here = dirname(__file__)
    templateLoader = jinja2.FileSystemLoader(here)
    templateEnv = jinja2.Environment(loader=templateLoader)
    data = library_template_variables()
    data.update(app_template_variables())

    for template_fn in map(basename, glob(join(here, '*.jinja2'))):
        output_fn = splitext(template_fn)[0]
        print('Rendering %s to %s...' % (template_fn, output_fn))

        template = templateEnv.get_template(template_fn)
        output_text = template.render(data)
        with open(output_fn, 'w') as f:
            f.write(output_text)


if __name__ == '__main__':
    main()