diff --git a/.travis.yml b/.travis.yml index a4614a6b..10d66819 100644 --- a/.travis.yml +++ b/.travis.yml @@ -24,6 +24,7 @@ env: - TEST_DIR=tests/examples - TEST_DIR=tests/em/fdem/inverse/adjoint - TEST_DIR=tests/em/fdem/forward + - TEST_DIR=tests/docs # Setup anaconda before_install: @@ -35,7 +36,7 @@ before_install: # Install packages install: - - conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython nose vtk + - conda install --yes pip python=$TRAVIS_PYTHON_VERSION numpy scipy matplotlib cython ipython nose vtk sphinx - pip install nose-cov python-coveralls - git clone https://github.com/rowanc1/pymatsolver.git @@ -46,8 +47,10 @@ install: # Run test script: + # test docs - nosetests $TEST_DIR --with-cov --cov SimPEG --cov-config .coveragerc -v -s + # Calculate coverage after_success: - coveralls --config_file .coveragerc diff --git a/SimPEG/EM/FDEM/ProblemFDEM.py b/SimPEG/EM/FDEM/ProblemFDEM.py index 9eb2e915..c4f24e15 100644 --- a/SimPEG/EM/FDEM/ProblemFDEM.py +++ b/SimPEG/EM/FDEM/ProblemFDEM.py @@ -31,6 +31,7 @@ class BaseFDEMProblem(BaseEMProblem): if using the H-J formulation (:code:`Problem3D_j` or :code:`Problem3D_h`). Note that here, :math:`\mathbf{s_m}` is an integrated quantity. The problem performs the elimination so that we are solving the system for \\\(\\\mathbf{e},\\\mathbf{b},\\\mathbf{j} \\\) or \\\(\\\mathbf{h}\\\) + """ surveyPair = SurveyFDEM @@ -444,6 +445,7 @@ class Problem3D_j(BaseFDEMProblem): \mathbf{h} = \\frac{1}{i \omega} \mathbf{M_{\mu}^e}^{-1} \\left(-\mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{j} + \mathbf{M^e} \mathbf{s_m} \\right) + and solve for \\\(\\\mathbf{j}\\\) using .. math :: @@ -608,9 +610,11 @@ class Problem3D_h(BaseFDEMProblem): .. math:: \mathbf{A} = \mathbf{C}^{\\top} \mathbf{M_{\\rho}^f} \mathbf{C} + i \omega \mathbf{M_{\mu}^e} + :param float freq: Frequency :rtype: scipy.sparse.csr_matrix :return: A + """ MeMu = self.MeMu @@ -653,6 +657,7 @@ class Problem3D_h(BaseFDEMProblem): :param float freq: Frequency :rtype: numpy.ndarray :return: RHS (nE, nSrc) + """ s_m, s_e = self.getSourceTerm(freq) diff --git a/SimPEG/Maps.py b/SimPEG/Maps.py index 3e97499f..ecfd51e1 100644 --- a/SimPEG/Maps.py +++ b/SimPEG/Maps.py @@ -41,8 +41,8 @@ class IdentityMap(object): If this is a meshless mapping (i.e. nP is defined independently) the shape will be the the shape (nP,nP). - :rtype: (int,int) - :return: shape of the operator as a tuple + :rtype: tuple + :return: shape of the operator as a tuple (int,int) """ if self._nP is not None: return (self.nP, self.nP) @@ -86,7 +86,7 @@ class IdentityMap(object): The derivative of the transformation. :param numpy.array m: model - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: derivative of transformed model """ @@ -216,7 +216,7 @@ class ExpMap(IdentityMap): def deriv(self, m): """ :param numpy.array m: model - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: derivative of transformed model The *transform* changes the model into the physical property. @@ -366,7 +366,7 @@ class SurjectVertical1D(IdentityMap): def deriv(self, m): """ :param numpy.array m: model - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: derivative of transformed model """ repNum = self.mesh.vnC[:self.mesh.dim-1].prod() @@ -427,7 +427,7 @@ class Surject2Dto3D(IdentityMap): def deriv(self, m): """ :param numpy.array m: model - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: derivative of transformed model """ inds = self * np.arange(self.nP) diff --git a/SimPEG/Mesh/BaseMesh.py b/SimPEG/Mesh/BaseMesh.py index 14b3aecf..ba2ce920 100644 --- a/SimPEG/Mesh/BaseMesh.py +++ b/SimPEG/Mesh/BaseMesh.py @@ -7,8 +7,8 @@ class BaseMesh(object): BaseMesh does all the counting you don't want to do. BaseMesh should be inherited by meshes with a regular structure. - :param numpy.array,list n: number of cells in each direction (dim, ) - :param numpy.array,list x0: Origin of the mesh (dim, ) + :param numpy.array n: (or list) number of cells in each direction (dim, ) + :param numpy.array x0: (or list) Origin of the mesh (dim, ) """ @@ -34,8 +34,8 @@ class BaseMesh(object): """ Origin of the mesh - :rtype: numpy.array (dim, ) - :return: x0 + :rtype: numpy.array + :return: x0, (dim, ) """ return self._x0 @@ -116,8 +116,8 @@ class BaseMesh(object): """ Total number of edges in each direction - :rtype: numpy.array (dim, ) - :return: [nEx, nEy, nEz] + :rtype: numpy.array + :return: [nEx, nEy, nEz], (dim, ) .. plot:: :include-source: @@ -173,8 +173,8 @@ class BaseMesh(object): """ Total number of faces in each direction - :rtype: numpy.array (dim, ) - :return: [nFx, nFy, nFz] + :rtype: numpy.array + :return: [nFx, nFy, nFz], (dim, ) .. plot:: :include-source: @@ -200,8 +200,8 @@ class BaseMesh(object): """ Face Normals - :rtype: numpy.array (sum(nF), dim) - :return: normals + :rtype: numpy.array + :return: normals, (sum(nF), dim) """ if self.dim == 2: nX = np.c_[np.ones(self.nFx), np.zeros(self.nFx)] @@ -218,8 +218,8 @@ class BaseMesh(object): """ Edge Tangents - :rtype: numpy.array (sum(nE), dim) - :return: normals + :rtype: numpy.array + :return: normals, (sum(nE), dim) """ if self.dim == 2: tX = np.c_[np.ones(self.nEx), np.zeros(self.nEx)] @@ -236,8 +236,9 @@ class BaseMesh(object): Given a vector, fV, in cartesian coordinates, this will project it onto the mesh using the normals :param numpy.array fV: face vector with shape (nF, dim) - :rtype: numpy.array with shape (nF, ) - :return: projected face vector + :rtype: numpy.array + :return: projected face vector, (nF, ) + """ assert isinstance(fV, np.ndarray), 'fV must be an ndarray' assert len(fV.shape) == 2 and fV.shape[0] == self.nF and fV.shape[1] == self.dim, 'fV must be an ndarray of shape (nF x dim)' @@ -248,8 +249,9 @@ class BaseMesh(object): Given a vector, eV, in cartesian coordinates, this will project it onto the mesh using the tangents :param numpy.array eV: edge vector with shape (nE, dim) - :rtype: numpy.array with shape (nE, ) - :return: projected edge vector + :rtype: numpy.array + :return: projected edge vector, (nE, ) + """ assert isinstance(eV, np.ndarray), 'eV must be an ndarray' assert len(eV.shape) == 2 and eV.shape[0] == self.nE and eV.shape[1] == self.dim, 'eV must be an ndarray of shape (nE x dim)' diff --git a/SimPEG/Mesh/CylMesh.py b/SimPEG/Mesh/CylMesh.py index f0b6751e..f1258184 100644 --- a/SimPEG/Mesh/CylMesh.py +++ b/SimPEG/Mesh/CylMesh.py @@ -68,8 +68,8 @@ class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView): """ Number of x-faces in each direction - :rtype: numpy.array (dim, ) - :return: vnFx + :rtype: numpy.array + :return: vnFx, (dim, ) """ return self.vnC @@ -78,8 +78,8 @@ class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView): """ Number of y-edges in each direction - :rtype: numpy.array (dim, ) - :return: vnEy or None if dim < 2 + :rtype: numpy.array + :return: vnEy or None if dim < 2, (dim, ) """ nNx = self.nNx if self.isSymmetric else self.nNx - 1 return np.r_[nNx, self.nCy, self.nNz] @@ -89,8 +89,8 @@ class CylMesh(BaseTensorMesh, BaseRectangularMesh, InnerProducts, CylView): """ Number of z-edges in each direction - :rtype: numpy.array (dim, ) - :return: vnEz or None if nCy > 1 + :rtype: numpy.array + :return: vnEz or None if nCy > 1, (dim, ) """ if self.isSymmetric: return np.r_[self.nNx, self.nNy, self.nCz] diff --git a/SimPEG/Mesh/InnerProducts.py b/SimPEG/Mesh/InnerProducts.py index 42a08702..8415b7ad 100644 --- a/SimPEG/Mesh/InnerProducts.py +++ b/SimPEG/Mesh/InnerProducts.py @@ -16,7 +16,7 @@ class InnerProducts(object): :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :param bool doFast: do a faster implementation if available. - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: M, the inner product matrix (nF, nF) """ return self._getInnerProduct('F', prop=prop, invProp=invProp, invMat=invMat, doFast=doFast) @@ -27,7 +27,7 @@ class InnerProducts(object): :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :param bool doFast: do a faster implementation if available. - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: M, the inner product matrix (nE, nE) """ return self._getInnerProduct('E', prop=prop, invProp=invProp, invMat=invMat, doFast=doFast) @@ -39,7 +39,7 @@ class InnerProducts(object): :param bool invProp: inverts the material property :param bool invMat: inverts the matrix :param bool doFast: do a faster implementation if available. - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: M, the inner product matrix (nE, nE) """ assert projType in ['F', 'E'], "projType must be 'F' for faces or 'E' for edges" @@ -121,7 +121,7 @@ class InnerProducts(object): Given u, dMdmu returns (nF, nC*nA) :param np.ndarray u: vector that multiplies dMdmu - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: dMdmu, the derivative of the inner product matrix for a certain u """ return self._getInnerProductDeriv(prop, 'F', doFast=doFast, invProp=invProp, invMat=invMat) @@ -133,7 +133,7 @@ class InnerProducts(object): :param bool doFast: do a faster implementation if available. :param bool invProp: inverts the material property :param bool invMat: inverts the matrix - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: dMdm, the derivative of the inner product matrix (nE, nC*nA) """ return self._getInnerProductDeriv(prop, 'E', doFast=doFast, invProp=invProp, invMat=invMat) @@ -145,7 +145,7 @@ class InnerProducts(object): :param bool doFast: do a faster implementation if available. :param bool invProp: inverts the material property :param bool invMat: inverts the matrix - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: dMdm, the derivative of the inner product matrix (nE, nC*nA) """ fast = None @@ -169,7 +169,7 @@ class InnerProducts(object): :param numpy.array v: vector to multiply (required in the general implementation) :param list P: list of projection matrices :param str projType: 'F' for faces 'E' for edges - :rtype: scipy.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: dMdm, the derivative of the inner product matrix (n, nC*nA) """ assert projType in ['F', 'E'], "projType must be 'F' for faces or 'E' for edges" diff --git a/SimPEG/Mesh/TreeMesh.py b/SimPEG/Mesh/TreeMesh.py index 2c75fda1..d994e3a5 100644 --- a/SimPEG/Mesh/TreeMesh.py +++ b/SimPEG/Mesh/TreeMesh.py @@ -1875,7 +1875,7 @@ class TreeMesh(BaseTensorMesh, InnerProducts, TreeMeshIO): :param numpy.ndarray locs: Location of points to interpolate to :param str locType: What to interpolate (see below) - :rtype: scipy.sparse.csr.csr_matrix + :rtype: scipy.sparse.csr_matrix :return: M, the interpolation matrix locType can be:: diff --git a/SimPEG/Utils/meshutils.py b/SimPEG/Utils/meshutils.py index 1415e7b8..53cda719 100644 --- a/SimPEG/Utils/meshutils.py +++ b/SimPEG/Utils/meshutils.py @@ -104,18 +104,17 @@ def closestPoints(mesh, pts, gridLoc='CC'): def ExtractCoreMesh(xyzlim, mesh, meshType='tensor'): """ - Extracts Core Mesh from Global mesh + Extracts Core Mesh from Global mesh - :param numpy.ndarray xyzlim: 2D array [ndim x 2] - :param simpeg.Mesh.BaseMesh mesh: The mesh + :param numpy.ndarray xyzlim: 2D array [ndim x 2] + :param simpeg.Mesh.BaseMesh mesh: The mesh - This function ouputs:: + This function ouputs:: - - actind: corresponding boolean index from global to core - - meshcore: core SimPEG mesh - - Warning: 1D and 2D has not been tested + - actind: corresponding boolean index from global to core + - meshcore: core SimPEG mesh + Warning: 1D and 2D has not been tested """ from SimPEG import Mesh if mesh.dim == 1: diff --git a/docs/api_ForwardProblem.rst b/docs/api_ForwardProblem.rst index 0bf9596f..efefedc9 100644 --- a/docs/api_ForwardProblem.rst +++ b/docs/api_ForwardProblem.rst @@ -67,13 +67,13 @@ The API Problem ------- -.. automodule:: SimPEG.Problem +.. autoclass:: SimPEG.Problem :members: :undoc-members: Survey ------ -.. automodule:: SimPEG.Survey +.. autoclass:: SimPEG.Survey :members: :undoc-members: diff --git a/docs/api_InnerProducts.rst b/docs/api_InnerProducts.rst index bc9426c6..a57a4c91 100644 --- a/docs/api_InnerProducts.rst +++ b/docs/api_InnerProducts.rst @@ -266,6 +266,6 @@ These are computed for each of the 8 projections, horizontally concatenated, and The API ------- -.. automodule:: SimPEG.Mesh.InnerProducts +.. autoclass:: SimPEG.Mesh.InnerProducts :members: :undoc-members: diff --git a/docs/api_Inversion.rst b/docs/api_Inversion.rst index 5cac5f0c..ec98ba0d 100644 --- a/docs/api_Inversion.rst +++ b/docs/api_Inversion.rst @@ -3,7 +3,7 @@ InvProblem ********** -.. automodule:: SimPEG.InvProblem +.. autoclass:: SimPEG.InvProblem :show-inheritance: :members: :undoc-members: @@ -12,7 +12,7 @@ InvProblem Inversion ********* -.. automodule:: SimPEG.Inversion +.. autoclass:: SimPEG.Inversion :show-inheritance: :members: :undoc-members: @@ -20,7 +20,7 @@ Inversion Directives ********** -.. automodule:: SimPEG.Directives +.. autoclass:: SimPEG.Directives :show-inheritance: :members: :undoc-members: diff --git a/docs/api_Mesh.rst b/docs/api_Mesh.rst index ed216b13..1043703b 100644 --- a/docs/api_Mesh.rst +++ b/docs/api_Mesh.rst @@ -188,6 +188,6 @@ other types of meshes in this SimPEG framework. The API ======= -.. automodule:: SimPEG.Mesh.BaseMesh +.. autoclass:: SimPEG.Mesh.BaseMesh :members: :undoc-members: diff --git a/docs/api_MeshCode.rst b/docs/api_MeshCode.rst index 2d7cab9f..aab8a849 100644 --- a/docs/api_MeshCode.rst +++ b/docs/api_MeshCode.rst @@ -3,34 +3,31 @@ Tensor Mesh =========== -.. automodule:: SimPEG.Mesh.TensorMesh - :show-inheritance: +.. autoclass:: SimPEG.Mesh.TensorMesh :members: :undoc-members: - + :show-inheritance: Cylindrical Mesh ================ -.. automodule:: SimPEG.Mesh.CylMesh - :show-inheritance: +.. autoclass:: SimPEG.Mesh.CylMesh :members: :undoc-members: - + :show-inheritance: Tree Mesh ========= .. autoclass:: SimPEG.Mesh.TreeMesh.TreeMesh - :show-inheritance: :members: :undoc-members: - + :show-inheritance: Curvilinear Mesh ================ -.. automodule:: SimPEG.Mesh.CurvilinearMesh - :show-inheritance: +.. autoclass:: SimPEG.Mesh.CurvilinearMesh :members: :undoc-members: + :show-inheritance: \ No newline at end of file diff --git a/docs/api_Solver.rst b/docs/api_Solver.rst index d96bd9b2..2d237c46 100644 --- a/docs/api_Solver.rst +++ b/docs/api_Solver.rst @@ -46,6 +46,8 @@ The API ======= .. autofunction:: SimPEG.Utils.SolverUtils.SolverWrapD + :noindex: .. autofunction:: SimPEG.Utils.SolverUtils.SolverWrapI + :noindex: diff --git a/docs/api_Utils.rst b/docs/api_Utils.rst index f051f51a..e6f7bb27 100644 --- a/docs/api_Utils.rst +++ b/docs/api_Utils.rst @@ -51,7 +51,6 @@ Interpolation Utilities Counter Utilities ================= - .. code-block:: python :linenos: @@ -73,7 +72,6 @@ Counter Utilities c.counter.summary() - .. code-block:: text :linenos: @@ -83,6 +81,8 @@ Counter Utilities Times: mean sum MyClass.MySecondMethod : 1.70e-06, 5.10e-04, 300x + + The API ------- diff --git a/docs/conf.py b/docs/conf.py index 6c03c6ee..334caf27 100644 --- a/docs/conf.py +++ b/docs/conf.py @@ -28,7 +28,7 @@ sys.path.append('../') # Add any Sphinx extension module names here, as strings. They can be extensions # coming with Sphinx (named 'sphinx.ext.*') or your custom ones. -extensions = ['sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinx.ext.autodoc', 'matplotlib.sphinxext.plot_directive'] +extensions = ['sphinx.ext.todo', 'sphinx.ext.mathjax', 'sphinx.ext.viewcode', 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'matplotlib.sphinxext.plot_directive'] # Add any paths that contain templates here, relative to this directory. templates_path = ['_templates'] @@ -129,7 +129,7 @@ except Exception, e: # Add any paths that contain custom static files (such as style sheets) here, # relative to this directory. They are copied after the builtin static files, # so a file named "default.css" will overwrite the builtin "default.css". -html_static_path = ['_static'] +html_static_path = [] # If not '', a 'Last updated on:' timestamp is inserted at every page bottom, # using the given strftime format. @@ -229,6 +229,12 @@ man_pages = [ # If true, show URL addresses after external links. #man_show_urls = False +# Intersphinx +intersphinx_mapping = {'python': ('http://docs.python.org/2', None), + 'numpy': ('http://docs.scipy.org/doc/numpy/', None), + 'scipy': ('http://docs.scipy.org/doc/scipy/reference/', None), + 'matplotlib': ('http://matplotlib.sourceforge.net/', None)} + # -- Options for Texinfo output ------------------------------------------------ diff --git a/tests/docs/test_docs.py b/tests/docs/test_docs.py new file mode 100644 index 00000000..4bd10d6c --- /dev/null +++ b/tests/docs/test_docs.py @@ -0,0 +1,43 @@ +import subprocess +import unittest +import os + +class Doc_Test(unittest.TestCase): + + @property + def path_to_docs(self): + dirname, filename = os.path.split(os.path.abspath(__file__)) + return os.path.sep.join(dirname.split(os.path.sep)[:-2] + ['docs']) + + def test_html(self): + doctrees_path = os.path.sep.join(self.path_to_docs.split(os.path.sep) + ['_build']+['doctrees']) + html_path = os.path.sep.join(self.path_to_docs.split(os.path.sep) + ['_build']+['html']) + + check = subprocess.call(["sphinx-build", "-nW", "-b", "html", "-d", + "%s"%(doctrees_path) , + "%s"%(self.path_to_docs), + "%s"%(html_path)]) + assert check == 0 + + # def test_latex(self): + # doctrees_path = os.path.sep.join(self.path_to_docs.split(os.path.sep) + ['_build']+['doctrees']) + # latex_path = os.path.sep.join(self.path_to_docs.split(os.path.sep) + ['_build']+['latex']) + + # check = subprocess.call(["sphinx-build", "-nW", "-b", "latex", "-d", + # "%s"%(doctrees_path), + # "%s"%(self.path_to_docs), + # "%s"%(latex_path)]) + # assert check == 0 + + # def test_linkcheck(self): + # doctrees_path = os.path.sep.join(self.path_to_docs.split(os.path.sep) + ['_build']+['doctrees']) + # link_path = os.path.sep.join(self.path_to_docs.split(os.path.sep) + ['_build']) + + # check = subprocess.call(["sphinx-build", "-nW", "-b", "linkcheck", "-d", + # "%s"%(doctrees_path), + # "%s"%(self.path_to_docs), + # "%s"%(link_path)]) + # assert check == 0 + +if __name__ == '__main__': + unittest.main() \ No newline at end of file