Commit cf4c2287 authored by Peter Eastman's avatar Peter Eastman
Browse files

Use Doxygen to generate API docs for Python. This involved lots of changes...

Use Doxygen to generate API docs for Python.  This involved lots of changes both to Python API generation and to Doxygen doc generation.
parent c8764170
......@@ -491,42 +491,75 @@ ENDIF (EXECUTABLE_OUTPUT_PATH)
find_package(Doxygen QUIET)
mark_as_advanced(CLEAR DOXYGEN_EXECUTABLE)
IF(DOXYGEN_EXECUTABLE)
SET(DOXY_CONFIG "${CMAKE_CURRENT_BINARY_DIR}/Doxyfile")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in
${DOXY_CONFIG}
# Generate C++ API documentation
SET(DOXY_CONFIG_C++ "${CMAKE_CURRENT_BINARY_DIR}/DoxyfileC++")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/docs/DoxyfileC++.in
${DOXY_CONFIG_C++}
@ONLY )
FILE(GLOB_RECURSE OPENMM_INCLUDES "openmm/include/*.h")
FILE(GLOB_RECURSE OLLA_INCLUDES "olla/include/*.h")
ADD_CUSTOM_COMMAND(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/html/index.html"
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG}
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/api-c++/index.html"
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG_C++}
DEPENDS ${OPENMM_INCLUDES} ${OLLA_INCLUDES}
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Generating API documentation using Doxygen")
ADD_CUSTOM_TARGET(DoxygenApiDocs
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/html/index.html"
COMMENT "Generating API documentation using Doxygen"
COMMENT "Generating C++ API documentation using Doxygen")
ADD_CUSTOM_TARGET(C++ApiDocs
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/api-c++/index.html"
COMMENT "Generating C++ API documentation using Doxygen"
SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/DoxyfileC++.in"
${OPENMM_INCLUDES}
${OLLA_INCLUDES}
)
FILE(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/html/")
INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/html/"
DESTINATION "docs/api/")
FILE(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/api-c++/")
INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/api-c++/"
DESTINATION "docs/api-c++/")
INSTALL(FILES "docs/API Reference.html"
DESTINATION "docs/")
ADD_CUSTOM_TARGET(DoxygenApiDocs
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/api-c++/index.html"
COMMENT "Generating C++ API documentation using Doxygen"
SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/docs/DoxyfileC++.in"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/DoxyfilePython.in"
${OPENMM_INCLUDES}
${OLLA_INCLUDES}
)
set(OPENMM_GENERATE_API_DOCS OFF CACHE BOOL "Whether to create API documentation using Doxygen")
if(OPENMM_GENERATE_API_DOCS)
ADD_CUSTOM_TARGET(GenerateDoxygenApiDocs ALL
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/html/index.html"
COMMENT "Generating API documentation using Doxygen"
IF (OPENMM_GENERATE_API_DOCS)
SET_TARGET_PROPERTIES(DoxygenApiDocs PROPERTIES EXCLUDE_FROM_ALL FALSE)
ENDIF (OPENMM_GENERATE_API_DOCS)
# Generate Python API documentation
IF (OPENMM_BUILD_PYTHON_WRAPPERS)
SET(DOXY_CONFIG_PYTHON "${CMAKE_CURRENT_BINARY_DIR}/DoxyfilePython")
CONFIGURE_FILE(${CMAKE_CURRENT_SOURCE_DIR}/docs/DoxyfilePython.in
${DOXY_CONFIG_PYTHON}
@ONLY )
ADD_CUSTOM_COMMAND(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/api-python/index.html"
COMMAND ${DOXYGEN_EXECUTABLE} ${DOXY_CONFIG_PYTHON}
DEPENDS RunSwig
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}"
COMMENT "Generating Python API documentation using Doxygen")
ADD_CUSTOM_TARGET(PythonApiDocs
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/api-python/index.html"
COMMENT "Generating Python API documentation using Doxygen"
SOURCES
"${CMAKE_CURRENT_SOURCE_DIR}/docs/Doxyfile.in"
"${CMAKE_CURRENT_SOURCE_DIR}/docs/DoxyfilePython.in"
${OPENMM_INCLUDES}
${OLLA_INCLUDES}
)
endif(OPENMM_GENERATE_API_DOCS)
FILE(MAKE_DIRECTORY "${PROJECT_BINARY_DIR}/api-python/")
INSTALL(DIRECTORY "${PROJECT_BINARY_DIR}/api-python/"
DESTINATION "docs/api-python/")
INSTALL(FILES "docs/API Reference.html"
DESTINATION "docs/")
ADD_DEPENDENCIES(DoxygenApiDocs PythonApiDocs)
ENDIF (OPENMM_BUILD_PYTHON_WRAPPERS)
ENDIF(DOXYGEN_EXECUTABLE)
install(FILES docs/UsersGuide/OpenMMUsersGuide.pdf
......
......@@ -85,7 +85,7 @@ RECURSIVE = YES
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS = */tests/* \
*/src/* \
*/openmmapi/src/* \
*/.svn/* \
*/olla/include/openmm/kernels.h
EXCLUDE_SYMBOLS =
......@@ -117,7 +117,7 @@ IGNORE_PREFIX =
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = html
HTML_OUTPUT = api-c++
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
......@@ -200,7 +200,7 @@ SKIP_FUNCTION_MACROS = YES
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = "html/@PROJECT_NAME@DoxygenTagfile"
GENERATE_TAGFILE = "api-c++/@PROJECT_NAME@DoxygenTagfile"
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
......
# Doxyfile 1.5.3
#---------------------------------------------------------------------------
# Project related configuration options
#---------------------------------------------------------------------------
DOXYFILE_ENCODING = UTF-8
PROJECT_NAME = @PROJECT_NAME@
PROJECT_NUMBER =
OUTPUT_DIRECTORY =
CREATE_SUBDIRS = NO
OUTPUT_LANGUAGE = English
BRIEF_MEMBER_DESC = YES
REPEAT_BRIEF = YES
ABBREVIATE_BRIEF =
ALWAYS_DETAILED_SEC = NO
INLINE_INHERITED_MEMB = NO
FULL_PATH_NAMES = NO
STRIP_FROM_PATH =
STRIP_FROM_INC_PATH =
SHORT_NAMES = NO
JAVADOC_AUTOBRIEF = YES
QT_AUTOBRIEF = NO
MULTILINE_CPP_IS_BRIEF = NO
DETAILS_AT_TOP = YES
INHERIT_DOCS = YES
SEPARATE_MEMBER_PAGES = NO
TAB_SIZE = 4
ALIASES =
OPTIMIZE_OUTPUT_FOR_C = NO
OPTIMIZE_OUTPUT_JAVA = YES
BUILTIN_STL_SUPPORT = NO
CPP_CLI_SUPPORT = NO
DISTRIBUTE_GROUP_DOC = YES
SUBGROUPING = YES
#---------------------------------------------------------------------------
# Build related configuration options
#---------------------------------------------------------------------------
EXTRACT_ALL = YES
EXTRACT_PRIVATE = NO
EXTRACT_STATIC = NO
EXTRACT_LOCAL_CLASSES = YES
EXTRACT_LOCAL_METHODS = NO
EXTRACT_ANON_NSPACES = NO
HIDE_UNDOC_MEMBERS = NO
HIDE_UNDOC_CLASSES = NO
HIDE_FRIEND_COMPOUNDS = NO
HIDE_IN_BODY_DOCS = YES
INTERNAL_DOCS = NO
CASE_SENSE_NAMES = YES
HIDE_SCOPE_NAMES = YES
SHOW_INCLUDE_FILES = YES
INLINE_INFO = YES
SORT_MEMBER_DOCS = YES
SORT_BRIEF_DOCS = NO
SORT_BY_SCOPE_NAME = NO
GENERATE_TODOLIST = YES
GENERATE_TESTLIST = YES
GENERATE_BUGLIST = YES
GENERATE_DEPRECATEDLIST= YES
ENABLED_SECTIONS =
MAX_INITIALIZER_LINES = 30
SHOW_USED_FILES = YES
SHOW_DIRECTORIES = YES
FILE_VERSION_FILTER =
SHOW_NAMESPACES = NO
SHOW_FILES = NO
SHOW_DIRECTORIES = NO
#---------------------------------------------------------------------------
# configuration options related to warning and progress messages
#---------------------------------------------------------------------------
QUIET = NO
WARNINGS = YES
WARN_IF_UNDOCUMENTED = YES
WARN_IF_DOC_ERROR = YES
WARN_NO_PARAMDOC = NO
WARN_FORMAT = "$file:$line: $text "
WARN_LOGFILE =
#---------------------------------------------------------------------------
# configuration options related to the input files
#---------------------------------------------------------------------------
INPUT = "@CMAKE_BINARY_DIR@/python/simtk/openmm" "@CMAKE_BINARY_DIR@/python/simtk/openmm/app"
INPUT_ENCODING = UTF-8
FILE_PATTERNS =
RECURSIVE = NO
EXCLUDE =
EXCLUDE_SYMLINKS = NO
EXCLUDE_PATTERNS =
EXCLUDE_SYMBOLS =
EXAMPLE_PATH =
EXAMPLE_PATTERNS =
EXAMPLE_RECURSIVE = NO
IMAGE_PATH =
INPUT_FILTER = "@PYTHON_EXECUTABLE@ @CMAKE_BINARY_DIR@/python/filterPythonFiles.py"
FILTER_PATTERNS =
FILTER_SOURCE_FILES = YES
#---------------------------------------------------------------------------
# configuration options related to source browsing
#---------------------------------------------------------------------------
SOURCE_BROWSER = NO
INLINE_SOURCES = NO
STRIP_CODE_COMMENTS = YES
REFERENCED_BY_RELATION = YES
REFERENCES_RELATION = YES
REFERENCES_LINK_SOURCE = YES
USE_HTAGS = NO
VERBATIM_HEADERS = YES
#---------------------------------------------------------------------------
# configuration options related to the alphabetical class index
#---------------------------------------------------------------------------
ALPHABETICAL_INDEX = NO
COLS_IN_ALPHA_INDEX = 5
IGNORE_PREFIX =
#---------------------------------------------------------------------------
# configuration options related to the HTML output
#---------------------------------------------------------------------------
GENERATE_HTML = YES
HTML_OUTPUT = api-python
HTML_FILE_EXTENSION = .html
HTML_HEADER =
HTML_FOOTER =
HTML_STYLESHEET =
HTML_ALIGN_MEMBERS = YES
GENERATE_HTMLHELP = NO
HTML_DYNAMIC_SECTIONS = YES
CHM_FILE =
HHC_LOCATION =
GENERATE_CHI = NO
BINARY_TOC = NO
TOC_EXPAND = NO
DISABLE_INDEX = NO
ENUM_VALUES_PER_LINE = 4
GENERATE_TREEVIEW = YES
TREEVIEW_WIDTH = 250
#---------------------------------------------------------------------------
# configuration options related to the LaTeX output
#---------------------------------------------------------------------------
GENERATE_LATEX = NO
LATEX_OUTPUT = latex
LATEX_CMD_NAME = latex
MAKEINDEX_CMD_NAME = makeindex
COMPACT_LATEX = NO
PAPER_TYPE = a4wide
EXTRA_PACKAGES =
LATEX_HEADER =
PDF_HYPERLINKS = NO
USE_PDFLATEX = NO
LATEX_BATCHMODE = NO
LATEX_HIDE_INDICES = NO
#---------------------------------------------------------------------------
# configuration options related to the RTF output
#---------------------------------------------------------------------------
GENERATE_RTF = NO
RTF_OUTPUT = rtf
COMPACT_RTF = NO
RTF_HYPERLINKS = NO
RTF_STYLESHEET_FILE =
RTF_EXTENSIONS_FILE =
#---------------------------------------------------------------------------
# configuration options related to the man page output
#---------------------------------------------------------------------------
GENERATE_MAN = NO
MAN_OUTPUT = man
MAN_EXTENSION = .3
MAN_LINKS = NO
#---------------------------------------------------------------------------
# configuration options related to the XML output
#---------------------------------------------------------------------------
GENERATE_XML = NO
XML_OUTPUT = xml
XML_SCHEMA =
XML_DTD =
XML_PROGRAMLISTING = YES
#---------------------------------------------------------------------------
# configuration options for the AutoGen Definitions output
#---------------------------------------------------------------------------
GENERATE_AUTOGEN_DEF = NO
#---------------------------------------------------------------------------
# configuration options related to the Perl module output
#---------------------------------------------------------------------------
GENERATE_PERLMOD = NO
PERLMOD_LATEX = NO
PERLMOD_PRETTY = YES
PERLMOD_MAKEVAR_PREFIX =
#---------------------------------------------------------------------------
# Configuration options related to the preprocessor
#---------------------------------------------------------------------------
ENABLE_PREPROCESSING = YES
MACRO_EXPANSION = YES
EXPAND_ONLY_PREDEF = YES
SEARCH_INCLUDES = YES
INCLUDE_PATH =
INCLUDE_FILE_PATTERNS =
PREDEFINED =
EXPAND_AS_DEFINED =
SKIP_FUNCTION_MACROS = YES
#---------------------------------------------------------------------------
# Configuration::additions related to external references
#---------------------------------------------------------------------------
TAGFILES =
GENERATE_TAGFILE = "api-python/@PROJECT_NAME@DoxygenTagfile"
ALLEXTERNALS = NO
EXTERNAL_GROUPS = YES
PERL_PATH = /usr/bin/perl
#---------------------------------------------------------------------------
# Configuration options related to the dot tool
#---------------------------------------------------------------------------
CLASS_DIAGRAMS = YES
MSCGEN_PATH = /Applications/Doxygen.app/Contents/Resources/
HIDE_UNDOC_RELATIONS = YES
HAVE_DOT = NO
CLASS_GRAPH = YES
COLLABORATION_GRAPH = YES
GROUP_GRAPHS = YES
UML_LOOK = NO
TEMPLATE_RELATIONS = YES
INCLUDE_GRAPH = YES
INCLUDED_BY_GRAPH = YES
CALL_GRAPH = NO
CALLER_GRAPH = NO
GRAPHICAL_HIERARCHY = YES
DIRECTORY_GRAPH = YES
DOT_IMAGE_FORMAT = png
DOT_PATH =
DOTFILE_DIRS =
DOT_GRAPH_MAX_NODES = 50
MAX_DOT_GRAPH_DEPTH = 0
DOT_TRANSPARENT = NO
DOT_MULTI_TARGETS = NO
GENERATE_LEGEND = YES
DOT_CLEANUP = YES
#---------------------------------------------------------------------------
# Configuration::additions related to the search engine
#---------------------------------------------------------------------------
SEARCHENGINE = YES
......@@ -83,9 +83,6 @@ endif(SWIG_VERSION_ERROR)
find_package(Doxygen REQUIRED)
mark_as_advanced(CLEAR DOXYGEN_EXECUTABLE)
find_package(Java REQUIRED)
mark_as_advanced(CLEAR JAVA_RUNTIME)
# SWIG_OPENMM_DIR is package area where swig files will be created/used
set(SWIG_OPENMM_DIR "${OPENMM_PYTHON_STAGING_DIR}/src/swig_doxygen")
file(MAKE_DIRECTORY ${SWIG_OPENMM_DIR}/swig_lib/python)
......@@ -100,32 +97,13 @@ configure_file(
# Step 2 - Run doxygen in non-package area
add_custom_command(
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/index.xml" "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/combine.xslt"
OUTPUT "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/index.xml"
COMMAND "${DOXYGEN_EXECUTABLE}"
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/Doxyfile"
WORKING_DIRECTORY "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen"
COMMENT "Parsing OpenMM header files with doxygen..."
)
# Step 3 - Run xslt to create combined xml file
add_custom_command(
OUTPUT "${SWIG_OPENMM_DIR}/OpenMM_headers.xml"
COMMAND ${JAVA_RUNTIME}
-jar "${CMAKE_SOURCE_DIR}/wrappers/saxonb9-1-0-7j/saxon9.jar"
-t
-s:"${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/index.xml"
-xsl:"${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/combine.xslt"
-o:OpenMM_headers.xml
DEPENDS "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/index.xml" "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/combine.xslt"
WORKING_DIRECTORY "${SWIG_OPENMM_DIR}"
COMMENT "Creating combined OpenMM API xml file..."
)
add_custom_target(CreateCombinedXmlFile DEPENDS
"${SWIG_OPENMM_DIR}/OpenMM_headers.xml"
"${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/index.xml"
"${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/combine.xslt"
${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/Doxyfile)
# OpenMM REFERENCE platform first
# Files which will be created by python script and used by swig (dynamically generated)
......@@ -153,7 +131,7 @@ set(SWIG_INPUT_FILES2
add_custom_command(
OUTPUT ${SWIG_INPUT_FILES_REF}
COMMAND ${PYTHON_EXECUTABLE} "${SWIG_OPENMM_DIR}/swigInputBuilder.py"
-i OpenMM_headers.xml
-i "${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml"
-c swigInputConfig.py
-d OpenMM_docstring.i
-o OpenMM_headers.i
......@@ -163,7 +141,7 @@ add_custom_command(
DEPENDS
"${SWIG_OPENMM_DIR}/swigInputConfig.py"
"${SWIG_OPENMM_DIR}/swigInputBuilder.py"
"${SWIG_OPENMM_DIR}/OpenMM_headers.xml"
"${CMAKE_CURRENT_BINARY_DIR}/src/swig_doxygen/doxygen/xml/index.xml"
COMMENT "Creating OpenMM Python swig input files..."
)
......
import sys
# Doxygen does a bad job of generating documentation based on docstrings. This script is run as a filter
# on each file, and converts the docstrings into Doxygen style comments so we get better documentation.
input = open(sys.argv[1])
while True:
line = input.readline()
if len(line) == 0:
break
stripped = line.lstrip()
if stripped.startswith('def') or stripped.startswith('class'):
prefix = line[:len(line)-len(stripped)]
split = stripped.split()
if split[0] == 'class' and split[1][0].islower():
# Classes that start with a lowercase letter were defined by SWIG. We want to hide them.
print "%s## @private" % prefix
if split[1][0] == '_' and split[1][1] != '_':
# Names starting with a single _ are assumed to be private.
print "%s## @private" % prefix
# We're at the start of a class or function definition. Find all lines that contain the declaration.
declaration = line
while len(line) > 0 and line.find(':') == -1:
line = input.readline()
declaration += line
# Now look for a docstring.
docstrings = []
line = input.readline()
stripped = line.lstrip()
if stripped.startswith('"""'):
line = stripped[3:]
readingParameters = False
while line.find('"""') == -1:
docstrings.append(line)
line = input.readline()
if line.strip() == 'Parameters:':
readingParameters = True
line = input.readline()
stripped = line.lstrip()
if readingParameters and stripped.startswith('- '):
line = "@param %s" % stripped[2:]
elif stripped.startswith('Returns:'):
line = "@return %s" % stripped[8:]
line = line[:line.find('"""')]
docstrings.append(line)
# Print out the docstring in Doxygen syntax, followed by the declaration.
for s in docstrings:
print "%s##%s" % (prefix, s.rstrip())
print declaration
if len(docstrings) == 0:
print line
else:
print line
\ No newline at end of file
......@@ -251,7 +251,7 @@ class ForceField(object):
Allowed values are None, HBonds, AllBonds, or HAngles.
- rigidWater (boolean=True) If true, water molecules will be fully rigid regardless of the value passed for the constraints argument
- removeCMMotion (boolean=True) If true, a CMMotionRemover will be added to the System
- Arbitrary additional keyword arguments may also be specified. This allows extra parameters to be specified that are specific to
- - Arbitrary additional keyword arguments may also be specified. This allows extra parameters to be specified that are specific to
particular force fields.
Returns: the newly created System
"""
......@@ -525,7 +525,7 @@ def _findAtomMatches(atoms, template, bondedTo, externalBonds, matches, hasMatch
# and returns the corresponding generator object; 2) a createForce() method that constructs the Force object and adds it
# to the System. The static method should be added to the parsers map.
## @private
class HarmonicBondGenerator:
"""A HarmonicBondGenerator constructs a HarmonicBondForce."""
......@@ -572,6 +572,7 @@ class HarmonicBondGenerator:
parsers["HarmonicBondForce"] = HarmonicBondGenerator.parseElement
## @private
class HarmonicAngleGenerator:
"""A HarmonicAngleGenerator constructs a HarmonicAngleForce."""
......@@ -640,6 +641,7 @@ class HarmonicAngleGenerator:
parsers["HarmonicAngleForce"] = HarmonicAngleGenerator.parseElement
## @private
class PeriodicTorsion:
"""A PeriodicTorsion records the information for a periodic torsion definition."""
......@@ -652,6 +654,7 @@ class PeriodicTorsion:
self.phase = []
self.k = []
## @private
class PeriodicTorsionGenerator:
"""A PeriodicTorsionGenerator constructs a PeriodicTorsionForce."""
......@@ -739,6 +742,7 @@ class PeriodicTorsionGenerator:
parsers["PeriodicTorsionForce"] = PeriodicTorsionGenerator.parseElement
## @private
class RBTorsion:
"""An RBTorsion records the information for a Ryckaert-Bellemans torsion definition."""
......@@ -749,6 +753,7 @@ class RBTorsion:
self.types4 = types[3]
self.c = c
## @private
class RBTorsionGenerator:
"""An RBTorsionGenerator constructs an RBTorsionForce."""
......@@ -832,6 +837,7 @@ class RBTorsionGenerator:
parsers["RBTorsionForce"] = RBTorsionGenerator.parseElement
## @private
class CMAPTorsion:
"""A CMAPTorsion records the information for a CMAP torsion definition."""
......@@ -843,6 +849,7 @@ class CMAPTorsion:
self.types5 = types[4]
self.map = map
## @private
class CMAPTorsionGenerator:
"""A CMAPTorsionGenerator constructs a CMAPTorsionForce."""
......@@ -922,6 +929,7 @@ class CMAPTorsionGenerator:
parsers["CMAPTorsionForce"] = CMAPTorsionGenerator.parseElement
## @private
class NonbondedGenerator:
"""A NonbondedGenerator constructs a NonbondedForce."""
......@@ -983,6 +991,7 @@ class NonbondedGenerator:
parsers["NonbondedForce"] = NonbondedGenerator.parseElement
## @private
class GBSAOBCGenerator:
"""A GBSAOBCGenerator constructs a GBSAOBCForce."""
......@@ -1025,6 +1034,7 @@ class GBSAOBCGenerator:
parsers["GBSAOBCForce"] = GBSAOBCGenerator.parseElement
## @private
class GBVIGenerator:
"""A GBVIGenerator constructs a GBVIForce."""
......@@ -1112,6 +1122,7 @@ class GBVIGenerator:
parsers["GBVIForce"] = GBVIGenerator.parseElement
## @private
class CustomBondGenerator:
"""A CustomBondGenerator constructs a CustomBondForce."""
......@@ -1158,6 +1169,7 @@ class CustomBondGenerator:
parsers["CustomBondForce"] = CustomBondGenerator.parseElement
## @private
class CustomAngleGenerator:
"""A CustomAngleGenerator constructs a CustomAngleForce."""
......@@ -1208,6 +1220,7 @@ class CustomAngleGenerator:
parsers["CustomAngleForce"] = CustomAngleGenerator.parseElement
## @private
class CustomTorsion:
"""A CustomTorsion records the information for a custom torsion definition."""
......@@ -1218,6 +1231,7 @@ class CustomTorsion:
self.types4 = types[3]
self.paramValues = paramValues
## @private
class CustomTorsionGenerator:
"""A CustomTorsionGenerator constructs a CustomTorsionForce."""
......@@ -1307,6 +1321,7 @@ class CustomTorsionGenerator:
parsers["CustomTorsionForce"] = CustomTorsionGenerator.parseElement
## @private
class CustomGBGenerator:
"""A CustomGBGenerator constructs a CustomGBForce."""
......@@ -1401,6 +1416,7 @@ def countConstraint(data):
print "Constraints bond=%d angle=%d total=%d" % (bondCount, angleCount, (bondCount+angleCount))
## @private
class AmoebaHarmonicBondGenerator:
#=============================================================================================
......@@ -1515,6 +1531,7 @@ def addAngleConstraint(angle, idealAngle, data, sys):
return
#=============================================================================================
## @private
class AmoebaHarmonicAngleGenerator:
#=============================================================================================
......@@ -1730,6 +1747,7 @@ parsers["AmoebaHarmonicAngleForce"] = AmoebaHarmonicAngleGenerator.parseElement
# AmoebaHarmonicInPlaneAngleForce
#=============================================================================================
## @private
class AmoebaOutOfPlaneBendGenerator:
#=============================================================================================
......@@ -2010,6 +2028,7 @@ parsers["AmoebaOutOfPlaneBendForce"] = AmoebaOutOfPlaneBendGenerator.parseElemen
#=============================================================================================
## @private
class AmoebaTorsionGenerator:
#=============================================================================================
......@@ -2129,6 +2148,7 @@ parsers["AmoebaTorsionForce"] = AmoebaTorsionGenerator.parseElement
#=============================================================================================
## @private
class AmoebaPiTorsionGenerator:
#=============================================================================================
......@@ -2247,6 +2267,7 @@ parsers["AmoebaPiTorsionForce"] = AmoebaPiTorsionGenerator.parseElement
#=============================================================================================
## @private
class AmoebaTorsionTorsionGenerator:
#=============================================================================================
......@@ -2493,6 +2514,7 @@ parsers["AmoebaTorsionTorsionForce"] = AmoebaTorsionTorsionGenerator.parseElemen
#=============================================================================================
## @private
class AmoebaStretchBendGenerator:
#=============================================================================================
......@@ -2641,6 +2663,7 @@ parsers["AmoebaStretchBendForce"] = AmoebaStretchBendGenerator.parseElement
#=============================================================================================
## @private
class AmoebaVdwGenerator:
"""A AmoebaVdwGenerator constructs a AmoebaVdwForce."""
......@@ -2832,6 +2855,7 @@ parsers["AmoebaVdwForce"] = AmoebaVdwGenerator.parseElement
#=============================================================================================
## @private
class AmoebaMultipoleGenerator:
#=============================================================================================
......@@ -3501,6 +3525,7 @@ parsers["AmoebaMultipoleForce"] = AmoebaMultipoleGenerator.parseElement
#=============================================================================================
## @private
class AmoebaWcaDispersionGenerator:
"""A AmoebaWcaDispersionGenerator constructs a AmoebaWcaDispersionForce."""
......@@ -3591,6 +3616,7 @@ parsers["AmoebaWcaDispersionForce"] = AmoebaWcaDispersionGenerator.parseElement
#=============================================================================================
## @private
class AmoebaGeneralizedKirkwoodGenerator:
"""A AmoebaGeneralizedKirkwoodGenerator constructs a AmoebaGeneralizedKirkwoodForce."""
......@@ -3864,6 +3890,7 @@ parsers["AmoebaGeneralizedKirkwoodForce"] = AmoebaGeneralizedKirkwoodGenerator.p
#=============================================================================================
## @private
class AmoebaUreyBradleyGenerator:
#=============================================================================================
......
......@@ -426,16 +426,20 @@ class Modeller(object):
Aspartic acid:
ASH: Neutral form with a hydrogen on one of the delta oxygens
ASP: Negatively charged form without a hydrogen on either delta oxygen
Cysteine:
CYS: Neutral form with a hydrogen on the sulfur
CYX: No hydrogen on the sulfur (either negatively charged, or part of a disulfide bond)
Glutamic acid:
GLH: Neutral form with a hydrogen on one of the epsilon oxygens
GLU: Negatively charged form without a hydrogen on either epsilon oxygen
Histidine:
HID: Neutral form with a hydrogen on the ND1 atom
HIE: Neutral form with a hydrogen on the NE2 atom
HIP: Positively charged form with hydrogens on both ND1 and NE2
Lysine:
LYN: Neutral form with two hydrogens on the zeta nitrogen
LYS: Positively charged form with three hydrogens on the zeta nitrogen
......
......@@ -17,6 +17,8 @@ import xml.etree.ElementTree as etree
INDENT = " ";
docTags = {'emphasis':'i', 'bold':'b', 'itemizedlist':'ul', 'listitem':'li', 'preformatted':'pre', 'computeroutput':'tt'}
def trimToSingleSpace(text):
if text is None or len(text) == 0:
return ""
......@@ -29,13 +31,30 @@ def trimToSingleSpace(text):
t = "%s " % t
return t
def getNodeText(node):
if node.text is not None:
s = node.text
else:
s = ""
for n in node:
if n.tag == "para":
s = "%s%s\n\n" % (s, getNodeText(n))
elif n.tag == "ref":
s = "%s%s" % (s, getNodeText(n))
else:
if n.tag in docTags:
tag = docTags[n.tag]
s = "%s<%s>%s</%s>" % (s, tag, getNodeText(n), tag)
if n.tail is not None:
s = "%s%s" % (s, n.tail)
return s
def getText(subNodePath, node):
s=""
s = ""
for n in node.findall(subNodePath):
s = "%s%s" % (s, trimToSingleSpace(n.text))
for r in n.findall("ref"):
s = "%s%s%s" % (s, trimToSingleSpace(r.text), trimToSingleSpace(r.tail))
s = "%s%s" % (s, trimToSingleSpace(n.tail))
s = "%s%s" % (s, trimToSingleSpace(getNodeText(n)))
if n.tag == "para":
s = "%s\n\n" % s
return s.strip()
OPENMM_RE_PATTERN=re.compile("(.*)OpenMM:[a-zA-Z:]*:(.*)")
......@@ -92,7 +111,7 @@ def getClassMethodList(classNode, skipMethods):
class SwigInputBuilder:
def __init__(self,
inputFilename,
inputDirname,
configFilename,
outputFilename=None,
docstringFilename=None,
......@@ -110,7 +129,12 @@ class SwigInputBuilder:
items[2]=int(items[2])
self.skipMethods.append(tuple(items))
self.doc = etree.parse(inputFilename)
# Read all the XML files and merge them into a single document.
self.doc = etree.ElementTree(etree.Element('root'))
for file in os.listdir(inputDirname):
root = etree.parse(os.path.join(inputDirname, file)).getroot()
for node in root:
self.doc.getroot().append(node)
if outputFilename:
self.fOut = open(outputFilename, 'w')
......@@ -220,6 +244,11 @@ class SwigInputBuilder:
self.fOut.write("\n/* Class Declarations */\n\n")
for classNode in self._orderedClassNodes:
className = stripOpenmmPrefix(getText("compoundname", classNode))
if self.fOutDocstring:
dNode = classNode.find('detaileddescription')
if dNode is not None:
docstring = getNodeText(dNode).strip().replace('"', '\\"')
self.fOutDocstring.write('%%feature("docstring") %s "%s";\n' % (className, docstring))
self.fOut.write("class %s" % className)
if className in self.configModule.MISSING_BASE_CLASSES:
self.fOut.write(" : public %s" %
......@@ -498,10 +527,13 @@ class SwigInputBuilder:
dString=description
except IndexError:
pass
for pNode in findNodes(dNode, 'para/parameterlist/parameteritem'):
params = findNodes(dNode, 'para/parameterlist/parameteritem')
if len(params) > 0:
dString="%s\n Parameters:" % dString
for pNode in params:
argName = getText('parameternamelist/parametername', pNode)
argDoc = getText('parameterdescription/para', pNode)
dString="%s\n %s -- %s" % (dString, argName, argDoc)
dString="%s\n - %s %s" % (dString, argName, argDoc)
dString.strip()
if dString:
dString=re.sub(r'([^\\])"', r'\g<1>\"', dString)
......@@ -527,7 +559,7 @@ class SwigInputBuilder:
def parseCommandLine():
opts, args_proper = getopt.getopt(sys.argv[1:], 'hi:c:o:d:a:z:s:')
inputFilename = None
inputDirname = None
configFilename = None
outputFilename = ""
docstringFilename = ""
......@@ -536,24 +568,24 @@ def parseCommandLine():
skipAdditionalMethods = []
for option, parameter in opts:
if option=='-h': usageError()
if option=='-i': inputFilename = parameter
if option=='-i': inputDirname = parameter
if option=='-c': configFilename=parameter
if option=='-o': outputFilename = parameter
if option=='-d': docstringFilename = parameter
if option=='-a': pythonprependFilename=parameter
if option=='-z': pythonappendFilename=parameter
if option=='-s': skipAdditionalMethods.append(parameter)
if not inputFilename: usageError()
if not inputDirname: usageError()
if not configFilename: usageError()
return (args_proper, inputFilename, configFilename, outputFilename,
return (args_proper, inputDirname, configFilename, outputFilename,
docstringFilename,
pythonprependFilename, pythonappendFilename, skipAdditionalMethods)
def main():
(args_proper, inputFilename, configFilename, outputFilename,
(args_proper, inputDirname, configFilename, outputFilename,
docstringFilename, pythonprependFilename, pythonappendFilename,
skipAdditionalMethods) = parseCommandLine()
sBuilder = SwigInputBuilder(inputFilename, configFilename, outputFilename,
sBuilder = SwigInputBuilder(inputDirname, configFilename, outputFilename,
docstringFilename, pythonprependFilename,
pythonappendFilename, skipAdditionalMethods)
#print "Calling writeSwigFile\n"
......@@ -568,7 +600,7 @@ def usageError():
% os.path.basename(sys.argv[0]))
sys.stdout.write(' %s -c inputConfigFilename\n' \
% (' '*len(os.path.basename(sys.argv[0]))))
sys.stdout.write(' %s[-o swigInputFilename]\n' \
sys.stdout.write(' %s[-o swigInputDirname]\n' \
% (' '*len(os.path.basename(sys.argv[0]))))
sys.stdout.write(' %s[-d docstringFilename]\n' \
% (' '*len(os.path.basename(sys.argv[0]))))
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment