diff --git a/.github/ISSUE_TEMPLATE/release_checklist.md b/.github/ISSUE_TEMPLATE/release_checklist.md index 0f56027..6107962 100644 --- a/.github/ISSUE_TEMPLATE/release_checklist.md +++ b/.github/ISSUE_TEMPLATE/release_checklist.md @@ -6,30 +6,41 @@ labels: "release" assignees: "" --- -### PyPI/GitHub release checklist: +### PyPI/GitHub rc-release preparation checklist: - [ ] All PRs/issues attached to the release are merged. - [ ] All the badges on the README are passing. - [ ] License information is verified as correct. If you are unsure, please comment below. - [ ] Locally rendered documentation contains all appropriate pages, including API references (check no modules are - missing), tutorials, and other human written text is up-to-date with any changes in the code. -- [ ] Installation instructions in the README, documentation and on the website (e.g., diffpy.org) are updated. + missing), tutorials, and other human-written text is up-to-date with any changes in the code. +- [ ] Installation instructions in the README, documentation, and the website are updated. - [ ] Successfully run any tutorial examples or do functional testing with the latest Python version. - [ ] Grammar and writing quality are checked (no typos). +- [ ] Install `pip install build twine`, run `python -m build` and `twine check dist/*` to ensure that the package can be built and is correctly formatted for PyPI release. -Please mention @sbillinge here when you are ready for PyPI/GitHub release. Include any additional comments necessary, such as -version information and details about the pre-release here: +Please tag the maintainer (e.g., @username) in the comment here when you are ready for the PyPI/GitHub release. Include any additional comments necessary, such as version information and details about the pre-release here: -### conda-forge release checklist: +### PyPI/GitHub full-release preparation checklist: - +- [ ] Create a new conda environment and install the rc from PyPI (`pip install ==??`) +- [ ] License information on PyPI is correct. +- [ ] Docs are deployed successfully to `https:///`. +- [ ] Successfully run all tests, tutorial examples or do functional testing. +Please let the maintainer know that all checks are done and the package is ready for full release. + +### conda-forge release preparation checklist: + + + +- [ ] Ensure that the full release has appeared on PyPI successfully. - [ ] New package dependencies listed in `conda.txt` and `test.txt` are added to `meta.yaml` in the feedstock. -- [ ] All relevant issues in the feedstock are addressed in the release PR. +- [ ] Close any open issues on the feedstock. Reach out to the maintainer if you have questions. +- [ ] Tag the maintainer for conda-forge release. ### Post-release checklist -- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. -- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. +- [ ] Run tutorial examples and conduct functional testing using the installation guide in the README. Attach screenshots/results as comments. +- [ ] Documentation (README, tutorials, API references, and websites) is deployed without broken links or missing figures. diff --git a/doc/source/conf.py b/doc/source/conf.py index 287c517..4245ea3 100644 --- a/doc/source/conf.py +++ b/doc/source/conf.py @@ -221,7 +221,13 @@ # (source start file, target name, title, # author, documentclass [howto, manual, or own class]). latex_documents = [ - ("index", "diffpy.nmf_mapping.tex", "diffpy.nmf_mapping Documentation", ab_authors, "manual"), + ( + "index", + "diffpy.nmf_mapping.tex", + "diffpy.nmf_mapping Documentation", + ab_authors, + "manual", + ), ] # The name of an image file (relative to this directory) to place at the top of @@ -249,7 +255,15 @@ # One entry per manual page. List of tuples # (source start file, name, description, authors, manual section). -man_pages = [("index", "diffpy.nmf_mapping", "diffpy.nmf_mapping Documentation", ab_authors, 1)] +man_pages = [ + ( + "index", + "diffpy.nmf_mapping", + "diffpy.nmf_mapping Documentation", + ab_authors, + 1, + ) +] # If true, show URL addresses after external links. # man_show_urls = False diff --git a/src/__init__.py b/src/__init__.py index 521e31a..736037d 100644 --- a/src/__init__.py +++ b/src/__init__.py @@ -13,8 +13,7 @@ # ############################################################################## -"""nmf_mapping - tools for performing NMF on PDF and XRD data. -""" +"""nmf_mapping - tools for performing NMF on PDF and XRD data.""" __import__("pkg_resources").declare_namespace(__name__) diff --git a/src/diffpy/nmf_mapping/main.py b/src/diffpy/nmf_mapping/main.py index 06daff0..639e624 100644 --- a/src/diffpy/nmf_mapping/main.py +++ b/src/diffpy/nmf_mapping/main.py @@ -31,7 +31,11 @@ def main(args=None): as well as the reconstruction error as a fxn of component """ - parser = ArgumentParser(prog="nmf_mapping", description=_BANNER, formatter_class=RawTextHelpFormatter) + parser = ArgumentParser( + prog="nmf_mapping", + description=_BANNER, + formatter_class=RawTextHelpFormatter, + ) def tup(s): if not isinstance(s, str): @@ -45,7 +49,10 @@ def tup(s): # args parser.add_argument( - "directory", default=None, type=str, help="a directory of PDFs to calculate NMF decomposition" + "directory", + default=None, + type=str, + help="a directory of PDFs to calculate NMF decomposition", ) group = parser.add_mutually_exclusive_group() parser.add_argument( @@ -105,25 +112,37 @@ def tup(s): nargs="*", help="the x-range over which to calculate NMF, can be multiple ranges (e.g. --xrange 5,10 12,15)", ) - parser.add_argument("--show", default=True, type=boolean_string, help="whether to show the plot") + parser.add_argument( + "--show", + default=True, + type=boolean_string, + help="whether to show the plot", + ) args0 = Namespace() args1, _ = parser.parse_known_args(args, namespace=args0) input_list, data_list = nmf.load_data(args1.directory, args1.xrd) if args1.pca_thresh: - df_components, df_component_weight_timeseries, df_reconstruction_error, df_explained_var_ratio = ( - nmf.NMF_decomposition( - input_list, - args1.xrange, - args1.threshold, - additional_comp=False, - improve_thresh=args1.improve_thresh, - n_iter=args1.n_iter, - pca_thresh=args1.pca_thresh, - ) + ( + df_components, + df_component_weight_timeseries, + df_reconstruction_error, + df_explained_var_ratio, + ) = nmf.NMF_decomposition( + input_list, + args1.xrange, + args1.threshold, + additional_comp=False, + improve_thresh=args1.improve_thresh, + n_iter=args1.n_iter, + pca_thresh=args1.pca_thresh, ) else: - df_components, df_component_weight_timeseries, df_reconstruction_error = nmf.NMF_decomposition( + ( + df_components, + df_component_weight_timeseries, + df_reconstruction_error, + ) = nmf.NMF_decomposition( input_list, args1.xrange, args1.threshold, @@ -149,7 +168,11 @@ def tup(s): os.path.join(os.getcwd(), "nmf_result", "component_index_vs_pratio_col.json") ) df_component_weight_timeseries.to_csv( - os.path.join(os.getcwd(), "nmf_result", output_fn + "component_row_pratio_col.txt"), + os.path.join( + os.getcwd(), + "nmf_result", + output_fn + "component_row_pratio_col.txt", + ), header=None, index=False, sep=" ", @@ -196,7 +219,11 @@ def tup(s): if args1.xrd: np.savetxt( - os.path.join(os.getcwd(), "nmf_result", output_fn + f"_comp{i}" + ".xy"), + os.path.join( + os.getcwd(), + "nmf_result", + output_fn + f"_comp{i}" + ".xy", + ), data, header=f"NMF Generated XRD\nSource = nmfMapping\n" f"Date = {output_fn}\n{args1.x_units} Intensity\n", @@ -205,7 +232,11 @@ def tup(s): ) else: np.savetxt( - os.path.join(os.getcwd(), "nmf_result", output_fn + f"_comp{i}" + ".cgr"), + os.path.join( + os.getcwd(), + "nmf_result", + output_fn + f"_comp{i}" + ".cgr", + ), data, header=f"NMF Generated PDF\nSource: nmfMapping\n" f"Date: {output_fn}\nr g", fmt="%s", diff --git a/src/diffpy/nmf_mapping/nmf_mapping_code.py b/src/diffpy/nmf_mapping/nmf_mapping_code.py index 3c73ebf..638abd4 100644 --- a/src/diffpy/nmf_mapping/nmf_mapping_code.py +++ b/src/diffpy/nmf_mapping/nmf_mapping_code.py @@ -98,7 +98,13 @@ def load_data(dir, xrd=False): # TODO Add regularization on the frobenius norm in order to prevent creation of an excessive number of components def NMF_decomposition( - data_arr, x_range=None, thresh=None, additional_comp=False, improve_thresh=None, n_iter=None, pca_thresh=None + data_arr, + x_range=None, + thresh=None, + additional_comp=False, + improve_thresh=None, + n_iter=None, + pca_thresh=None, ): """ Takes a 3D array of PDFs and returns the structurally significant @@ -208,8 +214,17 @@ def NMF_decomposition( df_component_weight_timeseries = pd.DataFrame(nmf_weight, index=range(n_comp)) if pca_thresh: - return df_components, df_component_weight_timeseries, df_reconstruction_error, df_explained_var_ratio - return df_components, df_component_weight_timeseries, df_reconstruction_error + return ( + df_components, + df_component_weight_timeseries, + df_reconstruction_error, + df_explained_var_ratio, + ) + return ( + df_components, + df_component_weight_timeseries, + df_reconstruction_error, + ) def component_plot(df_components, xrd=False, x_units=None, show=True): @@ -244,7 +259,11 @@ def component_plot(df_components, xrd=False, x_units=None, show=True): shift = max_range # seq to align with input phase for i, s in enumerate(data_list): - ax.plot(df.index.to_numpy(dtype=np.single), df[s].to_numpy() + i * shift, label=s) + ax.plot( + df.index.to_numpy(dtype=np.single), + df[s].to_numpy() + i * shift, + label=s, + ) ax.legend(loc="best") if xrd: if x_units == "twotheta" or x_units == "ttheta": diff --git a/src/diffpy/version.py b/src/diffpy/version.py index 2200d1c..45c8a92 100644 --- a/src/diffpy/version.py +++ b/src/diffpy/version.py @@ -13,8 +13,7 @@ # ############################################################################## -"""Definition of __version__ and __date__ for diffpy.nmf_mapping. -""" +"""Definition of __version__ and __date__ for diffpy.nmf_mapping.""" __id__ = "$Id$" diff --git a/tests/test_NMF_analysis_code.py b/tests/test_NMF_analysis_code.py index 971ca95..b4151fa 100644 --- a/tests/test_NMF_analysis_code.py +++ b/tests/test_NMF_analysis_code.py @@ -14,7 +14,11 @@ test_map = [ ([data_dir, "--xrange", "5,10"], "output_1", "Number of components: 3\n"), ([data_dir], "output_2", "Number of components: 3\n"), - ([data_dir, "--xrange", "5,10", "12,15"], "output_3", "Number of components: 3\n"), + ( + [data_dir, "--xrange", "5,10", "12,15"], + "output_3", + "Number of components: 3\n", + ), ] diff --git a/tests/test_version.py b/tests/test_version.py index 1167910..8513431 100644 --- a/tests/test_version.py +++ b/tests/test_version.py @@ -1,5 +1,4 @@ -"""Unit tests for __version__.py -""" +"""Unit tests for __version__.py""" import diffpy.nmf_mapping