From 1c4386ae4e684f16d8fc6e4daf4f83c6d94b5180 Mon Sep 17 00:00:00 2001 From: John Halloran Date: Sun, 8 Feb 2026 23:44:53 -0500 Subject: [PATCH 1/3] refactor: move doc to docs and update requirements --- doc/Makefile | 194 --------------------- doc/make.bat | 36 ---- doc/source/_static/.placeholder | 0 doc/source/api/diffpy.snmf.rst | 68 -------- doc/source/conf.py | 300 -------------------------------- doc/source/index.rst | 91 ---------- doc/source/license.rst | 39 ----- doc/source/quickstart.rst | 22 --- doc/source/release.rst | 5 - docs/source/conf.py | 2 +- requirements/docs.txt | 2 +- 11 files changed, 2 insertions(+), 757 deletions(-) delete mode 100644 doc/Makefile delete mode 100644 doc/make.bat delete mode 100644 doc/source/_static/.placeholder delete mode 100644 doc/source/api/diffpy.snmf.rst delete mode 100644 doc/source/conf.py delete mode 100644 doc/source/index.rst delete mode 100644 doc/source/license.rst delete mode 100644 doc/source/quickstart.rst delete mode 100644 doc/source/release.rst diff --git a/doc/Makefile b/doc/Makefile deleted file mode 100644 index fdc96a7a..00000000 --- a/doc/Makefile +++ /dev/null @@ -1,194 +0,0 @@ -# Makefile for Sphinx documentation -# - -# You can set these variables from the command line. -SPHINXOPTS = -SPHINXBUILD = sphinx-build -PAPER = -BUILDDIR = build -BASENAME = $(subst .,,$(subst $() $(),,diffpy.snmf)) - -# User-friendly check for sphinx-build -ifeq ($(shell which $(SPHINXBUILD) >/dev/null 2>&1; echo $$?), 1) -$(error The '$(SPHINXBUILD)' command was not found. Make sure you have Sphinx installed, then set the SPHINXBUILD environment variable to point to the full path of the '$(SPHINXBUILD)' executable. Alternatively you can add the directory with the executable to your PATH. If you don't have Sphinx installed, grab it from http://sphinx-doc.org/) -endif - -# Internal variables. -PAPEROPT_a4 = -D latex_paper_size=a4 -PAPEROPT_letter = -D latex_paper_size=letter -ALLSPHINXOPTS = -d $(BUILDDIR)/doctrees $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source -# the i18n builder cannot share the environment and doctrees with the others -I18NSPHINXOPTS = $(PAPEROPT_$(PAPER)) $(SPHINXOPTS) source - -.PHONY: help clean html dirhtml singlehtml pickle json htmlhelp qthelp devhelp epub latex latexpdf text man changes linkcheck doctest gettext - -help: - @echo "Please use \`make ' where is one of" - @echo " html to make standalone HTML files" - @echo " dirhtml to make HTML files named index.html in directories" - @echo " singlehtml to make a single large HTML file" - @echo " pickle to make pickle files" - @echo " json to make JSON files" - @echo " htmlhelp to make HTML files and a HTML help project" - @echo " qthelp to make HTML files and a qthelp project" - @echo " devhelp to make HTML files and a Devhelp project" - @echo " epub to make an epub" - @echo " latex to make LaTeX files, you can set PAPER=a4 or PAPER=letter" - @echo " latexpdf to make LaTeX files and run them through pdflatex" - @echo " latexpdfja to make LaTeX files and run them through platex/dvipdfmx" - @echo " text to make text files" - @echo " man to make manual pages" - @echo " texinfo to make Texinfo files" - @echo " info to make Texinfo files and run them through makeinfo" - @echo " gettext to make PO message catalogs" - @echo " changes to make an overview of all changed/added/deprecated items" - @echo " xml to make Docutils-native XML files" - @echo " pseudoxml to make pseudoxml-XML files for display purposes" - @echo " linkcheck to check all external links for integrity" - @echo " doctest to run all doctests embedded in the documentation (if enabled)" - -clean: - rm -rf $(BUILDDIR)/* - -html: - $(SPHINXBUILD) -b html $(ALLSPHINXOPTS) $(BUILDDIR)/html - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/html." - -dirhtml: - $(SPHINXBUILD) -b dirhtml $(ALLSPHINXOPTS) $(BUILDDIR)/dirhtml - @echo - @echo "Build finished. The HTML pages are in $(BUILDDIR)/dirhtml." - -singlehtml: - $(SPHINXBUILD) -b singlehtml $(ALLSPHINXOPTS) $(BUILDDIR)/singlehtml - @echo - @echo "Build finished. The HTML page is in $(BUILDDIR)/singlehtml." - -pickle: - $(SPHINXBUILD) -b pickle $(ALLSPHINXOPTS) $(BUILDDIR)/pickle - @echo - @echo "Build finished; now you can process the pickle files." - -json: - $(SPHINXBUILD) -b json $(ALLSPHINXOPTS) $(BUILDDIR)/json - @echo - @echo "Build finished; now you can process the JSON files." - -htmlhelp: - $(SPHINXBUILD) -b htmlhelp $(ALLSPHINXOPTS) $(BUILDDIR)/htmlhelp - @echo - @echo "Build finished; now you can run HTML Help Workshop with the" \ - ".hhp project file in $(BUILDDIR)/htmlhelp." - -qthelp: - $(SPHINXBUILD) -b qthelp $(ALLSPHINXOPTS) $(BUILDDIR)/qthelp - @echo - @echo "Build finished; now you can run "qcollectiongenerator" with the" \ - ".qhcp project file in $(BUILDDIR)/qthelp, like this:" - @echo "# qcollectiongenerator $(BUILDDIR)/qthelp/$(BASENAME).qhcp" - @echo "To view the help file:" - @echo "# assistant -collectionFile $(BUILDDIR)/qthelp/$(BASENAME).qhc" - -devhelp: - $(SPHINXBUILD) -b devhelp $(ALLSPHINXOPTS) $(BUILDDIR)/devhelp - @echo - @echo "Build finished." - @echo "To view the help file:" - @echo "# mkdir -p $$HOME/.local/share/devhelp/$(BASENAME)" - @echo "# ln -s $(BUILDDIR)/devhelp $$HOME/.local/share/devhelp/$(BASENAME)" - @echo "# devhelp" - -epub: - $(SPHINXBUILD) -b epub $(ALLSPHINXOPTS) $(BUILDDIR)/epub - @echo - @echo "Build finished. The epub file is in $(BUILDDIR)/epub." - -latex: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo - @echo "Build finished; the LaTeX files are in $(BUILDDIR)/latex." - @echo "Run \`make' in that directory to run these through (pdf)latex" \ - "(use \`make latexpdf' here to do that automatically)." - -latexpdf: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through pdflatex..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -latexpdfja: - $(SPHINXBUILD) -b latex $(ALLSPHINXOPTS) $(BUILDDIR)/latex - @echo "Running LaTeX files through platex and dvipdfmx..." - $(MAKE) -C $(BUILDDIR)/latex all-pdf-ja - @echo "pdflatex finished; the PDF files are in $(BUILDDIR)/latex." - -text: - $(SPHINXBUILD) -b text $(ALLSPHINXOPTS) $(BUILDDIR)/text - @echo - @echo "Build finished. The text files are in $(BUILDDIR)/text." - -man: - $(SPHINXBUILD) -b man $(ALLSPHINXOPTS) $(BUILDDIR)/man - @echo - @echo "Build finished. The manual pages are in $(BUILDDIR)/man." - -texinfo: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo - @echo "Build finished. The Texinfo files are in $(BUILDDIR)/texinfo." - @echo "Run \`make' in that directory to run these through makeinfo" \ - "(use \`make info' here to do that automatically)." - -info: - $(SPHINXBUILD) -b texinfo $(ALLSPHINXOPTS) $(BUILDDIR)/texinfo - @echo "Running Texinfo files through makeinfo..." - make -C $(BUILDDIR)/texinfo info - @echo "makeinfo finished; the Info files are in $(BUILDDIR)/texinfo." - -gettext: - $(SPHINXBUILD) -b gettext $(I18NSPHINXOPTS) $(BUILDDIR)/locale - @echo - @echo "Build finished. The message catalogs are in $(BUILDDIR)/locale." - -changes: - $(SPHINXBUILD) -b changes $(ALLSPHINXOPTS) $(BUILDDIR)/changes - @echo - @echo "The overview file is in $(BUILDDIR)/changes." - -linkcheck: - $(SPHINXBUILD) -b linkcheck $(ALLSPHINXOPTS) $(BUILDDIR)/linkcheck - @echo - @echo "Link check complete; look for any errors in the above output " \ - "or in $(BUILDDIR)/linkcheck/output.txt." - -doctest: - $(SPHINXBUILD) -b doctest $(ALLSPHINXOPTS) $(BUILDDIR)/doctest - @echo "Testing of doctests in the sources finished, look at the " \ - "results in $(BUILDDIR)/doctest/output.txt." - -# Manual publishing to the gh-pages branch - -GITREPOPATH = $(shell cd $(CURDIR) && git rev-parse --git-dir) -GITREMOTE = origin -GITREMOTEURL = $(shell git config --get remote.$(GITREMOTE).url) -GITLASTCOMMIT = $(shell git rev-parse --short HEAD) - -publish: - @test -d build/html || \ - ( echo >&2 "Run 'make html' first!"; false ) - git show-ref --verify --quiet refs/heads/gh-pages || \ - git branch --track gh-pages $(GITREMOTE)/gh-pages - test -d build/gh-pages || \ - git clone -s -b gh-pages $(GITREPOPATH) build/gh-pages - cd build/gh-pages && \ - git pull $(GITREMOTEURL) gh-pages - rsync -acv --delete --exclude=.git --exclude=.rsync-exclude \ - --exclude-from=build/gh-pages/.rsync-exclude \ - --link-dest=$(CURDIR)/build/html build/html/ build/gh-pages/ - cd build/gh-pages && \ - git add --all . && \ - git diff --cached --quiet || \ - git commit -m "Sync with the source at $(GITLASTCOMMIT)." - cd build/gh-pages && \ - git push origin gh-pages diff --git a/doc/make.bat b/doc/make.bat deleted file mode 100644 index ac53d5bd..00000000 --- a/doc/make.bat +++ /dev/null @@ -1,36 +0,0 @@ -@ECHO OFF - -pushd %~dp0 - -REM Command file for Sphinx documentation - -if "%SPHINXBUILD%" == "" ( - set SPHINXBUILD=sphinx-build -) -set SOURCEDIR=source -set BUILDDIR=build -set SPHINXPROJ=PackagingScientificPython - -if "%1" == "" goto help - -%SPHINXBUILD% >NUL 2>NUL -if errorlevel 9009 ( - echo. - echo.The 'sphinx-build' command was not found. Make sure you have Sphinx - echo.installed, then set the SPHINXBUILD environment variable to point - echo.to the full path of the 'sphinx-build' executable. Alternatively you - echo.may add the Sphinx directory to PATH. - echo. - echo.If you don't have Sphinx installed, grab it from - echo.http://sphinx-doc.org/ - exit /b 1 -) - -%SPHINXBUILD% -M %1 %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% -goto end - -:help -%SPHINXBUILD% -M help %SOURCEDIR% %BUILDDIR% %SPHINXOPTS% - -:end -popd diff --git a/doc/source/_static/.placeholder b/doc/source/_static/.placeholder deleted file mode 100644 index e69de29b..00000000 diff --git a/doc/source/api/diffpy.snmf.rst b/doc/source/api/diffpy.snmf.rst deleted file mode 100644 index 9a808f6d..00000000 --- a/doc/source/api/diffpy.snmf.rst +++ /dev/null @@ -1,68 +0,0 @@ -:tocdepth: -1 - -diffpy.snmf package -=================== - -.. automodule:: diffpy.snmf - :members: - :undoc-members: - :show-inheritance: - -Submodules ----------- - -diffpy.snmf.subroutines module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.subroutines - :members: - :undoc-members: - :show-inheritance: - -diffpy.snmf.containers module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.containers - :members: - :undoc-members: - :show-inheritance: - -diffpy.snmf.io module -^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.io - :members: - :undoc-members: - :show-inheritance: - -diffpy.snmf.polynomials module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.polynomials - :members: - :undoc-members: - :show-inheritance: - -diffpy.snmf.optimizers module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.optimizers - :members: - :undoc-members: - :show-inheritance: - -diffpy.snmf.factorizers module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.factorizers - :members: - :undoc-members: - :show-inheritance: - -diffpy.snmf.stretchednmfapp module -^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. automodule:: diffpy.snmf.stretchednmfapp - :members: - :undoc-members: - :show-inheritance: diff --git a/doc/source/conf.py b/doc/source/conf.py deleted file mode 100644 index 429473a8..00000000 --- a/doc/source/conf.py +++ /dev/null @@ -1,300 +0,0 @@ -#!/usr/bin/env python -# -*- coding: utf-8 -*- -# -# diffpy.snmf documentation build configuration file, created by -# sphinx-quickstart on Thu Jan 30 15:49:41 2014. -# -# This file is execfile()d with the current directory set to its -# containing dir. -# -# Note that not all possible configuration values are present in this -# autogenerated file. -# -# All configuration values have a default; values that are commented out -# serve to show the default. - -import sys -import time -from importlib.metadata import version -from pathlib import Path - -# If extensions (or modules to document with autodoc) are in another directory, -# add these directories to sys.path here. If the directory is relative to the -# documentation root, use Path().resolve() to make it absolute, -# like shown here. -# sys.path.insert(0, str(Path(".").resolve())) -sys.path.insert(0, str(Path("../..").resolve())) -sys.path.insert(0, str(Path("../../src").resolve())) - -# abbreviations -ab_authors = "Billinge Group members and community contributors" - -# -- General configuration ------------------------------------------------ - -# If your documentation needs a minimal Sphinx version, state it here. -# needs_sphinx = '1.0' - -# 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.autodoc", - "sphinx.ext.napoleon", - "sphinx.ext.todo", - "sphinx.ext.viewcode", - "sphinx.ext.intersphinx", - "sphinx_rtd_theme", - "m2r", -] - -# Add any paths that contain templates here, relative to this directory. -templates_path = ["_templates"] - -# The suffix(es) of source filenames. -# You can specify multiple suffix as a list of string: -# -source_suffix = [".rst", ".md"] - -# The encoding of source files. -# source_encoding = 'utf-8-sig' - -# The master toctree document. -master_doc = "index" - -# General information about the project. -project = "diffpy.snmf" -copyright = ( - "2023-%Y, The Trustees of Columbia University in the City of New York" -) - -# The version info for the project you're documenting, acts as replacement for -# |version| and |release|, also used in various other places throughout the -# built documents. - -fullversion = version(project) -# The short X.Y version. -version = "".join(fullversion.split(".post")[:1]) -# The full version, including alpha/beta/rc tags. -release = fullversion - -# The language for content autogenerated by Sphinx. Refer to documentation -# for a list of supported languages. -# language = None - -# There are two options for replacing |today|: either, you set today to some -# non-false value, then it is used: -# today = '' -today = time.strftime("%B %d, %Y", time.localtime()) -year = today.split()[-1] -# Else, today_fmt is used as the format for a strftime call. -# today_fmt = '%B %d, %Y' -# substitute YEAR in the copyright string -copyright = copyright.replace("%Y", year) - -# List of patterns, relative to source directory, that match files and -# directories to ignore when looking for source files. -exclude_patterns = ["build"] - -# The reST default role (used for this markup: `text`) to use for all -# documents. -# default_role = None - -# If true, '()' will be appended to :func: etc. cross-reference text. -# add_function_parentheses = True - -# If true, the current module name will be prepended to all description -# unit titles (such as .. function::). -# add_module_names = True - -# If true, sectionauthor and moduleauthor directives will be shown in the -# output. They are ignored by default. -# show_authors = False - -# The name of the Pygments (syntax highlighting) style to use. -pygments_style = "sphinx" - -# A list of ignored prefixes for module index sorting. -modindex_common_prefix = ["diffpy.snmf"] - -# Display all warnings for missing links. -nitpicky = True - -# -- Options for HTML output ---------------------------------------------- - -# The theme to use for HTML and HTML Help pages. See the documentation for -# a list of builtin themes. -# -html_theme = "sphinx_rtd_theme" - -# Theme options are theme-specific and customize the look and feel of a theme -# further. For a list of options available for each theme, see the -# documentation. -# -html_theme_options = { - "navigation_with_keys": "true", -} - -# Add any paths that contain custom themes here, relative to this directory. -# html_theme_path = [] - -# The name for this set of Sphinx documents. If None, it defaults to -# " v documentation". -# html_title = None - -# A shorter title for the navigation bar. Default is the same as html_title. -# html_short_title = None - -# The name of an image file (relative to this directory) to place at the top -# of the sidebar. -# html_logo = None - -# The name of an image file (within the static path) to use as favicon of the -# docs. This file should be a Windows icon file (.ico) being 16x16 or 32x32 -# pixels large. -# html_favicon = None - -# 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'] - -# Add any extra paths that contain custom files (such as robots.txt or -# .htaccess) here, relative to this directory. These files are copied -# directly to the root of the documentation. -# html_extra_path = [] - -# If not '', a 'Last updated on:' timestamp is inserted at every page bottom, -# using the given strftime format. -# html_last_updated_fmt = '%b %d, %Y' - -# If true, SmartyPants will be used to convert quotes and dashes to -# typographically correct entities. -# html_use_smartypants = True - -# Custom sidebar templates, maps document names to template names. -# html_sidebars = {} - -# Additional templates that should be rendered to pages, maps page names to -# template names. -# html_additional_pages = {} - -# If false, no module index is generated. -# html_domain_indices = True - -# If false, no index is generated. -# html_use_index = True - -# If true, the index is split into individual pages for each letter. -# html_split_index = False - -# If true, links to the reST sources are added to the pages. -# html_show_sourcelink = True - -# If true, "Created using Sphinx" is shown in the HTML footer. Default is True. -# html_show_sphinx = True - -# If true, "(C) Copyright ..." is shown in the HTML footer. Default is True. -# html_show_copyright = True - -# If true, an OpenSearch description file will be output, and all pages will -# contain a tag referring to it. The value of this option must be the -# base URL from which the finished HTML is served. -# html_use_opensearch = '' - -# This is the file name suffix for HTML files (e.g. ".xhtml"). -# html_file_suffix = None - -# Output file base name for HTML help builder. -basename = "diffpy.snmf".replace(" ", "").replace(".", "") -htmlhelp_basename = basename + "doc" - - -# -- Options for LaTeX output --------------------------------------------- - -latex_elements = { - # The paper size ('letterpaper' or 'a4paper'). - # 'papersize': 'letterpaper', - # The font size ('10pt', '11pt' or '12pt'). - # 'pointsize': '10pt', - # Additional stuff for the LaTeX preamble. - # 'preamble': '', -} - -# Grouping the document tree into LaTeX files. List of tuples -# (source start file, target name, title, -# author, documentclass [howto, manual, or own class]). -latex_documents = [ - ( - "index", - "diffpy.snmf.tex", - "diffpy.snmf Documentation", - ab_authors, - "manual", - ), -] - -# The name of an image file (relative to this directory) to place at the top of -# the title page. -# latex_logo = None - -# For "manual" documents, if this is true, then toplevel headings are parts, -# not chapters. -# latex_use_parts = False - -# If true, show page references after internal links. -# latex_show_pagerefs = False - -# If true, show URL addresses after external links. -# latex_show_urls = False - -# Documents to append as an appendix to all manuals. -# latex_appendices = [] - -# If false, no module index is generated. -# latex_domain_indices = True - - -# -- Options for manual page output --------------------------------------- - -# One entry per manual page. List of tuples -# (source start file, name, description, authors, manual section). -man_pages = [ - ("index", "diffpy.snmf", "diffpy.snmf Documentation", ab_authors, 1) -] - -# If true, show URL addresses after external links. -# man_show_urls = False - - -# -- Options for Texinfo output ------------------------------------------- - -# Grouping the document tree into Texinfo files. List of tuples -# (source start file, target name, title, author, -# dir menu entry, description, category) -texinfo_documents = [ - ( - "index", - "diffpy.snmf", - "diffpy.snmf Documentation", - ab_authors, - "diffpy.snmf", - "One line description of project.", - "Miscellaneous", - ), -] - -# Documents to append as an appendix to all manuals. -# texinfo_appendices = [] - -# If false, no module index is generated. -# texinfo_domain_indices = True - -# How to display URL addresses: 'footnote', 'no', or 'inline'. -# texinfo_show_urls = 'footnote' - -# If true, do not generate a @detailmenu in the "Top" node's menu. -# texinfo_no_detailmenu = False - - -# Example configuration for intersphinx: refer to the Python standard library. -# intersphinx_mapping = {'http://docs.python.org/': None} diff --git a/doc/source/index.rst b/doc/source/index.rst deleted file mode 100644 index b7755b07..00000000 --- a/doc/source/index.rst +++ /dev/null @@ -1,91 +0,0 @@ -Welcome to SNMF's Documentation! -==================================== - -``SNMF``: This library implements the stretched non negative matrix factorization (sNMF) and sparse stretched NMF -(ssNMF) algorithms described in the paper "Stretched Non-negative Matrix Factorization" by Ran Gu et al. (2023), -which is referenced under the Citation section below. - -This algorithm is designed to do an NMF factorization on a set of signals ignoring any uniform stretching of the signal -on the independent variable axis. For example, for powder diffraction data taken from samples containing multiple -chemical phases where the measurements were done at different temperatures and the materials were undergoing thermal -expansion. - -Introduction -++++++++++++ - -``snmf`` is a Python package that increases the insight one can obtain from a measured series time-dependent signals -through applying the stretched nonnegative matrix factorization and spare stretched nonnegative matrix factorization -algorithms. The package seeks to answer the question: "What are the structural signals composing my measured signal at -each moment in time?" - -One approach is to take the conventional nonnegative matrix factorization model and extend it by introducing a -stretching factor matrix that accounts for isotropic stretching of measured signals and returns components that explain -variability beyond this stretching. Conventional nonnegative matrix factorization (nmf) obtains component signals and -the weightings of the component signals at each moment in time from a series of data. However, this model assumes the -components themselves are constant in time, making this model unable to capture the changing of the components -themselves. - -``snmf`` consider components that change with time by introducing a stretching factor for each component at each moment -in time that isotropically stretches the component signals.The algorithm will attempt to find three matrices, a -"component" matrix that stores the component signals, a "stretching factor" matrix that stores the stretching factors of -the components at each moment in time, and a "weights" matrix that stores the weights of each component at each moment -in time. ``snmf`` will then plot the components, stretching factors, and weights. - -One import use case of ``snmf`` is for powder diffraction data taken from samples containing multiple -chemical phases where the measurements were done at different temperatures and the materials were undergoing thermal -expansion. The key advantage of ``snmf`` is that it accurately reflects the isotropic change of the atomic distances -within the chemical phases through its addition of stretching factors. - -It is important to note that the user must specify the number of component signals to obtain from the experimental data. -Non-physical results may be obtained if the number of anticipated component signals is too high. - -Citation --------- - -If you use this program for a scientific research that leads -to publication, we ask that you acknowledge use of the program -by citing the following paper in your publication: - - Ran Gu, Yevgeny Rakita, Ling Lan, Zach Thatcher, Gabrielle E. Kamm, Daniel O’Nolan, Brennan Mcbride, Allison Wustrow, James R. Neilson, Karena W. Chapman, Qiang Du, and Simon J. L. Billinge, - `Stretched Non-negative Matrix Factorization - `__, - *npj Comput Mater* **10**, 193 (2024). - - -Authors -------- - -``snmf`` implements the algorithms described in ...., developed by members of the Billinge Group at -Columbia University, Brookhaven National Laboratory, Stony Brook University, Nankai University, and Colorado State -University including Ran Gu, Yevgeny Rakita, Ling Lan, Zach Thatcher, Gabrielle E. Kamm, Daniel O'Nolan, Brennan Mcbride, -Jame R. Neilson, Karena W. Chapman, Qiang Du, and Simon J. L. Billinge. - -This software implementation was developed by members of the Billinge Group at Columbia University and Brookhaven -National Laboratory including Ran Gu, Adeolu Ajayi, Qiang Du, and Simon J. L. Billinge. - -For a detailed list of contributors, check `here -`_. - -To get started, please go to :ref:`quick_start` - -.. toctree:: - :maxdepth: 3 - :hidden: - - quickstart - -.. toctree:: - :maxdepth: 4 - :caption: Contents: - - license - release - Package API - -.. include:: ../../CHANGELOG.rst - -Indices -------- - -* :ref:`genindex` -* :ref:`search` diff --git a/doc/source/license.rst b/doc/source/license.rst deleted file mode 100644 index 573ccaf2..00000000 --- a/doc/source/license.rst +++ /dev/null @@ -1,39 +0,0 @@ -:tocdepth: -1 - -.. index:: license - -License -####### - -OPEN SOURCE LICENSE AGREEMENT -============================= -BSD 3-Clause License - -Copyright (c) 2023-2024, The Trustees of Columbia University in -the City of New York. -All Rights Reserved. - -Redistribution and use in source and binary forms, with or without -modification, are permitted provided that the following conditions are met: - -1. Redistributions of source code must retain the above copyright notice, this - list of conditions and the following disclaimer. - -2. Redistributions in binary form must reproduce the above copyright notice, - this list of conditions and the following disclaimer in the documentation - and/or other materials provided with the distribution. - -3. Neither the name of the copyright holder nor the names of its - contributors may be used to endorse or promote products derived from - this software without specific prior written permission. - -THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" -AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE -DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE -FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL -DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR -SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER -CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, -OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE -OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. diff --git a/doc/source/quickstart.rst b/doc/source/quickstart.rst deleted file mode 100644 index 33dab12f..00000000 --- a/doc/source/quickstart.rst +++ /dev/null @@ -1,22 +0,0 @@ -.. _quick_start: - -Tutorial (To be added) -################# - -Welcome! This will be a quick tutorial to accquaint users with `snmf`. - -Basic Workflow -======================= - - 1. Add a step-by-step guide to the basic workflow of the software. - -Extra Tutorials -=============== - -Add extra tutorials here - -Bug Reports -=========== - -Please enjoy using our software! If you come across any bugs in the -application, please report them to diffpy-users@googlegroups.com. diff --git a/doc/source/release.rst b/doc/source/release.rst deleted file mode 100644 index 27cd0cc9..00000000 --- a/doc/source/release.rst +++ /dev/null @@ -1,5 +0,0 @@ -:tocdepth: -1 - -.. index:: release notes - -.. include:: ../../CHANGELOG.rst diff --git a/docs/source/conf.py b/docs/source/conf.py index 46f083e3..bd778162 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -50,7 +50,7 @@ "sphinx.ext.intersphinx", "sphinx_rtd_theme", "sphinx_copybutton", - "m2r", + "m2r2", ] # Add any paths that contain templates here, relative to this directory. diff --git a/requirements/docs.txt b/requirements/docs.txt index 5f34c6ed..1de813f9 100644 --- a/requirements/docs.txt +++ b/requirements/docs.txt @@ -2,4 +2,4 @@ sphinx sphinx_rtd_theme sphinx-copybutton doctr -m2r +m2r2 From 23a385427ea92cf26a7c2083fc5ab6bbe953efd9 Mon Sep 17 00:00:00 2001 From: John Halloran Date: Mon, 9 Feb 2026 01:24:35 -0500 Subject: [PATCH 2/3] docs: remove old tables and recreate getting started page --- docs/source/api/diffpy.snmf.rst | 30 ---------- docs/source/getting-started.rst | 79 ++++++++++++++++++++++++++ docs/source/index.rst | 1 - docs/source/snippets/example-table.rst | 28 --------- 4 files changed, 79 insertions(+), 59 deletions(-) delete mode 100644 docs/source/api/diffpy.snmf.rst create mode 100644 docs/source/getting-started.rst delete mode 100644 docs/source/snippets/example-table.rst diff --git a/docs/source/api/diffpy.snmf.rst b/docs/source/api/diffpy.snmf.rst deleted file mode 100644 index 28f90a6d..00000000 --- a/docs/source/api/diffpy.snmf.rst +++ /dev/null @@ -1,30 +0,0 @@ -:tocdepth: -1 - -|title| -======= - -.. |title| replace:: diffpy.snmf package - -.. automodule:: diffpy.snmf - :members: - :undoc-members: - :show-inheritance: - -Subpackages ------------ - -.. toctree:: - diffpy.snmf.example_package - -Submodules ----------- - -|module| --------- - -.. |module| replace:: diffpy.snmf.example_submodule module - -.. automodule:: diffpy.snmf.example_submodule - :members: - :undoc-members: - :show-inheritance: diff --git a/docs/source/getting-started.rst b/docs/source/getting-started.rst new file mode 100644 index 00000000..0dac4fdd --- /dev/null +++ b/docs/source/getting-started.rst @@ -0,0 +1,79 @@ +.. _getting-started: + +Getting started +=============== + +``diffpy.snmf`` implements the stretched NMF algorithm for factorizing signal +sets while accounting for uniform stretching along the independent axis. + +Installation +------------ + +The preferred method is conda: + +.. code-block:: bash + + conda config --add channels conda-forge + conda create -n diffpy.snmf_env diffpy.snmf + conda activate diffpy.snmf_env + +Alternatively, install from PyPI with pip: + +.. code-block:: bash + + pip install diffpy.snmf + +For source installs (after cloning the repo): + +.. code-block:: bash + + pip install . + +Quick check +----------- + +Verify the CLI and Python import: + +.. code-block:: bash + + diffpy.snmf --version + python -c "import diffpy.snmf; print(diffpy.snmf.__version__)" + +Basic usage +----------- + +The main entry point is the ``SNMFOptimizer`` class. Provide a source matrix +with shape ``(length_of_signal, number_of_signals)`` and either ``n_components`` +or ``init_weights``. + +.. code-block:: python + + import numpy as np + from diffpy.snmf.snmf_class import SNMFOptimizer + + rng = np.random.default_rng(0) + # Example data: 200 points across 8 signals + source_matrix = rng.random((200, 8)) + + model = SNMFOptimizer( + source_matrix, + n_components=3, + random_state=0, + ) + + model.fit(rho=0, eta=0) + + components = model.components_ + weights = model.weights_ + stretch = model.stretch_ + +Notes +----- + +- ``rho`` controls the stretching penalty (set to ``0`` for no stretching). +- ``eta`` controls sparsity (start at ``0`` and tune after selecting ``rho``). + +Next steps +---------- + +Browse the rest of the docs for release notes and license information. diff --git a/docs/source/index.rst b/docs/source/index.rst index 37181798..bd65010f 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -44,7 +44,6 @@ Table of contents :maxdepth: 2 getting-started - Package API release license diff --git a/docs/source/snippets/example-table.rst b/docs/source/snippets/example-table.rst deleted file mode 100644 index 7c4c11da..00000000 --- a/docs/source/snippets/example-table.rst +++ /dev/null @@ -1,28 +0,0 @@ -.. list-table:: 5 levels of reusing/sharing code - :widths: 5 15 40 40 - :header-rows: 1 - - * - Level - - Name - - Scope - - How to setup - * - 1 - - ``function`` - - Reuse code in the single file. - - See Level 1 tutorial - * - 2 - - ``module`` - - Reuse code across files. - - See Level 2 tutorial - * - 3 - - ``workspace`` - - Reuse code across project folders. - - ``package create workspace`` - * - 4 - - ``system`` - - Reuse code across any files in the computer. - - ``package create system`` - * - 5 - - ``public`` - - Share code as publicly installable package. - - ``package create public`` From 8177ab2b5709ed216cb94e325c6c10f2e9c5e59d Mon Sep 17 00:00:00 2001 From: John Halloran Date: Mon, 9 Feb 2026 01:30:50 -0500 Subject: [PATCH 3/3] docs: load documentation from snmf_class.py --- docs/source/api/snmf_class.rst | 7 ++++ docs/source/conf.py | 5 ++- docs/source/index.rst | 1 + src/diffpy/snmf/snmf_class.py | 61 ++++++++++++++++++---------------- 4 files changed, 45 insertions(+), 29 deletions(-) create mode 100644 docs/source/api/snmf_class.rst diff --git a/docs/source/api/snmf_class.rst b/docs/source/api/snmf_class.rst new file mode 100644 index 00000000..955f6780 --- /dev/null +++ b/docs/source/api/snmf_class.rst @@ -0,0 +1,7 @@ +SNMFOptimizer +============= + +.. autoclass:: diffpy.snmf.snmf_class.SNMFOptimizer + :members: __init__, fit + :undoc-members: + :show-inheritance: diff --git a/docs/source/conf.py b/docs/source/conf.py index bd778162..f9afe77c 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -319,4 +319,7 @@ # Example configuration for intersphinx: refer to the Python standard library. -# intersphinx_mapping = {'http://docs.python.org/': None} +intersphinx_mapping = { + "python": ("https://docs.python.org/3", None), + "numpy": ("https://numpy.org/doc/stable", None), +} diff --git a/docs/source/index.rst b/docs/source/index.rst index bd65010f..69b5af7d 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -44,6 +44,7 @@ Table of contents :maxdepth: 2 getting-started + api/snmf_class release license diff --git a/src/diffpy/snmf/snmf_class.py b/src/diffpy/snmf/snmf_class.py index c1ddd5af..db983a34 100644 --- a/src/diffpy/snmf/snmf_class.py +++ b/src/diffpy/snmf/snmf_class.py @@ -13,7 +13,7 @@ class SNMFOptimizer: Instantiating the SNMFOptimizer class prepares initial guesses and sets up the optimization. It can then be run using fit(). The results matrices can be accessed as instance attributes of the - class (components_, weights_, and stretch_). + class (``components_``, ``weights_``, and ``stretch_``). For more information on sNMF, please reference: Gu, R., Rakita, Y., Lan, L. et al. @@ -22,16 +22,16 @@ class (components_, weights_, and stretch_). Attributes ---------- - source_matrix : ndarray + source_matrix : numpy.ndarray The original, unmodified data to be decomposed and later, compared against. Shape is (length_of_signal, number_of_signals). - stretch_ : ndarray + stretch_ : numpy.ndarray The best guess (or while running, the current guess) for the stretching factor matrix. - components_ : ndarray + components_ : numpy.ndarray The best guess (or while running, the current guess) for the matrix of component intensities. - weights_ : ndarray + weights_ : numpy.ndarray The best guess (or while running, the current guess) for the matrix of component weights. rho : float @@ -87,37 +87,39 @@ def __init__( Parameters ---------- - source_matrix : ndarray + source_matrix : numpy.ndarray The data to be decomposed. Shape is (length_of_signal, number_of_conditions). - init_weights : ndarray Optional Default = rng.beta(a=2.0, b=2.0) + init_weights : numpy.ndarray The initial guesses for the component weights at each stretching condition. Shape is (number_of_components, number_of_signals). - Must provide exactly one of this or n_components. - init_components : ndarray Optional Default = rng.random() + Optional. Must provide exactly one of this or n_components. + init_components : numpy.ndarray The initial guesses for the intensities of each component per row/sample/angle. Shape is (length_of_signal, number_of_components). - init_stretch : ndarray Optional Default = np.ones() + rng.normal() + Optional. + init_stretch : numpy.ndarray The initial guesses for the stretching factor for each component, at each condition (for each signal). Shape is (number_of_components, number_of_signals). - max_iter : int Optional Default = 500 + Optional. + max_iter : int The maximum number of times to update each of A, X, and Y before - stopping the optimization. - tol : float Optional Default = 5e-7 + stopping the optimization. Optional. + tol : float The convergence threshold. This is the minimum fractional improvement in the objective function to allow without terminating the optimization. Note that a minimum of 20 updates are run before - this parameter is checked. - n_components : int Optional Default = None + this parameter is checked. Optional. + n_components : int The number of components to extract from source_matrix. Must be - provided when and only when Y0 is not provided. - random_state : int Optional Default = None + provided when and only when Y0 is not provided. Optional. + random_state : int The seed for the initial guesses at the matrices (A, X, and Y) - created by the decomposition. - show_plots : boolean Optional Default = False - Enables plotting at each step of the decomposition. + created by the decomposition. Optional. + show_plots : bool + Enables plotting at each step of the decomposition. Optional. """ self.source_matrix = source_matrix @@ -189,20 +191,23 @@ def fit(self, rho=0, eta=0, reset=True): Parameters ---------- - rho : float Optional Default = 0 - The stretching factor that influences the decomposition. Zero + rho : float + The stretching factor that influences the decomposition. Optional. + Zero corresponds to no stretching present. Relatively insensitive and typically adjusted in powers of 10. - eta : int Optional Default = 0 - The sparsity factor that influences the decomposition. Should be + eta : int + The sparsity factor that influences the decomposition. Optional. + Should be set to zero for non-sparse data such as PDF. Can be used to improve results for sparse data such as XRD, but due to instability, should be used only after first selecting the best value for rho. Suggested adjustment is by powers of 2. - reset : boolean Optional Default = True - Whether to return to the initial set of components_, weights_, - and stretch_ before running the optimization. When set to False, - sequential calls to fit() will use the output of the previous + reset : bool + Whether to return to the initial set of ``components_``, + ``weights_``, and ``stretch_`` before running the optimization. + Optional. When set to False, sequential calls to fit() will use + the output of the previous fit() as their input. """