From 8737a7f98127de0b71da98653d66e356ea417b09 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 24 Mar 2017 08:48:42 -0400 Subject: [PATCH 01/82] README --- README.rst | 78 ++++++++++++++---------------------------------------- 1 file changed, 20 insertions(+), 58 deletions(-) diff --git a/README.rst b/README.rst index aa8b895..c112da7 100644 --- a/README.rst +++ b/README.rst @@ -3,13 +3,28 @@ Fusion Data Platform ============================== -Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, analysis methods, and visualization. +Fusion Data Platform (FDP) is a Python package and data framework for magnetic fusion experiments. FDP provides an extensible software layer that unites data access, management, analysis, and visualization. -* Github repository: https://github.com/Fusion-Data-Platform/fdp * Documentation: http://Fusion-Data-Platform.github.io/ +* Github repository: https://github.com/Fusion-Data-Platform/fdp + +Example usage +------------------------------ + + >>> nstxu.s204551.mpts.te.plot() + >>> nstxu.s204620.equilibria.efit02.kappa.plot() + >>> nstxu.s204670.bes.ch01.plotfft() + + +Features +------------------------------ + +* Reduce + +FDP reduces barriers to entry for new users and facilitates collaborative development of analysis and visualization tools. FDP is build on the popular and free platform of Python, Numpy, and Matplotlib, and FDP is collaboratively developed as an open-source project on Github. + +Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, analysis methods, and visualization. -Project objectives -============================== * Integrate data sources, data, and analysis methods in a single, extensible data object @@ -26,63 +41,10 @@ Project objectives * Platform-independent: desktop Mac/PC, Linux cluster * Command-line tool or import into code -Example usage -============================== - -Initiate an FDP session:: - - >>> import fdp - >>> nstxu = fdp.nstxu() - -List diagnostics:: - - >>> dir(nstxu.s141000) - ['bes', 'chers', 'equilibria', 'filterscopes', 'magnetics', 'mpts', 'mse', 'usxr'] - -View logbook entries:: - - >>> nstxu.s141000.logbook() - -List signals:: - - >>> nstxu.s141000.equilibria.efit02.listSignals() - ['psirz', 'qpsi', 'shot', 'userid', 'wmhd'] - >>> nstxu.s204620.chers.listSignals() - ['ft', 'nc', 'ti', 'valid', 'vt'] - -Plot a signal:: - - >>> nstxu.s141000.mpts.te.plot() - -List methods for a signal:: - - >>> nstxu.s141000.bes.d1ch01.listMethods() - ['animate', 'fft', 'loadConfig', 'plotfft'] - -Load shots for an XP:: - - >>> xp1013 = nstxu.filter_shots(xp=1013) - >>> dir(xp1013) - ['s141382', 's141383', 's141384', 's141385', 's141386', 's141387', - 's141388', 's141389', 's141390', 's141391', 's141392', 's141393', - 's141394', 's141395', 's141396', 's141397', 's141398', 's141399', - 's141400', 's141401', 's141402', 's141403', 's141404', 's141405', - 's141406', 's141407', 's141408', 's141409', 's141410', 's141411', - 's141412', 's141413', 's141414'] - -As the examples above illustrate, the FDP data object is organized like this:: - - .... - -or, for diagnostic sub-containers like spline profiles and x-ray arrays:: - - ..... Lead developers -============================== +------------------------------ * David R. Smith, U. Wisconsin-Madison * Kevin Tritz, The Johns Hopkins U. * Howard Yuh, Nova Photonics - -PPPL cluster support from John Schmitt From 1e86438a7158b4b3adf93fb0f24bb68005c2b99f Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 24 Mar 2017 09:19:02 -0400 Subject: [PATCH 02/82] README --- README.rst | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/README.rst b/README.rst index c112da7..fa9f815 100644 --- a/README.rst +++ b/README.rst @@ -8,6 +8,7 @@ Fusion Data Platform (FDP) is a Python package and data framework for magnetic f * Documentation: http://Fusion-Data-Platform.github.io/ * Github repository: https://github.com/Fusion-Data-Platform/fdp + Example usage ------------------------------ @@ -19,16 +20,13 @@ Example usage Features ------------------------------ -* Reduce - -FDP reduces barriers to entry for new users and facilitates collaborative development of analysis and visualization tools. FDP is build on the popular and free platform of Python, Numpy, and Matplotlib, and FDP is collaboratively developed as an open-source project on Github. +FDP reduces barriers to entry for new users and facilitates collaborative development of analysis and visualization tools. -Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, analysis methods, and visualization. +* Integrate data sources, data, and analysis methods in a single, extensible data object +* Streamline data access for multiple facilities, diagnostics, and databases -* Integrate data sources, data, and analysis methods in a single, extensible data object - * Streamline data access for multiple facilities, diagnostics, and databases * Organize data and analysis methods in an intuitive object-oriented framework * Promote collaborative code development and reduce inefficient code duplication From 30b41e5527b228398df7954883ee33010dd9f643 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 24 Mar 2017 11:43:13 -0400 Subject: [PATCH 03/82] misc --- LICENSE.rst | 2 +- README.rst | 16 +++--- docs/source/conf.py | 6 +-- examples/plot_efit.py | 9 ++-- fdp/methods/__init__.py | 7 ++- fdp/methods/info.py | 8 +++ fdp/methods/nstxu/equilibria/__init__.py | 3 +- fdp/methods/nstxu/equilibria/bfield.py | 30 ++++++++++++ fdp/methods/nstxu/equilibria/utilities.py | 4 +- fdp/methods/timeindex.py | 21 ++++++++ fdp/modules/nstxu/equilibria/efit.xml | 60 ++++++++++++----------- 11 files changed, 115 insertions(+), 51 deletions(-) create mode 100644 fdp/methods/nstxu/equilibria/bfield.py create mode 100644 fdp/methods/timeindex.py diff --git a/LICENSE.rst b/LICENSE.rst index d5dfa0f..c4346db 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -1,7 +1,7 @@ The MIT License (MIT) -Copyright (c) 2015 John Schmitt, David R. Smith, Kevin Tritz, Howard Yuh +Copyright (c) 2015-2017 David R. Smith, Kevin Tritz, Howard Yuh Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal diff --git a/README.rst b/README.rst index aa8b895..7c751ad 100644 --- a/README.rst +++ b/README.rst @@ -40,7 +40,7 @@ List diagnostics:: ['bes', 'chers', 'equilibria', 'filterscopes', 'magnetics', 'mpts', 'mse', 'usxr'] View logbook entries:: - + >>> nstxu.s141000.logbook() List signals:: @@ -63,11 +63,11 @@ Load shots for an XP:: >>> xp1013 = nstxu.filter_shots(xp=1013) >>> dir(xp1013) - ['s141382', 's141383', 's141384', 's141385', 's141386', 's141387', - 's141388', 's141389', 's141390', 's141391', 's141392', 's141393', - 's141394', 's141395', 's141396', 's141397', 's141398', 's141399', - 's141400', 's141401', 's141402', 's141403', 's141404', 's141405', - 's141406', 's141407', 's141408', 's141409', 's141410', 's141411', + ['s141382', 's141383', 's141384', 's141385', 's141386', 's141387', + 's141388', 's141389', 's141390', 's141391', 's141392', 's141393', + 's141394', 's141395', 's141396', 's141397', 's141398', 's141399', + 's141400', 's141401', 's141402', 's141403', 's141404', 's141405', + 's141406', 's141407', 's141408', 's141409', 's141410', 's141411', 's141412', 's141413', 's141414'] As the examples above illustrate, the FDP data object is organized like this:: @@ -83,6 +83,4 @@ Lead developers * David R. Smith, U. Wisconsin-Madison * Kevin Tritz, The Johns Hopkins U. -* Howard Yuh, Nova Photonics - -PPPL cluster support from John Schmitt +* Howard Yuh, Nova Photonics \ No newline at end of file diff --git a/docs/source/conf.py b/docs/source/conf.py index 3f6834b..b8e831b 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -58,8 +58,8 @@ # General information about the project. project = u'Fusion Data Framework' -copyright = u'2015, John Schmitt, David R. Smith, Kevin Tritz, Howard Yuh' -author = u'John Schmitt, David R. Smith, Kevin Tritz, Howard Yuh' +copyright = u'2015-2017 David R. Smith, Kevin Tritz, Howard Yuh' +author = u'David R. Smith, Kevin Tritz, Howard Yuh' # The version info for the project you're documenting, acts as replacement for # |version| and |release|, also used in various other places throughout the @@ -248,7 +248,7 @@ # author, documentclass [howto, manual, or own class]). latex_documents = [ (master_doc, 'FusionDataFramework.tex', u'Fusion Data Framework Documentation', - u'John Schmitt, David R. Smith, Kevin Tritz, Howard Yuh', 'manual'), + u'David R. Smith, Kevin Tritz, Howard Yuh', 'manual'), ] # The name of an image file (relative to this directory) to place at the top of diff --git a/examples/plot_efit.py b/examples/plot_efit.py index f9ea2fe..aad6809 100644 --- a/examples/plot_efit.py +++ b/examples/plot_efit.py @@ -9,8 +9,9 @@ nstx = fdp.nstx() -eq=nstx.s204551.equilibria.efit01 -eq.ipmeas.plot() +eq=nstx.s204551.equilibria -eq2=nstx.s204551.equilibria.efit02 -eq2.kappa.plot() +efit02 = eq.efit02 +efit02.ipmeas.plot() + +efit02.bfield(radius=145, time=0.6) \ No newline at end of file diff --git a/fdp/methods/__init__.py b/fdp/methods/__init__.py index d0b58a9..1b50dfe 100755 --- a/fdp/methods/__init__.py +++ b/fdp/methods/__init__.py @@ -11,9 +11,12 @@ from .plot import plot from ._netcat import _netcat from .listmethods import listSignals, listMethods, listContainers, listAttributes -from .info import info +from .info import info, isSignal, isContainer, isAxis from .fft import fft, plotfft +from .timeindex import getTimeIndex __all__ = ['plot', '_netcat', 'listSignals', 'listMethods', 'listContainers', 'listAttributes', - 'info', 'fft', 'plotfft'] + 'info', 'isSignal', 'isContainer', 'isAxis', + 'fft', 'plotfft', + 'getTimeIndex'] diff --git a/fdp/methods/info.py b/fdp/methods/info.py index 0552937..c1c1651 100644 --- a/fdp/methods/info.py +++ b/fdp/methods/info.py @@ -7,6 +7,14 @@ from ..classes import utilities +def isSignal(obj): + return utilities.isSignal(obj) + +def isContainer(obj): + return utilities.isContainer(obj) + +def isAxis(obj): + return utilities.isAxis(obj) def info(obj, *args, **kwargs): if utilities.isSignal(obj): diff --git a/fdp/methods/nstxu/equilibria/__init__.py b/fdp/methods/nstxu/equilibria/__init__.py index f956445..8efba5e 100644 --- a/fdp/methods/nstxu/equilibria/__init__.py +++ b/fdp/methods/nstxu/equilibria/__init__.py @@ -7,5 +7,6 @@ from .utilities import create_efit_objs as _preprocess +from .bfield import bfield -__all__ = ['_preprocess'] +__all__ = ['_preprocess', 'bfield'] diff --git a/fdp/methods/nstxu/equilibria/bfield.py b/fdp/methods/nstxu/equilibria/bfield.py new file mode 100644 index 0000000..4795e9d --- /dev/null +++ b/fdp/methods/nstxu/equilibria/bfield.py @@ -0,0 +1,30 @@ +# -*- coding: utf-8 -*- +""" +Created on Mon Oct 19 15:42:07 2015 + +@author: ktritz +""" + +import warnings + + +def bfield(obj, radius=None, z=None, time=None): + # must call from equilibrium container + if not obj.isContainer(): + warnings.warn('Must call bfield() from equilibrium container, returning') + return + + # if nstx.shot.equilibria.bfield(), default to efit02 + if obj._name == 'equilibria': + print('Using EFIT02') + eqdata = obj.efit02 + else: + eqdata = obj + + # defaults + if not radius: radius = 1.4 # major radius in m + if not z: z = 0.0 # height in m + if not time: time = 0.5 # time in s + + # get time index + tindex = eqdata.rmaxis.getTimeIndex(time=time) diff --git a/fdp/methods/nstxu/equilibria/utilities.py b/fdp/methods/nstxu/equilibria/utilities.py index b51803e..62d0660 100644 --- a/fdp/methods/nstxu/equilibria/utilities.py +++ b/fdp/methods/nstxu/equilibria/utilities.py @@ -13,8 +13,8 @@ def create_efit_objs(self): - ContainerClassName = 'ContainerEquilibria' for efit in self.check_efit(): + ContainerClassName = 'Container'+efit.capitalize() branch = '.'.join(['equilibria', efit]) # ContainerClassName = ''.join(['Equilibria', efit.capitalize()]) if branch not in _tree_dict: @@ -30,7 +30,7 @@ def create_efit_objs(self): ContainerClass = type(ContainerClassName, (Container,), {}) init_class(ContainerClass, _tree_dict[branch], root=self._root, container='equilibria', classparent=self.__class__) - ContainerClass._name = 'efit' + ContainerClass._name = efit Container._classes[ContainerClassName] = ContainerClass else: ContainerClass = Container._classes[ContainerClassName] diff --git a/fdp/methods/timeindex.py b/fdp/methods/timeindex.py new file mode 100644 index 0000000..6c6b3cb --- /dev/null +++ b/fdp/methods/timeindex.py @@ -0,0 +1,21 @@ +# -*- coding: utf-8 -*- +""" +Created on Thu Jul 7 19:10:56 2016 + +@author: drsmith +""" + +import numpy as np + +def getTimeIndex(obj, time=0.0): + """ + Return time index <= input time + """ + if not obj.isSignal(): + print('getTimeIndex() is only valid for signals, returning') + return + indlist = np.nonzero(obj.time<=time) + if indlist[0].size>0: + return indlist[0][-1] + else: + return None \ No newline at end of file diff --git a/fdp/modules/nstxu/equilibria/efit.xml b/fdp/modules/nstxu/equilibria/efit.xml index 14e9858..1f7256b 100644 --- a/fdp/modules/nstxu/equilibria/efit.xml +++ b/fdp/modules/nstxu/equilibria/efit.xml @@ -2,39 +2,41 @@ - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + - - - + + + - - - - - + + + + + \ No newline at end of file From e3e064dc8ccf9774b60b357f8ec8e27d5f064b34 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 24 Mar 2017 15:00:28 -0400 Subject: [PATCH 04/82] docs and README --- README.rst | 50 +++++++++++++++++------------------- docs/source/introduction.rst | 2 +- 2 files changed, 24 insertions(+), 28 deletions(-) diff --git a/README.rst b/README.rst index e380930..2243494 100644 --- a/README.rst +++ b/README.rst @@ -1,46 +1,42 @@ .. Restructured Text (RST) Syntax Primer: http://sphinx-doc.org/rest.html Fusion Data Platform -============================== +=========================== -Fusion Data Platform (FDP) is a Python package and data framework for magnetic fusion experiments. FDP provides an extensible software layer that unites data access, management, analysis, and visualization. +Fusion Data Platform (FDP) is a Python package and data framework for magnetic fusion experiments. * Documentation: http://Fusion-Data-Platform.github.io/ * Github repository: https://github.com/Fusion-Data-Platform/fdp +* Google group: https://groups.google.com/forum/#!forum/fusion-data-platform +**Description** -Example usage ------------------------------- +* An extensible software layer that unites data access, management, analysis, and visualization in a single data object +* A descriptive data object that users can easily inspect to find data and analysis methods +* A data object that handles data access (servers, nodes, trees, tables, etc.) behind the scenes +* A collaborative platform for development of analysis tools +* Intelligent multi-dimensional slicing documents singleton dimensions (e.g. a radial profile knows the time slice to which it corresponds) +* Built with popular, open-source packages like Numpy and Matplotlib +**Example usage** + + >>> import fdp + >>> nstxu = fdp.nstxu() >>> nstxu.s204551.mpts.te.plot() >>> nstxu.s204620.equilibria.efit02.kappa.plot() >>> nstxu.s204670.bes.ch01.plotfft() + +Python's tab-complete feature presents users with data containers like ``mpts`` and ``efit02``, data signals like ``te`` and ``kappa``, and data methods like ``plot()`` and ``plotfft()``. +Exercise: Create 2D plots of electron density for every shot in XP 1013:: -Features ------------------------------- - -FDP reduces barriers to entry for new users and facilitates collaborative development of analysis and visualization tools. - -* Integrate data sources, data, and analysis methods in a single, extensible data object -* Streamline data access for multiple facilities, diagnostics, and databases - - - - * Organize data and analysis methods in an intuitive object-oriented framework - -* Promote collaborative code development and reduce inefficient code duplication - -* Reduce barriers to entry for new students and scientists - -* Free components and flexible usage - - * Python, Numpy, Matplotlib, Github, etc. - * Platform-independent: desktop Mac/PC, Linux cluster - * Command-line tool or import into code + import fdp + nstxu = fdp.nstxu() + xp1013 = nstxu.filter_shots(xp=1013) + for shot in xp1013: + shot.mpts.ne.plot() -Lead developers ------------------------------- +**Lead developers** * David R. Smith, U. Wisconsin-Madison * Kevin Tritz, The Johns Hopkins U. diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst index 1e61b11..6aabad0 100755 --- a/docs/source/introduction.rst +++ b/docs/source/introduction.rst @@ -2,7 +2,7 @@ ***************************************** -Introduction +Overview ***************************************** From 65e0d6976fa12239c8041c27adcc23ac6c88b6ef Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Thu, 6 Apr 2017 17:15:23 -0400 Subject: [PATCH 05/82] modified docs --- LICENSE.rst | 2 ++ Makefile | 54 ++++++++++++++++++++++++++++++++++-- README.rst | 29 ++++++++----------- docs/source/conf.py | 19 ++++--------- docs/source/index.rst | 23 +++++++-------- docs/source/introduction.rst | 14 ---------- docs/source/license.rst | 1 + docs/source/overview.rst | 1 + 8 files changed, 81 insertions(+), 62 deletions(-) delete mode 100755 docs/source/introduction.rst create mode 100644 docs/source/license.rst create mode 100755 docs/source/overview.rst diff --git a/LICENSE.rst b/LICENSE.rst index c4346db..bf9b46d 100644 --- a/LICENSE.rst +++ b/LICENSE.rst @@ -1,3 +1,5 @@ +License +========== The MIT License (MIT) diff --git a/Makefile b/Makefile index 706963a..edd261c 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,55 @@ -.PHONY: build-docs +.DEFAULT_GOAL := help DOCDIR = docs -build-docs: - rm -rf $(DOCDIR)/build/html/ + +define PRINT_HELP_PYSCRIPT +import re, sys +for line in sys.stdin: + match = re.match(r'^([a-zA-Z_-]+):.*?## (.*)$$', line) + if match: + target, help = match.groups() + print("%-20s %s" % (target, help)) +endef +export PRINT_HELP_PYSCRIPT + + +define BROWSER_PYSCRIPT +import os, webbrowser, sys +try: + from urllib import pathname2url +except: + from urllib.request import pathname2url + +webbrowser.open("file://" + pathname2url(os.path.abspath(sys.argv[1]))) +endef +export BROWSER_PYSCRIPT +BROWSER := python -c "$$BROWSER_PYSCRIPT" + + +.PHONY: help +help: ## show help message + @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) + + +.PHONY: docs +docs: ## build HTML documents $(MAKE) -C $(DOCDIR) html + @$(BROWSER) docs/build/html/index.html + + +.PHONY: clean +clean: clean-pyc clean-docs ## remove all build, docs, and Python artifacts + + +.PHONY: clean-docs +clean-docs: ## remove docs/build + rm -rf docs/build + + +.PHONY: clean-pyc +clean-pyc: ## remove Python file artifacts + find . -name '*.pyc' -exec rm -f {} + + find . -name '*.pyo' -exec rm -f {} + + find . -name '*~' -exec rm -f {} + + find . -name '__pycache__' -exec rm -fr {} + diff --git a/README.rst b/README.rst index 2243494..a114558 100644 --- a/README.rst +++ b/README.rst @@ -3,38 +3,31 @@ Fusion Data Platform =========================== -Fusion Data Platform (FDP) is a Python package and data framework for magnetic fusion experiments. +Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, management, analysis methods, and visualization. -* Documentation: http://Fusion-Data-Platform.github.io/ * Github repository: https://github.com/Fusion-Data-Platform/fdp +* Documentation: http://Fusion-Data-Platform.github.io/ * Google group: https://groups.google.com/forum/#!forum/fusion-data-platform **Description** * An extensible software layer that unites data access, management, analysis, and visualization in a single data object -* A descriptive data object that users can easily inspect to find data and analysis methods -* A data object that handles data access (servers, nodes, trees, tables, etc.) behind the scenes -* A collaborative platform for development of analysis tools -* Intelligent multi-dimensional slicing documents singleton dimensions (e.g. a radial profile knows the time slice to which it corresponds) +* A descriptive data object that users can query to find data and analysis methods +* A data object that handles data access (servers, trees, nodes, queries) behind the scenes +* A collaborative development plateform for data analysis tools * Built with popular, open-source packages like Numpy and Matplotlib **Example usage** - >>> import fdp - >>> nstxu = fdp.nstxu() - >>> nstxu.s204551.mpts.te.plot() - >>> nstxu.s204620.equilibria.efit02.kappa.plot() - >>> nstxu.s204670.bes.ch01.plotfft() - -Python's tab-complete feature presents users with data containers like ``mpts`` and ``efit02``, data signals like ``te`` and ``kappa``, and data methods like ``plot()`` and ``plotfft()``. - -Exercise: Create 2D plots of electron density for every shot in XP 1013:: +.. code-block:: python import fdp nstxu = fdp.nstxu() - xp1013 = nstxu.filter_shots(xp=1013) - for shot in xp1013: - shot.mpts.ne.plot() + nstxu.s204551.mpts.te.plot() + nstxu.s204620.equilibria.efit02.kappa.plot() + nstxu.s204670.bes.ch01.plotfft() + +Python's tab-complete feature presents users with data containers like ``mpts`` and ``efit02``, data signals like ``te`` and ``kappa``, and data methods like ``plot()`` and ``plotfft()``. **Lead developers** diff --git a/docs/source/conf.py b/docs/source/conf.py index b8e831b..4f0f0be 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -35,10 +35,10 @@ # ones. extensions = [ 'sphinx.ext.autodoc', - 'sphinx.ext.doctest', - 'sphinx.ext.intersphinx', - 'sphinx.ext.coverage', - 'sphinx.ext.mathjax', + #'sphinx.ext.doctest', + #'sphinx.ext.intersphinx', + #'sphinx.ext.coverage', + #'sphinx.ext.mathjax', 'sphinx.ext.viewcode', ] @@ -119,7 +119,7 @@ # The theme to use for HTML and HTML Help pages. See the documentation for # a list of builtin themes. -html_theme = 'sphinx_rtd_theme' +html_theme = 'default' # 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 @@ -165,15 +165,6 @@ # Custom sidebar templates, maps document names to template names. #html_sidebars = {} -html_sidebars = { - '**': [ - 'about.html', - 'navigation.html', - 'relations.html', - 'searchbox.html', - 'genindex.html' - ] -} # Additional templates that should be rendered to pages, maps page names to # template names. diff --git a/docs/source/index.rst b/docs/source/index.rst index 9ab2c3a..413fe5d 100755 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,28 +1,25 @@ -.. Restructured Text (RST) Syntax Primer: http://sphinx-doc.org/rest.html - - -##################################### Fusion Data Platform -##################################### +====================================== .. only:: html - Fusion Data Platform (FDP) is a data framework for magnetic fusion experiments. FDP streamlines data discovery, analysis methods, and visualization. + Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, management, analysis methods, and visualization. * Github repository: https://github.com/Fusion-Data-Platform/fdp * Documentation: http://Fusion-Data-Platform.github.io/ + * Google group: https://groups.google.com/forum/#!forum/fusion-data-platform -Table of Contents -====================== +**Contents** .. toctree:: - :maxdepth: 3 + :maxdepth: 2 - introduction.rst - user_guide.rst - developer_guide.rst - project_documents.rst + Overview + user_guide + developer_guide + project_documents + license diff --git a/docs/source/introduction.rst b/docs/source/introduction.rst deleted file mode 100755 index 6aabad0..0000000 --- a/docs/source/introduction.rst +++ /dev/null @@ -1,14 +0,0 @@ -.. Restructured Text (RST) Syntax Primer: http://sphinx-doc.org/rest.html - - -***************************************** -Overview -***************************************** - - -.. include:: ../../README.rst - -License -=============== - -.. include:: ../../LICENSE.rst diff --git a/docs/source/license.rst b/docs/source/license.rst new file mode 100644 index 0000000..2a90cf4 --- /dev/null +++ b/docs/source/license.rst @@ -0,0 +1 @@ +.. include:: ../../LICENSE.rst \ No newline at end of file diff --git a/docs/source/overview.rst b/docs/source/overview.rst new file mode 100755 index 0000000..a6210d3 --- /dev/null +++ b/docs/source/overview.rst @@ -0,0 +1 @@ +.. include:: ../../README.rst From 4898554e0ffe9e5c479c8ab8c62bcb3eb2d7a1eb Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 12:01:22 -0400 Subject: [PATCH 06/82] added bumpversion and flake8 integration --- .bumpversion.cfg | 15 +++++++++++++++ .flake8 | 8 ++++++++ .gitignore | 16 ++++++++++++++-- docs/source/conf.py | 4 ++-- fdp/__init__.py | 2 ++ 5 files changed, 41 insertions(+), 4 deletions(-) create mode 100644 .bumpversion.cfg create mode 100644 .flake8 diff --git a/.bumpversion.cfg b/.bumpversion.cfg new file mode 100644 index 0000000..0d85283 --- /dev/null +++ b/.bumpversion.cfg @@ -0,0 +1,15 @@ +[bumpversion] +current_version = 0.1.0 +commit = True +tag = True +verbose = True +list = True + +[bumpversion:file:fdp/__init__.py] +search = __version__ = '{current_version}' +replace = __version__ = '{new_version}' + +[bumpversion:file:docs/source/conf.py] +search = version = '{current_version}' +replace = version = '{new_version}' + diff --git a/.flake8 b/.flake8 new file mode 100644 index 0000000..602e1e1 --- /dev/null +++ b/.flake8 @@ -0,0 +1,8 @@ +[flake8] +exclude = docs +max-line-length = 79 +show-source = True +statistics = True +output-file = flake8.output.txt +tee = True +max-complexity = 10 diff --git a/.gitignore b/.gitignore index 40906ea..fff3332 100644 --- a/.gitignore +++ b/.gitignore @@ -3,8 +3,10 @@ # *~ -*.pyc -docs/build +*.py[cod] +__pycache__/ +*$py.class +docs/build/ *.ipynb .ipynb_checkpoints .spyderproject @@ -12,6 +14,16 @@ anaconda .DS_Store spyder_crash.log +# Unit test / coverage reports +htmlcov/ +.tox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +flake8.output.txt + # # exceptions diff --git a/docs/source/conf.py b/docs/source/conf.py index 4f0f0be..7db8f55 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,9 +66,9 @@ # built documents. # # The short X.Y version. -version = '0.0' +version = '0.1.0' # The full version, including alpha/beta/rc tags. -release = '0.0.0' +release = version # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/fdp/__init__.py b/fdp/__init__.py index 299fa3f..5d41627 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,6 +7,8 @@ from .classes import fdp +__version__ = '0.1.0' + def nstxu(): return fdp.Fdp().nstxu From 5109342124eb46184bce66d1b0bf5e4a6a7ce108 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 12:14:57 -0400 Subject: [PATCH 07/82] ran autopep8 in classes and methods to fix some pep8 conformance --- fdp/__init__.py | 7 +- fdp/classes/container.py | 77 +++-- fdp/classes/crosssignal.py | 331 +++++++++++----------- fdp/classes/datasources.py | 1 + fdp/classes/fdp.py | 6 +- fdp/classes/fdp_globals.py | 5 +- fdp/classes/fft.py | 65 +++-- fdp/classes/gui.py | 48 ++-- fdp/classes/logbook.py | 7 +- fdp/classes/machine.py | 41 +-- fdp/classes/node.py | 1 + fdp/classes/parse.py | 20 +- fdp/classes/shot.py | 16 +- fdp/classes/signal.py | 178 ++++++------ fdp/classes/utilities.py | 6 +- fdp/methods/_netcat.py | 1 + fdp/methods/check_efit.py | 1 - fdp/methods/currentshot.py | 1 + fdp/methods/fft.py | 12 +- fdp/methods/info.py | 6 +- fdp/methods/listmethods.py | 10 +- fdp/methods/logbook.py | 1 - fdp/methods/nstxu/__init__.py | 1 - fdp/methods/nstxu/bes/__init__.py | 2 +- fdp/methods/nstxu/bes/animation.py | 161 +++++------ fdp/methods/nstxu/bes/configuration.py | 10 +- fdp/methods/nstxu/bes/crosspower.py | 107 +++---- fdp/methods/nstxu/bes/fft.py | 4 +- fdp/methods/nstxu/bes/gui.py | 2 +- fdp/methods/nstxu/bes/movie.py | 175 ++++++------ fdp/methods/nstxu/bes/utilities.py | 2 +- fdp/methods/nstxu/chers/__init__.py | 1 - fdp/methods/nstxu/equilibria/bfield.py | 12 +- fdp/methods/nstxu/equilibria/utilities.py | 2 +- fdp/methods/nstxu/mpts/change_units.py | 1 - fdp/methods/nstxu/overviewgui.py | 1 - fdp/methods/nstxu/shottime.py | 1 + fdp/methods/plot.py | 94 +++--- fdp/methods/timeindex.py | 7 +- 39 files changed, 755 insertions(+), 669 deletions(-) diff --git a/fdp/__init__.py b/fdp/__init__.py index 5d41627..f43dfdb 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -9,17 +9,22 @@ __version__ = '0.1.0' + def nstxu(): return fdp.Fdp().nstxu + def nstx(): return nstxu() + def diiid(): return fdp.Fdp().diiid + def d3d(): return diiid() + def cmod(): - return fdp.Fdp().cmod \ No newline at end of file + return fdp.Fdp().cmod diff --git a/fdp/classes/container.py b/fdp/classes/container.py index d9cbcd0..ad1cb41 100755 --- a/fdp/classes/container.py +++ b/fdp/classes/container.py @@ -20,13 +20,14 @@ def init_class(cls, module_tree, **kwargs): cls._name = module_tree.get('name') - if VERBOSE: print('init_class({})'.format(cls._name)) + if VERBOSE: + print('init_class({})'.format(cls._name)) if cls not in cls._instances: cls._instances[cls] = {} for read_only in ['root', 'container', 'classparent']: try: - setattr(cls, '_'+read_only, kwargs[read_only]) + setattr(cls, '_' + read_only, kwargs[read_only]) # print(cls._name, read_only, kwargs.get(read_only, 'Not there')) except: pass @@ -34,11 +35,12 @@ def init_class(cls, module_tree, **kwargs): for item in ['mdstree', 'mdspath', 'units']: getitem = module_tree.get(item) if getitem is not None: - setattr(cls, '_'+item, getitem) + setattr(cls, '_' + item, getitem) cls._base_items = set(cls.__dict__.keys()) - if VERBOSE: print('init_class({}) Calling parse_method({})'. - format(cls._name, cls._name)) + if VERBOSE: + print('init_class({}) Calling parse_method({})'. + format(cls._name, cls._name)) parse.parse_method(cls) @@ -60,11 +62,12 @@ def __init__(self, module_tree, top=False, **kwargs): self._dynamic_containers = {} self._tags = [] self._title = module_tree.get('title') - if VERBOSE: print(' {}.__init__()'.format(self._name)) + if VERBOSE: + print(' {}.__init__()'.format(self._name)) self._desc = module_tree.get('desc') for read_only in ['parent']: - setattr(self, '_'+read_only, kwargs.get(read_only, None)) + setattr(self, '_' + read_only, kwargs.get(read_only, None)) try: self.shot = kwargs['shot'] @@ -81,7 +84,8 @@ def __init__(self, module_tree, top=False, **kwargs): if top: self._get_dynamic_containers() - if VERBOSE: print(' {}.__init__() Begin module parsing'.format(self._name)) + if VERBOSE: + print(' {}.__init__() Begin module parsing'.format(self._name)) for node in module_tree.findall('node'): branch_str = self._get_branchstr() @@ -101,8 +105,9 @@ def __init__(self, module_tree, top=False, **kwargs): setattr(self, method_defaults, defaults_dict) for element in module_tree.findall('axis'): - if VERBOSE: print(' {}.__init__ Begin parsing axis {}'. - format(self._name,element.get('name'))) + if VERBOSE: + print(' {}.__init__ Begin parsing axis {}'. + format(self._name, element.get('name'))) signal_list = parse.parse_signal(self, element) branch_str = self._get_branchstr() for signal_dict in signal_list: @@ -118,10 +123,11 @@ def __init__(self, module_tree, top=False, **kwargs): if not refs: refs = SignalObj.axes for axis, ref in zip(SignalObj.axes, refs): - setattr(SignalObj, axis, getattr(self, '_'+ref)) + setattr(SignalObj, axis, getattr(self, '_' + ref)) setattr(self, ''.join(['_', signal_dict['_name']]), SignalObj) - if VERBOSE: print(' {}.__init__ End parsing axis {}'. - format(self._name,element.get('name'))) + if VERBOSE: + print(' {}.__init__ End parsing axis {}'. + format(self._name, element.get('name'))) for branch in module_tree.findall('container'): name = branch.get('name') @@ -139,8 +145,9 @@ def __init__(self, module_tree, top=False, **kwargs): self._containers[name] = ContainerObj for element in module_tree.findall('signal'): - if VERBOSE: print(' {}.__init__ Begin parsing signal {}'. - format(self._name,element.get('name'))) + if VERBOSE: + print(' {}.__init__ Begin parsing signal {}'. + format(self._name, element.get('name'))) signal_list = parse.parse_signal(self, element) branch_str = self._get_branchstr() for signal_dict in signal_list: @@ -157,24 +164,28 @@ def __init__(self, module_tree, top=False, **kwargs): if not refs: refs = SignalObj.axes for axis, ref in zip(SignalObj.axes, refs): - setattr(SignalObj, axis, getattr(self, '_'+ref)) + setattr(SignalObj, axis, getattr(self, '_' + ref)) for default in element.findall('defaults'): - method_defaults, defaults_dict = parse.parse_defaults(default) + method_defaults, defaults_dict = parse.parse_defaults( + default) if hasattr(self, method_defaults): defaults_dict.update(getattr(self, method_defaults)) setattr(SignalObj, method_defaults, defaults_dict) setattr(self, signal_dict['_name'], SignalObj) self._signals[signal_dict['_name']] = SignalObj - if VERBOSE: print(' {}.__init__ End parsing signal {}'. - format(self._name,element.get('name'))) + if VERBOSE: + print(' {}.__init__ End parsing signal {}'. + format(self._name, element.get('name'))) if top and hasattr(self, '_preprocess'): self._preprocess() - if VERBOSE: print(' {}.__init__() End module parsing'.format(self._name)) + if VERBOSE: + print(' {}.__init__() End module parsing'.format(self._name)) def __getattr__(self, attribute): - if VERBOSE: print(' {}.__getattr__({})'.format(self._name, attribute)) + if VERBOSE: + print(' {}.__getattr__({})'.format(self._name, attribute)) try: if self._dynamic_containers[attribute] is None: branch_path = '.'.join([self._get_branch(), attribute]) @@ -183,7 +194,7 @@ def __getattr__(self, attribute): format(self._name, attribute)) self._dynamic_containers[attribute] = \ Factory(branch_path, root=self._root, - shot=self.shot, parent=self) + shot=self.shot, parent=self) return self._dynamic_containers[attribute] except KeyError: @@ -219,9 +230,9 @@ def _get_dynamic_containers(self): return files = os.listdir(container_dir) self._dynamic_containers = {container: None for container in - files if os.path.isdir( - os.path.join(container_dir, container)) and - container[0] is not '_'} + files if os.path.isdir( + os.path.join(container_dir, container)) and + container[0] is not '_'} @classmethod def _get_path(cls): @@ -244,10 +255,12 @@ def __dir__(self): def __iter__(self): if not len(self._signals): - items = sorted(self._containers.values(), key= lambda obj: obj._name.lower()) + items = sorted(self._containers.values(), + key=lambda obj: obj._name.lower()) # items.extend(self._dynamic_containers.values()) else: - items = sorted(self._signals.values(), key= lambda obj: obj._name.lower()) + items = sorted(self._signals.values(), + key=lambda obj: obj._name.lower()) return iter(items) @classmethod @@ -299,8 +312,9 @@ def Factory(module_branch, root=None, shot=None, parent=None): Factory method """ - if VERBOSE: print('Factory({}, root={}, shot={}, parent={})'. - format(module_branch, root, shot, parent)) + if VERBOSE: + print('Factory({}, root={}, shot={}, parent={})'. + format(module_branch, root, shot, parent)) module_branch = module_branch.lower() module_list = module_branch.split('.') module = module_list[-1] @@ -316,7 +330,8 @@ def Factory(module_branch, root=None, shot=None, parent=None): ContainerClassName = 'Container' + branch_str if ContainerClassName not in Container._classes: ContainerClass = type(ContainerClassName, (Container,), {}) - if VERBOSE: print('Factory() calling init_class()') + if VERBOSE: + print('Factory() calling init_class()') init_class(ContainerClass, _tree_dict[module_branch], root=root, container=module, classparent=parent.__class__) Container._classes[ContainerClassName] = ContainerClass @@ -326,4 +341,4 @@ def Factory(module_branch, root=None, shot=None, parent=None): return ContainerClass(_tree_dict[module_branch], shot=shot, parent=parent, top=True) except: - raise \ No newline at end of file + raise diff --git a/fdp/classes/crosssignal.py b/fdp/classes/crosssignal.py index 6509431..dd5f81d 100644 --- a/fdp/classes/crosssignal.py +++ b/fdp/classes/crosssignal.py @@ -12,6 +12,7 @@ import numpy as np from .fdp_globals import FdpError, FdpWarning + class CrossSignal(object): """ CrossSignal class @@ -73,7 +74,7 @@ def __init__(self, signal1, signal2, tmin=0.2, tmax=1.0, window='hann', nperseg=None, forcepower2=False, offsetminimum=False, offsetdc=False, normalizetodc=False, degrees=True, fmin=None, fmax=None, numfilttaps=None, removesawteeth=False): - + self.signal1 = signal1 self.signal2 = signal2 self.signal1time = signal1.time @@ -94,7 +95,7 @@ def __init__(self, signal1, signal2, tmin=0.2, tmax=1.0, window='hann', self.fmax = fmax self.numfilttaps = numfilttaps self.removesawteeth = removesawteeth - + if signal1 is signal2: self.same_signal = True else: @@ -104,7 +105,7 @@ def __init__(self, signal1, signal2, tmin=0.2, tmax=1.0, window='hann', self.detrend = 'constant' else: self.detrend = False - + # Preprocessing of input signals self.load_signals() if offsetminimum: @@ -128,15 +129,16 @@ def load_signals(self): """ Load data and check to ensure each signal has same time scaling. """ - + # Load data - self.signal1[:] - self.signal2[:] - self.signal1time[:] - self.signal2time[:] - + self.signal1[:] + self.signal2[:] + self.signal1time[:] + self.signal2time[:] + # Check to ensure both signals have same sampling rate - fs1 = 1 / np.mean(np.diff(np.array(self.signal1time))) # Not sure if np.array() needed + fs1 = 1 / np.mean(np.diff(np.array(self.signal1time)) + ) # Not sure if np.array() needed fs2 = 1 / np.mean(np.diff(np.array(self.signal2time))) if abs(fs1 - fs2) < 1e-3: self.fSample = (fs1 + fs2) / 2 @@ -148,12 +150,12 @@ def apply_offset_minimum(self): """ Get zero signal level by averaging 1000 points near beginning of shot together, then use this to offset signal. - + For BES, first 20 points exhibit turn on transient effects so second group of 1000 points is used. - + """ - + zerolevel1 = np.mean(self.signal1[1e3:2e3]) self.signal1 -= zerolevel1 zerolevel2 = np.mean(self.signal2[1e3:2e3]) @@ -164,7 +166,7 @@ def make_data_window(self): Reduce signals to only contain data in the specified time window. Then check to ensure each signal has same length. """ - + mask1 = np.logical_and(self.signal1time >= self.tmin, self.signal1time <= self.tmax) mask2 = np.logical_and(self.signal2time >= self.tmin, @@ -173,37 +175,37 @@ def make_data_window(self): self.signal2 = np.extract(mask2, self.signal2) self.signal1time = np.extract(mask1, self.signal1time) self.signal2time = np.extract(mask2, self.signal2time) - + # Check to ensure both signals have same number of points if len(self.signal1) == len(self.signal2): self.numpnts = len(self.signal1) else: raise FdpError('Input signals are different lengths') - + def filter_signals(self): 'Filter the input data over the user specified frequency range' - + # Check to see if either filter frequency has been set. If not, then # don't filter the data if self.fmin is not None or self.fmax is not None: - + # Set default values for unspecified frequencies and convert units # of specified frequencies from kHz to Hz if self.fmin is not None and self.fmax is not None: filttype = 'bandpass' - + if self.fmin is None: filttype = 'lowpass' - self.fmin = self.fNyquist / 2 # Placeholder valid frequency + self.fmin = self.fNyquist / 2 # Placeholder valid frequency else: self.fmin *= 1000 - + if self.fmax is None: filttype = 'highpass' - self.fmax = self.fNyquist / 2 # Placeholder valid frequency + self.fmax = self.fNyquist / 2 # Placeholder valid frequency else: self.fmax *= 1000 - + # Verify that frequencies are valid if self.fmin <= 0 or self.fmin >= self.fNyquist: raise FdpError('fmin is outside valid range') @@ -211,29 +213,29 @@ def filter_signals(self): raise FdpError('fmax is outside valid range') if self.fmax < self.fmin: raise FdpError('fmin is larger than fmax') - + # Calculate a "good" number of filter taps to use if self.numfilttaps is None: - numtaps = 501 # 501 currently, in future will improve + numtaps = 501 # 501 currently, in future will improve else: numtaps = self.numfilttaps - + # Verify that there are less taps than length of data if numtaps >= self.numpnts - 1: raise FdpError('Number of filter taps must be smaller than ' 'number of data points in signal - 1.') - + # Alert user that minimum cutoff frequency is too small if self.fNyquist / self.fmin > (numtaps // 2): raise FdpWarning('Cutoff frequency too small for specified ' 'numberof filter taps. Increase number of ' 'filter taps for lower cutoff frequency.') - + # Alert user that an odd number of filter coefficients are used - if numtaps % 2 == 0: # even number + if numtaps % 2 == 0: # even number raise FdpWarning('Even number of filter taps will phase shift' 'data.') - + # Filter data using FIR filter generated using window method # (Hamming window) if filttype == 'lowpass': @@ -241,10 +243,10 @@ def filter_signals(self): elif filttype == 'highpass': h = firwin(numtaps, self.fmin, pass_zero=False, nyq=self.fNyquist) - else: # bandpass + else: # bandpass h = firwin(numtaps, [self.fmin, self.fmax], pass_zero=False, nyq=self.fNyquist) - + self.signal1 = filtfilt(h, 1.0, self.signal1, padlen=numtaps) self.signal2 = filtfilt(h, 1.0, self.signal2, padlen=numtaps) @@ -262,255 +264,256 @@ def calc_csd(self): A one-sided spectrum is returned for real inputs The cross spectral density (units V**2/Hz) is calculated, as opposed to the cross spectrum (units V**2). - + csd is a 2D array containing the cross spectral density. Axis 0 is the frequency axis and axis 1 is the time axis. Entries in the times array are the center values for each time bin. """ - + # If the number of points per segement is not specified, calculate the # number that gives approximately equal time and frequency resolution. if self.nperseg is None: self.nperseg = int(np.sqrt(2 * self.numpnts)) - - # Use next power of 2 for nperseg if specified. FFT algorithm is most + + # Use next power of 2 for nperseg if specified. FFT algorithm is most # efficient when nperseg is a power of 2. if self.forcepower2 is True: self.nperseg = np.power(2, int(np.log2(self.nperseg - 1)) + 1) - + # Calculate cross spectral density self.freqs, self.times, self.csd = _spectral_helper( - self.signal1, - self.signal2, - fs=self.fSample, - window=self.window, - nperseg=self.nperseg, - detrend=self.detrend, - scaling='density', - mode='psd' - ) - + self.signal1, + self.signal2, + fs=self.fSample, + window=self.window, + nperseg=self.nperseg, + detrend=self.detrend, + scaling='density', + mode='psd' + ) + # Calculate auto spectral density of signal 1 _, _, self.asd1 = _spectral_helper( - self.signal1, - self.signal1, - fs=self.fSample, - window=self.window, - nperseg=self.nperseg, - detrend=self.detrend, - scaling='density', - mode='psd' - ) - + self.signal1, + self.signal1, + fs=self.fSample, + window=self.window, + nperseg=self.nperseg, + detrend=self.detrend, + scaling='density', + mode='psd' + ) + # Calculate auto spectral density of signal 2 _, _, self.asd2 = _spectral_helper( - self.signal2, - self.signal2, - fs=self.fSample, - window=self.window, - nperseg=self.nperseg, - detrend=self.detrend, - scaling='density', - mode='psd' - ) - + self.signal2, + self.signal2, + fs=self.fSample, + window=self.window, + nperseg=self.nperseg, + detrend=self.detrend, + scaling='density', + mode='psd' + ) + # Shift time bins to correspond to original data window self.times += (self.signal1time[0] + self.signal2time[0]) / 2 - + # Remove bins with sawtooth crashes if self.removesawteeth: self.remove_sawteeth() - + # Record number of bins (aka # segments or # realizations) in the ffts self.numbins = np.shape(self.csd)[-1] - + # Calculate time bin averaged spectral densities self.csd_binavg = np.mean(self.csd, axis=-1) self.asd1_binavg = np.mean(self.asd1, axis=-1) self.asd2_binavg = np.mean(self.asd2, axis=-1) - + # Convert frequency units from Hz to kHz self.freqs /= 1000 - + def calc_crosspower(self): 'Calculate the cross power (magnitude of cross spectral density)' - + self.crosspower = np.absolute(self.csd) self.crosspower_binavg = np.absolute(self.csd_binavg) - + def calc_crossphase(self): """ Calculate the cross phase (phase angle of cross spectral density) Result is between -180 degrees and 180 degrees (or -pi/2 to pi/2) """ - + self.crossphase = np.angle(self.csd) self.crossphase_binavg = np.angle(self.csd_binavg) - + # Unwrap phase to get rid of jumps from +pi to -pi (or vice-versa) # Doesn't seem to be fixing all the phase jumps self.crossphase = np.unwrap(self.crossphase, axis=0) self.crossphase_binavg = np.unwrap(self.crossphase_binavg) - + # Convert to degrees if requested if self.degrees: self.crossphase = np.rad2deg(self.crossphase) self.crossphase_binavg = np.rad2deg(self.crossphase_binavg) - + def calc_coherence(self): """ Calculate the magnitude squared coherence' - + Note that the coherence in each time bin is identically 1 so there is no use in an unaveraged coherence. """ - - # To avoid numerical errors set coherence to be identically 1 for + + # To avoid numerical errors set coherence to be identically 1 for # special cases (no averaging or autospectra) - if self.numbins == 1 or self.same_signal: + if self.numbins == 1 or self.same_signal: self.mscoherence = np.ones(len(self.csd_binavg)) else: - self.mscoherence = (np.absolute(self.csd_binavg)**2 - / (self.asd1_binavg * self.asd2_binavg)) - + self.mscoherence = (np.absolute(self.csd_binavg)**2 + / (self.asd1_binavg * self.asd2_binavg)) + # Calculate coherence (square root of magnitude squared coherence) self.coherence = np.sqrt(self.mscoherence) - - # Calculate the minimum statistically significant coherence for a + + # Calculate the minimum statistically significant coherence for a # 95% confidence interval if self.numbins == 1: self.minsig_mscoherence = 1. else: - self.minsig_mscoherence = 1 - 0.05**(1/(self.numbins - 1)) - + self.minsig_mscoherence = 1 - 0.05**(1 / (self.numbins - 1)) + self.minsig_coherence = np.sqrt(self.minsig_mscoherence) - + def calc_error(self): """ Calculate random errors using formulae from Bendat & Piersol textbook. """ - - # Crosspower error: Bendat & Piersol eq 11.23 (multiplied by crosspower) + + # Crosspower error: Bendat & Piersol eq 11.23 (multiplied by + # crosspower) self.crosspower_error = (self.crosspower_binavg - / (self.coherence * np.sqrt(self.numbins))) - + / (self.coherence * np.sqrt(self.numbins))) + # Crossphase error: Bendat & Piersol eq 11.62 self.crossphase_error = (np.sqrt(1. - self.mscoherence) - / (self.coherence * np.sqrt(2 * self.numbins))) + / (self.coherence * np.sqrt(2 * self.numbins))) if self.degrees: self.crossphase_error = np.rad2deg(self.crossphase_error) - + # Coherence error: Bendat & Piersol eq 11.47 (multiplied by coherence) self.mscoherence_error = (self.coherence * np.sqrt(2 / self.numbins) - * (1 - self.mscoherence)) - + * (1 - self.mscoherence)) + # Use of law of propagation of uncertainty to calculate coherence error self.coherence_error = self.mscoherence_error / (2 * self.coherence) - + def apply_normalize_to_dc(self): 'Normalize by dividing by the zero frequency value' - + for i in range(self.numbins): - self.asd1[:,i] /= self.asd1[0,i] - self.asd2[:,i] /= self.asd2[0,i] - self.crosspower[:,i] /= self.crosspower[0,i] - + self.asd1[:, i] /= self.asd1[0, i] + self.asd2[:, i] /= self.asd2[0, i] + self.crosspower[:, i] /= self.crosspower[0, i] + self.asd1_binavg /= self.asd1_binavg[0] self.asd2_binavg /= self.asd2_binavg[0] self.crosspower_binavg /= self.crosspower_binavg[0] - + def calc_correlation_fft(self): """ Calculate cross correlation of fluctuation component of input signals using the fft method to perform the convolution. This is faster than the integral definition method. - + Returns R(tau), where R(-tau) = F^-1[F[x(t)] * F[y(-t)]] and F[] denotes the Fourier transform. This calculation is equivalent to R[k] = Sum_i[x[i] * y[i + k]] """ - + # Segment the signals with nperseg points in each segment signal1_seg = [] signal2_seg = [] - nseg = self.numpnts // self.nperseg # Number of segments + nseg = self.numpnts // self.nperseg # Number of segments for i in range(nseg): start_i = i * self.nperseg signal1_seg.append(self.signal1[start_i:start_i + self.nperseg]) signal2_seg.append(self.signal2[start_i:start_i + self.nperseg]) signal1_seg = np.array(signal1_seg) signal2_seg = np.array(signal2_seg) - + xcorr = np.zeros((nseg, 2 * self.nperseg - 1)) autocorr1 = np.zeros((nseg, 2 * self.nperseg - 1)) autocorr2 = np.zeros((nseg, 2 * self.nperseg - 1)) xcorr_coef = np.zeros((nseg, 2 * self.nperseg - 1)) for i in range(nseg): - + # Subtract mean from each segment - signal1_seg[i,:] -= np.mean(signal1_seg, axis=1)[i] - signal2_seg[i,:] -= np.mean(signal2_seg, axis=1)[i] - + signal1_seg[i, :] -= np.mean(signal1_seg, axis=1)[i] + signal2_seg[i, :] -= np.mean(signal2_seg, axis=1)[i] + # Calculate cross-correlation for each segment # The second input is reversed to change the convolution to a # cross-correlation of the form Sum[x[i] * y[i - k]]. The - # output is then reversed to put the cross-correlation into + # output is then reversed to put the cross-correlation into # the more standard form Sum[x[i] * y[i +k]] - xcorr[i,:] = fftconvolve(signal1_seg[i,:], - signal2_seg[i,::-1])[::-1] - + xcorr[i, :] = fftconvolve(signal1_seg[i, :], + signal2_seg[i, ::-1])[::-1] + # Calculate autocorrelations for each segment - autocorr1[i,:] = fftconvolve(signal1_seg[i,:], - signal1_seg[i,::-1])[::-1] - autocorr2[i,:] = fftconvolve(signal2_seg[i,:], - signal2_seg[i,::-1])[::-1] - + autocorr1[i, :] = fftconvolve(signal1_seg[i, :], + signal1_seg[i, ::-1])[::-1] + autocorr2[i, :] = fftconvolve(signal2_seg[i, :], + signal2_seg[i, ::-1])[::-1] + # Calculate correlation coefficient - xcorr_coef[i,:] = xcorr[i,:] / np.sqrt( - autocorr1[i,self.nperseg-1] * autocorr2[i,self.nperseg-1]) - + xcorr_coef[i, :] = xcorr[i, :] / np.sqrt( + autocorr1[i, self.nperseg - 1] * autocorr2[i, self.nperseg - 1]) + # Average over all segments self.crosscorrelation = np.mean(xcorr, axis=0) self.autocorrelation1 = np.mean(autocorr1, axis=0) self.autocorrelation2 = np.mean(autocorr2, axis=0) self.correlation_coef = np.mean(xcorr_coef, axis=0) - + # Calculate envelope of correlation using analytic signal method self.correlation_coef_envelope = np.absolute( - hilbert(self.correlation_coef)) - + hilbert(self.correlation_coef)) + # Construct time axis for cross correlation self.time_delays = np.linspace(-(self.nperseg - 1), - (self.nperseg - 1), - 2*self.nperseg - 1) / self.fSample - + (self.nperseg - 1), + 2 * self.nperseg - 1) / self.fSample + def calc_correlation(self): """ Calculate cross correlation of the fluctuating parts of input signals. Warning: this method is slow, calc_correlation_fft is a faster alternative. """ - + # Calculate cross correlation using Numpy method self.crosscorrelation = np.correlate( - self.signal1 - np.mean(self.signal1), - self.signal2 - np.mean(self.signal2), - mode='Full') + self.signal1 - np.mean(self.signal1), + self.signal2 - np.mean(self.signal2), + mode='Full') self.crosscorrelation /= self.numpnts - + # Normalize correlation to produce correlation coefficient self.correlation_coef = self.crosscorrelation / np.sqrt( - np.var(self.signal1) * np.var(self.signal2)) - + np.var(self.signal1) * np.var(self.signal2)) + # Calculate envelope of correlation using analytic signal method self.correlation_coef_envelope = np.absolute( - hilbert(self.correlation_coef)) - + hilbert(self.correlation_coef)) + # Construct time axis for cross correlation self.time_delays = np.linspace(-(self.numpnts - 1), - (self.numpnts - 1), - 2*self.numpnts - 1) / self.fSample - + (self.numpnts - 1), + 2 * self.numpnts - 1) / self.fSample + def remove_sawteeth(self): """ Somehow remove time bins that contain sawteeth events. @@ -518,50 +521,54 @@ def remove_sawteeth(self): window 0.9 - 1.2 s. In future an automatic sawteeth detection scheme using frequency domain characteristics may be implemented. """ - + # Shot 204551 - sawtooth_times = np.array([0.921,0.944,0.967,0.989,1.011,1.036,1.058, - 1.081,1.106,1.127,1.150,1.171,1.193]) - + sawtooth_times = np.array([0.921, 0.944, 0.967, 0.989, 1.011, 1.036, 1.058, + 1.081, 1.106, 1.127, 1.150, 1.171, 1.193]) + # Shot 204963 # sawtooth_times = np.array([0.920,0.941,0.961,0.982,1.001,1.022,1.042, # 1.064,1.085,1.107,1.129,1.151,1.173,1.198]) - + for i in range(len(sawtooth_times)): t = sawtooth_times[i] index = np.searchsorted(self.times, t) - + # Delete 4 bins surrounding the sawtooth crash - self.csd = np.delete(self.csd, range(index-2, index+3), axis=-1) - self.asd1 = np.delete(self.asd1, range(index-2, index+3), axis=-1) - self.asd2 = np.delete(self.asd2, range(index-2, index+3), axis=-1) - self.times = np.delete(self.times, range(index-2, index+3), axis=-1) - + self.csd = np.delete(self.csd, range( + index - 2, index + 3), axis=-1) + self.asd1 = np.delete(self.asd1, range( + index - 2, index + 3), axis=-1) + self.asd2 = np.delete(self.asd2, range( + index - 2, index + 3), axis=-1) + self.times = np.delete(self.times, range( + index - 2, index + 3), axis=-1) + def phase_slope(self, fstart, fend): """ Calculate the slope of the crossphase over the user given frequency range using linear regression. The slope is returned in units of rad/Hz. - + To calculate the propagation from the crossphase slope use c = (2 * pi * d) / slope, where c is the propagation velocity, d is the distance between channels used in the crossphase, and slope is the crossphase slope returned by this function. - + Positive slope implies signal 2 leads signal 1 and negative slope implies signal 1 leads signal 2. """ - + # Find indices that define the specified frequency range istart = np.searchsorted(self.freqs, fstart) iend = np.searchsorted(self.freqs, fend) - + # Calculate crossphase slope over specified frequency range - slope, intercept, _, _, _ = linregress(self.freqs[istart:iend+1] * 1000, - self.crossphase_binavg[istart:iend+1]) - + slope, intercept, _, _, _ = linregress(self.freqs[istart:iend + 1] * 1000, + self.crossphase_binavg[istart:iend + 1]) + # Convert slope units to rad/Hz and return if self.degrees: slope = np.deg2rad(slope) intercept = np.deg2rad(intercept) - return slope, intercept \ No newline at end of file + return slope, intercept diff --git a/fdp/classes/datasources.py b/fdp/classes/datasources.py index f0d15f4..f46076a 100644 --- a/fdp/classes/datasources.py +++ b/fdp/classes/datasources.py @@ -32,6 +32,7 @@ } } + def machineAlias(machine): aliases = { diff --git a/fdp/classes/fdp.py b/fdp/classes/fdp.py index 2cd092f..fac3f87 100755 --- a/fdp/classes/fdp.py +++ b/fdp/classes/fdp.py @@ -15,9 +15,11 @@ class Fdp(object): """ The primary data object in FDP and the top-level container for machines. """ + def __getattr__(self, attribute): - if VERBOSE: print('{}.__getattr__({})'. - format(self.__class__, attribute)) + if VERBOSE: + print('{}.__getattr__({})'. + format(self.__class__, attribute)) machine_name = machineAlias(attribute) if machine_name not in MACHINES: raise FdpError('Invalid machine name') diff --git a/fdp/classes/fdp_globals.py b/fdp/classes/fdp_globals.py index 6773df5..0e03963 100755 --- a/fdp/classes/fdp_globals.py +++ b/fdp/classes/fdp_globals.py @@ -12,6 +12,7 @@ TKROOT = None FDP_DIR = os.path.dirname(os.path.dirname(os.path.abspath(__file__))) + class FdpError(Exception): """ Error class for FDF package @@ -21,12 +22,14 @@ class FdpError(Exception): raise FdfError('error message') """ + def __init__(self, message=''): self.message = message def __str__(self): return self.message + class FdpWarning(Warning): """ Warning class for FDF package @@ -36,9 +39,9 @@ class FdpWarning(Warning): warnings.warn("message", FdpWarning) """ + def __init__(self, message=''): self.message = message def __str__(self): return self.message - diff --git a/fdp/classes/fft.py b/fdp/classes/fft.py index 972bef0..1119da5 100644 --- a/fdp/classes/fft.py +++ b/fdp/classes/fft.py @@ -46,8 +46,8 @@ def __init__(self, signal, power2=None, tmin=0.2, tmax=1.0, if tmax > 10: # assume ms input and convert to s - tmin = tmin/1e3 - tmax = tmax/1e3 + tmin = tmin / 1e3 + tmax = tmax / 1e3 self.tmin = tmin self.tmax = tmax @@ -101,22 +101,23 @@ def loadSignal(self): def makeTimeBins(self): self.time = [] self.fft = [] - time_indices = np.where(np.logical_and(self.signal.time>=self.tmin, - self.signal.time<=self.tmax))[0] + time_indices = np.where(np.logical_and(self.signal.time >= self.tmin, + self.signal.time <= self.tmax))[0] istart = time_indices[0] - istop = time_indices[time_indices.size-1] + istop = time_indices[time_indices.size - 1] if self.power2 is None: # guess appropriate power2 value - self.power2 = np.int(np.sqrt((istop-istart+1)*self.overlapfactor)) + self.power2 = np.int( + np.sqrt((istop - istart + 1) * self.overlapfactor)) self.power2 = nextpow2(self.power2) self.nfft = self.power2 - t = np.mean(self.signal.time[istart:istart+self.power2]) - while self.signal.time[istart+self.power2-1] <= self.tmax: + t = np.mean(self.signal.time[istart:istart + self.power2]) + while self.signal.time[istart + self.power2 - 1] <= self.tmax: self.time.append(t) - self.fft.append(self.signal[istart:istart+self.power2]) + self.fft.append(self.signal[istart:istart + self.power2]) # candidate istart and t for next iteration - istart = istart + self.power2/self.overlapfactor - t = np.mean(self.signal.time[istart:istart+self.power2]) + istart = istart + self.power2 / self.overlapfactor + t = np.mean(self.signal.time[istart:istart + self.power2]) # convert lists to ndarrays # at this point, fft contains modified input signals self.fft = np.array(self.fft) @@ -126,63 +127,61 @@ def makeTimeBins(self): def applyMinimumOffset(self): zerosignal = np.min(self.signal[0:1e4]) self.fft -= zerosignal - + def applyDcOffset(self): # remove DC offset bin-wise for i in range(self.nbins): - self.fft[i,:] -= np.mean(self.fft[i,:]) - + self.fft[i, :] -= np.mean(self.fft[i, :]) + def applyHanningWindow(self): self.window = np.hanning(self.power2) for i in range(self.nbins): - self.fft[i,:] = np.multiply(self.fft[i,:], self.window) - + self.fft[i, :] = np.multiply(self.fft[i, :], self.window) + def calcIntegratedSignalPower(self): self.intpower = np.sum(np.square(np.absolute(self.fft)), axis=1) - + def calcFft(self): timeint = np.mean(np.diff(self.signal.time[0:1e4])) # complex-valued, double-sided FFT - self.fft = fftpack.fft(self.fft, + self.fft = fftpack.fft(self.fft, n=self.power2, axis=1) # frequency array in kHz - self.freq = fftpack.fftfreq(self.power2, d=timeint)/1e3 + self.freq = fftpack.fftfreq(self.power2, d=timeint) / 1e3 # check integrated power (bin-wise) self.checkIntegratedPower() # if real-valued input, convert to single-sided FFT if not self.iscomplexsignal: # complex-valued, single-sided FFT - ssfft = self.fft[:,0:self.power2/2+1].copy() - ssfft[:,1:self.power2/2] *= np.sqrt(2.0) + ssfft = self.fft[:, 0:self.power2 / 2 + 1].copy() + ssfft[:, 1:self.power2 / 2] *= np.sqrt(2.0) self.fft = ssfft - self.freq = self.freq[0:self.power2/2+1].copy() - self.freq[self.power2/2] = -self.freq[self.power2/2] + self.freq = self.freq[0:self.power2 / 2 + 1].copy() + self.freq[self.power2 / 2] = -self.freq[self.power2 / 2] # check integrated power (bin-wise) self.checkIntegratedPower() - + def applyNormalizeToDc(self): for i in range(self.nbins): - self.fft[i,:] /= np.real(self.fft[i,0]) - + self.fft[i, :] /= np.real(self.fft[i, 0]) + def calcPsd(self): # PSD in dB: 10*log10 (|FFT|^2) self.psd = np.square(np.absolute(self.fft)) - self.logpsd = 10*np.log10(self.psd) + self.logpsd = 10 * np.log10(self.psd) # bin-averaged PSD in dB: 10*log10 (|FFT|^2) self.binavg_psd = np.mean(self.psd, axis=0) - self.binavg_logpsd = 10*np.log10(self.binavg_psd) - - + self.binavg_logpsd = 10 * np.log10(self.binavg_psd) + def checkIntegratedPower(self): intpowercheck = np.sum(np.square(np.absolute(self.fft)), - axis=1)/self.power2 + axis=1) / self.power2 if not np.allclose(self.intpower, intpowercheck): raise FdpError('Integrated power mismatch') - def nextpow2(number): """Return next power of 2 (>= number)""" - exp = int(np.log2(number-1))+1 + exp = int(np.log2(number - 1)) + 1 return np.power(2, exp) diff --git a/fdp/classes/gui.py b/fdp/classes/gui.py index 10e1bd5..051089e 100644 --- a/fdp/classes/gui.py +++ b/fdp/classes/gui.py @@ -15,7 +15,7 @@ import threading import matplotlib as mpl -#mpl.use('TkAgg') +# mpl.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg from . import fdp_globals @@ -24,12 +24,12 @@ class BaseGui(threading.Thread): """ Base GUI class for FDP GUIs. - + Class attributes enable setting shot/times across all GUIs derived from this base class. """ - def __init__(self, obj, title='FDP GUI', parent=None, + def __init__(self, obj, title='FDP GUI', parent=None, defaultwidgets=True): super(BaseGui, self).__init__() self.title = title @@ -49,32 +49,32 @@ def run(self): else: self.topwindow = tk.Toplevel() self.topwindow.title(self.title) - self.controlframe = ttk.Frame(master=self.topwindow, - borderwidth=3, - relief='ridge', + self.controlframe = ttk.Frame(master=self.topwindow, + borderwidth=3, + relief='ridge', padding=2) self.controlframe.pack(side='left', fill='y') # dummy frame to set controlframe width controlwidth = ttk.Frame(master=self.controlframe, width=125) controlwidth.pack(side='top', fill='x') - + if self.defaultwidgets: self.addDefaultWidgets() - + self.figure = mpl.figure.Figure() - self.figureframe = ttk.Frame(master=self.topwindow, + self.figureframe = ttk.Frame(master=self.topwindow, borderwidth=3, relief='ridge') self.figureframe.pack(side='left', expand=1, fill='both') - self.canvas = FigureCanvasTkAgg(self.figure, + self.canvas = FigureCanvasTkAgg(self.figure, master=self.figureframe) self.canvas.get_tk_widget().pack(expand=1, fill='both') - + self.plotObject() - + self.topwindow.after(5000, self.checkShotKeys) self.topwindow.mainloop() - + def checkShotKeys(self): self.machinelock.acquire() with self.machinelock: @@ -85,7 +85,7 @@ def checkShotKeys(self): self.shotList.insert(i, key) self.shotkeys = newkeys self.topwindow.after(1000, self.checkShotKeys) - + def addDefaultWidgets(self): self.shotEntry = self.insertButtonEntry(text='Add shot', command=self.addShot) @@ -93,14 +93,14 @@ def addDefaultWidgets(self): self.insertShotListbox() self.tminEntry = self.insertTextEntry(text='Tmin (ms): ') self.tmaxEntry = self.insertTextEntry(text='Tmax (ms): ') - self.closeButton = self.insertButton(text='Close', + self.closeButton = self.insertButton(text='Close', command=self.topwindow.destroy) - self.printButton = self.insertButton(text='Save', + self.printButton = self.insertButton(text='Save', command=None) - + def shotEntryEvent(self, event): self.addShot() - + def addShot(self): try: shot = int(self.shotEntry.get()) @@ -110,23 +110,23 @@ def addShot(self): with self.machinelock: self.machine.addshot(shot) self.checkShotKeys() - + def plotObject(self): self.axes = self.figure.add_subplot(111) self.obj.plot(fig=self.figure, ax=self.axes) self.canvas.show() - + def insertButtonEntry(self, text=None, width=8, command=None): frame = ttk.Frame(master=self.controlframe, padding=2) frame.pack(side='top', fill='x') - button = ttk.Button(master=frame, + button = ttk.Button(master=frame, text=text, command=command) button.pack(side='left') entry = ttk.Entry(master=frame, width=width) entry.pack(side='right') return entry - + def insertTextEntry(self, text=None, width=8): frame = ttk.Frame(master=self.controlframe, padding=2) frame.pack(side='top', fill='x') @@ -149,11 +149,11 @@ def insertShotListbox(self): for key in self.shotkeys: self.shotList.insert(tk.END, key) self.shotList.pack(side='right', anchor=tk.N) - + def insertButton(self, text=None, width=20, command=None): frame = ttk.Frame(master=self.controlframe, padding=2) frame.pack(side='bottom', fill='x') - button = ttk.Button(master=frame, text=text, + button = ttk.Button(master=frame, text=text, command=command, width=width) button.pack(side='left') diff --git a/fdp/classes/logbook.py b/fdp/classes/logbook.py index fc01099..bf46701 100755 --- a/fdp/classes/logbook.py +++ b/fdp/classes/logbook.py @@ -59,7 +59,8 @@ def _make_logbook_connection(self): port=self._credentials['port'], as_dict=True) except: - txt = '{} logbook connection failed. '.format(self._name.upper()) + txt = '{} logbook connection failed. '.format( + self._name.upper()) txt = txt + 'Server credentials:' for key in self._credentials: txt = txt + ' {0}:{1}'.format(key, self._credentials[key]) @@ -127,14 +128,14 @@ def get_shotlist(self, date=None, xp=None, verbose=False): print(' {shot} in XP {xp}'.format(**row)) # add shots to shotlist shotlist.extend([row['shot'] for row in rows - if row['shot'] is not None]) + if row['shot'] is not None]) cursor.close() return np.unique(shotlist) def get_entries(self, shot=None, date=None, xp=None): # return list of lobgook entries (dictionaries) for shot(s) - shotlist=[] + shotlist = [] if shot and not isinstance(shot, list): shot = [shot] if shot: diff --git a/fdp/classes/machine.py b/fdp/classes/machine.py index 3d3cd23..6b3b768 100755 --- a/fdp/classes/machine.py +++ b/fdp/classes/machine.py @@ -39,12 +39,14 @@ def __init__(self, name='nstxu', shotlist=None, xp=None, date=None): self._shots = {} # shot dictionary with shot number (int) keys self._classlist = {} self._name = machineAlias(name) - if VERBOSE: print('{}.__init__'.format(self._name)) + if VERBOSE: + print('{}.__init__'.format(self._name)) self._logbook = Logbook(name=self._name, root=self) self._eventConnection = mds.Connection(EVENT_SERVERS[self._name]) if len(self._connections) is 0: - if VERBOSE: print('{}.__init__ Precaching MDS connections...'. - format(self._name)) + if VERBOSE: + print('{}.__init__ Precaching MDS connections...'. + format(self._name)) for _ in range(2): try: connection = mds.Connection(MDS_SERVERS[self._name]) @@ -54,21 +56,24 @@ def __init__(self, name='nstxu', shotlist=None, xp=None, date=None): msg = 'MDSplus connection to {} failed'.format( MDS_SERVERS[self._name]) raise FdpError(msg) - if VERBOSE: print('{}.__init__ Finished MDS'.format(self._name)) + if VERBOSE: + print('{}.__init__ Finished MDS'.format(self._name)) self.s0 = Shot(0, root=self, parent=self) if shotlist or xp or date: self.addshot(shotlist=shotlist, xp=xp, date=date) def __getattr__(self, name): - if VERBOSE: print('{}.__getattr__({})'.format(self._name, name)) + if VERBOSE: + print('{}.__getattr__({})'.format(self._name, name)) try: shot = int(name.split('s')[1]) except: raise AttributeError("'{}' object has no attribute '{}'".format( type(self), name)) if (shot not in self._shots): - if VERBOSE: print('{}.__getattr__: loading shot {}'. - format(self._name, shot)) + if VERBOSE: + print('{}.__getattr__: loading shot {}'. + format(self._name, shot)) self._shots[shot] = Shot(shot, root=self, parent=self) return self._shots[shot] @@ -88,7 +93,8 @@ def __delitem__(self, item): self._shots.__delitem__(item) def __getitem__(self, item): - if VERBOSE: print('{}.__getitem__({})'.format(self._name, item)) + if VERBOSE: + print('{}.__getitem__({})'.format(self._name, item)) if item == 0: return self.s0 return self._shots[item] @@ -98,7 +104,8 @@ def __setitem__(self, item, value): def __dir__(self): shotlist = ['s0'] - shotlist.extend(['s{}'.format(shot) for shot in self._shots.iterkeys()]) + shotlist.extend(['s{}'.format(shot) + for shot in self._shots.iterkeys()]) return shotlist def _get_connection(self, shot, tree): @@ -176,14 +183,16 @@ def _get_mdsdata(self, signal): return data def _get_modules(self): - if VERBOSE: print('{}._get_modules()'.format(self._name)) + if VERBOSE: + print('{}._get_modules()'.format(self._name)) if self._modules is None: - if VERBOSE: print('{}._get_modules() Surveying diagnostic modules'. - format(self._name)) + if VERBOSE: + print('{}._get_modules() Surveying diagnostic modules'. + format(self._name)) module_dir = os.path.join(FDP_DIR, 'modules', self._name) self._modules = [module for module in os.listdir(module_dir) - if os.path.isdir(os.path.join(module_dir, module)) and - module[0] is not '_'] + if os.path.isdir(os.path.join(module_dir, module)) and + module[0] is not '_'] return self._modules def addshot(self, shotlist=None, date=None, xp=None, verbose=False): @@ -274,7 +283,7 @@ def find(self, tag, obj=None): for signal in container._signals.values(): if signal._contains(tag): branch_str = '.'.join([signal._get_branch(), - signal._name]) + signal._name]) find_list.add(branch_str) if obj is None or obj.lower() == 'axis': for signal in container._signals.values(): @@ -282,7 +291,7 @@ def find(self, tag, obj=None): axis = getattr(signal, axis_str) if axis._contains(tag): branch_str = '.'.join([signal._get_branch(), - signal._name, axis._name]) + signal._name, axis._name]) find_list.add(branch_str) if obj is None or obj.lower() == 'container': if container._contains(tag): diff --git a/fdp/classes/node.py b/fdp/classes/node.py index 7f18925..d6b0d57 100755 --- a/fdp/classes/node.py +++ b/fdp/classes/node.py @@ -13,6 +13,7 @@ class Node(object): """ Node class """ + def __init__(self, element, parent=None): self._parent = parent self._name = element.get('name') diff --git a/fdp/classes/parse.py b/fdp/classes/parse.py index 4a55cc1..a8d9f41 100755 --- a/fdp/classes/parse.py +++ b/fdp/classes/parse.py @@ -11,7 +11,8 @@ def parse_method(obj, level=None): def debug(msg=''): - if VERBOSE: print('parse_method(): {}'.format(msg)) + if VERBOSE: + print('parse_method(): {}'.format(msg)) debug('begin') if level is 'top': # logic for initial parse of fdp/methods @@ -22,7 +23,7 @@ def debug(msg=''): # logic for parsing fdp/methods/ module = obj._name method_path = os.path.join(FDP_DIR, 'methods') - module_chain = 'methods.'+module + module_chain = 'methods.' + module else: # logic for parsing everything below fdp/methods/ branch = obj._get_branch() @@ -38,7 +39,8 @@ def debug(msg=''): debug('finding {}'.format(module_chain)) if os.path.exists(os.path.join(method_path, module)): debug('importing {}'.format(module_chain)) - method_object = __import__(module_chain, globals(), locals(), ['__file__'], 2) + method_object = __import__( + module_chain, globals(), locals(), ['__file__'], 2) if hasattr(method_object, '__all__') and method_object.__all__: debug('{}.__all__ exists'.format(module_chain)) for method in method_object.__all__: @@ -82,9 +84,11 @@ def fill_signal_dict(name=None, units=None, axes=None, '_empty': True, 'point_axes': []} + def parse_signal(obj, element): def debug(msg=''): - if VERBOSE: print('parse_signal(): {}'.format(msg)) + if VERBOSE: + print('parse_signal(): {}'.format(msg)) debug('begin with obj {} and element {}'. format(obj._name, element.get('name'))) units = parse_units(obj, element) @@ -124,14 +128,14 @@ def debug(msg=''): nameend = int(name_list[0]) else: start = int(number_list[0]) - end = int(number_list[1])+1 + end = int(number_list[1]) + 1 namestart = int(name_list[0]) - nameend = int(name_list[1])+1 + nameend = int(name_list[1]) + 1 signal_dict = [] - if len(name_list)==3: + if len(name_list) == 3: digits = int(name_list[2]) else: - digits = int(np.ceil(np.log10(end-1))) + digits = int(np.ceil(np.log10(end - 1))) for i, index in enumerate(range(start, end)): nrange = range(namestart, nameend) name = element.get('name').format(str(nrange[i]).zfill(digits)) diff --git a/fdp/classes/shot.py b/fdp/classes/shot.py index 201e718..7f8f319 100755 --- a/fdp/classes/shot.py +++ b/fdp/classes/shot.py @@ -16,7 +16,8 @@ class Shot(MutableMapping): def __init__(self, shot, root=None, parent=None): self.shot = shot - if VERBOSE: print(' s{}.__init__'.format(self.shot)) + if VERBOSE: + print(' s{}.__init__'.format(self.shot)) #self._shotobj = self self._root = root self._parent = parent @@ -28,11 +29,13 @@ def __init__(self, shot, root=None, parent=None): self._efits = [] def __getattr__(self, attribute): - if VERBOSE: print(' s{}.__getattr__({})'.format(self.shot, attribute)) + if VERBOSE: + print(' s{}.__getattr__({})'.format(self.shot, attribute)) if attribute in self._modules: if self._modules[attribute] is None: - if VERBOSE: print(' s{}.__getattr__({}) calling Factory()'. - format(self.shot, attribute)) + if VERBOSE: + print(' s{}.__getattr__({}) calling Factory()'. + format(self.shot, attribute)) self._modules[attribute] = container.Factory(attribute, root=self._root, shot=self.shot, @@ -66,7 +69,8 @@ def __delitem__(self, item): pass def __getitem__(self, item): - if VERBOSE: print(' s{}.__getitem__({})'.format(self.shot, item)) + if VERBOSE: + print(' s{}.__getitem__({})'.format(self.shot, item)) return self._modules[item] def __setitem__(self, item, value): @@ -132,4 +136,4 @@ def check_efit(self): if data and data is not '*': tree_exists.append(tree) self._efits = tree_exists - return self._efits \ No newline at end of file + return self._efits diff --git a/fdp/classes/signal.py b/fdp/classes/signal.py index e501d4f..dc026f8 100755 --- a/fdp/classes/signal.py +++ b/fdp/classes/signal.py @@ -75,11 +75,11 @@ def __array_finalize__(self, obj): print(' obj.axes is {}'.format(objaxes)) print(' obj._slic is {}'.format(objslic)) - for key,val in objdict.iteritems(): + for key, val in objdict.iteritems(): if objaxes and key in objaxes: # skip copy of axis attributes pass - elif key in ['axes','point_axes']: + elif key in ['axes', 'point_axes']: # shallow copy obj.axes and obj.point_axes setattr(self, key, val[:]) else: @@ -93,12 +93,12 @@ def __array_finalize__(self, obj): self.axes = obj.axes[::-1] _deltmpattr = True if objdict.get('_debug'): - _deltmpattr=False + _deltmpattr = False if objaxes: for axis in objaxes: if objslic: - #slice axis according to _slic + # slice axis according to _slic obj_axis = getattr(obj, axis) if type(objslic) is slice or type(objslic) is list: # logic for 1D arrays @@ -108,12 +108,12 @@ def __array_finalize__(self, obj): setattr(self, axis, obj_axis[objslic]) elif type(objslic) is tuple: # logic for multi-dim arrays - slic_axis=tuple([objslic[objaxes.index(axisaxis)] for - axisaxis in (obj_axis.axes + [axis])]) + slic_axis = tuple([objslic[objaxes.index(axisaxis)] for + axisaxis in (obj_axis.axes + [axis])]) if VERBOSE: print(' {}.__array_finalize__: slicing axis {} with {}'. format(self._name, axis, slic_axis)) - if isinstance(slic_axis[0], (int,long,float,np.generic)): + if isinstance(slic_axis[0], (int, long, float, np.generic)): if VERBOSE: print(' {}.__array_finalize__: single-point slice'. format(self._name)) @@ -121,8 +121,8 @@ def __array_finalize__(self, obj): if axis in self.point_axes: raise FdpError('Point axis already present') self.point_axes.append({'axis': axis, - 'value': obj_axis[slic_axis], - 'units': obj_axis.units}) + 'value': obj_axis[slic_axis], + 'units': obj_axis.units}) self.axes.remove(axis) elif isinstance(slic_axis[0], slice): setattr(self, axis, obj_axis[slic_axis]) @@ -159,22 +159,22 @@ def __array_finalize__(self, obj): # setattr(self, 'axes', axes) # end "if objaxes" block - #clean-up temp attributes - def delattrtry(ob,at): + # clean-up temp attributes + def delattrtry(ob, at): try: - delattr(ob,at) + delattr(ob, at) except: pass if _deltmpattr: - delattrtry(self,'_slic') - delattrtry(self,'_fname') - delattrtry(self,'_fargs') - delattrtry(self,'_fkwargs') - delattrtry(obj,'_slic') - delattrtry(obj,'_fname') - delattrtry(obj,'_fargs') - delattrtry(obj,'_fkwargs') + delattrtry(self, '_slic') + delattrtry(self, '_fname') + delattrtry(self, '_fargs') + delattrtry(self, '_fkwargs') + delattrtry(obj, '_slic') + delattrtry(obj, '_fname') + delattrtry(obj, '_fargs') + delattrtry(obj, '_fkwargs') if VERBOSE: print(' {}.__array_finalize__: END'. @@ -200,8 +200,7 @@ def __array_prepare__(self, out_arr, context=None): #print('__array_prepare__: context is %s' % context) return np.ndarray.__array_prepare__(self, out_arr, context) - - def __getitem__(self,index): + def __getitem__(self, index): ''' self must be Signal class for this to be called, so therefore must have the _slic attribute. The _slic attribute preserves indexing for attributes @@ -215,60 +214,62 @@ def __getitem__(self,index): #print(' {}.__getitem__: self.shape is {}'.format(self._name, self.shape)) #print(' {}.__getitem__: type(index) is {}'.format(self._name, type(index))) - #This passes index to array_finalize after a new signal obj is created to assign axes + # This passes index to array_finalize after a new signal obj is created + # to assign axes def parseindex(index, dims): - #format index to account for single elements and pad with appropriate slices. - #int2slc=lambda i: slice(-1,-2,-1) if int(i) == -1 else slice(int(i),int(i)+1) - if VERBOSE: - print(' {}.__getitem__.parseindex(): BEGIN with index {} and dims {}'. - format(self._name, index, dims)) - if isinstance(index, (list, slice, np.ndarray)): - # index is list, slice, or ndarray - if VERBOSE: - print(' {}.__getitem__.parseindex(): index is list|slice|ndarray'. - format(self._name)) - if dims < 2: - if VERBOSE: - print(' {}.__getitem__.parseindex(): ndim < 2 and returning'. - format(self._name)) - return index - else: - if VERBOSE: - print(' {}.__getitem__.parseindex(): ndim >= 2'. - format(self._name)) - newindex=[index] - elif isinstance(index, (int, long, float, np.generic)): - if VERBOSE: - print(' {}.__getitem__.parseindex(): index is int|long|float|generic'. - format(self._name)) - newindex = [int(index)] - elif isinstance(index, tuple): - if VERBOSE: - print(' {}.__getitem__.parseindex(): index is tuple'. - format(self._name)) - newindex = [int(i) if isinstance(i, (int, long, float, np.generic)) - else i for i in index] - # check for ellipses in newindex - ellipsisbool=[Ellipsis is i for i in newindex] - if sum(ellipsisbool) > 0: - # elipses exists - ellipsisindex = ellipsisbool.index(True) - slcpadding = ([slice(None)]*(dims-len(newindex)+1)) - newindex = newindex[:ellipsisindex] \ - + slcpadding \ - + newindex[ellipsisindex+1:] - else: - # no elipses - newindex = newindex + ([slice(None)]*(dims-len(newindex))) - if VERBOSE: - print(' {}.__getitem__.parseindex(): END with newindex {}'. - format(self._name, newindex)) - return tuple(newindex) + # format index to account for single elements and pad with appropriate slices. + #int2slc=lambda i: slice(-1,-2,-1) if int(i) == -1 else slice(int(i),int(i)+1) + if VERBOSE: + print(' {}.__getitem__.parseindex(): BEGIN with index {} and dims {}'. + format(self._name, index, dims)) + if isinstance(index, (list, slice, np.ndarray)): + # index is list, slice, or ndarray + if VERBOSE: + print(' {}.__getitem__.parseindex(): index is list|slice|ndarray'. + format(self._name)) + if dims < 2: + if VERBOSE: + print(' {}.__getitem__.parseindex(): ndim < 2 and returning'. + format(self._name)) + return index + else: + if VERBOSE: + print(' {}.__getitem__.parseindex(): ndim >= 2'. + format(self._name)) + newindex = [index] + elif isinstance(index, (int, long, float, np.generic)): + if VERBOSE: + print(' {}.__getitem__.parseindex(): index is int|long|float|generic'. + format(self._name)) + newindex = [int(index)] + elif isinstance(index, tuple): + if VERBOSE: + print(' {}.__getitem__.parseindex(): index is tuple'. + format(self._name)) + newindex = [int(i) if isinstance(i, (int, long, float, np.generic)) + else i for i in index] + # check for ellipses in newindex + ellipsisbool = [Ellipsis is i for i in newindex] + if sum(ellipsisbool) > 0: + # elipses exists + ellipsisindex = ellipsisbool.index(True) + slcpadding = ([slice(None)] * (dims - len(newindex) + 1)) + newindex = newindex[:ellipsisindex] \ + + slcpadding \ + + newindex[ellipsisindex + 1:] + else: + # no elipses + newindex = newindex + ([slice(None)] * (dims - len(newindex))) + if VERBOSE: + print(' {}.__getitem__.parseindex(): END with newindex {}'. + format(self._name, newindex)) + return tuple(newindex) slcindex = parseindex(index, self.ndim) self._slic = slcindex if VERBOSE: - print(' {}.__getitem__: slcindex is {}'.format(self._name, slcindex)) + print(' {}.__getitem__: slcindex is {}'.format( + self._name, slcindex)) if self._empty is True: self._get_mdsdata() @@ -279,17 +280,19 @@ def parseindex(index, dims): format(self._name)) # super().__getitem__() calls __array_finalize__() - return super(Signal,self).__getitem__(slcindex) + return super(Signal, self).__getitem__(slcindex) def _get_mdsdata(self): if self._empty is True: # get MDSplus data - if VERBOSE: print(' {}._get_mdsdata: BEGIN'.format(self._name)) + if VERBOSE: + print(' {}._get_mdsdata: BEGIN'.format(self._name)) data = self._root._get_mdsdata(self) self.resize(data.shape, refcheck=False) self[:] = data - if VERBOSE: print(' {}._get_mdsdata: END'.format(self._name)) - self._empty=False + if VERBOSE: + print(' {}._get_mdsdata: END'.format(self._name)) + self._empty = False def __getattr__(self, attribute): if attribute is '_parent' or self._parent is None: @@ -308,7 +311,7 @@ def __repr__(self): self._get_mdsdata() if VERBOSE: print(' {}.__repr__ CALLING SUPER()'.format(self._name)) - return super(Signal,self).__repr__() + return super(Signal, self).__repr__() def __str__(self): if VERBOSE: @@ -317,7 +320,7 @@ def __str__(self): self._get_mdsdata() if VERBOSE: print(' {}.__str__ CALLING SUPER()'.format(self._name)) - return super(Signal,self).__str__() + return super(Signal, self).__str__() def __getslice__(self, start, stop): """ @@ -349,11 +352,11 @@ def __call__(self, **kwargs): axis = self.axes.index(kwarg) axis_value = getattr(self, kwarg) try: - axis_inds = [np.abs(value-axis_value[:]).argmin() + axis_inds = [np.abs(value - axis_value[:]).argmin() for value in values] slc[axis] = slice(axis_inds[0], axis_inds[1]) except TypeError: - axis_ind = np.abs(values-axis_value[:]).argmin() + axis_ind = np.abs(values - axis_value[:]).argmin() #axis_inds = [axis_ind, axis_ind+1] slc[axis] = axis_ind return self[tuple(slc)] @@ -364,20 +367,19 @@ def __nonzero__(self): def sigwrapper(f): def inner(*args, **kwargs): #print("getarg decorator: Function {} arguments were: {}, {}".format(f.__name__,args, kwargs)) - args[0]._fname=f.__name__ - if len(args)>1: args[0]._fargs=args[1:] - args[0]._fkwargs=kwargs + args[0]._fname = f.__name__ + if len(args) > 1: + args[0]._fargs = args[1:] + args[0]._fkwargs = kwargs return f(*args, **kwargs) return inner @sigwrapper def amin(self, *args, **kwargs): - args[0]._fname=f.__name__ - args[0]._fkwargs=kwargs - return super(Signal,self).amin(*args, **kwargs) + args[0]._fname = f.__name__ + args[0]._fkwargs = kwargs + return super(Signal, self).amin(*args, **kwargs) @sigwrapper def transpose(self, *args, **kwargs): - return super(Signal,self).transpose(*args, **kwargs) - - + return super(Signal, self).transpose(*args, **kwargs) diff --git a/fdp/classes/utilities.py b/fdp/classes/utilities.py index 82036f6..b755fb8 100644 --- a/fdp/classes/utilities.py +++ b/fdp/classes/utilities.py @@ -2,14 +2,18 @@ from . import container, signal, shot + def isContainer(obj): return issubclass(type(obj), container.Container) and 'Container' in str(type(obj)) + def isSignal(obj): return issubclass(type(obj), signal.Signal) and 'Signal' in str(type(obj)) + def isAxis(obj): return issubclass(type(obj), signal.Signal) and 'Axis' in str(type(obj)) + def isShot(obj): - return issubclass(type(obj), shot.Shot) and 'Shot' in str(type(obj)) \ No newline at end of file + return issubclass(type(obj), shot.Shot) and 'Shot' in str(type(obj)) diff --git a/fdp/methods/_netcat.py b/fdp/methods/_netcat.py index 653da96..7075614 100644 --- a/fdp/methods/_netcat.py +++ b/fdp/methods/_netcat.py @@ -7,6 +7,7 @@ import socket + def _netcat(self, hostname, port, content): s = socket.socket(socket.AF_INET, socket.SOCK_STREAM) s.connect((hostname, port)) diff --git a/fdp/methods/check_efit.py b/fdp/methods/check_efit.py index 16c9c84..e27f321 100644 --- a/fdp/methods/check_efit.py +++ b/fdp/methods/check_efit.py @@ -4,4 +4,3 @@ @author: drsmith """ - diff --git a/fdp/methods/currentshot.py b/fdp/methods/currentshot.py index 8fe620d..5d78f3a 100644 --- a/fdp/methods/currentshot.py +++ b/fdp/methods/currentshot.py @@ -5,5 +5,6 @@ @author: ktritz """ + def currentshot(self): return self._connections[0].get('current_shot("nstx")').value diff --git a/fdp/methods/fft.py b/fdp/methods/fft.py index be104af..218ccf8 100644 --- a/fdp/methods/fft.py +++ b/fdp/methods/fft.py @@ -14,6 +14,7 @@ from ..classes.fft import Fft from .listmethods import listSignals + def fft(obj, *args, **kwargs): """ Calculate FFT(s) for signal or container. @@ -30,6 +31,7 @@ def fft(obj, *args, **kwargs): ffts.append(Fft(signal, *args, **kwargs)) return ffts + def plotfft(signal, fmax=None, *args, **kwargs): """ Plot spectrogram @@ -39,24 +41,24 @@ def plotfft(signal, fmax=None, *args, **kwargs): return sigfft = fft(signal, *args, **kwargs) fig = plt.figure() - ax = fig.add_subplot(1,1,1) + ax = fig.add_subplot(1, 1, 1) pcm = ax.pcolormesh(sigfft.time, sigfft.freq, sigfft.logpsd.transpose(), cmap=plt.cm.YlGnBu) - pcm.set_clim([sigfft.logpsd.max()-100, sigfft.logpsd.max()-20]) + pcm.set_clim([sigfft.logpsd.max() - 100, sigfft.logpsd.max() - 20]) cb = plt.colorbar(pcm, ax=ax) cb.set_label(r'$10\,\log_{10}(|FFT|^2)$ $(V^2/Hz)$') ax.set_xlabel('Time (s)') ax.set_ylabel('Frequency (kHz)') tmin = kwargs.get('tmin', 0) tmax = kwargs.get('tmax', 2) - ax.set_xlim([tmin,tmax]) + ax.set_xlim([tmin, tmax]) if fmax: if sigfft.iscomplexsignal: - ax.set_ylim([-fmax,fmax]) + ax.set_ylim([-fmax, fmax]) else: - ax.set_ylim([0,fmax]) + ax.set_ylim([0, fmax]) ax.set_title('{} | {} | {}'.format( sigfft.shot, sigfft.parentname.upper(), diff --git a/fdp/methods/info.py b/fdp/methods/info.py index c1c1651..88438bc 100644 --- a/fdp/methods/info.py +++ b/fdp/methods/info.py @@ -5,17 +5,21 @@ @author: drsmith """ -from ..classes import utilities +from ..classes import utilities + def isSignal(obj): return utilities.isSignal(obj) + def isContainer(obj): return utilities.isContainer(obj) + def isAxis(obj): return utilities.isAxis(obj) + def info(obj, *args, **kwargs): if utilities.isSignal(obj): infoSignal(obj, *args, **kwargs) diff --git a/fdp/methods/listmethods.py b/fdp/methods/listmethods.py index 906da54..c0c6dc3 100644 --- a/fdp/methods/listmethods.py +++ b/fdp/methods/listmethods.py @@ -17,6 +17,7 @@ def listSignals(obj): signals.append(attrname) return signals + def listContainers(obj): attrnames = dir(obj) containers = [] @@ -26,6 +27,7 @@ def listContainers(obj): containers.append(attrname) return containers + def listMethods(obj): methods = [] while True: @@ -41,14 +43,14 @@ def listMethods(obj): break return methods + def listAttributes(obj): attrnames = dir(obj) attributes = [] for attrname in attrnames: attr = getattr(obj, attrname) if not isContainer(attr) and \ - not isSignal(attr) and \ - not hasattr(attr, '__func__'): - attributes.append(attrname) + not isSignal(attr) and \ + not hasattr(attr, '__func__'): + attributes.append(attrname) return attributes - diff --git a/fdp/methods/logbook.py b/fdp/methods/logbook.py index 16c9c84..e27f321 100644 --- a/fdp/methods/logbook.py +++ b/fdp/methods/logbook.py @@ -4,4 +4,3 @@ @author: drsmith """ - diff --git a/fdp/methods/nstxu/__init__.py b/fdp/methods/nstxu/__init__.py index fd93ad1..a6f4b69 100644 --- a/fdp/methods/nstxu/__init__.py +++ b/fdp/methods/nstxu/__init__.py @@ -4,4 +4,3 @@ @author: ktritz """ - diff --git a/fdp/methods/nstxu/bes/__init__.py b/fdp/methods/nstxu/bes/__init__.py index d339fe7..034590d 100644 --- a/fdp/methods/nstxu/bes/__init__.py +++ b/fdp/methods/nstxu/bes/__init__.py @@ -26,5 +26,5 @@ __all__ = ['fft', 'plotfft', 'powerspectrum', 'animate', 'loadConfig', 'movie', 'gui', - 'crosssignal','plotcrosspower', 'plotcoherence', 'plotcrossphase', + 'crosssignal', 'plotcrosspower', 'plotcoherence', 'plotcrossphase', 'plotcorrelation'] diff --git a/fdp/methods/nstxu/bes/animation.py b/fdp/methods/nstxu/bes/animation.py index 4ac2ed2..9f8fe71 100644 --- a/fdp/methods/nstxu/bes/animation.py +++ b/fdp/methods/nstxu/bes/animation.py @@ -16,6 +16,7 @@ from ....classes.fdp_globals import FdpError from ....classes.utilities import isContainer + def animate(*args, **kwargs): """Plot 2D signals""" return Animation(*args, **kwargs) @@ -29,15 +30,15 @@ def __init__(self, container, tmin=0.0, tmax=5.0, savemovie=False, hightimeres=False, - saveeps = False): + saveeps=False): if not isContainer(container): raise FdpError("Use at container level, not signal level") self.container = container - if tmax>10: + if tmax > 10: # if tmax large, assume ms input and convert to s - tmin = tmin/1e3 - tmax = tmax/1e3 + tmin = tmin / 1e3 + tmax = tmax / 1e3 self.tmin = tmin self.tmax = tmax self.hightimeres = hightimeres @@ -63,7 +64,7 @@ def __init__(self, container, self.loadData() self.applyNormalization() self.filterData() - #self.gridData() + # self.gridData() self.makeAnimation() if self.savemovie: self.saveAnimationVideo() @@ -77,59 +78,63 @@ def loadConfig(self): def setTimeIndices(self): time = self.signals[0].time self.shot = self.signals[0].shot - time_indices = np.where(np.logical_and(time>=self.tmin, - time<=self.tmax))[0] + time_indices = np.where(np.logical_and(time >= self.tmin, + time <= self.tmax))[0] self.istart = time_indices[0] - self.istop = time_indices[time_indices.size-1] + self.istop = time_indices[time_indices.size - 1] - self.time = time[self.istart:self.istop+1] + self.time = time[self.istart:self.istop + 1] self.ntime = self.time.size print('Data points: {}'.format(self.ntime)) def loadData(self): - self.data = np.ones((7,9,self.ntime))*(-1) - self.datamask = np.zeros((7,9),dtype=bool) + self.data = np.ones((7, 9, self.ntime)) * (-1) + self.datamask = np.zeros((7, 9), dtype=bool) for signal in self.signals: if not hasattr(signal, 'row'): continue row = signal.row column = signal.column zerosignal = np.mean(signal[0:1e3]) - self.data[row-1,column-1,:] = signal[self.istart:self.istop+1] - zerosignal + self.data[row - 1, column - 1, + :] = signal[self.istart:self.istop + 1] - zerosignal #self.data[row-1,column-1,:] = signal[self.istart:self.istop+1] - self.datamask[row-1,column-1] = True + self.datamask[row - 1, column - 1] = True def applyNormalization(self): - nrow,ncol,_ = self.data.shape + nrow, ncol, _ = self.data.shape # column-wise normalization factor self.colcal = np.zeros((ncol,)) for col in np.arange(ncol): - rowmask = self.datamask[:,col] + rowmask = self.datamask[:, col] if not rowmask.any(): continue - self.colcal[col] = np.mean(self.data[rowmask.nonzero(),col,0:self.ntime/20]) + self.colcal[col] = np.mean( + self.data[rowmask.nonzero(), col, 0:self.ntime / 20]) # boxcar filter column-wise normalization factor tmp = self.colcal.copy() for col in np.arange(ncol): - if col==0 or col==ncol-1: + if col == 0 or col == ncol - 1: continue - d = self.colcal[col-1:col+2] - if np.count_nonzero(d)!=3: + d = self.colcal[col - 1:col + 2] + if np.count_nonzero(d) != 3: continue tmp[col] = np.mean(d) self.colcal = tmp.copy() # apply normalization to data array for row in np.arange(nrow): for col in np.arange(ncol): - if self.datamask[row,col]: - self.data[row,col,:] = self.data[row,col,:] * self.colcal[col] / np.mean(self.data[row,col,0:self.ntime/20]) + if self.datamask[row, col]: + self.data[row, col, :] = self.data[row, col, :] * \ + self.colcal[col] / \ + np.mean(self.data[row, col, 0:self.ntime / 20]) def filterData(self): self.filter = scipy.signal.daub(4) - self.filter = self.filter/np.sum(self.filter) + self.filter = self.filter / np.sum(self.filter) self.fdata = scipy.signal.lfilter(self.filter, [1], - self.data, - axis=2) + self.data, + axis=2) #self.fdata = scipy.signal.decimate(self.fdata, 2, axis=2) #self.ftime = self.time[::2] self.ftime = self.time @@ -137,34 +142,33 @@ def filterData(self): def gridData(self): nrad = 9 npol = 7 - rgrid = np.arange(1,nrad+1) - pgrid = np.arange(1,npol+1) - rr,pp = np.meshgrid(rgrid, pgrid) + rgrid = np.arange(1, nrad + 1) + pgrid = np.arange(1, npol + 1) + rr, pp = np.meshgrid(rgrid, pgrid) print(pp.shape) - rnew = np.arange(0.5,nrad+0.51,0.25) - pnew = np.arange(0.5,npol+0.51,0.25) - self.gdata = np.zeros((pnew.size,rnew.size,self.ftime.size)) + rnew = np.arange(0.5, nrad + 0.51, 0.25) + pnew = np.arange(0.5, npol + 0.51, 0.25) + self.gdata = np.zeros((pnew.size, rnew.size, self.ftime.size)) print('starting interpolation') for i in np.arange(self.ftime.size): - if i!=0 and np.mod(i+1,100)==0: - print(' frame {} of {}'.format(i+1,self.ftime.size)) + if i != 0 and np.mod(i + 1, 100) == 0: + print(' frame {} of {}'.format(i + 1, self.ftime.size)) f = scipy.interpolate.interp2d(rr, pp, - self.fdata[:,:,i].squeeze(), + self.fdata[:, :, i].squeeze(), kind='linear') - self.gdata[:,:,i] = f(rnew,pnew) - + self.gdata[:, :, i] = f(rnew, pnew) def plotContourf(self, axes=None, index=None): - return axes.contourf(np.arange(1,10.1), - np.arange(1,8.1), - self.fdata[::-1,:,index], + return axes.contourf(np.arange(1, 10.1), + np.arange(1, 8.1), + self.fdata[::-1, :, index], cmap=plt.cm.YlGnBu) def plotPColorMesh(self, axes=None, index=None): - return axes.pcolormesh(np.arange(1,10.1), - np.arange(1,8.1), - self.fdata[::-1,:,index], + return axes.pcolormesh(np.arange(1, 10.1), + np.arange(1, 8.1), + self.fdata[::-1, :, index], cmap=plt.cm.YlGnBu) def makeAnimation(self): @@ -173,70 +177,70 @@ def makeAnimation(self): frameint = 2 else: frameint = 40 - nframes = np.int(self.ftime.size/frameint) - self.fig = plt.figure(figsize=(6.4,7)) - ax1 = self.fig.add_subplot(2,1,1) + nframes = np.int(self.ftime.size / frameint) + self.fig = plt.figure(figsize=(6.4, 7)) + ax1 = self.fig.add_subplot(2, 1, 1) ax1.set_xlabel('Radial channels') ax1.set_ylabel('Poloidal channels') ax1.set_aspect('equal') - ax2 = self.fig.add_subplot(2,1,2) - ax2.set_xlim(np.array([self.tmin,self.tmax])*1e3) + ax2 = self.fig.add_subplot(2, 1, 2) + ax2.set_xlim(np.array([self.tmin, self.tmax]) * 1e3) ax2.set_xlabel('Time (ms)') ax2.set_ylabel('Signal (V)') self.fig.subplots_adjust(hspace=0.38) print('starting frame loop with {} frames'.format(nframes)) clim = [np.amin(self.fdata), np.amax(self.fdata)] for i in np.arange(nframes): - if i!=0 and np.mod(i+1,20)==0: - print(' frame {} of {}'.format(i+1,nframes)) + if i != 0 and np.mod(i + 1, 20) == 0: + print(' frame {} of {}'.format(i + 1, nframes)) #im = self.plotContourf(axes=ax1, index=i*frameint) - im = self.plotPColorMesh(axes=ax1, index=i*frameint) + im = self.plotPColorMesh(axes=ax1, index=i * frameint) im.set_clim(clim) - if i==0: + if i == 0: cb = plt.colorbar(im, ax=ax1) cb.set_label('Signal (V)') cb.draw_all() - pt = ax2.plot(self.ftime*1e3, self.fdata[0,1,:], 'b', - self.ftime*1e3, self.fdata[4,1,:], 'g', - self.ftime*1e3, self.fdata[0,6,:], 'c', - self.ftime*1e3, self.fdata[5,6,:], 'm') + pt = ax2.plot(self.ftime * 1e3, self.fdata[0, 1, :], 'b', + self.ftime * 1e3, self.fdata[4, 1, :], 'g', + self.ftime * 1e3, self.fdata[0, 6, :], 'c', + self.ftime * 1e3, self.fdata[5, 6, :], 'm') ax2.get_xaxis().get_major_formatter().set_useOffset(False) ax1_title = ax1.annotate('BES | {} | t={:.3f} ms'.format( self.shot, - self.ftime[i*frameint]*1e3), + self.ftime[i * frameint] * 1e3), xy=(0.5, 1.04), xycoords='axes fraction', - horizontalalignment ='center', + horizontalalignment='center', size='large') - ln = ax2.plot(np.ones(2)*self.ftime[i*frameint]*1e3, + ln = ax2.plot(np.ones(2) * self.ftime[i * frameint] * 1e3, ax2.get_ylim(), 'r') an_l0 = ax2.annotate('Core Top', - xy=(self.ftime[0]*1e3+0.01, - self.fdata[0,1,15]+0.6), - color='b') + xy=(self.ftime[0] * 1e3 + 0.01, + self.fdata[0, 1, 15] + 0.6), + color='b') an_l1 = ax2.annotate('Core Bottom', - xy=(self.ftime[0]*1e3+0.01, - self.fdata[4,1,15]-0.6), - color='g') + xy=(self.ftime[0] * 1e3 + 0.01, + self.fdata[4, 1, 15] - 0.6), + color='g') an_l2 = ax2.annotate('SOL Top', - xy=(self.ftime[0]*1e3+0.01, - self.fdata[0,6,15]+0.6), - color='c') + xy=(self.ftime[0] * 1e3 + 0.01, + self.fdata[0, 6, 15] + 0.6), + color='c') an_l3 = ax2.annotate('SOL Bottom', - xy=(self.ftime[0]*1e3+0.01, - self.fdata[5,6,15]-0.6), - color='m') + xy=(self.ftime[0] * 1e3 + 0.01, + self.fdata[5, 6, 15] - 0.6), + color='m') ax2_title = ax2.annotate('BES | {}'.format(self.shot), - xy=(0.5, 1.04), - xycoords='axes fraction', - horizontalalignment ='center', - size='large') + xy=(0.5, 1.04), + xycoords='axes fraction', + horizontalalignment='center', + size='large') plt.draw() if self.saveeps: filename = 'Bes2d_{}_{}.eps'.format( - self.shot, - np.int(self.ftime[i*frameint]*1e7)) + self.shot, + np.int(self.ftime[i * frameint] * 1e7)) self.fig.savefig(filename, format='eps', transparent=True) ax1.cla() ax2.cla() @@ -245,9 +249,9 @@ def makeAnimation(self): an_l0, an_l1, an_l2, an_l3, ax2_title] gc.disable() # disable garbage collection to keep list appends fast if hasattr(im, 'collections'): - ims.append(im.collections+artists) + ims.append(im.collections + artists) else: - ims.append([im]+artists) + ims.append([im] + artists) gc.enable() if self.savemovie: @@ -261,8 +265,7 @@ def saveAnimationVideo(self): print('calling ArtistAnimation.save()') filename = 'Bes2d_{}_{}ms.mp4'.format( self.shot, - np.int(self.tmin*1e3)) + np.int(self.tmin * 1e3)) writer = animation.FFMpegWriter(fps=30, bitrate=1e5) self.animation.save(filename, writer=writer) - diff --git a/fdp/methods/nstxu/bes/configuration.py b/fdp/methods/nstxu/bes/configuration.py index b5ad7a2..04bb642 100644 --- a/fdp/methods/nstxu/bes/configuration.py +++ b/fdp/methods/nstxu/bes/configuration.py @@ -13,28 +13,30 @@ from ....classes.utilities import isContainer from ....classes.fdp_globals import FdpWarning + def loadConfig(container=None): """ """ if not isContainer(container): - raise FdpError("loadConfig() is a BES container method, not signal method") + raise FdpError( + "loadConfig() is a BES container method, not signal method") config_file = os.path.join(os.path.dirname(__file__), 'configuration.xml') tree = ET.parse(config_file) root = tree.getroot() shot = container.shot configname = None for shotrange in root: - if shotrange.tag=='shotrange': + if shotrange.tag == 'shotrange': start = int(shotrange.attrib['start']) stop = int(shotrange.attrib['stop']) - if shot>=start and shot<=stop: + if shot >= start and shot <= stop: configname = shotrange.attrib['config'] break if configname is None: warn("Invalid shot for configuration", FdpWarning) return for config in root: - if config.tag=='config' and config.attrib['name']==configname: + if config.tag == 'config' and config.attrib['name'] == configname: for channel in config: signal = getattr(container, channel.attrib['name']) signal.row = int(channel.attrib['row']) diff --git a/fdp/methods/nstxu/bes/crosspower.py b/fdp/methods/nstxu/bes/crosspower.py index 7d6fa95..60e4242 100644 --- a/fdp/methods/nstxu/bes/crosspower.py +++ b/fdp/methods/nstxu/bes/crosspower.py @@ -16,10 +16,10 @@ def crosssignal(container, sig1name='ch01', sig2name='ch02', - tmin=0.5, tmax=0.55, window='hann', nperseg=None, - forcepower2=False, offsetminimum=True, offsetdc=False, - normalizetodc=True, degrees=True, fmin=None, fmax=None, - numfilttaps=None, removesawteeth=False): + tmin=0.5, tmax=0.55, window='hann', nperseg=None, + forcepower2=False, offsetminimum=True, offsetdc=False, + normalizetodc=True, degrees=True, fmin=None, fmax=None, + numfilttaps=None, removesawteeth=False): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return @@ -49,43 +49,44 @@ def plotcrosspower(container, *args, **kwargs): mask = np.logical_and(fmin <= cs.freqs, cs.freqs <= fmax) if spectrum: - logcrosspower = 10*np.log10(cs.crosspower[mask,:]) + logcrosspower = 10 * np.log10(cs.crosspower[mask, :]) fig = plt.figure() ax = fig.add_subplot(111) pcm = ax.pcolormesh(cs.times, - cs.freqs[mask], - logcrosspower, - cmap=plt.cm.YlGnBu) - pcm.set_clim([logcrosspower.max()-100, logcrosspower.max()-20]) + cs.freqs[mask], + logcrosspower, + cmap=plt.cm.YlGnBu) + pcm.set_clim([logcrosspower.max() - 100, logcrosspower.max() - 20]) cb = plt.colorbar(pcm, ax=ax) cb.set_label(r'$10\,\log_{10}(Crosspower)$ $(V^2/Hz)$') ax.set_xlabel('Time (s)') ax.set_ylabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Crosspower'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) else: crosspower = cs.crosspower_binavg[mask] stdev = cs.crosspower_error[mask] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(cs.freqs[mask], crosspower, 'k-') - ax.fill_between(cs.freqs[mask], crosspower-stdev, - crosspower+stdev, alpha=0.5, linewidth=0, + ax.fill_between(cs.freqs[mask], crosspower - stdev, + crosspower + stdev, alpha=0.5, linewidth=0, facecolor='black') ax.set_yscale('log') ax.set_xlabel('Frequency (kHz)') ax.set_ylabel(r'$10\,\log_{10}(Crosspower)$ $(V^2/Hz)$') ax.set_title('{} -- {} -- {}/{} -- Crosspower'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) plt.tight_layout() return cs + def plotcrossphase(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) @@ -107,42 +108,43 @@ def plotcrossphase(container, *args, **kwargs): mask = np.logical_and(fmin <= cs.freqs, cs.freqs <= fmax) if spectrum: - crossphase = cs.crossphase[mask,:] + crossphase = cs.crossphase[mask, :] fig = plt.figure() ax = fig.add_subplot(111) pcm = ax.pcolormesh(cs.times, - cs.freqs[mask], - crossphase, - cmap=plt.cm.RdBu) + cs.freqs[mask], + crossphase, + cmap=plt.cm.RdBu) pcm.set_clim([-50, 300]) cb = plt.colorbar(pcm, ax=ax) cb.set_label(r'Angle (' + units + ')') - ax.set_ylim([fmin,fmax]) + ax.set_ylim([fmin, fmax]) ax.set_xlabel('Time (s)') ax.set_ylabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Crossphase'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) else: crossphase = cs.crossphase_binavg[mask] stdev = cs.crossphase_error[mask] fig = plt.figure() ax = fig.add_subplot(111) ax.plot(cs.freqs[mask], crossphase, 'k-') - ax.fill_between(cs.freqs[mask], crossphase-stdev, crossphase+stdev, + ax.fill_between(cs.freqs[mask], crossphase - stdev, crossphase + stdev, alpha=0.5, linewidth=0, facecolor='black') ax.set_xlabel('Frequency (kHz)') ax.set_ylabel('Angle (' + units + ')') ax.set_title('{} -- {} -- {}/{} -- Crossphase'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) plt.tight_layout() return cs + def plotcoherence(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) @@ -161,23 +163,26 @@ def plotcoherence(container, *args, **kwargs): fig = plt.figure() ax = fig.add_subplot(111) ax.plot(cs.freqs[mask], coherence, 'k-') - ax.plot((fmin, fmax),(cs.minsig_coherence, cs.minsig_coherence), 'k--') - ax.fill_between(cs.freqs[mask], coherence-stdev, coherence+stdev, + ax.plot((fmin, fmax), (cs.minsig_coherence, cs.minsig_coherence), 'k--') + ax.fill_between(cs.freqs[mask], coherence - stdev, coherence + stdev, alpha=0.5, linewidth=0, facecolor='black') - ax.set_ylim([0,1]) + ax.set_ylim([0, 1]) ax.set_xlabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Coherence'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) -<<<<<<< HEAD + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) + -======= +<< << << < HEAD + +== == == = plt.tight_layout() ->>>>>>> master +>>>>>> > master return cs + def plotcorrelation(container, *args, **kwargs): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) @@ -188,16 +193,16 @@ def plotcorrelation(container, *args, **kwargs): ax = fig.add_subplot(111) if envelope: ax.plot(cs.time_delays * 1000000., cs.correlation_coef_envelope, 'k-') - ax.plot((0,0),(0,1), 'k-') + ax.plot((0, 0), (0, 1), 'k-') else: ax.plot(cs.time_delays * 1000000., cs.correlation_coef, 'k-') - ax.plot((0,0),(-1,1), 'k-') - ax.set_xlim([-250,250]) + ax.plot((0, 0), (-1, 1), 'k-') + ax.set_xlim([-250, 250]) ax.set_xlabel('Time delay (us)') ax.set_title('{} -- {} -- {}/{} -- Time-lag cross-correlation'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) plt.tight_layout() - return cs \ No newline at end of file + return cs diff --git a/fdp/methods/nstxu/bes/fft.py b/fdp/methods/nstxu/bes/fft.py index 8e87259..043297f 100644 --- a/fdp/methods/nstxu/bes/fft.py +++ b/fdp/methods/nstxu/bes/fft.py @@ -50,7 +50,7 @@ def plotfft(signal, fmax=None, *args, **kwargs): sigfft.freq, sigfft.logpsd.transpose(), cmap=plt.cm.YlGnBu) - pcm.set_clim([sigfft.logpsd.max()-100, sigfft.logpsd.max()-20]) + pcm.set_clim([sigfft.logpsd.max() - 100, sigfft.logpsd.max() - 20]) cb = plt.colorbar(pcm, ax=ax) cb.set_label(r'$10\,\log_{10}(|FFT|^2)$ $(V^2/Hz)$') ax.set_xlabel('Time (s)') @@ -86,7 +86,7 @@ def powerspectrum(signal, fmax=None, *args, **kwargs): sigfft = fft(signal, *args, **kwargs) psd = np.square(np.absolute(sigfft.fft)) # bin-averaged PSD, in dB - sigfft.bapsd = 10*np.log10(np.mean(psd, axis=0)) + sigfft.bapsd = 10 * np.log10(np.mean(psd, axis=0)) fig = plt.figure() ax = fig.add_subplot(1, 1, 1) ax.plot(sigfft.freq, sigfft.bapsd) diff --git a/fdp/methods/nstxu/bes/gui.py b/fdp/methods/nstxu/bes/gui.py index 1f6f471..3478eb4 100644 --- a/fdp/methods/nstxu/bes/gui.py +++ b/fdp/methods/nstxu/bes/gui.py @@ -18,7 +18,7 @@ def plotObject(self): channels = ['ch01', 'ch09', 'ch17', 'ch25', 'ch33', 'ch41'] for i, channel in enumerate(channels): - ax = self.figure.add_subplot(2, 3, i+1) + ax = self.figure.add_subplot(2, 3, i + 1) ch = getattr(self.obj, channel) ch.plot(fig=self.figure, ax=ax) self.canvas.show() diff --git a/fdp/methods/nstxu/bes/movie.py b/fdp/methods/nstxu/bes/movie.py index c88a311..d6cedb9 100644 --- a/fdp/methods/nstxu/bes/movie.py +++ b/fdp/methods/nstxu/bes/movie.py @@ -17,221 +17,224 @@ from fdp.classes.utilities import isContainer from . import utilities as UT + def movie(*args, **kwargs): """Plot 2D signals""" return Movie(*args, **kwargs) - + class Movie(object): """ """ - - def __init__(self, container, + + def __init__(self, container, tmin=0.0, tmax=5.0, savemovie=False, hightimeres=False): - + if not isContainer(container): raise FdpError("Use at container level, not signal level") self.container = container - if tmax>10: + if tmax > 10: # if tmax large, assume ms input and convert to s - tmin = tmin/1e3 - tmax = tmax/1e3 + tmin = tmin / 1e3 + tmax = tmax / 1e3 self.tmin = tmin self.tmax = tmax self.hightimeres = hightimeres - + self.signals = None self.data = None self.time = None self.istart = None self.istop = None - + self.writer = None - + self.filter = None self.fdata = None self.ftime = None self.cdata = None - + self.getSignals() self.loadConfig() self.setTimeIndices() self.loadData() - #self.applyNormalization() + # self.applyNormalization() self.filterData() - #self.gridData() + # self.gridData() self.makeAnimation() if savemovie: self.saveAnimationVideo() - + def getSignals(self): self.signals = UT.get_signals_in_container(self.container) - + def loadConfig(self): self.container.loadConfig() - + def readromercsv(self): """ do stuff """ - + def setPositions(self): """ do stuff """ - + def setTimeIndices(self): time = self.signals[0].time self.shot = self.signals[0].shot - time_indices = np.where(np.logical_and(time>=self.tmin, - time<=self.tmax))[0] + time_indices = np.where(np.logical_and(time >= self.tmin, + time <= self.tmax))[0] self.istart = time_indices[0] - self.istop = time_indices[time_indices.size-1] - - self.time = time[self.istart:self.istop+1] + self.istop = time_indices[time_indices.size - 1] + + self.time = time[self.istart:self.istop + 1] self.ntime = self.time.size print('Data points: {}'.format(self.ntime)) def loadData(self): - self.data = np.ones((7,9,self.ntime))*(-1) - self.datamask = np.zeros((7,9),dtype=bool) + self.data = np.ones((7, 9, self.ntime)) * (-1) + self.datamask = np.zeros((7, 9), dtype=bool) for signal in self.signals: if not hasattr(signal, 'row'): continue row = signal.row column = signal.column zerosignal = np.mean(signal[0:1e3]) - self.data[row-1,column-1,:] = signal[self.istart:self.istop+1] - zerosignal - self.datamask[row-1,column-1] = True - + self.data[row - 1, column - 1, + :] = signal[self.istart:self.istop + 1] - zerosignal + self.datamask[row - 1, column - 1] = True + def applyNormalization(self): - nrow,ncol,_ = self.data.shape - + nrow, ncol, _ = self.data.shape + # column-wise normalization factor self.colcal = np.zeros((ncol,)) for col in np.arange(ncol): - rowmask = self.datamask[:,col] + rowmask = self.datamask[:, col] if not rowmask.any(): continue - self.colcal[col] = np.mean(self.data[rowmask.nonzero(),col,0:self.ntime/20]) - + self.colcal[col] = np.mean( + self.data[rowmask.nonzero(), col, 0:self.ntime / 20]) + # boxcar filter column-wise normalization factor tmp = self.colcal.copy() for col in np.arange(ncol): - if col==0 or col==ncol-1: + if col == 0 or col == ncol - 1: continue - d = self.colcal[col-1:col+2] - if np.count_nonzero(d)!=3: + d = self.colcal[col - 1:col + 2] + if np.count_nonzero(d) != 3: continue tmp[col] = np.mean(d) self.colcal = tmp.copy() - + # apply normalization to data array for row in np.arange(nrow): for col in np.arange(ncol): - if self.datamask[row,col]: - self.data[row,col,:] = self.data[row,col,:] * self.colcal[col] / np.mean(self.data[row,col,0:self.ntime/20]) - + if self.datamask[row, col]: + self.data[row, col, :] = self.data[row, col, :] * \ + self.colcal[col] / \ + np.mean(self.data[row, col, 0:self.ntime / 20]) + def filterData(self): - nrow, ncol, _ = self.data.shape - self.fdata = np.zeros((7,9,self.ntime)) + nrow, ncol, _ = self.data.shape + self.fdata = np.zeros((7, 9, self.ntime)) for row in range(nrow): for col in range(ncol): - if self.datamask[row,col]: - self.fdata[row,col,:] -= np.mean(self.data[row,col,:]) + if self.datamask[row, col]: + self.fdata[row, col, :] -= np.mean(self.data[row, col, :]) self.ftime = self.time - + def gridData(self): nrad = 9 npol = 7 - rgrid = np.arange(1,nrad+1) - pgrid = np.arange(1,npol+1) - rr,pp = np.meshgrid(rgrid, pgrid) + rgrid = np.arange(1, nrad + 1) + pgrid = np.arange(1, npol + 1) + rr, pp = np.meshgrid(rgrid, pgrid) print(pp.shape) - rnew = np.arange(0.5,nrad+0.51,0.25) - pnew = np.arange(0.5,npol+0.51,0.25) - self.gdata = np.zeros((pnew.size,rnew.size,self.ftime.size)) + rnew = np.arange(0.5, nrad + 0.51, 0.25) + pnew = np.arange(0.5, npol + 0.51, 0.25) + self.gdata = np.zeros((pnew.size, rnew.size, self.ftime.size)) print('starting interpolation') for i in np.arange(self.ftime.size): - if i!=0 and np.mod(i+1,100)==0: - print(' frame {} of {}'.format(i+1,self.ftime.size)) + if i != 0 and np.mod(i + 1, 100) == 0: + print(' frame {} of {}'.format(i + 1, self.ftime.size)) f = scipy.interpolate.interp2d(rr, pp, - self.fdata[:,:,i].squeeze(), + self.fdata[:, :, i].squeeze(), kind='linear') - self.gdata[:,:,i] = f(rnew,pnew) - - + self.gdata[:, :, i] = f(rnew, pnew) + def plotContourf(self, axes=None, index=None): - return axes.contourf(np.arange(1,10.1), - np.arange(1,8.1), - self.fdata[::-1,:,index], + return axes.contourf(np.arange(1, 10.1), + np.arange(1, 8.1), + self.fdata[::-1, :, index], cmap=plt.cm.YlGnBu) - + def plotPColorMesh(self, axes=None, index=None): - return axes.pcolormesh(np.arange(1,10.1), - np.arange(1,8.1), - self.fdata[::-1,:,index], + return axes.pcolormesh(np.arange(1, 10.1), + np.arange(1, 8.1), + self.fdata[::-1, :, index], cmap=plt.cm.YlGnBu) - + def makeAnimation(self): ims = [] - + if self.hightimeres: frameint = 2 else: frameint = 40 - nframes = np.int(self.ftime.size/frameint) - - self.fig = plt.figure(figsize=(6.4,7)) - ax1 = self.fig.add_subplot(1,1,1) + nframes = np.int(self.ftime.size / frameint) + + self.fig = plt.figure(figsize=(6.4, 7)) + ax1 = self.fig.add_subplot(1, 1, 1) ax1.set_xlabel('Radial channels') ax1.set_ylabel('Poloidal channels') ax1.set_aspect('equal') - + clim = [np.amin(self.fdata), np.amax(self.fdata)] print('starting frame loop with {} frames'.format(nframes)) - + for i in np.arange(nframes): - if i!=0 and np.mod(i+1,20)==0: - print(' frame {} of {}'.format(i+1,nframes)) + if i != 0 and np.mod(i + 1, 20) == 0: + print(' frame {} of {}'.format(i + 1, nframes)) #im = self.plotContourf(axes=ax1, index=i*frameint) - im = self.plotPColorMesh(axes=ax1, index=i*frameint) + im = self.plotPColorMesh(axes=ax1, index=i * frameint) im.set_clim(clim) - if i==0: + if i == 0: cb = plt.colorbar(im, ax=ax1) cb.set_label('Signal (V)') cb.draw_all() ax1_title = ax1.annotate('BES | {} | t={:.3f} ms'.format( self.shot, - self.ftime[i*frameint]*1e3), - xy=(0.5, 1.04), + self.ftime[i * frameint] * 1e3), + xy=(0.5, 1.04), xycoords='axes fraction', - horizontalalignment ='center', + horizontalalignment='center', size='large') plt.draw() artists = [cb.solids, ax1_title] gc.disable() # disable garbage collection to keep list appends fast if hasattr(im, 'collections'): - ims.append(im.collections+artists) + ims.append(im.collections + artists) else: - ims.append([im]+artists) + ims.append([im] + artists) gc.enable() - + print('calling ArtistAnimation') - self.animation = animation.ArtistAnimation(self.fig, ims, + self.animation = animation.ArtistAnimation(self.fig, ims, blit=False, interval=50, repeat=False) - + def saveAnimationVideo(self): print('calling ArtistAnimation.save()') filename = 'Bes2d_{}_{}ms.mp4'.format( self.shot, - np.int(self.tmin*1e3)) + np.int(self.tmin * 1e3)) writer = animation.FFMpegWriter(fps=30, bitrate=1e5) self.animation.save(filename, writer=writer) - diff --git a/fdp/methods/nstxu/bes/utilities.py b/fdp/methods/nstxu/bes/utilities.py index 66db32e..7938d30 100644 --- a/fdp/methods/nstxu/bes/utilities.py +++ b/fdp/methods/nstxu/bes/utilities.py @@ -8,6 +8,7 @@ from ....classes.fdp_globals import FdpError from ....classes.utilities import isSignal, isContainer + def get_signals_in_container(container): """Return list of attribute names corresponding to valid signals""" if not isContainer(container): @@ -23,4 +24,3 @@ def get_signals_in_container(container): except: print('{} is empty, ignoring'.format(attrname)) return valid_signals - diff --git a/fdp/methods/nstxu/chers/__init__.py b/fdp/methods/nstxu/chers/__init__.py index 633f866..40a96af 100644 --- a/fdp/methods/nstxu/chers/__init__.py +++ b/fdp/methods/nstxu/chers/__init__.py @@ -1,2 +1 @@ # -*- coding: utf-8 -*- - diff --git a/fdp/methods/nstxu/equilibria/bfield.py b/fdp/methods/nstxu/equilibria/bfield.py index 4795e9d..c181dd4 100644 --- a/fdp/methods/nstxu/equilibria/bfield.py +++ b/fdp/methods/nstxu/equilibria/bfield.py @@ -11,7 +11,8 @@ def bfield(obj, radius=None, z=None, time=None): # must call from equilibrium container if not obj.isContainer(): - warnings.warn('Must call bfield() from equilibrium container, returning') + warnings.warn( + 'Must call bfield() from equilibrium container, returning') return # if nstx.shot.equilibria.bfield(), default to efit02 @@ -22,9 +23,12 @@ def bfield(obj, radius=None, z=None, time=None): eqdata = obj # defaults - if not radius: radius = 1.4 # major radius in m - if not z: z = 0.0 # height in m - if not time: time = 0.5 # time in s + if not radius: + radius = 1.4 # major radius in m + if not z: + z = 0.0 # height in m + if not time: + time = 0.5 # time in s # get time index tindex = eqdata.rmaxis.getTimeIndex(time=time) diff --git a/fdp/methods/nstxu/equilibria/utilities.py b/fdp/methods/nstxu/equilibria/utilities.py index 62d0660..6585555 100644 --- a/fdp/methods/nstxu/equilibria/utilities.py +++ b/fdp/methods/nstxu/equilibria/utilities.py @@ -14,7 +14,7 @@ def create_efit_objs(self): for efit in self.check_efit(): - ContainerClassName = 'Container'+efit.capitalize() + ContainerClassName = 'Container' + efit.capitalize() branch = '.'.join(['equilibria', efit]) # ContainerClassName = ''.join(['Equilibria', efit.capitalize()]) if branch not in _tree_dict: diff --git a/fdp/methods/nstxu/mpts/change_units.py b/fdp/methods/nstxu/mpts/change_units.py index 52bc622..952c4dc 100644 --- a/fdp/methods/nstxu/mpts/change_units.py +++ b/fdp/methods/nstxu/mpts/change_units.py @@ -14,4 +14,3 @@ def change_units(signal, data): data *= 1.e6 signal.units = 'm^-3' return data - \ No newline at end of file diff --git a/fdp/methods/nstxu/overviewgui.py b/fdp/methods/nstxu/overviewgui.py index ce0692b..9430669 100644 --- a/fdp/methods/nstxu/overviewgui.py +++ b/fdp/methods/nstxu/overviewgui.py @@ -4,4 +4,3 @@ @author: drsmith """ - diff --git a/fdp/methods/nstxu/shottime.py b/fdp/methods/nstxu/shottime.py index adf8c14..8637d68 100644 --- a/fdp/methods/nstxu/shottime.py +++ b/fdp/methods/nstxu/shottime.py @@ -5,5 +5,6 @@ @author: ktritz """ + def shottime(self): return float(self._netcat('skylark', 8530, '')) diff --git a/fdp/methods/plot.py b/fdp/methods/plot.py index 9bd0a22..b41ae66 100755 --- a/fdp/methods/plot.py +++ b/fdp/methods/plot.py @@ -11,13 +11,13 @@ import numpy as np import numba as nb #import matplotlib as mpl -#mpl.use('TkAgg') +# mpl.use('TkAgg') import matplotlib.pyplot as plt #import pyqtgraph as pg from ..classes.fdp_globals import FdpWarning -#pg.mkQApp() +# pg.mkQApp() def plot1d(signal, tmin=0.0, tmax=None, **kwargs): @@ -64,6 +64,7 @@ def plot2d(signal, tmin=0.0, tmax=None, **kwargs): cbar = plt.colorbar(artist, format='%.1e') cbar.set_label(signal.units, rotation=270) + def set_range(data, default_min, default_max): max_range = np.array(data).max() min_range = np.array(data).min() @@ -77,16 +78,18 @@ def set_range(data, default_min, default_max): if default_min > 0.0: min_index = np.where(cumulative > default_min * cumulative[-1])[0][0] min_range = hist_data[1][min_index] - min_range -= 0.15*abs(min_range) + min_range -= 0.15 * abs(min_range) return min_range, max_range def plot3d(data, xaxis, yaxis, zaxis, **kwargs): print('3D') + def update3d(value): pass + def plot4d(data, xaxis, yaxis, zaxis, taxis, **kwargs): print('4D') @@ -125,9 +128,9 @@ def plot(signal, fig=None, ax=None, **kwargs): if ax is None: ax = fig.add_subplot(111) - if 1: # dims > 1: + if 1: # dims > 1: plot_methods[dims](signal, axes=ax, **defaults) - #fig.show() + # fig.show() else: if not len(fig.axes): ax = PlotAxes(plot_methods[dims], fig, [0.1, 0.1, 0.8, 0.8]) @@ -177,9 +180,9 @@ def plot_container(container, **kwargs): if plot_sigs is not None: plot_sigs = plot_sigs.split(',') vstack, hstack = tuple(map(int, stack.split(','))) - num = hstack*vstack + num = hstack * vstack index = 0 - fig = plt.figure(figsize=(2+3*hstack, 4+2*vstack)) + fig = plt.figure(figsize=(2 + 3 * hstack, 4 + 2 * vstack)) # title = container._get_branch().upper() # plt.suptitle('Shot #{} {}'.format(container.shot, title), # x=0.5, y=1.00, fontsize=20, horizontalalignment='center') @@ -212,9 +215,10 @@ def plot(self, signal, *args, **kwargs): index_list = [] stride = kwargs.get('stride', 0) if stride: - stride_levels = np.floor(np.log(signal.size/3000)/np.log(stride)) + stride_levels = np.floor( + np.log(signal.size / 3000) / np.log(stride)) index_list = [numba_decimate_stride(signal, int(level)) - for level in np.arange(stride_levels)+1] + for level in np.arange(stride_levels) + 1] myplot = signal, index_list, args, kwargs self._plot_objects.append(myplot) self._update_plot(myplot) @@ -248,15 +252,16 @@ def _update_plot(self, myplot): ymin, ymax = self.get_ylim() ixmin = np.searchsorted(x, xmin, side='left') - ixmax = np.searchsorted(x, xmax*1.1, side='right') + ixmax = np.searchsorted(x, xmax * 1.1, side='right') stride = kwargs.pop('stride', 0) kwargs.pop('type', None) kwargs.pop('stack', None) stride_level = 0 if stride: - stride_level = int(np.floor(np.log((ixmax-ixmin)/nx)/np.log(stride))) + stride_level = int( + np.floor(np.log((ixmax - ixmin) / nx) / np.log(stride))) if stride_level: - dec_index = index_list[stride_level-1] + dec_index = index_list[stride_level - 1] dec_min = np.searchsorted(dec_index, ixmin, side='left') dec_max = np.searchsorted(dec_index, ixmax, side='right') index = dec_index[dec_min:dec_max] @@ -269,7 +274,8 @@ def _update_plot(self, myplot): dec_index = numba_decimate(ydata) else: dec_index = decimate_plot(ydata) - super(PlotAxes, self).plot(xdata[dec_index], ydata[dec_index], *args, **kwargs) + super(PlotAxes, self).plot( + xdata[dec_index], ydata[dec_index], *args, **kwargs) def _set_limits(self, signal): if len(signal.axes) > 1: @@ -296,7 +302,7 @@ def _set_limits(self, signal): self.limits = ((xmin, xmax), (ymin, ymax)) -#class PyQTPlot(pg.PlotCurveItem): +# class PyQTPlot(pg.PlotCurveItem): # def __init__(self, *args, **kwds): # self.hdf5 = None # self.limit = 10000 # maximum number of samples to be plotted @@ -368,20 +374,20 @@ def _set_limits(self, signal): def decimate_plot(data, pixels=2000): # returns a decimated indices array to visually approximate a plot with # points >> pixels - if data.size <= pixels*2: + if data.size <= pixels * 2: return np.arange(data.size) - stride = (data.size-2)/(pixels-1) - endpoint = (pixels-1)*stride+1 - data2D = data[1:endpoint].reshape((pixels-1, stride)) - column_offset = np.arange(pixels-1)*stride + 1 - data_min = data2D.argmin(axis=1)+column_offset - data_max = data2D.argmax(axis=1)+column_offset + stride = (data.size - 2) / (pixels - 1) + endpoint = (pixels - 1) * stride + 1 + data2D = data[1:endpoint].reshape((pixels - 1, stride)) + column_offset = np.arange(pixels - 1) * stride + 1 + data_min = data2D.argmin(axis=1) + column_offset + data_max = data2D.argmax(axis=1) + column_offset data_endmin = data[endpoint:-2].argmin() + endpoint data_endmax = data[endpoint:-2].argmax() + endpoint decimate_index = np.dstack((data_min, data_max)).flatten() decimate_index = np.concatenate(([0], decimate_index, [data_endmin], [data_endmax], - [data.size-1])) + [data.size - 1])) return np.sort(decimate_index) @@ -389,21 +395,21 @@ def decimate_plot(data, pixels=2000): def numba_decimate(data, pixels=2000): # returns a decimated indices array to visually approximate a plot with # points >> pixels - output = np.zeros(2*pixels+2, dtype=np.int64) - if data.size <= pixels*2: + output = np.zeros(2 * pixels + 2, dtype=np.int64) + if data.size <= pixels * 2: return np.arange(data.size) - stride = (data.size-2)/(pixels-1) + stride = (data.size - 2) / (pixels - 1) output[0] = 0 - output[-1] = data.size-1 - for pixel in range(1, pixels+1): - offset = 1 + stride * (pixel-1) + output[-1] = data.size - 1 + for pixel in range(1, pixels + 1): + offset = 1 + stride * (pixel - 1) arrmin = data[offset] arrmax = data[offset] minind = offset maxind = offset - if offset+stride > data.size-1: - stride = data.size-offset-1 - for index in range(offset+1, offset+stride): + if offset + stride > data.size - 1: + stride = data.size - offset - 1 + for index in range(offset + 1, offset + stride): check = data[index] if check < arrmin: minind = index @@ -413,11 +419,11 @@ def numba_decimate(data, pixels=2000): maxind = index arrmax = check if maxind > minind: - output[2*pixel-1] = minind - output[2*pixel] = maxind + output[2 * pixel - 1] = minind + output[2 * pixel] = maxind else: - output[2*pixel-1] = maxind - output[2*pixel] = minind + output[2 * pixel - 1] = maxind + output[2 * pixel] = minind return output @@ -425,19 +431,19 @@ def numba_decimate(data, pixels=2000): def numba_decimate_stride(data, stride): # returns a decimated indices array to visually approximate a plot with # points >> pixels - elements = 2*int((data.size-2)/stride) + 2 + elements = 2 * int((data.size - 2) / stride) + 2 output = np.zeros(elements, dtype=np.int64) output[0] = 0 - output[-1] = data.size-1 - for element in range(1, elements-1, 2): - offset = 1 + stride * (element-1)/2 + output[-1] = data.size - 1 + for element in range(1, elements - 1, 2): + offset = 1 + stride * (element - 1) / 2 arrmin = data[offset] arrmax = data[offset] minind = offset maxind = offset - if offset+stride > data.size-1: - stride = data.size-offset-1 - for index in range(offset+1, offset+stride): + if offset + stride > data.size - 1: + stride = data.size - offset - 1 + for index in range(offset + 1, offset + stride): check = data[index] if check < arrmin: minind = index @@ -448,8 +454,8 @@ def numba_decimate_stride(data, stride): arrmax = check if maxind > minind: output[element] = minind - output[element+1] = maxind + output[element + 1] = maxind else: output[element] = maxind - output[element+1] = minind + output[element + 1] = minind return output diff --git a/fdp/methods/timeindex.py b/fdp/methods/timeindex.py index 6c6b3cb..2286c07 100644 --- a/fdp/methods/timeindex.py +++ b/fdp/methods/timeindex.py @@ -7,6 +7,7 @@ import numpy as np + def getTimeIndex(obj, time=0.0): """ Return time index <= input time @@ -14,8 +15,8 @@ def getTimeIndex(obj, time=0.0): if not obj.isSignal(): print('getTimeIndex() is only valid for signals, returning') return - indlist = np.nonzero(obj.time<=time) - if indlist[0].size>0: + indlist = np.nonzero(obj.time <= time) + if indlist[0].size > 0: return indlist[0][-1] else: - return None \ No newline at end of file + return None From 03a5a22df25d284b060536bf51e9f5d7f2236a7f Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 12:24:17 -0400 Subject: [PATCH 08/82] Makefile edits, including adding 'lint' recipe to run flake8 --- Makefile | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/Makefile b/Makefile index edd261c..80e036a 100644 --- a/Makefile +++ b/Makefile @@ -28,16 +28,29 @@ BROWSER := python -c "$$BROWSER_PYSCRIPT" .PHONY: help -help: ## show help message +help: ## show this help message @python -c "$$PRINT_HELP_PYSCRIPT" < $(MAKEFILE_LIST) .PHONY: docs -docs: ## build HTML documents +docs: docs-html docs-pdf ## build HTML and PDF documents + + +.PHONY: docs-html +docs-html: ## build HTML documents $(MAKE) -C $(DOCDIR) html @$(BROWSER) docs/build/html/index.html +.PHONY: docs-pdf +docs-pdf: ## build PDF documents + $(MAKE) -C $(DOCDIR) latexpdf + + +.PHONY: lint +lint: ## run flake8 for code quality review + flake8 --exit-zero fdp/ + .PHONY: clean clean: clean-pyc clean-docs ## remove all build, docs, and Python artifacts From 1e5adaadb94ac6d03134578681fddec8c8645e09 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 12:45:25 -0400 Subject: [PATCH 09/82] added 'autopep' recipe in Makefile; ran autopep8 in test/ --- Makefile | 9 +++- fdp/methods/nstxu/bes/crosspower.py | 6 --- test/setup.py | 2 +- test/testCrossCorrelation.py | 74 ++++++++++++++--------------- test/testFilter.py | 41 ++++++++-------- test/testNstxu.py | 15 +++--- test/testNstxuBes.py | 6 ++- test/testNstxuDiagnostics.py | 10 ++-- test/testNstxuShot.py | 12 +++-- 9 files changed, 93 insertions(+), 82 deletions(-) diff --git a/Makefile b/Makefile index 80e036a..59f668a 100644 --- a/Makefile +++ b/Makefile @@ -49,7 +49,14 @@ docs-pdf: ## build PDF documents .PHONY: lint lint: ## run flake8 for code quality review - flake8 --exit-zero fdp/ + flake8 --exit-zero fdp/ test/ + + +.PHONY: autopep +autopep: ## run autopep8 to fix minor pep8 violations + autopep8 --in-place -r fdp/ + autopep8 --in-place -r test/ + .PHONY: clean clean: clean-pyc clean-docs ## remove all build, docs, and Python artifacts diff --git a/fdp/methods/nstxu/bes/crosspower.py b/fdp/methods/nstxu/bes/crosspower.py index 60e4242..9bf5a2c 100644 --- a/fdp/methods/nstxu/bes/crosspower.py +++ b/fdp/methods/nstxu/bes/crosspower.py @@ -173,13 +173,7 @@ def plotcoherence(container, *args, **kwargs): container._name.upper(), cs.signal1name.upper(), cs.signal2name.upper())) - - -<< << << < HEAD - -== == == = plt.tight_layout() ->>>>>> > master return cs diff --git a/test/setup.py b/test/setup.py index c97edae..eaa09a8 100644 --- a/test/setup.py +++ b/test/setup.py @@ -21,4 +21,4 @@ def setUp(self, shotnumber=204952): """ self.nstxu = fdp.nstx() self.shotnumber = shotnumber - self.shot = getattr(self.nstxu, 's'+repr(self.shotnumber)) + self.shot = getattr(self.nstxu, 's' + repr(self.shotnumber)) diff --git a/test/testCrossCorrelation.py b/test/testCrossCorrelation.py index c4a6e3d..742a9b1 100644 --- a/test/testCrossCorrelation.py +++ b/test/testCrossCorrelation.py @@ -9,13 +9,13 @@ import matplotlib.pyplot as plt # Take correlation between two 10 kHz sine waves with 5 us offset -fs = 2e6 # sampling frequency -T = 10e-3 # 10 ms sampling period -t = np.arange(int(fs * T)) / fs # array of time points -numpnts = len(t) # Number of points in signals (N=800 for this case) +fs = 2e6 # sampling frequency +T = 10e-3 # 10 ms sampling period +t = np.arange(int(fs * T)) / fs # array of time points +numpnts = len(t) # Number of points in signals (N=800 for this case) -f = 10e3 # sine wave frequency -dt = np.random.normal(5e-6, 10e-6, numpnts) # time offset +f = 10e3 # sine wave frequency +dt = np.random.normal(5e-6, 10e-6, numpnts) # time offset x = np.sin(2 * np.pi * f * t) y = np.sin(2 * np.pi * f * (t + dt)) @@ -25,7 +25,7 @@ # Begin code copied from CrossSignal class signal1_seg = [] signal2_seg = [] -nseg = numpnts // nperseg # Number of segments +nseg = numpnts // nperseg # Number of segments for i in range(nseg): start_i = i * nperseg signal1_seg.append(x[start_i:start_i + nperseg]) @@ -38,53 +38,53 @@ autocorr2 = np.zeros((nseg, 2 * nperseg - 1)) xcorr_coef = np.zeros((nseg, 2 * nperseg - 1)) for i in range(nseg): - + # Subtract mean from each segment - signal1_seg[i,:] -= np.mean(signal1_seg, axis=1)[i] - signal2_seg[i,:] -= np.mean(signal2_seg, axis=1)[i] - + signal1_seg[i, :] -= np.mean(signal1_seg, axis=1)[i] + signal2_seg[i, :] -= np.mean(signal2_seg, axis=1)[i] + # Calculate cross-correlation for each segment # The second input is reversed to change the convolution to a # cross-correlation of the form Sum[x[i] * y[i - k]]. The - # output is then reversed to put the cross-correlation into + # output is then reversed to put the cross-correlation into # the more standard form Sum[x[i] * y[i +k]] - xcorr[i,:] = fftconvolve(signal1_seg[i,:], - signal2_seg[i,::-1])[::-1] - + xcorr[i, :] = fftconvolve(signal1_seg[i, :], + signal2_seg[i, ::-1])[::-1] + # Calculate autocorrelations for each segment - autocorr1[i,:] = fftconvolve(signal1_seg[i,:], - signal1_seg[i,::-1])[::-1] - autocorr2[i,:] = fftconvolve(signal2_seg[i,:], - signal2_seg[i,::-1])[::-1] - + autocorr1[i, :] = fftconvolve(signal1_seg[i, :], + signal1_seg[i, ::-1])[::-1] + autocorr2[i, :] = fftconvolve(signal2_seg[i, :], + signal2_seg[i, ::-1])[::-1] + # Calculate correlation coefficient - xcorr_coef[i,:] = xcorr[i,:] / np.sqrt( - autocorr1[i,nperseg-1] * autocorr2[i,nperseg-1]) - + xcorr_coef[i, :] = xcorr[i, :] / np.sqrt( + autocorr1[i, nperseg - 1] * autocorr2[i, nperseg - 1]) + # Average over all segments crosscorrelation = np.mean(xcorr, axis=0) autocorrelation1 = np.mean(autocorr1, axis=0) autocorrelation2 = np.mean(autocorr2, axis=0) correlation_coef = np.mean(xcorr_coef, axis=0) - + # Calculate envelope of correlation using analytic signal method correlation_coef_envelope = np.absolute( - hilbert(correlation_coef)) - + hilbert(correlation_coef)) + # Construct time axis for cross correlation time_delays = np.linspace(-(nperseg - 1), - (nperseg - 1), - 2*nperseg - 1) / fs + (nperseg - 1), + 2 * nperseg - 1) / fs fig2 = plt.figure() -ax2 = fig2.add_subplot(111) # for some reason this is preferred over fig.gca() -ax2.set_xlim([0,0.5e-3]) +ax2 = fig2.add_subplot(111) # for some reason this is preferred over fig.gca() +ax2.set_xlim([0, 0.5e-3]) ax2.set_xlabel('Time') ax2.set_ylabel('y') ax2.plot(t, y) fig1 = plt.figure() -ax1 = fig1.add_subplot(111) # for some reason this is preferred over fig.gca() +ax1 = fig1.add_subplot(111) # for some reason this is preferred over fig.gca() ax1.set_xlim([-10e-6, 10e-6]) ax1.set_ylim([0.9, 1.0]) ax1.set_xlabel('Time delay') @@ -100,7 +100,7 @@ # ============================================================================= # Calculate cross correlation using integral definition #cc_integral = np.zeros(2 * N - 1) -#for k in range(len(cc_integral)): +# for k in range(len(cc_integral)): # if k in range(N): # First half is zero and negative time shift # for j in range(N - 1 - k, N): # cc_integral[k] += x[j] * y[j + k - (N - 1)] @@ -112,12 +112,12 @@ #cc_integral = correlate(x,y) #cc_timeaxis = np.linspace(-(N - 1), N - 1, 2 * N - 1) / fs # -## Calculate cross correlation using fft method -#cc_fft = fftconvolve(x, y[::-1]) # Reverse y to compute correlation instead of convolve +# Calculate cross correlation using fft method +# cc_fft = fftconvolve(x, y[::-1]) # Reverse y to compute correlation instead of convolve # -## Plot results +# Plot results #fig1 = plt.figure() -#ax1 = fig1.add_subplot(111) # for some reason this is preferred over fig.gca() +# ax1 = fig1.add_subplot(111) # for some reason this is preferred over fig.gca() #ax1.set_xlim([-100e-6, 100e-6]) #ax1.set_xlabel('Time delay') #ax1.set_ylabel('Cross correlation') @@ -130,4 +130,4 @@ #ax2.set_xlabel('Time delay') #ax2.set_ylabel('Cross correlation') #ax2.set_title('FFT method') -#ax2.plot(cc_timeaxis, cc_fft) \ No newline at end of file +#ax2.plot(cc_timeaxis, cc_fft) diff --git a/test/testFilter.py b/test/testFilter.py index c9a3656..6e7dd66 100644 --- a/test/testFilter.py +++ b/test/testFilter.py @@ -12,30 +12,31 @@ import matplotlib.pyplot as plt from scipy.signal import firwin, filtfilt, freqz + def filter_signal(signal, fNyq, fmin=None, fmax=None, numfilttaps=None): 'Band pass filter the input data' - + # Check to see if either filter frequency has been set. If not, then # don't filter the data if fmin is not None or fmax is not None: - + # Set default values for unspecified frequencies and convert units # of specified frequencies from kHz to Hz if fmin is not None and fmax is not None: filttype = 'bandpass' - + if fmin is None: filttype = 'lowpass' - fmin = fNyq / 2 # Placeholder valid frequency + fmin = fNyq / 2 # Placeholder valid frequency else: fmin *= 1000 - + if fmax is None: filttype = 'highpass' - fmax = fNyq / 2 # Placeholder valid frequency + fmax = fNyq / 2 # Placeholder valid frequency else: fmax *= 1000 - + # Verify that frequencies are valid if fmin <= 0 or fmin >= fNyq: raise FdpError('fmin is outside valid range') @@ -43,7 +44,7 @@ def filter_signal(signal, fNyq, fmin=None, fmax=None, numfilttaps=None): raise FdpError('fmax is outside valid range') if fmax < fmin: raise FdpError('fmin is larger than fmax') - + # Filter data using FIR filter generated using window # method (Hamming window) numpnts = len(signal) @@ -51,34 +52,36 @@ def filter_signal(signal, fNyq, fmin=None, fmax=None, numfilttaps=None): numtaps = 2 * (numpnts // 2) - 1 else: numtaps = numfilttaps - + if filttype == 'lowpass': h = firwin(numtaps, fmax, nyq=fNyq) elif filttype == 'highpass': h = firwin(numtaps, fmin, pass_zero=False, nyq=fNyq) - else: # bandpass + else: # bandpass h = firwin(numtaps, [fmin, fmax], pass_zero=False, nyq=fNyq) - + w, b = freqz(h, worN=2000) fig = plt.figure() ax = fig.add_subplot(111) ax.plot(w * fNyq / np.pi, 20 * np.log10(abs(b))) ax.set_xlabel('Frequency (Hz)') ax.set_ylabel('Amplitude (dB)') - + return filtfilt(h, 1.0, signal, padlen=numtaps) else: return signal + # ============================================================================= # Start of test # ============================================================================= -T = 0.01 # width of time window -fs = 2e6 # sampling frequency +T = 0.01 # width of time window +fs = 2e6 # sampling frequency fNyq = fs / 2 -t = np.arange(int(fs * T)) / fs # time array -x = np.sin(2*np.pi*100*t)+0.2*np.sin(2*np.pi*1e3*t)+0.1*np.sin(2*np.pi*10e3*t) +t = np.arange(int(fs * T)) / fs # time array +x = np.sin(2 * np.pi * 100 * t) + 0.2 * np.sin(2 * np.pi * + 1e3 * t) + 0.1 * np.sin(2 * np.pi * 10e3 * t) fmin = 0.5 fmax = 2. @@ -87,10 +90,10 @@ def filter_signal(signal, fNyq, fmin=None, fmax=None, numfilttaps=None): fig1 = plt.figure() ax1 = fig1.add_subplot(111) -ax1.plot(t,x) +ax1.plot(t, x) ax1.set_title('Unfiltered') fig2 = plt.figure() ax2 = fig2.add_subplot(111) -ax2.plot(t,x_filt) -ax2.set_title('Filtered') \ No newline at end of file +ax2.plot(t, x_filt) +ax2.set_title('Filtered') diff --git a/test/testNstxu.py b/test/testNstxu.py index a85aa4e..26a7325 100644 --- a/test/testNstxu.py +++ b/test/testNstxu.py @@ -15,7 +15,7 @@ class TestNstxu(SetupNstxu): - + def testNstxuMachine(self): """ Assert fdp has 'nstx' and 'nstxu' attributes. @@ -25,13 +25,13 @@ def testNstxuMachine(self): self.assertTrue(hasattr(fdp, 'nstx'), 'fdp.nstx() missing') self.assertTrue(isinstance(self.nstxu, fdp.classes.machine.Machine), 'fdp.nstxu() does not return machine.Machine instance') - + def testS0Attribute(self): """ Assert nstxu has 's0' attribute """ self.assertTrue(hasattr(self.nstxu, 's0')) - + def testDiagnosticContainers(self): """ Assert nstxu.s0 has diagnostic attributes @@ -56,7 +56,7 @@ def testDiagnosticContainers(self): fdp.classes.container.Container), '{} is not container.Container subclass'.format( repr(container))) - + def testLogbookConnection(self): """ Assert Logbook object @@ -68,11 +68,11 @@ def testLogbookConnection(self): logbook._make_logbook_connection() self.assertIsNotNone(logbook._logbook_connection, 'nstxu._logbook._logbook_connection is None') - self.assertTrue(isinstance(logbook._logbook_connection, + self.assertTrue(isinstance(logbook._logbook_connection, pymssql.Connection), 'nstxu._logbook._logbook_connection \ is not pymssql.Connection instance') - + def testMdsConnection(self): """ Assert that self._connections is list of mds.Connection objects @@ -83,6 +83,7 @@ def testMdsConnection(self): 'nstxu._connections[0].socket is None') self.assertIsNotNone(self.nstxu._connections[0].hostspec, 'nstxu._connections[0].hostspec is None') - + + if __name__ == '__main__': unittest.main() diff --git a/test/testNstxuBes.py b/test/testNstxuBes.py index ef22a2c..af5758b 100644 --- a/test/testNstxuBes.py +++ b/test/testNstxuBes.py @@ -11,17 +11,19 @@ print('running tests in {}'.format(__file__)) + class TestBes(SetupNstxu): - + def testContainerClass(self): self.assertTrue(hasattr(self.shot, 'bes')) self.assertTrue(isinstance(self.shot.bes, fdp.classes.container.Container)) - + def testSignalClass(self): self.assertTrue(hasattr(self.shot.bes, 'ch01')) self.assertTrue(isinstance(self.shot.bes.ch01, fdp.classes.fdpsignal.Signal)) + if __name__ == '__main__': unittest.main() diff --git a/test/testNstxuDiagnostics.py b/test/testNstxuDiagnostics.py index 28621b9..1af7974 100644 --- a/test/testNstxuDiagnostics.py +++ b/test/testNstxuDiagnostics.py @@ -12,8 +12,9 @@ print('running tests in {}'.format(__file__)) + class TestNstxuDiagnostics(SetupNstxu): - + def testSignalAxes(self, container=None): """ Recursively parse tree @@ -28,7 +29,8 @@ def testSignalAxes(self, container=None): if isinstance(container._parent, fdp.classes.shot.Shot): print('Parsing {}'.format(container._name)) else: - print('Parsing {}.{}'.format(container._parent._name, container._name)) + print('Parsing {}.{}'.format( + container._parent._name, container._name)) for attrname in dir(container): attr = getattr(container, attrname) if isContainer(attr): @@ -51,9 +53,9 @@ def testSignalAxes(self, container=None): for sigattrname in dir(attr): sigattr = getattr(attr, sigattrname) if isAxis(sigattr): - self.assertIn(sigattrname, attr.axes, + self.assertIn(sigattrname, attr.axes, "{} is axis but not in 'axes' attr for signal {}".format( - sigattrname, attr._name)) + sigattrname, attr._name)) if __name__ == '__main__': diff --git a/test/testNstxuShot.py b/test/testNstxuShot.py index 27d84c4..d198350 100644 --- a/test/testNstxuShot.py +++ b/test/testNstxuShot.py @@ -11,15 +11,16 @@ print('running tests in {}'.format(__file__)) + class TestNstxuShot(SetupNstxu): - + def testShotClass(self): - shotattrname = 's'+repr(self.shotnumber) + shotattrname = 's' + repr(self.shotnumber) self.assertTrue(hasattr(self.nstxu, shotattrname), 'nstxu does not have {} attribute'.format(shotattrname)) self.assertTrue(issubclass(type(self.shot), fdp.classes.shot.Shot), '{} is not shot.Shot subclass'.format(repr(self.shot))) - + def testDiagnsticContainers(self): """ Assert all shot attributes are containers @@ -29,18 +30,19 @@ def testDiagnsticContainers(self): diag = getattr(self.shot, diagnostic) self.assertTrue(issubclass(type(diag), fdp.classes.container.Container), '{} is not subclass of container.Container'.format(repr(diag))) - + def testLogbook(self): """ Assert logbook entries """ pass - + def testTestShot(self): """ Assert test shot with <6 digits """ pass + if __name__ == '__main__': unittest.main() From 8da9fb27a325b4ebcf4ca939234ea44fd2115b8d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 13:14:23 -0400 Subject: [PATCH 10/82] ran autopep8 --- fdp/classes/crosssignal.py | 34 ++++++++++++++--------------- fdp/methods/nstxu/bes/crosspower.py | 16 +++++++------- 2 files changed, 25 insertions(+), 25 deletions(-) diff --git a/fdp/classes/crosssignal.py b/fdp/classes/crosssignal.py index 4cc7329..9de3f6b 100644 --- a/fdp/classes/crosssignal.py +++ b/fdp/classes/crosssignal.py @@ -76,9 +76,9 @@ class CrossSignal(object): def __init__(self, signal1, signal2, tmin=0.2, tmax=1.0, window='hann', nperseg=None, forcepower2=False, offsetminimum=False, offsetdc=False, normalizetodc=False, degrees=True, - fmin=None, fmax=None, numfilttaps=None, sawteethtimes=None, + fmin=None, fmax=None, numfilttaps=None, sawteethtimes=None, sawteethbins=0): - + self.signal1 = signal1 self.signal2 = signal2 self.signal1time = signal1.time @@ -100,7 +100,7 @@ def __init__(self, signal1, signal2, tmin=0.2, tmax=1.0, window='hann', self.numfilttaps = numfilttaps self.sawteethtimes = sawteethtimes self.sawteethbins = sawteethbins - + if signal1 is signal2: self.same_signal = True else: @@ -462,11 +462,11 @@ def calc_correlation_fft(self): # Calculate cross-correlation for each segment # The second input is reversed to change the convolution to a # cross-correlation of the form Sum[x[i] * y[i - k]]. The - # output is then reversed to put the cross-correlation into + # output is then reversed to put the cross-correlation into # the more standard form Sum[x[i] * y[i + k]] - xcorr[i,:] = fftconvolve(signal1_seg[i,:], - signal2_seg[i,::-1])[::-1] - + xcorr[i, :] = fftconvolve(signal1_seg[i, :], + signal2_seg[i, ::-1])[::-1] + # Calculate autocorrelations for each segment autocorr1[i, :] = fftconvolve(signal1_seg[i, :], signal1_seg[i, ::-1])[::-1] @@ -526,21 +526,21 @@ def remove_sawteeth(self): for i in range(len(self.sawteethtimes)): t = self.sawteethtimes[i] index = np.searchsorted(self.times, t) - + # Delete bins before and after the sawtooth crash - self.csd = np.delete(self.csd, range(index-self.sawteethbins, - index+self.sawteethbins+1), + self.csd = np.delete(self.csd, range(index - self.sawteethbins, + index + self.sawteethbins + 1), axis=-1) - self.asd1 = np.delete(self.asd1, range(index-self.sawteethbins, - index+self.sawteethbins+1), + self.asd1 = np.delete(self.asd1, range(index - self.sawteethbins, + index + self.sawteethbins + 1), axis=-1) - self.asd2 = np.delete(self.asd2, range(index-self.sawteethbins, - index+self.sawteethbins+1), + self.asd2 = np.delete(self.asd2, range(index - self.sawteethbins, + index + self.sawteethbins + 1), axis=-1) - self.times = np.delete(self.times, range(index-self.sawteethbins, - index+self.sawteethbins+1), + self.times = np.delete(self.times, range(index - self.sawteethbins, + index + self.sawteethbins + 1), axis=-1) - + def phase_slope(self, fstart, fend): """ Calculate the slope of the crossphase over the user given frequency diff --git a/fdp/methods/nstxu/bes/crosspower.py b/fdp/methods/nstxu/bes/crosspower.py index 79dc1a9..30955b7 100644 --- a/fdp/methods/nstxu/bes/crosspower.py +++ b/fdp/methods/nstxu/bes/crosspower.py @@ -16,10 +16,10 @@ def crosssignal(container, sig1name='ch01', sig2name='ch02', - tmin=0.5, tmax=0.55, window='hann', nperseg=None, - forcepower2=False, offsetminimum=True, offsetdc=False, - normalizetodc=True, degrees=True, fmin=None, fmax=None, - numfilttaps=None, sawteethtimes=None, sawteethbins=0): + tmin=0.5, tmax=0.55, window='hann', nperseg=None, + forcepower2=False, offsetminimum=True, offsetdc=False, + normalizetodc=True, degrees=True, fmin=None, fmax=None, + numfilttaps=None, sawteethtimes=None, sawteethbins=0): if not isContainer(container): warn("Method valid only at container-level", FdpWarning) return @@ -169,10 +169,10 @@ def plotcoherence(container, *args, **kwargs): ax.set_ylim([0, 1]) ax.set_xlabel('Frequency (kHz)') ax.set_title('{} -- {} -- {}/{} -- Coherence'.format( - container.shot, - container._name.upper(), - cs.signal1name.upper(), - cs.signal2name.upper())) + container.shot, + container._name.upper(), + cs.signal1name.upper(), + cs.signal2name.upper())) plt.tight_layout() return cs From 89352045be725bb8e34935aec25d279f386f2bdd Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 14:03:34 -0400 Subject: [PATCH 11/82] edited README --- README.rst | 23 ++++++++++++++--------- 1 file changed, 14 insertions(+), 9 deletions(-) diff --git a/README.rst b/README.rst index a114558..abfe4d6 100644 --- a/README.rst +++ b/README.rst @@ -3,18 +3,19 @@ Fusion Data Platform =========================== -Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, management, analysis methods, and visualization. +Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. +FDP streamlines data discovery, management, analysis methods, and visualization. -* Github repository: https://github.com/Fusion-Data-Platform/fdp +* Github: https://github.com/Fusion-Data-Platform/fdp * Documentation: http://Fusion-Data-Platform.github.io/ * Google group: https://groups.google.com/forum/#!forum/fusion-data-platform -**Description** +**Description and features** -* An extensible software layer that unites data access, management, analysis, and visualization in a single data object +* An extensible software layer that unites data access, management, analysis, and visualization * A descriptive data object that users can query to find data and analysis methods -* A data object that handles data access (servers, trees, nodes, queries) behind the scenes -* A collaborative development plateform for data analysis tools +* Data access tasks (servers, trees, nodes, queries) are handled behind the scenes +* A collaborative development platform for data analysis tools * Built with popular, open-source packages like Numpy and Matplotlib **Example usage** @@ -23,11 +24,15 @@ Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion exp import fdp nstxu = fdp.nstxu() + nstxu.s204551.logbook() nstxu.s204551.mpts.te.plot() - nstxu.s204620.equilibria.efit02.kappa.plot() - nstxu.s204670.bes.ch01.plotfft() + nstxu.s204551.equilibria.efit02.kappa.plot() -Python's tab-complete feature presents users with data containers like ``mpts`` and ``efit02``, data signals like ``te`` and ``kappa``, and data methods like ``plot()`` and ``plotfft()``. +``nstxu`` is a data object that abstracts the NSTX-U device with easy access to shots, diagnostics, signals, and data methods. The typical heirarchy is:: + + ...[].. + +Users can discover data containers like ``mpts``, data signals like ``te``, and data methods like ``plot()`` with Python's tab-complete functionality. **Lead developers** From c714cbca9a14f3e24d75a98b9488668953f2631d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:07:55 -0400 Subject: [PATCH 12/82] added recipe in Makefile to create AUTHORS.txt --- AUTHORS.txt | 18 ++++++++++++++++++ Makefile | 33 ++++++++++++++++++++++++++++++--- 2 files changed, 48 insertions(+), 3 deletions(-) create mode 100644 AUTHORS.txt diff --git a/AUTHORS.txt b/AUTHORS.txt new file mode 100644 index 0000000..ca61988 --- /dev/null +++ b/AUTHORS.txt @@ -0,0 +1,18 @@ +Lead developers: + David R. Smith + Kevin Tritz + Howard Yuh +Commits from authors: + 204 David R. Smith + 37 ktritz + 22 dmkriete + 2 hyyuh + 1 Howard Yuh +Commits from obsolete FDF repository: + 261 David R. Smith + 41 Kevin Tritz + 17 ktritz + 10 Howard Yuh + 7 John Schmitt + 4 hyyuh + 2 jcschmitt diff --git a/Makefile b/Makefile index 59f668a..6f68198 100644 --- a/Makefile +++ b/Makefile @@ -1,7 +1,26 @@ .DEFAULT_GOAL := help -DOCDIR = docs +define LEAD_AUTHORS +Lead developers: + David R. Smith + Kevin Tritz + Howard Yuh +endef +export LEAD_AUTHORS + + +define FDF_SHORTLOG +Commits from obsolete FDF repository: + 261 David R. Smith + 41 Kevin Tritz + 17 ktritz + 10 Howard Yuh + 7 John Schmitt + 4 hyyuh + 2 jcschmitt +endef +export FDF_SHORTLOG define PRINT_HELP_PYSCRIPT import re, sys @@ -38,13 +57,13 @@ docs: docs-html docs-pdf ## build HTML and PDF documents .PHONY: docs-html docs-html: ## build HTML documents - $(MAKE) -C $(DOCDIR) html + $(MAKE) -C docs/ html @$(BROWSER) docs/build/html/index.html .PHONY: docs-pdf docs-pdf: ## build PDF documents - $(MAKE) -C $(DOCDIR) latexpdf + $(MAKE) -C docs/ latexpdf .PHONY: lint @@ -58,6 +77,14 @@ autopep: ## run autopep8 to fix minor pep8 violations autopep8 --in-place -r test/ +.PHONY: authors +authors: ## create AUTHORS.txt + @echo "$$LEAD_AUTHORS" > AUTHORS.txt + @echo "Commits from authors:" >> AUTHORS.txt + @git shortlog -s -n >> AUTHORS.txt + @echo "$$FDF_SHORTLOG" >> AUTHORS.txt + + .PHONY: clean clean: clean-pyc clean-docs ## remove all build, docs, and Python artifacts From 8084533b19980e5f4283b3657f47fe65b588016d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:14:49 -0400 Subject: [PATCH 13/82] reverted versions to 0.0.0 --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 0d85283..ab4bcf9 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.0 +current_version = 0.0.0 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index 7db8f55..06e357e 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.1.0' +version = '0.0.0' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index f43dfdb..9a8a865 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.1.0' +__version__ = '0.0.0' def nstxu(): From fbedd9a166a138e00c758720422556fa29353961 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:34:19 -0400 Subject: [PATCH 14/82] added recipe to Makefile --- Makefile | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/Makefile b/Makefile index 6f68198..0f2cbd8 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,12 @@ authors: ## create AUTHORS.txt @echo "$$FDF_SHORTLOG" >> AUTHORS.txt +.PHONY: bump-minor +bump-minor: ## bump minor version and push new tag + # `bumpversion` creates commit and tag + bumpversion minor + git push --tags + .PHONY: clean clean: clean-pyc clean-docs ## remove all build, docs, and Python artifacts From bb0408616217b170ce2cef721210b6f1a273ab01 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:34:44 -0400 Subject: [PATCH 15/82] =?UTF-8?q?Bump=20version:=200.0.0=20=E2=86=92=200.1?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index ab4bcf9..0d85283 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.0.0 +current_version = 0.1.0 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index 06e357e..7db8f55 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.0.0' +version = '0.1.0' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index 9a8a865..f43dfdb 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.0.0' +__version__ = '0.1.0' def nstxu(): From c6d65ccc8e1a16be8534edad79787eac07c677a6 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:36:22 -0400 Subject: [PATCH 16/82] added recipe in Makefile --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 0f2cbd8..a558dcc 100644 --- a/Makefile +++ b/Makefile @@ -91,6 +91,14 @@ bump-minor: ## bump minor version and push new tag bumpversion minor git push --tags + +.PHONY: bump-patch +bump-patch: ## bump patch version and push new tag + # `bumpversion` creates commit and tag + bumpversion patch + git push --tags + + .PHONY: clean clean: clean-pyc clean-docs ## remove all build, docs, and Python artifacts From 47bfa73637cc5c671fcfa8d57e7445c281e87d77 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:36:33 -0400 Subject: [PATCH 17/82] =?UTF-8?q?Bump=20version:=200.1.0=20=E2=86=92=200.1?= =?UTF-8?q?.1?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 0d85283..8c44d54 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.0 +current_version = 0.1.1 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index 7db8f55..6d9d53e 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.1.0' +version = '0.1.1' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index f43dfdb..642428f 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.1.0' +__version__ = '0.1.1' def nstxu(): From a16db5c339685b5f73bb3bae6383c038bc3c87fd Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:38:13 -0400 Subject: [PATCH 18/82] added recipe in Makefile --- Makefile | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/Makefile b/Makefile index a558dcc..ab683b5 100644 --- a/Makefile +++ b/Makefile @@ -85,6 +85,13 @@ authors: ## create AUTHORS.txt @echo "$$FDF_SHORTLOG" >> AUTHORS.txt +.PHONY: bump-major +bump-major: ## bump major version and push new tag + # `bumpversion` creates commit and tag + bumpversion major + git push --tags + + .PHONY: bump-minor bump-minor: ## bump minor version and push new tag # `bumpversion` creates commit and tag From 2e6f692aba3b8af1a83e6bab8acdf3cd690355f9 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:55:57 -0400 Subject: [PATCH 19/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 16 +++++++++------- 2 files changed, 10 insertions(+), 7 deletions(-) create mode 100644 CHANGELOG.txt diff --git a/CHANGELOG.txt b/CHANGELOG.txt new file mode 100644 index 0000000..535fcc0 --- /dev/null +++ b/CHANGELOG.txt @@ -0,0 +1 @@ +a16db5c added recipe in Makefile diff --git a/Makefile b/Makefile index ab683b5..79fc7c4 100644 --- a/Makefile +++ b/Makefile @@ -87,23 +87,25 @@ authors: ## create AUTHORS.txt .PHONY: bump-major bump-major: ## bump major version and push new tag - # `bumpversion` creates commit and tag - bumpversion major + bumpversion major # runs 'git commit' and 'git tag git push --tags .PHONY: bump-minor bump-minor: ## bump minor version and push new tag - # `bumpversion` creates commit and tag - bumpversion minor + bumpversion minor # runs 'git commit' and 'git tag git push --tags .PHONY: bump-patch bump-patch: ## bump patch version and push new tag - # `bumpversion` creates commit and tag - bumpversion patch - git push --tags + @cp CHANGELOG.txt CHANGELOG.copy.txt + git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt + git add CHANGELOG.txt Makefile + git commit -m "updated CHANGELOG.txt" + bumpversion --dry-run patch # runs 'git commit' and 'git tag + #@git push --tags + @rm -f CHANGELOG.copy.txt .PHONY: clean From 5817adfae1a148dda6b6a186fb9b3a7ebb73e17d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:59:02 -0400 Subject: [PATCH 20/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 3 ++- 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 535fcc0..567a534 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1 +1,2 @@ +2e6f692 updated CHANGELOG.txt a16db5c added recipe in Makefile diff --git a/Makefile b/Makefile index 79fc7c4..892a5ee 100644 --- a/Makefile +++ b/Makefile @@ -100,10 +100,11 @@ bump-minor: ## bump minor version and push new tag .PHONY: bump-patch bump-patch: ## bump patch version and push new tag @cp CHANGELOG.txt CHANGELOG.copy.txt + @git rm CHANGELOG.txt git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add CHANGELOG.txt Makefile git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run patch # runs 'git commit' and 'git tag + bumpversion --dry-run patch # runs 'git commit' and 'git tag' #@git push --tags @rm -f CHANGELOG.copy.txt From 7061e58d95db337e6563dc0b01eff33a8b4b7d22 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 16:59:22 -0400 Subject: [PATCH 21/82] updated CHANGELOG.txt --- .gitignore | 1 + CHANGELOG.txt | 1 + Makefile | 2 +- 3 files changed, 3 insertions(+), 1 deletion(-) diff --git a/.gitignore b/.gitignore index fff3332..5249a6a 100644 --- a/.gitignore +++ b/.gitignore @@ -13,6 +13,7 @@ docs/build/ anaconda .DS_Store spyder_crash.log +CHANGELOG.copy.txt # Unit test / coverage reports htmlcov/ diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 567a534..0c3775d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,2 +1,3 @@ +5817adf updated CHANGELOG.txt 2e6f692 updated CHANGELOG.txt a16db5c added recipe in Makefile diff --git a/Makefile b/Makefile index 892a5ee..1005510 100644 --- a/Makefile +++ b/Makefile @@ -102,7 +102,7 @@ bump-patch: ## bump patch version and push new tag @cp CHANGELOG.txt CHANGELOG.copy.txt @git rm CHANGELOG.txt git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt - git add CHANGELOG.txt Makefile + git add -A git commit -m "updated CHANGELOG.txt" bumpversion --dry-run patch # runs 'git commit' and 'git tag' #@git push --tags From e44f558ff7131fd818cef48806548e6a4d26f426 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:00:14 -0400 Subject: [PATCH 22/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 0c3775d..2097f2a 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +7061e58 updated CHANGELOG.txt 5817adf updated CHANGELOG.txt 2e6f692 updated CHANGELOG.txt a16db5c added recipe in Makefile diff --git a/Makefile b/Makefile index 1005510..8e91e2f 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run patch # runs 'git commit' and 'git tag' + bumpversion --dry-run --list patch # runs 'git commit' and 'git tag' #@git push --tags @rm -f CHANGELOG.copy.txt From 21489ba54025e4c0d5a9ac75422f3d5e9d19739d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:02:22 -0400 Subject: [PATCH 23/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2097f2a..1373d16 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +e44f558 updated CHANGELOG.txt 7061e58 updated CHANGELOG.txt 5817adf updated CHANGELOG.txt 2e6f692 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 8e91e2f..b8a31d2 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch # runs 'git commit' and 'git tag' + bumpversion --dry-run --list patch | grep "new_version={}" #@git push --tags @rm -f CHANGELOG.copy.txt From cdf378985b29480d6af014d02f33639cdf3035b6 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:02:32 -0400 Subject: [PATCH 24/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 1373d16..98eadc7 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +21489ba updated CHANGELOG.txt e44f558 updated CHANGELOG.txt 7061e58 updated CHANGELOG.txt 5817adf updated CHANGELOG.txt diff --git a/Makefile b/Makefile index b8a31d2..83fc914 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "new_version={}" + bumpversion --dry-run --list patch | grep "new_version=" #@git push --tags @rm -f CHANGELOG.copy.txt From d2085a7cf958ff9070424d7dd3f76e89a2106d88 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:07:56 -0400 Subject: [PATCH 25/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 98eadc7..a6a39b1 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +cdf3789 updated CHANGELOG.txt 21489ba updated CHANGELOG.txt e44f558 updated CHANGELOG.txt 7061e58 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 83fc914..d51b318 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "new_version=" + bumpversion --dry-run --list patch | grep -e "^new_version=" #@git push --tags @rm -f CHANGELOG.copy.txt From f50fb46fbadbcff32a90294cfc338d3d99a32607 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:17:48 -0400 Subject: [PATCH 26/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index a6a39b1..5250eda 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +d2085a7 updated CHANGELOG.txt cdf3789 updated CHANGELOG.txt 21489ba updated CHANGELOG.txt e44f558 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index d51b318..9e2d534 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep -e "^new_version=" + bumpversion --dry-run --list patch | grep -e '[^=]*=\K' #@git push --tags @rm -f CHANGELOG.copy.txt From d96a74a217e0ae7ab19023c188ddc9b2d4250870 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:18:18 -0400 Subject: [PATCH 27/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5250eda..764836d 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +f50fb46 updated CHANGELOG.txt d2085a7 updated CHANGELOG.txt cdf3789 updated CHANGELOG.txt 21489ba updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 9e2d534..c5b8ccd 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep -e '[^=]*=\K' + bumpversion --dry-run --list patch | grep '[^=]*=\K' #@git push --tags @rm -f CHANGELOG.copy.txt From 179b44d41f8f140411429f2f330dd6a5400a76f5 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:18:25 -0400 Subject: [PATCH 28/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 764836d..99ea86b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +d96a74a updated CHANGELOG.txt f50fb46 updated CHANGELOG.txt d2085a7 updated CHANGELOG.txt cdf3789 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index c5b8ccd..29fa0e7 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep '[^=]*=\K' + bumpversion --dry-run --list patch | grep "[^=]*=\K" #@git push --tags @rm -f CHANGELOG.copy.txt From ec4cc442f4e259e023a0a660f866e7b3125372c8 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:18:42 -0400 Subject: [PATCH 29/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 99ea86b..341558e 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +179b44d updated CHANGELOG.txt d96a74a updated CHANGELOG.txt f50fb46 updated CHANGELOG.txt d2085a7 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 29fa0e7..629f011 100644 --- a/Makefile +++ b/Makefile @@ -99,12 +99,12 @@ bump-minor: ## bump minor version and push new tag .PHONY: bump-patch bump-patch: ## bump patch version and push new tag - @cp CHANGELOG.txt CHANGELOG.copy.txt + @cp -f CHANGELOG.txt CHANGELOG.copy.txt @git rm CHANGELOG.txt git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "[^=]*=\K" + bumpversion --dry-run --list patch | grep "[^=]*=\K$" #@git push --tags @rm -f CHANGELOG.copy.txt From 730c7370dea720f35dfda12e0cb761c3a325f8ec Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:18:53 -0400 Subject: [PATCH 30/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 341558e..f32304b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +ec4cc44 updated CHANGELOG.txt 179b44d updated CHANGELOG.txt d96a74a updated CHANGELOG.txt f50fb46 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 629f011..65ac3ca 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "[^=]*=\K$" + bumpversion --dry-run --list patch | grep "[^=]*=\K\$" #@git push --tags @rm -f CHANGELOG.copy.txt From de0202162715f67c10b2ad6114f251b24c81dba3 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:19:02 -0400 Subject: [PATCH 31/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index f32304b..320b92b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +730c737 updated CHANGELOG.txt ec4cc44 updated CHANGELOG.txt 179b44d updated CHANGELOG.txt d96a74a updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 65ac3ca..fb74ec7 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "[^=]*=\K\$" + bumpversion --dry-run --list patch | grep "[^=]*=\K$$" #@git push --tags @rm -f CHANGELOG.copy.txt From a2628036ca63e565bbc6b96462c0dffc927a039c Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:19:50 -0400 Subject: [PATCH 32/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 320b92b..5728d85 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +de02021 updated CHANGELOG.txt 730c737 updated CHANGELOG.txt ec4cc44 updated CHANGELOG.txt 179b44d updated CHANGELOG.txt diff --git a/Makefile b/Makefile index fb74ec7..1ad529b 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "[^=]*=\K$$" + bumpversion --dry-run --list patch | grep "new_version=\K$$" #@git push --tags @rm -f CHANGELOG.copy.txt From 17c067bb17cac299bd94f7c735b67171de54d323 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:28:20 -0400 Subject: [PATCH 33/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5728d85..5d60502 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +a262803 updated CHANGELOG.txt de02021 updated CHANGELOG.txt 730c737 updated CHANGELOG.txt ec4cc44 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 1ad529b..7b96055 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "new_version=\K$$" + bumpversion --dry-run --list patch | sed 's/^new_version=\(.*\)$$/\1/' #@git push --tags @rm -f CHANGELOG.copy.txt From 0166cba29c31199a365156cd3551b5e5e0bff453 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:30:12 -0400 Subject: [PATCH 34/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 5d60502..c54559b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +17c067b updated CHANGELOG.txt a262803 updated CHANGELOG.txt de02021 updated CHANGELOG.txt 730c737 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 7b96055..d999437 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | sed 's/^new_version=\(.*\)$$/\1/' + bumpversion --dry-run --list patch | sed -n 's/^new_version=\(.*\)$$/\1/' #@git push --tags @rm -f CHANGELOG.copy.txt From 5784200f1240cbf813878c77eb883e07a5b59aae Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:32:02 -0400 Subject: [PATCH 35/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index c54559b..6a4dfa9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +0166cba updated CHANGELOG.txt 17c067b updated CHANGELOG.txt a262803 updated CHANGELOG.txt de02021 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index d999437..64a1dc4 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | sed -n 's/^new_version=\(.*\)$$/\1/' + bumpversion --dry-run --list patch | grep '^new_version=.*$$' #@git push --tags @rm -f CHANGELOG.copy.txt From 4ba1ffedcf7937e2b3d3cd52003c3d741114605e Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:32:35 -0400 Subject: [PATCH 36/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6a4dfa9..6979935 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +5784200 updated CHANGELOG.txt 0166cba updated CHANGELOG.txt 17c067b updated CHANGELOG.txt a262803 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 64a1dc4..0262f30 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,7 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep '^new_version=.*$$' + bumpversion --dry-run --list patch | grep "^new_version=.*$$" | grep "[0-9\.]" #@git push --tags @rm -f CHANGELOG.copy.txt From 7d00add1ba0a82029545ac19de8a8f4e3fe78c18 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:33:08 -0400 Subject: [PATCH 37/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 4 +++- 2 files changed, 4 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6979935..94b92a9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +4ba1ffe updated CHANGELOG.txt 5784200 updated CHANGELOG.txt 0166cba updated CHANGELOG.txt 17c067b updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 0262f30..4eec6b1 100644 --- a/Makefile +++ b/Makefile @@ -104,7 +104,9 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | grep "^new_version=.*$$" | grep "[0-9\.]" + bumpversion --dry-run --list patch | \ + grep "^new_version=.*$$" | \ + grep -o "[0-9\.]" #@git push --tags @rm -f CHANGELOG.copy.txt From 28ad5d535dcd39e0e0aac4b20f35f706ef9bf0dd Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:33:46 -0400 Subject: [PATCH 38/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 94b92a9..3ee466f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +7d00add updated CHANGELOG.txt 4ba1ffe updated CHANGELOG.txt 5784200 updated CHANGELOG.txt 0166cba updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 4eec6b1..33a084f 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9\.]" + grep -o "[0-9\.]*" #@git push --tags @rm -f CHANGELOG.copy.txt From a379761979ac18bf69933844e9c2b144455d4e6a Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:35:16 -0400 Subject: [PATCH 39/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3ee466f..035884b 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +28ad5d5 updated CHANGELOG.txt 7d00add updated CHANGELOG.txt 4ba1ffe updated CHANGELOG.txt 5784200 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 33a084f..9918443 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9\.]*" + grep -o "[0-9.]*" #@git push --tags @rm -f CHANGELOG.copy.txt From e0693ed30798b5575990680a06fec898be88c4df Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:35:32 -0400 Subject: [PATCH 40/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 035884b..510a003 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +a379761 updated CHANGELOG.txt 28ad5d5 updated CHANGELOG.txt 7d00add updated CHANGELOG.txt 4ba1ffe updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 9918443..b87c933 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9.]*" + grep -o "[0-9.]" #@git push --tags @rm -f CHANGELOG.copy.txt From 67bc6f1dfef85ba03a4e6695f729b00b46011b05 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:37:11 -0400 Subject: [PATCH 41/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 510a003..3a29c7e 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +e0693ed updated CHANGELOG.txt a379761 updated CHANGELOG.txt 28ad5d5 updated CHANGELOG.txt 7d00add updated CHANGELOG.txt diff --git a/Makefile b/Makefile index b87c933..4eec6b1 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9.]" + grep -o "[0-9\.]" #@git push --tags @rm -f CHANGELOG.copy.txt From 81a4c5bdc778f7a4383df197ca30434f968cc6f9 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:38:43 -0400 Subject: [PATCH 42/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 3a29c7e..06b601e 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +67bc6f1 updated CHANGELOG.txt e0693ed updated CHANGELOG.txt a379761 updated CHANGELOG.txt 28ad5d5 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 4eec6b1..33a084f 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9\.]" + grep -o "[0-9\.]*" #@git push --tags @rm -f CHANGELOG.copy.txt From 4bbe78021f8282772bee2d9936cf00de6b9ec823 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:38:55 -0400 Subject: [PATCH 43/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 06b601e..b6afbb3 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +81a4c5b updated CHANGELOG.txt 67bc6f1 updated CHANGELOG.txt e0693ed updated CHANGELOG.txt a379761 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 33a084f..4eec6b1 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9\.]*" + grep -o "[0-9\.]" #@git push --tags @rm -f CHANGELOG.copy.txt From cc9f35a138143eba639b8a8aa234d34b2cc17901 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:39:49 -0400 Subject: [PATCH 44/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 2 +- 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index b6afbb3..167a423 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +4bbe780 updated CHANGELOG.txt 81a4c5b updated CHANGELOG.txt 67bc6f1 updated CHANGELOG.txt e0693ed updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 4eec6b1..164cac1 100644 --- a/Makefile +++ b/Makefile @@ -106,7 +106,7 @@ bump-patch: ## bump patch version and push new tag git commit -m "updated CHANGELOG.txt" bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9\.]" + grep -o "[0-9]*\.[0-9]*\.[0-9]*$$" #@git push --tags @rm -f CHANGELOG.copy.txt From 8ae14a5ba25fed9fd3fe4b481ab46e145c41ce53 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:40:57 -0400 Subject: [PATCH 45/82] updated CHANGELOG.txt --- CHANGELOG.txt | 1 + Makefile | 5 +++-- 2 files changed, 4 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 167a423..828df1e 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +cc9f35a updated CHANGELOG.txt 4bbe780 updated CHANGELOG.txt 81a4c5b updated CHANGELOG.txt 67bc6f1 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 164cac1..43c8c5a 100644 --- a/Makefile +++ b/Makefile @@ -104,9 +104,10 @@ bump-patch: ## bump patch version and push new tag git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt git add -A git commit -m "updated CHANGELOG.txt" - bumpversion --dry-run --list patch | \ + newversion := $(shell bumpversion --dry-run --list patch | \ grep "^new_version=.*$$" | \ - grep -o "[0-9]*\.[0-9]*\.[0-9]*$$" + grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") + echo newversion #@git push --tags @rm -f CHANGELOG.copy.txt From cc1e3555bee670bfbd8734be7a3736aeb9af508d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:48:06 -0400 Subject: [PATCH 46/82] misc --- CHANGELOG.txt | 1 + Makefile | 18 ++++++++++-------- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 828df1e..bcbfbfc 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +8ae14a5 updated CHANGELOG.txt cc9f35a updated CHANGELOG.txt 4bbe780 updated CHANGELOG.txt 81a4c5b updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 43c8c5a..286123c 100644 --- a/Makefile +++ b/Makefile @@ -1,6 +1,11 @@ .DEFAULT_GOAL := help +nextpatchversion := $(shell bumpversion \ + --no-commit --no-tag --dry-run --list patch --allow-dirty | \ + grep "^new_version=.*$$" | \ + grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") + define LEAD_AUTHORS Lead developers: David R. Smith @@ -99,17 +104,14 @@ bump-minor: ## bump minor version and push new tag .PHONY: bump-patch bump-patch: ## bump patch version and push new tag - @cp -f CHANGELOG.txt CHANGELOG.copy.txt + #@cp -f CHANGELOG.txt CHANGELOG.copy.txt @git rm CHANGELOG.txt git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt - git add -A - git commit -m "updated CHANGELOG.txt" - newversion := $(shell bumpversion --dry-run --list patch | \ - grep "^new_version=.*$$" | \ - grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") - echo newversion + #git add -A + #git commit -m "updated CHANGELOG.txt" + echo nextpatchversion #@git push --tags - @rm -f CHANGELOG.copy.txt + #@rm -f CHANGELOG.copy.txt .PHONY: clean From 1db2305c95f9264a7045185b6bd1aa2392c42a96 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:49:18 -0400 Subject: [PATCH 47/82] misc --- CHANGELOG.txt | 1 + Makefile | 4 ++-- 2 files changed, 3 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index bcbfbfc..6423f72 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,4 @@ +cc1e355 misc 8ae14a5 updated CHANGELOG.txt cc9f35a updated CHANGELOG.txt 4bbe780 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 286123c..4a750a6 100644 --- a/Makefile +++ b/Makefile @@ -104,14 +104,14 @@ bump-minor: ## bump minor version and push new tag .PHONY: bump-patch bump-patch: ## bump patch version and push new tag - #@cp -f CHANGELOG.txt CHANGELOG.copy.txt + @cp -f CHANGELOG.txt CHANGELOG.copy.txt @git rm CHANGELOG.txt git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt #git add -A #git commit -m "updated CHANGELOG.txt" echo nextpatchversion #@git push --tags - #@rm -f CHANGELOG.copy.txt + @rm -f CHANGELOG.copy.txt .PHONY: clean From 5e751ce82700a5d15bb1010ce4ec28c57f658705 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:53:39 -0400 Subject: [PATCH 48/82] updated CHANGELOG.txt --- CHANGELOG.txt | 5 +++++ Makefile | 12 +++++++----- 2 files changed, 12 insertions(+), 5 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 6423f72..2b54580 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,6 @@ +Release v0.1.2 + +1db2305 misc cc1e355 misc 8ae14a5 updated CHANGELOG.txt cc9f35a updated CHANGELOG.txt @@ -27,3 +30,5 @@ e44f558 updated CHANGELOG.txt 5817adf updated CHANGELOG.txt 2e6f692 updated CHANGELOG.txt a16db5c added recipe in Makefile + + diff --git a/Makefile b/Makefile index 4a750a6..8ad1251 100644 --- a/Makefile +++ b/Makefile @@ -105,11 +105,13 @@ bump-minor: ## bump minor version and push new tag .PHONY: bump-patch bump-patch: ## bump patch version and push new tag @cp -f CHANGELOG.txt CHANGELOG.copy.txt - @git rm CHANGELOG.txt - git log --oneline `git describe --tags --abbrev=0`..HEAD > CHANGELOG.txt - #git add -A - #git commit -m "updated CHANGELOG.txt" - echo nextpatchversion + @rm -f CHANGELOG.txt + @echo "Release v$(nextpatchversion)\n" > CHANGELOG.txt + @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt + @echo "\n" >> CHANGELOG.txt + @git add -A + @git commit -m "updated CHANGELOG.txt" + #@bumpversion patch #@git push --tags @rm -f CHANGELOG.copy.txt From c66e7e62615bdd5025e648e487cefe4660bdac9a Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:57:19 -0400 Subject: [PATCH 49/82] updated CHANGELOG.txt --- CHANGELOG.txt | 3 ++- Makefile | 4 +++- 2 files changed, 5 insertions(+), 2 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2b54580..66e5257 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,6 @@ -Release v0.1.2 +Release v0.1.2 -- 2017-04-07 +5e751ce updated CHANGELOG.txt 1db2305 misc cc1e355 misc 8ae14a5 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 8ad1251..e075d16 100644 --- a/Makefile +++ b/Makefile @@ -6,6 +6,8 @@ nextpatchversion := $(shell bumpversion \ grep "^new_version=.*$$" | \ grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") +today := $(shell date +%F) + define LEAD_AUTHORS Lead developers: David R. Smith @@ -106,7 +108,7 @@ bump-minor: ## bump minor version and push new tag bump-patch: ## bump patch version and push new tag @cp -f CHANGELOG.txt CHANGELOG.copy.txt @rm -f CHANGELOG.txt - @echo "Release v$(nextpatchversion)\n" > CHANGELOG.txt + @echo "Release v$(nextpatchversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt @git add -A From 40598a3cb3363f73e01e67fbe9cc1a4ef8628d62 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 17:59:17 -0400 Subject: [PATCH 50/82] updated CHANGELOG.txt --- CHANGELOG.txt | 36 ++++++++++++++++++++++++++++++++++++ Makefile | 1 + 2 files changed, 37 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 66e5257..01e2dce 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,41 @@ Release v0.1.2 -- 2017-04-07 +c66e7e6 updated CHANGELOG.txt +5e751ce updated CHANGELOG.txt +1db2305 misc +cc1e355 misc +8ae14a5 updated CHANGELOG.txt +cc9f35a updated CHANGELOG.txt +4bbe780 updated CHANGELOG.txt +81a4c5b updated CHANGELOG.txt +67bc6f1 updated CHANGELOG.txt +e0693ed updated CHANGELOG.txt +a379761 updated CHANGELOG.txt +28ad5d5 updated CHANGELOG.txt +7d00add updated CHANGELOG.txt +4ba1ffe updated CHANGELOG.txt +5784200 updated CHANGELOG.txt +0166cba updated CHANGELOG.txt +17c067b updated CHANGELOG.txt +a262803 updated CHANGELOG.txt +de02021 updated CHANGELOG.txt +730c737 updated CHANGELOG.txt +ec4cc44 updated CHANGELOG.txt +179b44d updated CHANGELOG.txt +d96a74a updated CHANGELOG.txt +f50fb46 updated CHANGELOG.txt +d2085a7 updated CHANGELOG.txt +cdf3789 updated CHANGELOG.txt +21489ba updated CHANGELOG.txt +e44f558 updated CHANGELOG.txt +7061e58 updated CHANGELOG.txt +5817adf updated CHANGELOG.txt +2e6f692 updated CHANGELOG.txt +a16db5c added recipe in Makefile + + +Release v0.1.2 -- 2017-04-07 + 5e751ce updated CHANGELOG.txt 1db2305 misc cc1e355 misc diff --git a/Makefile b/Makefile index e075d16..1d006e6 100644 --- a/Makefile +++ b/Makefile @@ -111,6 +111,7 @@ bump-patch: ## bump patch version and push new tag @echo "Release v$(nextpatchversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt + @cat CHANGELOG.copy.txt >> CHANGELOG.txt @git add -A @git commit -m "updated CHANGELOG.txt" #@bumpversion patch From 846e8a011cdb271e32fefaf908c6939c04be36df Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:00:21 -0400 Subject: [PATCH 51/82] updated CHANGELOG.txt --- CHANGELOG.txt | 36 +----------------------------------- Makefile | 6 +++--- 2 files changed, 4 insertions(+), 38 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 01e2dce..7e96392 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,5 +1,6 @@ Release v0.1.2 -- 2017-04-07 +40598a3 updated CHANGELOG.txt c66e7e6 updated CHANGELOG.txt 5e751ce updated CHANGELOG.txt 1db2305 misc @@ -34,38 +35,3 @@ e44f558 updated CHANGELOG.txt a16db5c added recipe in Makefile -Release v0.1.2 -- 2017-04-07 - -5e751ce updated CHANGELOG.txt -1db2305 misc -cc1e355 misc -8ae14a5 updated CHANGELOG.txt -cc9f35a updated CHANGELOG.txt -4bbe780 updated CHANGELOG.txt -81a4c5b updated CHANGELOG.txt -67bc6f1 updated CHANGELOG.txt -e0693ed updated CHANGELOG.txt -a379761 updated CHANGELOG.txt -28ad5d5 updated CHANGELOG.txt -7d00add updated CHANGELOG.txt -4ba1ffe updated CHANGELOG.txt -5784200 updated CHANGELOG.txt -0166cba updated CHANGELOG.txt -17c067b updated CHANGELOG.txt -a262803 updated CHANGELOG.txt -de02021 updated CHANGELOG.txt -730c737 updated CHANGELOG.txt -ec4cc44 updated CHANGELOG.txt -179b44d updated CHANGELOG.txt -d96a74a updated CHANGELOG.txt -f50fb46 updated CHANGELOG.txt -d2085a7 updated CHANGELOG.txt -cdf3789 updated CHANGELOG.txt -21489ba updated CHANGELOG.txt -e44f558 updated CHANGELOG.txt -7061e58 updated CHANGELOG.txt -5817adf updated CHANGELOG.txt -2e6f692 updated CHANGELOG.txt -a16db5c added recipe in Makefile - - diff --git a/Makefile b/Makefile index 1d006e6..00ad79c 100644 --- a/Makefile +++ b/Makefile @@ -112,11 +112,11 @@ bump-patch: ## bump patch version and push new tag @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt @cat CHANGELOG.copy.txt >> CHANGELOG.txt + @rm -f CHANGELOG.copy.txt @git add -A @git commit -m "updated CHANGELOG.txt" - #@bumpversion patch - #@git push --tags - @rm -f CHANGELOG.copy.txt + @bumpversion patch + @git push --tags .PHONY: clean From 797c65411429b944583d4ddb838d7682e9d7e8ea Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:00:21 -0400 Subject: [PATCH 52/82] =?UTF-8?q?Bump=20version:=200.1.1=20=E2=86=92=200.1?= =?UTF-8?q?.2?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 8c44d54..d8228ab 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.1 +current_version = 0.1.2 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index 6d9d53e..a90c39e 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.1.1' +version = '0.1.2' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index 642428f..76a5c36 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.1.1' +__version__ = '0.1.2' def nstxu(): From 9f002c79ada5487d63ddba7fdb1da47c4277c2ae Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:01:09 -0400 Subject: [PATCH 53/82] misc --- CHANGELOG.txt | 2 ++ 1 file changed, 2 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 7e96392..d262fea 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,5 @@ +test test test + Release v0.1.2 -- 2017-04-07 40598a3 updated CHANGELOG.txt From 206717a921bff54c8f459aaa1850b5cc658d6149 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:01:15 -0400 Subject: [PATCH 54/82] updated CHANGELOG.txt --- CHANGELOG.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index d262fea..2fe6cc9 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,8 @@ +Release v0.1.3 -- 2017-04-07 + +9f002c7 misc + + test test test Release v0.1.2 -- 2017-04-07 From b83d8560fd1f705ac6f30e1ad21f6241450bb1b9 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:01:15 -0400 Subject: [PATCH 55/82] =?UTF-8?q?Bump=20version:=200.1.2=20=E2=86=92=200.1?= =?UTF-8?q?.3?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index d8228ab..54cc785 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.2 +current_version = 0.1.3 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index a90c39e..caa81bb 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.1.2' +version = '0.1.3' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index 76a5c36..e1b8b49 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.1.2' +__version__ = '0.1.3' def nstxu(): From a2842c8c4de8eb77894776168fa5a1c77b2e8983 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:08:36 -0400 Subject: [PATCH 56/82] added automatic CHANGELOG.txt updates with 'bump-*' recipes in Makefile --- CHANGELOG.txt | 2 -- Makefile | 43 ++++++++++++++++++++++++++++++++++--------- 2 files changed, 34 insertions(+), 11 deletions(-) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index 2fe6cc9..ecc79ef 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -3,8 +3,6 @@ Release v0.1.3 -- 2017-04-07 9f002c7 misc -test test test - Release v0.1.2 -- 2017-04-07 40598a3 updated CHANGELOG.txt diff --git a/Makefile b/Makefile index 00ad79c..5bf21d2 100644 --- a/Makefile +++ b/Makefile @@ -1,13 +1,20 @@ .DEFAULT_GOAL := help +today := $(shell date +%F) +nextmajorversion := $(shell bumpversion \ + --no-commit --no-tag --dry-run --list major | \ + grep "^new_version=.*$$" | \ + grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") +nextminorversion := $(shell bumpversion \ + --no-commit --no-tag --dry-run --list minor | \ + grep "^new_version=.*$$" | \ + grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") nextpatchversion := $(shell bumpversion \ - --no-commit --no-tag --dry-run --list patch --allow-dirty | \ + --no-commit --no-tag --dry-run --list patch | \ grep "^new_version=.*$$" | \ grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") -today := $(shell date +%F) - define LEAD_AUTHORS Lead developers: David R. Smith @@ -94,14 +101,32 @@ authors: ## create AUTHORS.txt .PHONY: bump-major bump-major: ## bump major version and push new tag - bumpversion major # runs 'git commit' and 'git tag - git push --tags + @cp -f CHANGELOG.txt CHANGELOG.copy.txt + @rm -f CHANGELOG.txt + @echo "Release v$(nextmajorversion) -- $(today)\n" > CHANGELOG.txt + @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt + @echo "\n" >> CHANGELOG.txt + @cat CHANGELOG.copy.txt >> CHANGELOG.txt + @rm -f CHANGELOG.copy.txt + @git add CHANGELOG.txt + @git commit -m "updated CHANGELOG.txt" + @bumpversion major # runs 'git commit' and 'git tag' + @git push --tags .PHONY: bump-minor bump-minor: ## bump minor version and push new tag - bumpversion minor # runs 'git commit' and 'git tag - git push --tags + @cp -f CHANGELOG.txt CHANGELOG.copy.txt + @rm -f CHANGELOG.txt + @echo "Release v$(nextminorversion) -- $(today)\n" > CHANGELOG.txt + @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt + @echo "\n" >> CHANGELOG.txt + @cat CHANGELOG.copy.txt >> CHANGELOG.txt + @rm -f CHANGELOG.copy.txt + @git add CHANGELOG.txt + @git commit -m "updated CHANGELOG.txt" + @bumpversion minor # runs 'git commit' and 'git tag' + @git push --tags .PHONY: bump-patch @@ -113,9 +138,9 @@ bump-patch: ## bump patch version and push new tag @echo "\n" >> CHANGELOG.txt @cat CHANGELOG.copy.txt >> CHANGELOG.txt @rm -f CHANGELOG.copy.txt - @git add -A + @git add CHANGELOG.txt @git commit -m "updated CHANGELOG.txt" - @bumpversion patch + @bumpversion patch # runs 'git commit' and 'git tag' @git push --tags From 4659aa7d2cbb3e3ba3b807e07a632b788c9b36a1 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:08:49 -0400 Subject: [PATCH 57/82] updated CHANGELOG.txt --- CHANGELOG.txt | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGELOG.txt b/CHANGELOG.txt index ecc79ef..b676f36 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,8 @@ +Release v0.1.4 -- 2017-04-07 + +a2842c8 added automatic CHANGELOG.txt updates with 'bump-*' recipes in Makefile + + Release v0.1.3 -- 2017-04-07 9f002c7 misc From f815a6f2d389bc07e96fd3f4030389e18ae988e5 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:08:49 -0400 Subject: [PATCH 58/82] =?UTF-8?q?Bump=20version:=200.1.3=20=E2=86=92=200.1?= =?UTF-8?q?.4?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 54cc785..4daf757 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.3 +current_version = 0.1.4 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index caa81bb..16ea139 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.1.3' +version = '0.1.4' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index e1b8b49..76bd029 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.1.3' +__version__ = '0.1.4' def nstxu(): From a06ac9b410e5a84b635be1c3c8ddaed817b869ec Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Fri, 7 Apr 2017 18:12:33 -0400 Subject: [PATCH 59/82] run 'authors' recipe prior to 'bump-*' recipes in Makefile --- Makefile | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Makefile b/Makefile index 5bf21d2..16330a6 100644 --- a/Makefile +++ b/Makefile @@ -100,7 +100,7 @@ authors: ## create AUTHORS.txt .PHONY: bump-major -bump-major: ## bump major version and push new tag +bump-major: authors ## bump major version and push new tag @cp -f CHANGELOG.txt CHANGELOG.copy.txt @rm -f CHANGELOG.txt @echo "Release v$(nextmajorversion) -- $(today)\n" > CHANGELOG.txt @@ -108,14 +108,14 @@ bump-major: ## bump major version and push new tag @echo "\n" >> CHANGELOG.txt @cat CHANGELOG.copy.txt >> CHANGELOG.txt @rm -f CHANGELOG.copy.txt - @git add CHANGELOG.txt - @git commit -m "updated CHANGELOG.txt" + @git add CHANGELOG.txt AUTHORS.txt + @git commit -m "updated CHANGELOG.txt and AUTHORS.txt" @bumpversion major # runs 'git commit' and 'git tag' @git push --tags .PHONY: bump-minor -bump-minor: ## bump minor version and push new tag +bump-minor: authors ## bump minor version and push new tag @cp -f CHANGELOG.txt CHANGELOG.copy.txt @rm -f CHANGELOG.txt @echo "Release v$(nextminorversion) -- $(today)\n" > CHANGELOG.txt @@ -123,14 +123,14 @@ bump-minor: ## bump minor version and push new tag @echo "\n" >> CHANGELOG.txt @cat CHANGELOG.copy.txt >> CHANGELOG.txt @rm -f CHANGELOG.copy.txt - @git add CHANGELOG.txt - @git commit -m "updated CHANGELOG.txt" + @git add CHANGELOG.txt AUTHORS.txt + @git commit -m "updated CHANGELOG.txt and AUTHORS.txt" @bumpversion minor # runs 'git commit' and 'git tag' @git push --tags .PHONY: bump-patch -bump-patch: ## bump patch version and push new tag +bump-patch: authors ## bump patch version and push new tag @cp -f CHANGELOG.txt CHANGELOG.copy.txt @rm -f CHANGELOG.txt @echo "Release v$(nextpatchversion) -- $(today)\n" > CHANGELOG.txt @@ -138,8 +138,8 @@ bump-patch: ## bump patch version and push new tag @echo "\n" >> CHANGELOG.txt @cat CHANGELOG.copy.txt >> CHANGELOG.txt @rm -f CHANGELOG.copy.txt - @git add CHANGELOG.txt - @git commit -m "updated CHANGELOG.txt" + @git add CHANGELOG.txt AUTHORS.txt + @git commit -m "updated CHANGELOG.txt and AUTHORS.txt" @bumpversion patch # runs 'git commit' and 'git tag' @git push --tags From 17e9578f0023c30ddb0689b708f5ac1986210c67 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Sat, 8 Apr 2017 00:10:47 -0400 Subject: [PATCH 60/82] removed pushes from bumps in Makefile --- Makefile | 27 ++++++++++++--------------- 1 file changed, 12 insertions(+), 15 deletions(-) diff --git a/Makefile b/Makefile index 16330a6..63dd365 100644 --- a/Makefile +++ b/Makefile @@ -100,48 +100,45 @@ authors: ## create AUTHORS.txt .PHONY: bump-major -bump-major: authors ## bump major version and push new tag - @cp -f CHANGELOG.txt CHANGELOG.copy.txt +bump-major: authors ## bump major version, tag, and push + @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextmajorversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt - @cat CHANGELOG.copy.txt >> CHANGELOG.txt - @rm -f CHANGELOG.copy.txt + @cat tmp.txt >> CHANGELOG.txt + @rm -f tmp.txt @git add CHANGELOG.txt AUTHORS.txt @git commit -m "updated CHANGELOG.txt and AUTHORS.txt" @bumpversion major # runs 'git commit' and 'git tag' - @git push --tags .PHONY: bump-minor -bump-minor: authors ## bump minor version and push new tag - @cp -f CHANGELOG.txt CHANGELOG.copy.txt +bump-minor: authors ## bump minor version, tag, and push + @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextminorversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt - @cat CHANGELOG.copy.txt >> CHANGELOG.txt - @rm -f CHANGELOG.copy.txt + @cat tmp.txt >> CHANGELOG.txt + @rm -f tmp.txt @git add CHANGELOG.txt AUTHORS.txt @git commit -m "updated CHANGELOG.txt and AUTHORS.txt" @bumpversion minor # runs 'git commit' and 'git tag' - @git push --tags .PHONY: bump-patch -bump-patch: authors ## bump patch version and push new tag - @cp -f CHANGELOG.txt CHANGELOG.copy.txt +bump-patch: authors ## bump patch version, tag, and push + @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextpatchversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt - @cat CHANGELOG.copy.txt >> CHANGELOG.txt - @rm -f CHANGELOG.copy.txt + @cat tmp.txt >> CHANGELOG.txt + @rm -f tmp.txt @git add CHANGELOG.txt AUTHORS.txt @git commit -m "updated CHANGELOG.txt and AUTHORS.txt" @bumpversion patch # runs 'git commit' and 'git tag' - @git push --tags .PHONY: clean From fa1a1fb797159e757a2440b7af0fc2dcdaacffb1 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Sat, 8 Apr 2017 01:27:26 -0400 Subject: [PATCH 61/82] docs --- CHANGELOG.txt | 44 -------------------------------------- LICENSE.rst => LICENSE.txt | 5 ----- Makefile | 19 ++++++++-------- docs/source/authors.rst | 5 +++++ docs/source/changelog.rst | 5 +++++ docs/source/index.rst | 8 ++++--- docs/source/license.rst | 6 +++++- 7 files changed, 29 insertions(+), 63 deletions(-) rename LICENSE.rst => LICENSE.txt (96%) create mode 100644 docs/source/authors.rst create mode 100644 docs/source/changelog.rst diff --git a/CHANGELOG.txt b/CHANGELOG.txt index b676f36..ad9a8db 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,47 +1,3 @@ Release v0.1.4 -- 2017-04-07 a2842c8 added automatic CHANGELOG.txt updates with 'bump-*' recipes in Makefile - - -Release v0.1.3 -- 2017-04-07 - -9f002c7 misc - - -Release v0.1.2 -- 2017-04-07 - -40598a3 updated CHANGELOG.txt -c66e7e6 updated CHANGELOG.txt -5e751ce updated CHANGELOG.txt -1db2305 misc -cc1e355 misc -8ae14a5 updated CHANGELOG.txt -cc9f35a updated CHANGELOG.txt -4bbe780 updated CHANGELOG.txt -81a4c5b updated CHANGELOG.txt -67bc6f1 updated CHANGELOG.txt -e0693ed updated CHANGELOG.txt -a379761 updated CHANGELOG.txt -28ad5d5 updated CHANGELOG.txt -7d00add updated CHANGELOG.txt -4ba1ffe updated CHANGELOG.txt -5784200 updated CHANGELOG.txt -0166cba updated CHANGELOG.txt -17c067b updated CHANGELOG.txt -a262803 updated CHANGELOG.txt -de02021 updated CHANGELOG.txt -730c737 updated CHANGELOG.txt -ec4cc44 updated CHANGELOG.txt -179b44d updated CHANGELOG.txt -d96a74a updated CHANGELOG.txt -f50fb46 updated CHANGELOG.txt -d2085a7 updated CHANGELOG.txt -cdf3789 updated CHANGELOG.txt -21489ba updated CHANGELOG.txt -e44f558 updated CHANGELOG.txt -7061e58 updated CHANGELOG.txt -5817adf updated CHANGELOG.txt -2e6f692 updated CHANGELOG.txt -a16db5c added recipe in Makefile - - diff --git a/LICENSE.rst b/LICENSE.txt similarity index 96% rename from LICENSE.rst rename to LICENSE.txt index bf9b46d..03f578c 100644 --- a/LICENSE.rst +++ b/LICENSE.txt @@ -1,8 +1,3 @@ -License -========== - -The MIT License (MIT) - Copyright (c) 2015-2017 David R. Smith, Kevin Tritz, Howard Yuh Permission is hereby granted, free of charge, to any person obtaining a copy diff --git a/Makefile b/Makefile index 63dd365..d1f48da 100644 --- a/Makefile +++ b/Makefile @@ -3,15 +3,15 @@ today := $(shell date +%F) nextmajorversion := $(shell bumpversion \ - --no-commit --no-tag --dry-run --list major | \ + --no-commit --no-tag --dry-run --list major --allow-dirty | \ grep "^new_version=.*$$" | \ grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") nextminorversion := $(shell bumpversion \ - --no-commit --no-tag --dry-run --list minor | \ + --no-commit --no-tag --dry-run --list minor --allow-dirty | \ grep "^new_version=.*$$" | \ grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") nextpatchversion := $(shell bumpversion \ - --no-commit --no-tag --dry-run --list patch | \ + --no-commit --no-tag --dry-run --list patch --allow-dirty | \ grep "^new_version=.*$$" | \ grep -o "[0-9]*\.[0-9]*\.[0-9]*$$") @@ -66,7 +66,7 @@ help: ## show this help message .PHONY: docs -docs: docs-html docs-pdf ## build HTML and PDF documents +docs: docs-pdf docs-html ## build HTML and PDF documents .PHONY: docs-html @@ -92,7 +92,7 @@ autopep: ## run autopep8 to fix minor pep8 violations .PHONY: authors -authors: ## create AUTHORS.txt +authors: ## update AUTHORS.txt @echo "$$LEAD_AUTHORS" > AUTHORS.txt @echo "Commits from authors:" >> AUTHORS.txt @git shortlog -s -n >> AUTHORS.txt @@ -100,7 +100,7 @@ authors: ## create AUTHORS.txt .PHONY: bump-major -bump-major: authors ## bump major version, tag, and push +bump-major: authors ## bump major version and tag @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextmajorversion) -- $(today)\n" > CHANGELOG.txt @@ -114,9 +114,8 @@ bump-major: authors ## bump major version, tag, and push .PHONY: bump-minor -bump-minor: authors ## bump minor version, tag, and push - @cp -f CHANGELOG.txt tmp.txt - @rm -f CHANGELOG.txt +bump-minor: authors ## bump minor version and tag + @mv CHANGELOG.txt tmp.txt @echo "Release v$(nextminorversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @echo "\n" >> CHANGELOG.txt @@ -128,7 +127,7 @@ bump-minor: authors ## bump minor version, tag, and push .PHONY: bump-patch -bump-patch: authors ## bump patch version, tag, and push +bump-patch: authors ## bump patch version and tag @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextpatchversion) -- $(today)\n" > CHANGELOG.txt diff --git a/docs/source/authors.rst b/docs/source/authors.rst new file mode 100644 index 0000000..c86b6e5 --- /dev/null +++ b/docs/source/authors.rst @@ -0,0 +1,5 @@ +Authors +============== + +.. include:: ../../AUTHORS.txt + :literal: \ No newline at end of file diff --git a/docs/source/changelog.rst b/docs/source/changelog.rst new file mode 100644 index 0000000..e338e11 --- /dev/null +++ b/docs/source/changelog.rst @@ -0,0 +1,5 @@ +Change Log +============== + +.. include:: ../../CHANGELOG.txt + :literal: \ No newline at end of file diff --git a/docs/source/index.rst b/docs/source/index.rst index 413fe5d..06ae550 100755 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -2,9 +2,9 @@ Fusion Data Platform ====================================== .. only:: html - + Fusion Data Platform (FDP) is a data framework in Python for magnetic fusion experiments. FDP streamlines data discovery, management, analysis methods, and visualization. - + * Github repository: https://github.com/Fusion-Data-Platform/fdp * Documentation: http://Fusion-Data-Platform.github.io/ * Google group: https://groups.google.com/forum/#!forum/fusion-data-platform @@ -14,11 +14,13 @@ Fusion Data Platform .. toctree:: :maxdepth: 2 - + Overview user_guide developer_guide project_documents + authors + changelog license diff --git a/docs/source/license.rst b/docs/source/license.rst index 2a90cf4..f31a59b 100644 --- a/docs/source/license.rst +++ b/docs/source/license.rst @@ -1 +1,5 @@ -.. include:: ../../LICENSE.rst \ No newline at end of file +License +========= + +.. include:: ../../LICENSE.txt + :literal: \ No newline at end of file From bab6bbc77fe9c0d1bf48cd9fdd6a340d5bef7708 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Sun, 9 Apr 2017 13:24:09 -0400 Subject: [PATCH 62/82] docs --- CONTRIBUTING.rst | 19 +++++++++++++++++++ Makefile | 3 ++- docs/source/contributing.rst | 1 + docs/source/index.rst | 1 + 4 files changed, 23 insertions(+), 1 deletion(-) create mode 100644 CONTRIBUTING.rst create mode 100644 docs/source/contributing.rst diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst new file mode 100644 index 0000000..24de375 --- /dev/null +++ b/CONTRIBUTING.rst @@ -0,0 +1,19 @@ +How to contribute +======================== + +Github repository: https://github.com/Fusion-Data-Platform/fdp + +**Code** + +To contribute to the FDP code base, fork the repo at Github to create a personal repo and submit pull requests with your contributions. + + * https://guides.github.com/activities/forking/ + * https://help.github.com/articles/fork-a-repo/ + +**Bugs** + +Please report bugs as Github issues: https://github.com/Fusion-Data-Platform/fdp/issues + +**Style** + +Please adhere to the `PEP8 style guide `_. To run a PEP8 conformance scan and view the report, run ``make lint`` in the top-level directory. diff --git a/Makefile b/Makefile index d1f48da..b93c02b 100644 --- a/Makefile +++ b/Makefile @@ -82,7 +82,8 @@ docs-pdf: ## build PDF documents .PHONY: lint lint: ## run flake8 for code quality review - flake8 --exit-zero fdp/ test/ + @rm -f flake8.output.txt + flake8 --exit-zero fdp/ .PHONY: autopep diff --git a/docs/source/contributing.rst b/docs/source/contributing.rst new file mode 100644 index 0000000..ac7b6bc --- /dev/null +++ b/docs/source/contributing.rst @@ -0,0 +1 @@ +.. include:: ../../CONTRIBUTING.rst diff --git a/docs/source/index.rst b/docs/source/index.rst index 06ae550..f05fc57 100755 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -19,6 +19,7 @@ Fusion Data Platform user_guide developer_guide project_documents + Contributing authors changelog license From 7d32fd692cee2cf2179f4526ed2fddfe2484d044 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Sun, 9 Apr 2017 13:50:54 -0400 Subject: [PATCH 63/82] docs --- CONTRIBUTING.rst | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 24de375..64a8ae5 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -5,15 +5,15 @@ Github repository: https://github.com/Fusion-Data-Platform/fdp **Code** -To contribute to the FDP code base, fork the repo at Github to create a personal repo and submit pull requests with your contributions. +Thank you for your interest in the FDP project. To contribute to the FDP code base, fork the repo at Github to create a personal repo and submit pull requests with your contributions. Read more: * https://guides.github.com/activities/forking/ * https://help.github.com/articles/fork-a-repo/ **Bugs** -Please report bugs as Github issues: https://github.com/Fusion-Data-Platform/fdp/issues +Report bugs as Github issues: https://github.com/Fusion-Data-Platform/fdp/issues **Style** -Please adhere to the `PEP8 style guide `_. To run a PEP8 conformance scan and view the report, run ``make lint`` in the top-level directory. +Please try to follow the `PEP8 style guide `_. To scan for PEP8 conformance, run ``make lint`` in the top-level directory. From 09f779aeb86126ff2c9d6e976bf5de93451c544c Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 10 Apr 2017 14:29:28 -0400 Subject: [PATCH 64/82] changed iteritems to iter() --- fdp/classes/datasources.py | 4 ++-- fdp/classes/signal.py | 10 +++++----- 2 files changed, 7 insertions(+), 7 deletions(-) diff --git a/fdp/classes/datasources.py b/fdp/classes/datasources.py index f46076a..8968f7d 100644 --- a/fdp/classes/datasources.py +++ b/fdp/classes/datasources.py @@ -41,8 +41,8 @@ def machineAlias(machine): 'cmod': ['cmod', 'c-mod'] } - for key, value in aliases.iteritems(): - if machine.lower() in value: + for key in iter(aliases): + if machine.lower() in aliases[key]: return key # invalid machine name txt = '"{}" is not a valid machine name\n'.format(machine) diff --git a/fdp/classes/signal.py b/fdp/classes/signal.py index dc026f8..e9f9af9 100755 --- a/fdp/classes/signal.py +++ b/fdp/classes/signal.py @@ -43,8 +43,8 @@ def __new__(cls, input_array=[], **kwargs): format(kwargs['_name'], cls)) # ndarray.view().copy() calls __array_finalize__ obj = np.asanyarray(input_array).view(cls).copy() - for key, value in kwargs.iteritems(): - setattr(obj, key, value) + for key in iter(kwargs): + setattr(obj, key, kwargs[key]) return obj def __init__(self, **kwargs): @@ -75,15 +75,15 @@ def __array_finalize__(self, obj): print(' obj.axes is {}'.format(objaxes)) print(' obj._slic is {}'.format(objslic)) - for key, val in objdict.iteritems(): + for key in iter(objdict): if objaxes and key in objaxes: # skip copy of axis attributes pass elif key in ['axes', 'point_axes']: # shallow copy obj.axes and obj.point_axes - setattr(self, key, val[:]) + setattr(self, key, objdict[key][:]) else: - setattr(self, key, val) + setattr(self, key, objdict[key]) if objdict.get('_fname') == 'transpose': if objaxes is not None: From ea8852be66355079648507fca1c957cdf78c5795 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 10 Apr 2017 15:25:38 -0400 Subject: [PATCH 65/82] changed 'zero level' indices to floats --- fdp/classes/crosssignal.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/fdp/classes/crosssignal.py b/fdp/classes/crosssignal.py index 9de3f6b..e2bdbef 100644 --- a/fdp/classes/crosssignal.py +++ b/fdp/classes/crosssignal.py @@ -161,9 +161,9 @@ def apply_offset_minimum(self): """ - zerolevel1 = np.mean(self.signal1[1e3:2e3]) + zerolevel1 = np.mean(self.signal1[1000:2000]) self.signal1 -= zerolevel1 - zerolevel2 = np.mean(self.signal2[1e3:2e3]) + zerolevel2 = np.mean(self.signal2[1000:2000]) self.signal2 -= zerolevel2 def make_data_window(self): From ddd16a51318f864e14d534809f775d0dce13d276 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 10 Apr 2017 16:06:04 -0400 Subject: [PATCH 66/82] minor fixes --- fdp/classes/fft.py | 4 ++-- fdp/classes/machine.py | 1 + fdp/methods/plot.py | 4 ++-- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/fdp/classes/fft.py b/fdp/classes/fft.py index 1119da5..b3f8515 100644 --- a/fdp/classes/fft.py +++ b/fdp/classes/fft.py @@ -125,7 +125,7 @@ def makeTimeBins(self): self.nbins = self.time.size def applyMinimumOffset(self): - zerosignal = np.min(self.signal[0:1e4]) + zerosignal = np.min(self.signal[1000:9000]) self.fft -= zerosignal def applyDcOffset(self): @@ -142,7 +142,7 @@ def calcIntegratedSignalPower(self): self.intpower = np.sum(np.square(np.absolute(self.fft)), axis=1) def calcFft(self): - timeint = np.mean(np.diff(self.signal.time[0:1e4])) + timeint = np.mean(np.diff(self.signal.time[1000:9000])) # complex-valued, double-sided FFT self.fft = fftpack.fft(self.fft, n=self.power2, diff --git a/fdp/classes/machine.py b/fdp/classes/machine.py index 6b3b768..896fa7a 100755 --- a/fdp/classes/machine.py +++ b/fdp/classes/machine.py @@ -143,6 +143,7 @@ def _get_mdsdata(self, signal): msg = 'MDSplus connection error for shot {}, tree {}, and node {}'.format( signal.shot, signal._mdstree, signal._mdsnode) warn(msg, FdpWarning) + # TODO: return value of failed connection? return np.zeros(0) try: if hasattr(signal, '_raw_of') and signal._raw_of is not None: diff --git a/fdp/methods/plot.py b/fdp/methods/plot.py index b41ae66..038fd0f 100755 --- a/fdp/methods/plot.py +++ b/fdp/methods/plot.py @@ -105,10 +105,10 @@ def plot(signal, fig=None, ax=None, **kwargs): return signal[:] - if signal.size == 0: + if not signal: warn("Empty signal {}".format(signal._mdsnode), FdpWarning) signal.time[:] - if signal.time.size == 0: + if not signal.time: warn("Empty signal.time {}".format(signal.time._mdsnode), FdpWarning) dims = signal.ndim From 7adfae2f72bc8f6e12f92ce03712ef1dbc6eb5f4 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 10 Apr 2017 22:22:10 -0400 Subject: [PATCH 67/82] bfield() method for equilibria --- fdp/methods/nstxu/equilibria/bfield.py | 11 +++++------ fdp/methods/timeindex.py | 13 ++++++++----- 2 files changed, 13 insertions(+), 11 deletions(-) diff --git a/fdp/methods/nstxu/equilibria/bfield.py b/fdp/methods/nstxu/equilibria/bfield.py index c181dd4..bbff38d 100644 --- a/fdp/methods/nstxu/equilibria/bfield.py +++ b/fdp/methods/nstxu/equilibria/bfield.py @@ -1,13 +1,7 @@ # -*- coding: utf-8 -*- -""" -Created on Mon Oct 19 15:42:07 2015 - -@author: ktritz -""" import warnings - def bfield(obj, radius=None, z=None, time=None): # must call from equilibrium container if not obj.isContainer(): @@ -32,3 +26,8 @@ def bfield(obj, radius=None, z=None, time=None): # get time index tindex = eqdata.rmaxis.getTimeIndex(time=time) + + if eqdata.mw[tindex] <= 1 or eqdata.mh[tindex] <= 1: + warnings.warn( + 'Invalid reconstruction, returning') + return \ No newline at end of file diff --git a/fdp/methods/timeindex.py b/fdp/methods/timeindex.py index 2286c07..f97d421 100644 --- a/fdp/methods/timeindex.py +++ b/fdp/methods/timeindex.py @@ -8,15 +8,18 @@ import numpy as np -def getTimeIndex(obj, time=0.0): +def getTimeIndex(obj, time=None): """ Return time index <= input time """ if not obj.isSignal(): print('getTimeIndex() is only valid for signals, returning') return - indlist = np.nonzero(obj.time <= time) + if time is None: + print('getTimeIndex() requires a numeric scalar value') + return + output = None + indlist = np.nonzero(obj.time > time) if indlist[0].size > 0: - return indlist[0][-1] - else: - return None + output = indlist[0][0]-1 + return output \ No newline at end of file From a8e38e37000314ef5c29b83ecc5ee50b1e27f18d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Thu, 13 Apr 2017 19:10:57 -0400 Subject: [PATCH 68/82] fixed axis removal from multi-dim signals --- examples/plot_psirz.py | 12 ++++++++++-- fdp/classes/signal.py | 25 +++---------------------- 2 files changed, 13 insertions(+), 24 deletions(-) diff --git a/examples/plot_psirz.py b/examples/plot_psirz.py index 6ffb700..ec4de61 100644 --- a/examples/plot_psirz.py +++ b/examples/plot_psirz.py @@ -10,5 +10,13 @@ nstx = fdp.nstx() -eq = nstx.s204551.equilibria.efit01 -print(eq.psirz) \ No newline at end of file +psirz = nstx.s204551.equilibria.efit01.psirz +psirz[:] +print(psirz.shape, psirz.R.axes, dir(psirz.R)) +print(psirz) +print(psirz.shape, psirz.R.axes, dir(psirz.R)) + +b = psirz[0,:,:] +#print(b.shape, b.R.axes, dir(b.R)) +#print(b) +#print(b.shape, b.R.axes, dir(b.R)) diff --git a/fdp/classes/signal.py b/fdp/classes/signal.py index fa9e07c..b19270a 100755 --- a/fdp/classes/signal.py +++ b/fdp/classes/signal.py @@ -128,9 +128,9 @@ def __array_finalize__(self, obj): setattr(self, axis, obj_axis[slic_axis]) else: raise FdpError('slic_axis is unexpected type') - for axisaxis in obj_axis.axes: - if isinstance(objslic[objaxes.index(axisaxis)], (int, long, float, np.generic)): - obj_axis.axes.remove(axisaxis) +# for axisaxis in obj_axis.axes: +# if isinstance(objslic[objaxes.index(axisaxis)], (int, long, float, np.generic)): +# obj_axis.axes.remove(axisaxis) else: raise FdpError('obj._slic is unexpected type') else: @@ -139,25 +139,6 @@ def __array_finalize__(self, obj): print(' {}.__array_finalize__: copying axis {} to self'. format(self._name, axis)) setattr(self, axis, getattr(obj, axis, None)) - # remove all 'point_axes' keys from 'axes' list -# point_axes = getattr(self, 'point_axes') -# if point_axes: -# axes = getattr(self, 'axes') -# for pa in point_axes: -# axis = pa['axis'] -# if VERBOSE: -# print(' {}.__array_finalize__: Trying to delete {} axis'. -# format(self._name, axis)) -# if axis in axes: -# if VERBOSE: -# print('removing "{}" from self.axes'.format(axis)) -# axes.remove(axis) -# if hasattr(self, axis): -# if VERBOSE: -# print('deleting attr "{}" from self'.format(axis)) -# delattr(self, axis) -# setattr(self, 'axes', axes) - # end "if objaxes" block # clean-up temp attributes def delattrtry(ob, at): From be1449c4030f255cab8951ccec55fbfed6f95218 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 17 Apr 2017 14:53:09 -0400 Subject: [PATCH 69/82] minor --- CONTRIBUTING.rst | 37 +++++++++++++++++++++++++++++-------- Makefile | 6 +++--- README.rst | 6 +++++- 3 files changed, 37 insertions(+), 12 deletions(-) diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index 64a8ae5..d84d431 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -1,19 +1,40 @@ +======================== How to contribute ======================== -Github repository: https://github.com/Fusion-Data-Platform/fdp +* Github repository: https://github.com/Fusion-Data-Platform/fdp +* Submit bugs and feature requests as Github issues: https://github.com/Fusion-Data-Platform/fdp/issues +* Google group: https://groups.google.com/forum/#!forum/fusion-data-platform **Code** -Thank you for your interest in the FDP project. To contribute to the FDP code base, fork the repo at Github to create a personal repo and submit pull requests with your contributions. Read more: - - * https://guides.github.com/activities/forking/ - * https://help.github.com/articles/fork-a-repo/ +Thank you for your interest in the FDP project. To contribute to the FDP code base, fork the repo at Github and submit pull requests with your contributions. Read more: -**Bugs** - -Report bugs as Github issues: https://github.com/Fusion-Data-Platform/fdp/issues +* https://guides.github.com/activities/forking/ +* https://help.github.com/articles/fork-a-repo/ **Style** Please try to follow the `PEP8 style guide `_. To scan for PEP8 conformance, run ``make lint`` in the top-level directory. + +**Makefile utilities** + +The top-level ``Makefile`` contains several utilities for generating docs, code style/quality reviews, and versioning: + +.. code-block:: shell + + $ make help + help show this help message + docs build HTML and PDF documents + docs-html build HTML documents + docs-pdf build PDF documents + lint run flake8 for code quality review + autopep run autopep8 to fix minor pep8 violations + authors update AUTHORS.txt + bump-major update AUTHORS and CHANGELOG; bump major version and tag + bump-minor update AUTHORS and CHANGELOG; bump minor version and tag + bump-patch update AUTHORS and CHANGELOG; bump patch version and tag + clean remove all build, docs, and Python artifacts + clean-docs remove docs/build + clean-pyc remove Python file artifacts + diff --git a/Makefile b/Makefile index b93c02b..8848ab2 100644 --- a/Makefile +++ b/Makefile @@ -101,7 +101,7 @@ authors: ## update AUTHORS.txt .PHONY: bump-major -bump-major: authors ## bump major version and tag +bump-major: authors ## update AUTHORS and CHANGELOG; bump major version and tag @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextmajorversion) -- $(today)\n" > CHANGELOG.txt @@ -115,7 +115,7 @@ bump-major: authors ## bump major version and tag .PHONY: bump-minor -bump-minor: authors ## bump minor version and tag +bump-minor: authors ## update AUTHORS and CHANGELOG; bump minor version and tag @mv CHANGELOG.txt tmp.txt @echo "Release v$(nextminorversion) -- $(today)\n" > CHANGELOG.txt @git log --oneline `git describe --tags --abbrev=0`..HEAD >> CHANGELOG.txt @@ -128,7 +128,7 @@ bump-minor: authors ## bump minor version and tag .PHONY: bump-patch -bump-patch: authors ## bump patch version and tag +bump-patch: authors ## update AUTHORS and CHANGELOG; bump patch version and tag @cp -f CHANGELOG.txt tmp.txt @rm -f CHANGELOG.txt @echo "Release v$(nextpatchversion) -- $(today)\n" > CHANGELOG.txt diff --git a/README.rst b/README.rst index abfe4d6..d3b0c63 100644 --- a/README.rst +++ b/README.rst @@ -27,13 +27,17 @@ FDP streamlines data discovery, management, analysis methods, and visualization. nstxu.s204551.logbook() nstxu.s204551.mpts.te.plot() nstxu.s204551.equilibria.efit02.kappa.plot() - + ``nstxu`` is a data object that abstracts the NSTX-U device with easy access to shots, diagnostics, signals, and data methods. The typical heirarchy is:: ...[].. Users can discover data containers like ``mpts``, data signals like ``te``, and data methods like ``plot()`` with Python's tab-complete functionality. +**Contributing** + +To contribute to the FDP project, see ``CONTRIBUTING.rst`` in the top-level directory or ``Contributing`` in the docs. + **Lead developers** * David R. Smith, U. Wisconsin-Madison From 3f59f74c78646d1dd4fe662ba7d470eb3233bb65 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 17 Apr 2017 16:04:17 -0400 Subject: [PATCH 70/82] minor --- Makefile | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/Makefile b/Makefile index 8848ab2..1239f2e 100644 --- a/Makefile +++ b/Makefile @@ -80,6 +80,14 @@ docs-pdf: ## build PDF documents $(MAKE) -C docs/ latexpdf +.PHONY: outdated +outdated: # list outdated conda and pip packages + @echo "outdated conda packages" + @conda update --dry-run --all + @echo "outdated pip packages (may be managed by conda)" + @pip list --outdated + + .PHONY: lint lint: ## run flake8 for code quality review @rm -f flake8.output.txt From 534f00af9ef4f055be09147c0cf8e073fca54c13 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Mon, 17 Apr 2017 21:32:37 -0400 Subject: [PATCH 71/82] created new test directory and configured for pytest; run 'pytest' or 'make test' --- Makefile | 5 +++++ pytest.ini | 3 +++ test/conftest.py | 16 ++++++++++++++++ test/test_test.py | 10 ++++++++++ {test => test_old}/__init__.py | 0 {test => test_old}/run.py | 0 {test => test_old}/setup.py | 0 {test => test_old}/testCrossCorrelation.py | 0 {test => test_old}/testEmptySignal.py | 0 {test => test_old}/testEmptyTree.py | 0 {test => test_old}/testFilter.py | 0 {test => test_old}/testNstxu.py | 0 {test => test_old}/testNstxuBes.py | 0 {test => test_old}/testNstxuDiagnostics.py | 0 {test => test_old}/testNstxuShot.py | 0 15 files changed, 34 insertions(+) create mode 100644 pytest.ini create mode 100644 test/conftest.py create mode 100644 test/test_test.py rename {test => test_old}/__init__.py (100%) rename {test => test_old}/run.py (100%) rename {test => test_old}/setup.py (100%) rename {test => test_old}/testCrossCorrelation.py (100%) rename {test => test_old}/testEmptySignal.py (100%) rename {test => test_old}/testEmptyTree.py (100%) rename {test => test_old}/testFilter.py (100%) rename {test => test_old}/testNstxu.py (100%) rename {test => test_old}/testNstxuBes.py (100%) rename {test => test_old}/testNstxuDiagnostics.py (100%) rename {test => test_old}/testNstxuShot.py (100%) diff --git a/Makefile b/Makefile index 1239f2e..4b1dc77 100644 --- a/Makefile +++ b/Makefile @@ -88,6 +88,11 @@ outdated: # list outdated conda and pip packages @pip list --outdated +.PHONY: test +test: ## run pytest in current Python environment + pytest + + .PHONY: lint lint: ## run flake8 for code quality review @rm -f flake8.output.txt diff --git a/pytest.ini b/pytest.ini new file mode 100644 index 0000000..edea39b --- /dev/null +++ b/pytest.ini @@ -0,0 +1,3 @@ +[pytest] +testpaths = test +addopts = -ra --verbose --color=yes \ No newline at end of file diff --git a/test/conftest.py b/test/conftest.py new file mode 100644 index 0000000..fd2a290 --- /dev/null +++ b/test/conftest.py @@ -0,0 +1,16 @@ +import pytest +import fdp + +@pytest.fixture(scope="module") +def setup_nstx(): + return fdp.nstx() + +@pytest.fixture(scope="module") +def setup_shot(setup_fdp): + nstx = setup_fdp() + return nstx.s141000 + +@pytest.fixture(scope="module") +def setup_bes(setup_shot): + shot = setup_shot() + return shot.bes \ No newline at end of file diff --git a/test/test_test.py b/test/test_test.py new file mode 100644 index 0000000..86ea745 --- /dev/null +++ b/test/test_test.py @@ -0,0 +1,10 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 17 21:28:09 2017 + +@author: drsmith +""" + +def test_test(): + assert True \ No newline at end of file diff --git a/test/__init__.py b/test_old/__init__.py similarity index 100% rename from test/__init__.py rename to test_old/__init__.py diff --git a/test/run.py b/test_old/run.py similarity index 100% rename from test/run.py rename to test_old/run.py diff --git a/test/setup.py b/test_old/setup.py similarity index 100% rename from test/setup.py rename to test_old/setup.py diff --git a/test/testCrossCorrelation.py b/test_old/testCrossCorrelation.py similarity index 100% rename from test/testCrossCorrelation.py rename to test_old/testCrossCorrelation.py diff --git a/test/testEmptySignal.py b/test_old/testEmptySignal.py similarity index 100% rename from test/testEmptySignal.py rename to test_old/testEmptySignal.py diff --git a/test/testEmptyTree.py b/test_old/testEmptyTree.py similarity index 100% rename from test/testEmptyTree.py rename to test_old/testEmptyTree.py diff --git a/test/testFilter.py b/test_old/testFilter.py similarity index 100% rename from test/testFilter.py rename to test_old/testFilter.py diff --git a/test/testNstxu.py b/test_old/testNstxu.py similarity index 100% rename from test/testNstxu.py rename to test_old/testNstxu.py diff --git a/test/testNstxuBes.py b/test_old/testNstxuBes.py similarity index 100% rename from test/testNstxuBes.py rename to test_old/testNstxuBes.py diff --git a/test/testNstxuDiagnostics.py b/test_old/testNstxuDiagnostics.py similarity index 100% rename from test/testNstxuDiagnostics.py rename to test_old/testNstxuDiagnostics.py diff --git a/test/testNstxuShot.py b/test_old/testNstxuShot.py similarity index 100% rename from test/testNstxuShot.py rename to test_old/testNstxuShot.py From 8fbaf3016a37f02c17f700e8191eb8c353e64853 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Tue, 18 Apr 2017 07:40:45 -0400 Subject: [PATCH 72/82] pytest setup --- test/test_nstx/__init__.py | 0 test/{ => test_nstx}/conftest.py | 4 ++++ test/{ => test_nstx}/test_test.py | 2 +- 3 files changed, 5 insertions(+), 1 deletion(-) create mode 100644 test/test_nstx/__init__.py rename test/{ => test_nstx}/conftest.py (92%) rename test/{ => test_nstx}/test_test.py (88%) diff --git a/test/test_nstx/__init__.py b/test/test_nstx/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/test/conftest.py b/test/test_nstx/conftest.py similarity index 92% rename from test/conftest.py rename to test/test_nstx/conftest.py index fd2a290..099657b 100644 --- a/test/conftest.py +++ b/test/test_nstx/conftest.py @@ -1,3 +1,7 @@ +""" +pytest fixtures. +""" + import pytest import fdp diff --git a/test/test_test.py b/test/test_nstx/test_test.py similarity index 88% rename from test/test_test.py rename to test/test_nstx/test_test.py index 86ea745..97fe0bd 100644 --- a/test/test_test.py +++ b/test/test_nstx/test_test.py @@ -7,4 +7,4 @@ """ def test_test(): - assert True \ No newline at end of file + assert False \ No newline at end of file From af97cdaf5a68f9f6c15c0f28ba8240f2bd2c7838 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Tue, 18 Apr 2017 16:40:57 -0400 Subject: [PATCH 73/82] testing for logbook.py and machine.py --- .coveragerc | 18 +++++ CONTRIBUTING.rst | 1 + Makefile | 14 ++++ examples/logbook_example.py | 7 +- fdp/__init__.py | 20 +++--- fdp/classes/container.py | 4 +- fdp/classes/fdp.py | 6 +- fdp/classes/gui.py | 3 +- fdp/classes/logbook.py | 19 ++---- fdp/classes/machine.py | 119 +++++++++------------------------ fdp/classes/shot.py | 8 ++- test/skylark.py | 26 +++++++ test/test_nstx/__init__.py | 3 + test/test_nstx/conftest.py | 6 +- test/test_nstx/test_logbook.py | 21 ++++++ test/test_nstx/test_machine.py | 63 +++++++++++++++++ test/test_nstx/test_test.py | 10 --- 17 files changed, 221 insertions(+), 127 deletions(-) create mode 100644 .coveragerc create mode 100644 test/skylark.py create mode 100644 test/test_nstx/test_logbook.py create mode 100644 test/test_nstx/test_machine.py delete mode 100644 test/test_nstx/test_test.py diff --git a/.coveragerc b/.coveragerc new file mode 100644 index 0000000..a1498db --- /dev/null +++ b/.coveragerc @@ -0,0 +1,18 @@ +[run] +source = fdp +branch = True + +[report] +show_missing = True +ignore_errors = True +exclude_lines = + pragma: no cover + if self.debug: + if debug: + if self.verbose: + if verbose: + if VERBOSE: + if __name__ == .__main__.: + +[html] +directory = htmlcov diff --git a/CONTRIBUTING.rst b/CONTRIBUTING.rst index d84d431..f418736 100644 --- a/CONTRIBUTING.rst +++ b/CONTRIBUTING.rst @@ -28,6 +28,7 @@ The top-level ``Makefile`` contains several utilities for generating docs, code docs build HTML and PDF documents docs-html build HTML documents docs-pdf build PDF documents + test run pytest in current Python environment lint run flake8 for code quality review autopep run autopep8 to fix minor pep8 violations authors update AUTHORS.txt diff --git a/Makefile b/Makefile index 4b1dc77..27d103b 100644 --- a/Makefile +++ b/Makefile @@ -93,6 +93,20 @@ test: ## run pytest in current Python environment pytest +.PHONY: coverage +coverage: ## check test coverage and show report in terminal + @rm -f .coverage + coverage run --module pytest + coverage report + + +.PHONY: coverage-html +coverage-html: coverage ## check test coverage and show report in browser + @rm -fr htmlcov/ + @coverage html + @$(BROWSER) htmlcov/index.html + + .PHONY: lint lint: ## run flake8 for code quality review @rm -f flake8.output.txt diff --git a/examples/logbook_example.py b/examples/logbook_example.py index f9fbdf8..9dde1c0 100644 --- a/examples/logbook_example.py +++ b/examples/logbook_example.py @@ -9,4 +9,9 @@ nstx = fdp.nstx() -nstx.s204620.logbook() \ No newline at end of file +shotlist = [204620, 204551, 141000, 204670, 204956, 204990, 333333] + +nstx.addshot(shotlist) +for shot in nstx: + print('*** {} logbook ***'.format(shot.shot)) + shot.logbook() \ No newline at end of file diff --git a/fdp/__init__.py b/fdp/__init__.py index 76bd029..8dc4b24 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -10,21 +10,21 @@ __version__ = '0.1.4' -def nstxu(): - return fdp.Fdp().nstxu +def nstxu(*args, **kwargs): + return fdp.Fdp(*args, **kwargs).nstxu -def nstx(): - return nstxu() +def nstx(*args, **kwargs): + return nstxu(*args, **kwargs) -def diiid(): - return fdp.Fdp().diiid +def diiid(*args, **kwargs): + return fdp.Fdp(*args, **kwargs).diiid -def d3d(): - return diiid() +def d3d(*args, **kwargs): + return diiid(*args, **kwargs) -def cmod(): - return fdp.Fdp().cmod +def cmod(*args, **kwargs): + return fdp.Fdp(*args, **kwargs).cmod diff --git a/fdp/classes/container.py b/fdp/classes/container.py index ad1cb41..79722ff 100755 --- a/fdp/classes/container.py +++ b/fdp/classes/container.py @@ -246,8 +246,8 @@ def _get_path(cls): return path def __dir__(self): - items = self.__dict__.keys() - items.extend(self.__class__.__dict__.keys()) + items = list(self.__dict__.keys()) + items.extend(list(self.__class__.__dict__.keys())) if Signal not in self.__class__.mro(): items.extend(self._dynamic_containers.keys()) return [item for item in set(items).difference(self._base_items) diff --git a/fdp/classes/fdp.py b/fdp/classes/fdp.py index fac3f87..fbcc07e 100755 --- a/fdp/classes/fdp.py +++ b/fdp/classes/fdp.py @@ -16,6 +16,10 @@ class Fdp(object): The primary data object in FDP and the top-level container for machines. """ + def __init__(self, *args, **kwargs): + self.args = args + self.kwargs = kwargs + def __getattr__(self, attribute): if VERBOSE: print('{}.__getattr__({})'. @@ -30,7 +34,7 @@ def __getattr__(self, attribute): # parse fdp/methods and fdp/methods/ parse_method(MachineClass, level='top') parse_method(MachineClass, level=machine_name) - return MachineClass(machine_name) + return MachineClass(machine_name, *self.args, **self.kwargs) def __dir__(self): return MACHINES diff --git a/fdp/classes/gui.py b/fdp/classes/gui.py index 051089e..8a03dc5 100644 --- a/fdp/classes/gui.py +++ b/fdp/classes/gui.py @@ -9,9 +9,10 @@ from warnings import warn if sys.version_info[0] < 3: import Tkinter as tk + import ttk else: import tkinter as tk -import ttk + import tkinter.ttk as ttk import threading import matplotlib as mpl diff --git a/fdp/classes/logbook.py b/fdp/classes/logbook.py index bf46701..af286e8 100755 --- a/fdp/classes/logbook.py +++ b/fdp/classes/logbook.py @@ -99,37 +99,32 @@ def get_shotlist(self, date=None, xp=None, verbose=False): cursor = self._get_cursor() rows = [] shotlist = [] # start with empty shotlist - - if date and not isinstance(date, list): # if it's just a single date + if not date: + date = [] + if not xp: + xp = [] + if date and not isinstance(date, (list,tuple)): # if it's just a single date date = [date] # put it into a list for d in date: query = ('{0} and rundate={1} ORDER BY shot ASC'. format(self._shotlist_query_prefix, d)) cursor.execute(query) rows.extend(cursor.fetchall()) - - if xp and not isinstance(xp, list): # if it's just a single xp + if xp and not isinstance(xp, (list,tuple)): # if it's just a single xp xp = [xp] # put it into a list for x in xp: query = ('{0} and xp={1} ORDER BY shot ASC'. format(self._shotlist_query_prefix, x)) cursor.execute(query) rows.extend(cursor.fetchall()) - for row in rows: rundate = repr(row['rundate']) year = rundate[0:4] month = rundate[4:6] day = rundate[6:8] row['rundate'] = datetime.date(int(year), int(month), int(day)) - if verbose: - print('date {}'.format(rows[0]['rundate'])) - for row in rows: - print(' {shot} in XP {xp}'.format(**row)) # add shots to shotlist - shotlist.extend([row['shot'] for row in rows - if row['shot'] is not None]) - + shotlist.extend([row['shot'] for row in rows if row['shot'] is not None]) cursor.close() return np.unique(shotlist) diff --git a/fdp/classes/machine.py b/fdp/classes/machine.py index 896fa7a..a13cde2 100755 --- a/fdp/classes/machine.py +++ b/fdp/classes/machine.py @@ -39,41 +39,24 @@ def __init__(self, name='nstxu', shotlist=None, xp=None, date=None): self._shots = {} # shot dictionary with shot number (int) keys self._classlist = {} self._name = machineAlias(name) - if VERBOSE: - print('{}.__init__'.format(self._name)) self._logbook = Logbook(name=self._name, root=self) self._eventConnection = mds.Connection(EVENT_SERVERS[self._name]) if len(self._connections) is 0: - if VERBOSE: - print('{}.__init__ Precaching MDS connections...'. - format(self._name)) for _ in range(2): - try: - connection = mds.Connection(MDS_SERVERS[self._name]) - connection.tree = None - self._connections.append(connection) - except: - msg = 'MDSplus connection to {} failed'.format( - MDS_SERVERS[self._name]) - raise FdpError(msg) - if VERBOSE: - print('{}.__init__ Finished MDS'.format(self._name)) + connection = mds.Connection(MDS_SERVERS[self._name]) + connection.tree = None + self._connections.append(connection) self.s0 = Shot(0, root=self, parent=self) if shotlist or xp or date: self.addshot(shotlist=shotlist, xp=xp, date=date) def __getattr__(self, name): - if VERBOSE: - print('{}.__getattr__({})'.format(self._name, name)) try: shot = int(name.split('s')[1]) except: - raise AttributeError("'{}' object has no attribute '{}'".format( - type(self), name)) - if (shot not in self._shots): - if VERBOSE: - print('{}.__getattr__: loading shot {}'. - format(self._name, shot)) + msg = "'{}' object has no attribute '{}'".format(type(self), name) + raise AttributeError(msg) + if shot not in self._shots: self._shots[shot] = Shot(shot, root=self, parent=self) return self._shots[shot] @@ -105,7 +88,7 @@ def __setitem__(self, item, value): def __dir__(self): shotlist = ['s0'] shotlist.extend(['s{}'.format(shot) - for shot in self._shots.iterkeys()]) + for shot in iter(self._shots.keys())]) return shotlist def _get_connection(self, shot, tree): @@ -129,9 +112,6 @@ def _get_connection(self, shot, tree): return connection def _get_mdsdata(self, signal): - if VERBOSE: - print('{}._get_mdsdata({}): BEGIN'. - format(self._name, signal._name)) shot = signal.shot if shot is 0: print('No MDS data exists for model tree') @@ -147,56 +127,30 @@ def _get_mdsdata(self, signal): return np.zeros(0) try: if hasattr(signal, '_raw_of') and signal._raw_of is not None: - if VERBOSE: - print('{}._get_mdsdata({}): trying data.raw_of()'. - format(self._name, signal._name)) data = data.raw_of() - else: - if VERBOSE: - print('{}._get_mdsdata({}): no data.raw_of()'. - format(self._name, signal._name)) except: - if VERBOSE: - print('{}._get_mdsdata({}): threw exception'. - format(self._name, signal._name)) + pass try: if hasattr(signal, '_dim_of') and signal._dim_of is not None: - if VERBOSE: - print('{}._get_mdsdata({}): trying data.dim_of()'. - format(self._name, signal._name)) data = data.dim_of() - else: - if VERBOSE: - print('{}._get_mdsdata({}): no data.dim_of()'. - format(self._name, signal._name)) except: - if VERBOSE: - print('{}._get_mdsdata({}): threw exception'. - format(self._name, signal._name)) + pass data = data.value_of().value if signal._transpose is not None: data = data.transpose(signal._transpose) if hasattr(signal, '_postprocess'): data = signal._postprocess(data) - if VERBOSE: - print('{}._get_mdsdata({}): END with type(data) {}'. - format(self._name, signal._name, type(data))) return data def _get_modules(self): - if VERBOSE: - print('{}._get_modules()'.format(self._name)) if self._modules is None: - if VERBOSE: - print('{}._get_modules() Surveying diagnostic modules'. - format(self._name)) module_dir = os.path.join(FDP_DIR, 'modules', self._name) self._modules = [module for module in os.listdir(module_dir) if os.path.isdir(os.path.join(module_dir, module)) and module[0] is not '_'] return self._modules - def addshot(self, shotlist=None, date=None, xp=None, verbose=False): + def addshot(self, shotlist=None, date=None, xp=None): """ Load shots into the Machine class @@ -204,41 +158,41 @@ def addshot(self, shotlist=None, date=None, xp=None, verbose=False): >>> nstxu.addshot([140000 140001]) >>> nstxu.addshot(xp=1032) - >>> nstxu.addshot(date=20100817, verbose=True) Note: You can reference shots even if the shots have not been loaded. """ - if shotlist and not isinstance(shotlist, list): - shotlist = [shotlist] - if xp and not isinstance(xp, list): - xp = [xp] - if date and not isinstance(date, list): - date = [date] shots = [] if shotlist: - shots.extend([shotlist]) - if date or xp: - shots.extend(self._logbook.get_shotlist(date=date, xp=xp, - verbose=verbose)) + if not isinstance(shotlist, (list,tuple)): + shotlist = [shotlist] + shots.extend(list(shotlist)) + if date: + if not isinstance(date, (list,tuple)): + date = [date] + shots.extend(self._logbook.get_shotlist(date=list(date))) + if xp: + if not isinstance(xp, (list,tuple)): + xp = [xp] + shots.extend(self._logbook.get_shotlist(xp=list(xp))) for shot in np.unique(shots): if shot not in self._shots: self._shots[shot] = Shot(shot, root=self, parent=self) - def addxp(self, xp=[]): + def addxp(self, xp=None): self.addshot(xp=xp) - def adddate(self, date=[]): + def adddate(self, date=None): self.addshot(date=date) def listshot(self): - keys = self._shots.keys() + keys = list(self._shots.keys()) keys.sort() for shotkey in keys: shot = self._shots[shotkey] print('{} in XP {} on {}'.format(shot.shot, shot.xp, shot.date)) - def get_shotlist(self, date=[], xp=[], verbose=False): + def get_shotlist(self, date=None, xp=None, verbose=False): # return a list of shots return self._logbook.get_shotlist(date=date, xp=xp, verbose=verbose) @@ -303,7 +257,7 @@ def find(self, tag, obj=None): find_list.sort() return find_list - def filter_shots(self, date=[], xp=[]): + def filter_shots(self, date=None, xp=None): """ Get a Machine-like object with an immutable shotlist for XP(s) or date(s) @@ -330,7 +284,7 @@ class ImmutableMachine(Mapping): """ - def __init__(self, xp=[], date=[], parent=None): + def __init__(self, xp=None, date=None, parent=None): self._shots = {} self._parent = parent shotlist = self._parent.get_shotlist(xp=xp, date=date) @@ -348,14 +302,8 @@ def __getattr__(self, name): def __repr__(self): return ''.format(self._name.upper()) - def __iter__(self): - return iter(self._shots.values()) - - def __contains__(self, value): - return value in self._shots - - def __len__(self): - return len(self._shots.keys()) + def __delitem__(self, item): + pass def __getitem__(self, item): pass @@ -365,11 +313,10 @@ def __dir__(self): def logbook(self): for shotnum in self._shots: - shotObj = self._shots[shotnum] - shotObj.logbook() + shot = self._shots[shotnum] + shot.logbook() def list_shots(self): for shotnum in self._shots: - shotObj = self._shots[shotnum] - print('{} in XP {} on {}'.format( - shotObj.shot, shotObj.xp, shotObj.date)) + shot = self._shots[shotnum] + print('{} in XP {} on {}'.format(shot.shot, shot.xp, shot.date)) diff --git a/fdp/classes/shot.py b/fdp/classes/shot.py index 7f8f319..ddc2ac0 100755 --- a/fdp/classes/shot.py +++ b/fdp/classes/shot.py @@ -103,7 +103,7 @@ def _get_date(self): return date def logbook(self): - # return a list of logbook entries (dictionaries) + # show logbook entries if not self._logbook_entries: self._logbook_entries = self._logbook.get_entries(shot=self.shot) if self._logbook_entries: @@ -117,6 +117,12 @@ def logbook(self): else: print('No logbook entries for {}'.format(self.shot)) + def get_logbook(self): + # return a list of logbook entries + if not self._logbook_entries: + self._logbook_entries = self._logbook.get_entries(shot=self.shot) + return self._logbook_entries + def check_efit(self): if len(self._efits): return self._efits diff --git a/test/skylark.py b/test/skylark.py new file mode 100644 index 0000000..731047e --- /dev/null +++ b/test/skylark.py @@ -0,0 +1,26 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Tue Apr 18 12:10:25 2017 + +@author: drsmith +""" + +import socket + + +def try_connection(host=None, port=None): + try: + s = socket.create_connection((host, port), 3) + print('success: {} on port {}'.format(host, port)) + s.close() + return True + except Exception as ex: + print('Exception for host {} on port {}: {}'.format(host, port, ex)) + return False + +if __name__ == '__main__': + connections = [('skylark.pppl.gov', 8501), + ('sql2008.pppl.gov', 62917)] + for pair in connections: + try_connection(pair[0], pair[1]) \ No newline at end of file diff --git a/test/test_nstx/__init__.py b/test/test_nstx/__init__.py index e69de29..fa43e09 100644 --- a/test/test_nstx/__init__.py +++ b/test/test_nstx/__init__.py @@ -0,0 +1,3 @@ + +# some valid shots for testing +shotlist = [204620, 204551, 141000, 204670, 204956, 204990] \ No newline at end of file diff --git a/test/test_nstx/conftest.py b/test/test_nstx/conftest.py index 099657b..6fb94f9 100644 --- a/test/test_nstx/conftest.py +++ b/test/test_nstx/conftest.py @@ -10,11 +10,11 @@ def setup_nstx(): return fdp.nstx() @pytest.fixture(scope="module") -def setup_shot(setup_fdp): - nstx = setup_fdp() +def setup_shot(setup_nstx): + nstx = setup_nstx return nstx.s141000 @pytest.fixture(scope="module") def setup_bes(setup_shot): - shot = setup_shot() + shot = setup_shot return shot.bes \ No newline at end of file diff --git a/test/test_nstx/test_logbook.py b/test/test_nstx/test_logbook.py new file mode 100644 index 0000000..aa2c1a5 --- /dev/null +++ b/test/test_nstx/test_logbook.py @@ -0,0 +1,21 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Mon Apr 17 21:28:09 2017 + +@author: drsmith +""" + +from . import shotlist + +def test_logbook(setup_nstx): + nstx = setup_nstx + # load a valid shot and check logbook + nstx.addshot(shotlist=shotlist[0]) + shot = nstx[shotlist[0]] + assert isinstance(shot.get_logbook(), list) + assert len(shot.get_logbook()) > 0 + shot.logbook() + # load an invalid shot and check logbook + assert isinstance(nstx.s888888.get_logbook(), list) + assert len(nstx.s888888.get_logbook()) == 0 diff --git a/test/test_nstx/test_machine.py b/test/test_nstx/test_machine.py new file mode 100644 index 0000000..5c34484 --- /dev/null +++ b/test/test_nstx/test_machine.py @@ -0,0 +1,63 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- +""" +Created on Tue Apr 18 13:26:14 2017 + +@author: drsmith +""" + +import pytest +import fdp + +from . import shotlist + +def test_nstx_machine(setup_nstx): + nstx = setup_nstx + nstx.addshot(shotlist=shotlist[0:2]) + for shot in nstx: + pass + shotlist[0] in nstx + repr(nstx) + nstx.__delitem__(shotlist[0]) + with pytest.raises(AttributeError): + nstx.BadAttribute + nstx[0] + nstx.find('radius') + +def test_shots(): + """Test shot addition and management""" + nstx = fdp.nstx(shotlist=shotlist[2]) + assert shotlist[2] in nstx._shots + assert isinstance(nstx[shotlist[2]], fdp.classes.shot.Shot) + # add shot by method + nstx.addshot(shotlist=shotlist[0]) + assert shotlist[0] in nstx._shots + assert isinstance(nstx[shotlist[0]], fdp.classes.shot.Shot) + # add shot by attribute reference + shot = getattr(nstx, 's{}'.format(shotlist[1])) + assert shotlist[1] in nstx._shots + assert isinstance(shot, fdp.classes.shot.Shot) + # check shotlist + assert len(dir(nstx)) == 4 + assert len(nstx) == 3 + nstx.listshot() + +def test_xp(): + nstx = fdp.nstx() + nstx.addxp(xp=1037) + assert len(nstx) == 95 + +def test_date(): + nstx = fdp.nstx() + nstx.adddate(date='20160506') + assert len(nstx) == 30 + +def test_filter_xp(): + nstx = fdp.nstx() + xp1037 = nstx.filter_shots(xp=1037) + assert len(xp1037) == 95 + +def test_filter_date(): + nstx = fdp.nstx() + d = nstx.filter_shots(date='20160506') + assert len(d) == 30 \ No newline at end of file diff --git a/test/test_nstx/test_test.py b/test/test_nstx/test_test.py deleted file mode 100644 index 97fe0bd..0000000 --- a/test/test_nstx/test_test.py +++ /dev/null @@ -1,10 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Mon Apr 17 21:28:09 2017 - -@author: drsmith -""" - -def test_test(): - assert False \ No newline at end of file From 63ce1405456951f3d98e0f9fc14954f52706bfe1 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 09:58:55 -0400 Subject: [PATCH 74/82] tests --- fdp/classes/datasources.py | 32 +++++++++--------- fdp/classes/logbook.py | 4 ++- fdp/classes/machine.py | 19 ++++++++--- test/skylark.py | 26 -------------- test/test_nstx/__init__.py | 19 ++++++++++- test/test_nstx/conftest.py | 13 ++++--- test/test_nstx/test_bes.py | 9 +++++ test/test_nstx/test_logbook.py | 13 +++---- test/test_nstx/test_machine.py | 62 ++++++++++++++++++---------------- test/test_nstx/test_shot.py | 12 +++++++ 10 files changed, 119 insertions(+), 90 deletions(-) delete mode 100644 test/skylark.py create mode 100644 test/test_nstx/test_bes.py create mode 100644 test/test_nstx/test_shot.py diff --git a/fdp/classes/datasources.py b/fdp/classes/datasources.py index 8968f7d..5033655 100644 --- a/fdp/classes/datasources.py +++ b/fdp/classes/datasources.py @@ -13,33 +13,33 @@ MACHINES = ['nstxu', 'diiid', 'cmod'] MDS_SERVERS = { - 'nstxu': 'skylark.pppl.gov:8501' + 'nstxu': {'hostname':'skylark.pppl.gov', + 'port':'8501'} } EVENT_SERVERS = { - 'nstxu': 'skylark.pppl.gov:8501', - 'ltx': 'lithos.pppl.gov:8000' + 'nstxu': {'hostname':'skylark.pppl.gov', + 'port':'8501'}, + 'ltx': {'hostname':'lithos.pppl.gov', + 'port':'8000'} } LOGBOOK_CREDENTIALS = { - 'nstxu': { - 'server': 'sql2008.pppl.gov\sql2008', - 'username': os.getenv('USER') or os.getenv('USERNAME'), - 'password': 'pfcworld', - 'database': 'nstxlogs', - 'port': '62917', - 'table': 'entries' - } + 'nstxu': {'hostname': 'sql2008.pppl.gov', + 'server': 'sql2008.pppl.gov\sql2008', + 'username': os.getenv('USER') or os.getenv('USERNAME'), + 'password': 'pfcworld', + 'database': 'nstxlogs', + 'port': '62917', + 'table': 'entries'} } def machineAlias(machine): - aliases = { - 'nstxu': ['nstx', 'nstxu', 'nstx-u'], - 'diiid': ['diiid', 'diii-d', 'd3d'], - 'cmod': ['cmod', 'c-mod'] - } + aliases = {'nstxu': ['nstx', 'nstxu', 'nstx-u'], + 'diiid': ['diiid', 'diii-d', 'd3d'], + 'cmod': ['cmod', 'c-mod']} for key in iter(aliases): if machine.lower() in aliases[key]: diff --git a/fdp/classes/logbook.py b/fdp/classes/logbook.py index af286e8..d0d3c01 100755 --- a/fdp/classes/logbook.py +++ b/fdp/classes/logbook.py @@ -23,7 +23,7 @@ def __init__(self, name='nstxu', root=None): self._shot_query_prefix = '' self._logbook_connection = None - self._make_logbook_connection() + #self._make_logbook_connection() # dict of cached logbook entries # kw is shot, value is list of logbook entries @@ -67,6 +67,8 @@ def _make_logbook_connection(self): raise FdpError(txt) def _get_cursor(self): + if not self._logbook_connection: + self._make_logbook_connection() try: cursor = self._logbook_connection.cursor() cursor.execute('SET ROWCOUNT 500') diff --git a/fdp/classes/machine.py b/fdp/classes/machine.py index a13cde2..a99d1f8 100755 --- a/fdp/classes/machine.py +++ b/fdp/classes/machine.py @@ -40,10 +40,14 @@ def __init__(self, name='nstxu', shotlist=None, xp=None, date=None): self._classlist = {} self._name = machineAlias(name) self._logbook = Logbook(name=self._name, root=self) - self._eventConnection = mds.Connection(EVENT_SERVERS[self._name]) + event_server = EVENT_SERVERS[self._name] + self._eventConnection = mds.Connection('{}:{}'.format(event_server['hostname'], + event_server['port'])) if len(self._connections) is 0: + mds_server = MDS_SERVERS[self._name] for _ in range(2): - connection = mds.Connection(MDS_SERVERS[self._name]) + connection = mds.Connection('{}:{}'.format(mds_server['hostname'], + mds_server['port'])) connection.tree = None self._connections.append(connection) self.s0 = Shot(0, root=self, parent=self) @@ -76,8 +80,6 @@ def __delitem__(self, item): self._shots.__delitem__(item) def __getitem__(self, item): - if VERBOSE: - print('{}.__getitem__({})'.format(self._name, item)) if item == 0: return self.s0 return self._shots[item] @@ -302,6 +304,15 @@ def __getattr__(self, name): def __repr__(self): return ''.format(self._name.upper()) + def __iter__(self): + return iter(self._shots.values()) + + def __contains__(self, value): + return value in self._shots + + def __len__(self): + return len(self._shots.keys()) + def __delitem__(self, item): pass diff --git a/test/skylark.py b/test/skylark.py deleted file mode 100644 index 731047e..0000000 --- a/test/skylark.py +++ /dev/null @@ -1,26 +0,0 @@ -#!/usr/bin/env python3 -# -*- coding: utf-8 -*- -""" -Created on Tue Apr 18 12:10:25 2017 - -@author: drsmith -""" - -import socket - - -def try_connection(host=None, port=None): - try: - s = socket.create_connection((host, port), 3) - print('success: {} on port {}'.format(host, port)) - s.close() - return True - except Exception as ex: - print('Exception for host {} on port {}: {}'.format(host, port, ex)) - return False - -if __name__ == '__main__': - connections = [('skylark.pppl.gov', 8501), - ('sql2008.pppl.gov', 62917)] - for pair in connections: - try_connection(pair[0], pair[1]) \ No newline at end of file diff --git a/test/test_nstx/__init__.py b/test/test_nstx/__init__.py index fa43e09..dac2397 100644 --- a/test/test_nstx/__init__.py +++ b/test/test_nstx/__init__.py @@ -1,3 +1,20 @@ +import socket +from fdp.classes import datasources as ds # some valid shots for testing -shotlist = [204620, 204551, 141000, 204670, 204956, 204990] \ No newline at end of file +shotlist = [204620, 204551, 141000, 204670, 204956, 204990] + +def server_connection(): + machine=ds.machineAlias('nstx') + servers = [ds.MDS_SERVERS[machine], + ds.LOGBOOK_CREDENTIALS[machine]] + for server in servers: + hostname = server['hostname'] + port = server['port'] + try: + s = socket.create_connection((hostname, port), 3) + s.close() + except Exception as ex: + print('Exception for host {} on port {}: {}'.format(hostname, port, ex)) + return False + return True \ No newline at end of file diff --git a/test/test_nstx/conftest.py b/test/test_nstx/conftest.py index 6fb94f9..ab55427 100644 --- a/test/test_nstx/conftest.py +++ b/test/test_nstx/conftest.py @@ -5,16 +5,15 @@ import pytest import fdp +from . import shotlist + @pytest.fixture(scope="module") def setup_nstx(): - return fdp.nstx() + nstx = fdp.nstx() + nstx.addshot(shotlist=shotlist) + return nstx @pytest.fixture(scope="module") def setup_shot(setup_nstx): nstx = setup_nstx - return nstx.s141000 - -@pytest.fixture(scope="module") -def setup_bes(setup_shot): - shot = setup_shot - return shot.bes \ No newline at end of file + return nstx.s141000 \ No newline at end of file diff --git a/test/test_nstx/test_bes.py b/test/test_nstx/test_bes.py new file mode 100644 index 0000000..f2082ae --- /dev/null +++ b/test/test_nstx/test_bes.py @@ -0,0 +1,9 @@ + + +def test_bes(setup_nstx): + nstx = setup_nstx + dir(nstx.s141000.bes) + for signal in nstx.s141000.bes: + pass + nstx.s141000.bes.ch01[:] + nstx.s204320.bes.ch01[:] \ No newline at end of file diff --git a/test/test_nstx/test_logbook.py b/test/test_nstx/test_logbook.py index aa2c1a5..5404612 100644 --- a/test/test_nstx/test_logbook.py +++ b/test/test_nstx/test_logbook.py @@ -6,16 +6,17 @@ @author: drsmith """ -from . import shotlist - def test_logbook(setup_nstx): nstx = setup_nstx + shots = dir(nstx) # load a valid shot and check logbook - nstx.addshot(shotlist=shotlist[0]) - shot = nstx[shotlist[0]] + shot = getattr(nstx, shots[1]) assert isinstance(shot.get_logbook(), list) assert len(shot.get_logbook()) > 0 shot.logbook() # load an invalid shot and check logbook - assert isinstance(nstx.s888888.get_logbook(), list) - assert len(nstx.s888888.get_logbook()) == 0 + shot = nstx.s888888 + assert isinstance(shot.get_logbook(), list) + assert len(shot.get_logbook()) == 0 + shot.logbook() + diff --git a/test/test_nstx/test_machine.py b/test/test_nstx/test_machine.py index 5c34484..4f58a4c 100644 --- a/test/test_nstx/test_machine.py +++ b/test/test_nstx/test_machine.py @@ -11,53 +11,57 @@ from . import shotlist -def test_nstx_machine(setup_nstx): +def test_no_connection(setup_nstx): + nstx = setup_nstx + with pytest.raises(AttributeError): + nstx.BadAttribute + repr(nstx) + nstx[0] + nstx.find('radius') nstx = setup_nstx nstx.addshot(shotlist=shotlist[0:2]) for shot in nstx: pass shotlist[0] in nstx - repr(nstx) nstx.__delitem__(shotlist[0]) - with pytest.raises(AttributeError): - nstx.BadAttribute - nstx[0] - nstx.find('radius') -def test_shots(): - """Test shot addition and management""" - nstx = fdp.nstx(shotlist=shotlist[2]) - assert shotlist[2] in nstx._shots - assert isinstance(nstx[shotlist[2]], fdp.classes.shot.Shot) - # add shot by method - nstx.addshot(shotlist=shotlist[0]) - assert shotlist[0] in nstx._shots - assert isinstance(nstx[shotlist[0]], fdp.classes.shot.Shot) +def test_shot_management(): + ishot = 0 + # load shot with machine instantiation + nstx = fdp.nstx(shotlist=shotlist[ishot]) + assert shotlist[ishot] in nstx._shots + assert isinstance(nstx[shotlist[ishot]], fdp.classes.shot.Shot) + # load shot with adshot() method + ishot += 1 + nstx.addshot(shotlist=shotlist[ishot]) + assert shotlist[ishot] in nstx._shots + assert isinstance(nstx[shotlist[ishot]], fdp.classes.shot.Shot) # add shot by attribute reference - shot = getattr(nstx, 's{}'.format(shotlist[1])) - assert shotlist[1] in nstx._shots + ishot += 1 + shot = getattr(nstx, 's{}'.format(shotlist[ishot])) + assert shotlist[ishot] in nstx._shots assert isinstance(shot, fdp.classes.shot.Shot) # check shotlist assert len(dir(nstx)) == 4 assert len(nstx) == 3 nstx.listshot() -def test_xp(): +def test_load_xp(): nstx = fdp.nstx() - nstx.addxp(xp=1037) - assert len(nstx) == 95 + nstx.addxp(xp=1038) + assert len(nstx) == 24 -def test_date(): +def test_load_date(): nstx = fdp.nstx() nstx.adddate(date='20160506') assert len(nstx) == 30 -def test_filter_xp(): - nstx = fdp.nstx() - xp1037 = nstx.filter_shots(xp=1037) - assert len(xp1037) == 95 +def test_filter_xp(setup_nstx): + nstx = setup_nstx + xp1037 = nstx.filter_shots(xp=1038) + assert len(xp1037) == 24 -def test_filter_date(): - nstx = fdp.nstx() - d = nstx.filter_shots(date='20160506') - assert len(d) == 30 \ No newline at end of file +def test_filter_date(setup_nstx): + nstx = setup_nstx + runday = nstx.filter_shots(date='20160506') + assert len(runday) == 30 \ No newline at end of file diff --git a/test/test_nstx/test_shot.py b/test/test_nstx/test_shot.py new file mode 100644 index 0000000..027551b --- /dev/null +++ b/test/test_nstx/test_shot.py @@ -0,0 +1,12 @@ + + +def test_shot(setup_shot): + shot = setup_shot + dir(shot) + len(shot) + repr(shot) + shot.mpts + getattr(shot, 'chers') + shot.logbook() + shot.get_logbook() + shot.check_efit() \ No newline at end of file From ff08bd21836c3462516e8cf17d6e7fbf29eeb71c Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 10:47:25 -0400 Subject: [PATCH 75/82] tests --- fdp/classes/machine.py | 15 +++++---------- test/test_nstx/test_machine.py | 9 +++++++++ 2 files changed, 14 insertions(+), 10 deletions(-) diff --git a/fdp/classes/machine.py b/fdp/classes/machine.py index a99d1f8..72154ea 100755 --- a/fdp/classes/machine.py +++ b/fdp/classes/machine.py @@ -127,16 +127,10 @@ def _get_mdsdata(self, signal): warn(msg, FdpWarning) # TODO: return value of failed connection? return np.zeros(0) - try: - if hasattr(signal, '_raw_of') and signal._raw_of is not None: - data = data.raw_of() - except: - pass - try: - if hasattr(signal, '_dim_of') and signal._dim_of is not None: - data = data.dim_of() - except: - pass + if getattr(signal, '_raw_of', None) is not None: + data = data.raw_of() + if getattr(signal, '_dim_of', None) is not None: + data = data.dim_of() data = data.value_of().value if signal._transpose is not None: data = data.transpose(signal._transpose) @@ -289,6 +283,7 @@ class ImmutableMachine(Mapping): def __init__(self, xp=None, date=None, parent=None): self._shots = {} self._parent = parent + self._name = self._parent._name shotlist = self._parent.get_shotlist(xp=xp, date=date) for shot in shotlist: self._shots[shot] = getattr(self._parent, 's{}'.format(shot)) diff --git a/test/test_nstx/test_machine.py b/test/test_nstx/test_machine.py index 4f58a4c..c0f1141 100644 --- a/test/test_nstx/test_machine.py +++ b/test/test_nstx/test_machine.py @@ -59,7 +59,16 @@ def test_load_date(): def test_filter_xp(setup_nstx): nstx = setup_nstx xp1037 = nstx.filter_shots(xp=1038) + repr(xp1037) + with pytest.raises(AttributeError): + xp1037.BadAttribute assert len(xp1037) == 24 + for shot in xp1037: + pass + xp1037.logbook() + xp1037.list_shots() + dir(xp1037) + xp1037._shots[0] in xp1037 def test_filter_date(setup_nstx): nstx = setup_nstx From 74c271fadb45bbf2a481531b13a53bfe61120513 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 12:36:18 -0400 Subject: [PATCH 76/82] tests --- test/test_nstx/test_exceptions.py | 10 ++++++++++ test/test_nstx/test_fft.py | 8 ++++++++ test/test_nstx/test_signal.py | 15 +++++++++++++++ 3 files changed, 33 insertions(+) create mode 100644 test/test_nstx/test_exceptions.py create mode 100644 test/test_nstx/test_fft.py create mode 100644 test/test_nstx/test_signal.py diff --git a/test/test_nstx/test_exceptions.py b/test/test_nstx/test_exceptions.py new file mode 100644 index 0000000..3a72ca3 --- /dev/null +++ b/test/test_nstx/test_exceptions.py @@ -0,0 +1,10 @@ + +from warnings import warn +import pytest +from fdp.classes.fdp_globals import FdpError, FdpWarning + +def test_exceptions(): + with pytest.raises(FdpError): + raise FdpError("error message") + with pytest.raises(FdpWarning): + warn("warning message", FdpWarning) diff --git a/test/test_nstx/test_fft.py b/test/test_nstx/test_fft.py new file mode 100644 index 0000000..1f64921 --- /dev/null +++ b/test/test_nstx/test_fft.py @@ -0,0 +1,8 @@ + +def test_fft(setup_shot): + shot = setup_shot + kwargs = {'tmin':0.2, 'tmax':0.3} + shot.bes.ch01.plotfft(**kwargs) + shot.bes.ch01.powerspectrum(tmin=0.270, tmax=0.280, fmax=200, power2=4e3) + shot.magnetics.highn.highn_7.plotfft(**kwargs) + shot.usxr.hdown.hdown08.plotfft(**kwargs) diff --git a/test/test_nstx/test_signal.py b/test/test_nstx/test_signal.py new file mode 100644 index 0000000..11d169a --- /dev/null +++ b/test/test_nstx/test_signal.py @@ -0,0 +1,15 @@ +def test_1d_signals(setup_shot): + shot = setup_shot + signals = [shot.bes.ch01, + shot.magnetics.highn.highn_7, + shot.usxr.hdown.hdown08, + shot.equilibria.efit01.ipmeas, + shot.mpts.ld, + shot.nbi.total_power, + shot.engineering.ioh, + shot.rwn.irwm1] + for signal in signals: + signal[:] + signal.plot() + print(signal[0:9]) + signal.axes \ No newline at end of file From ea12a721bfe543ece826c09fdbae33129a7f5c8c Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 14:10:40 -0400 Subject: [PATCH 77/82] tests --- test/test_nstx/test_exceptions.py | 2 +- test/test_nstx/test_machine.py | 9 +- test/test_nstx/test_signal.py | 6 +- test_old/__init__.py | 6 -- test_old/run.py | 13 --- test_old/setup.py | 24 ------ test_old/testCrossCorrelation.py | 133 ------------------------------ test_old/testEmptySignal.py | 16 ---- test_old/testEmptyTree.py | 16 ---- test_old/testFilter.py | 99 ---------------------- test_old/testNstxu.py | 89 -------------------- test_old/testNstxuBes.py | 29 ------- test_old/testNstxuDiagnostics.py | 62 -------------- test_old/testNstxuShot.py | 48 ----------- 14 files changed, 11 insertions(+), 541 deletions(-) delete mode 100644 test_old/__init__.py delete mode 100644 test_old/run.py delete mode 100644 test_old/setup.py delete mode 100644 test_old/testCrossCorrelation.py delete mode 100644 test_old/testEmptySignal.py delete mode 100644 test_old/testEmptyTree.py delete mode 100644 test_old/testFilter.py delete mode 100644 test_old/testNstxu.py delete mode 100644 test_old/testNstxuBes.py delete mode 100644 test_old/testNstxuDiagnostics.py delete mode 100644 test_old/testNstxuShot.py diff --git a/test/test_nstx/test_exceptions.py b/test/test_nstx/test_exceptions.py index 3a72ca3..e78fca0 100644 --- a/test/test_nstx/test_exceptions.py +++ b/test/test_nstx/test_exceptions.py @@ -6,5 +6,5 @@ def test_exceptions(): with pytest.raises(FdpError): raise FdpError("error message") - with pytest.raises(FdpWarning): + with pytest.warns(FdpWarning): warn("warning message", FdpWarning) diff --git a/test/test_nstx/test_machine.py b/test/test_nstx/test_machine.py index c0f1141..3a330cd 100644 --- a/test/test_nstx/test_machine.py +++ b/test/test_nstx/test_machine.py @@ -29,17 +29,17 @@ def test_shot_management(): ishot = 0 # load shot with machine instantiation nstx = fdp.nstx(shotlist=shotlist[ishot]) - assert shotlist[ishot] in nstx._shots + assert shotlist[ishot] in nstx assert isinstance(nstx[shotlist[ishot]], fdp.classes.shot.Shot) # load shot with adshot() method ishot += 1 nstx.addshot(shotlist=shotlist[ishot]) - assert shotlist[ishot] in nstx._shots + assert shotlist[ishot] in nstx assert isinstance(nstx[shotlist[ishot]], fdp.classes.shot.Shot) # add shot by attribute reference ishot += 1 shot = getattr(nstx, 's{}'.format(shotlist[ishot])) - assert shotlist[ishot] in nstx._shots + assert shotlist[ishot] in nstx assert isinstance(shot, fdp.classes.shot.Shot) # check shotlist assert len(dir(nstx)) == 4 @@ -68,7 +68,8 @@ def test_filter_xp(setup_nstx): xp1037.logbook() xp1037.list_shots() dir(xp1037) - xp1037._shots[0] in xp1037 + keys = xp1037._shots.keys() + assert keys[0] in xp1037 def test_filter_date(setup_nstx): nstx = setup_nstx diff --git a/test/test_nstx/test_signal.py b/test/test_nstx/test_signal.py index 11d169a..f8a0df0 100644 --- a/test/test_nstx/test_signal.py +++ b/test/test_nstx/test_signal.py @@ -7,9 +7,13 @@ def test_1d_signals(setup_shot): shot.mpts.ld, shot.nbi.total_power, shot.engineering.ioh, - shot.rwn.irwm1] + shot.rwm.irwm1] for signal in signals: signal[:] + assert hasattr(signal, 'size') + assert signal.size > 0 + assert hasattr(signal, 'time') + assert signal.time.size > 0 signal.plot() print(signal[0:9]) signal.axes \ No newline at end of file diff --git a/test_old/__init__.py b/test_old/__init__.py deleted file mode 100644 index b837a18..0000000 --- a/test_old/__init__.py +++ /dev/null @@ -1,6 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sat Jun 25 13:47:47 2016 - -@author: drsmith -""" diff --git a/test_old/run.py b/test_old/run.py deleted file mode 100644 index 9a34a92..0000000 --- a/test_old/run.py +++ /dev/null @@ -1,13 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Run the FDP test suite: - - % python run.py - -""" - -import os.path -import unittest - -loader = unittest.defaultTestLoader.discover(os.path.dirname(__file__)) -unittest.TextTestRunner(verbosity=2).run(loader) diff --git a/test_old/setup.py b/test_old/setup.py deleted file mode 100644 index eaa09a8..0000000 --- a/test_old/setup.py +++ /dev/null @@ -1,24 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Jul 10 00:27:26 2016 - -@author: drsmith -""" - -import unittest -import fdp - - -class SetupNstxu(unittest.TestCase): - """ - Unittest setup for nstxu machine and shot attribute - """ - - def setUp(self, shotnumber=204952): - """ - Shot 204952: Valid MPTS, CHERS, BES, EFIT01, - Filterscopes, Neutrons, Magnetics, NBI, USXR, MSE - """ - self.nstxu = fdp.nstx() - self.shotnumber = shotnumber - self.shot = getattr(self.nstxu, 's' + repr(self.shotnumber)) diff --git a/test_old/testCrossCorrelation.py b/test_old/testCrossCorrelation.py deleted file mode 100644 index 742a9b1..0000000 --- a/test_old/testCrossCorrelation.py +++ /dev/null @@ -1,133 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Sep 12 11:00:36 2016 - -@author: dkriete -""" -import numpy as np -from scipy.signal import correlate, fftconvolve, hilbert -import matplotlib.pyplot as plt - -# Take correlation between two 10 kHz sine waves with 5 us offset -fs = 2e6 # sampling frequency -T = 10e-3 # 10 ms sampling period -t = np.arange(int(fs * T)) / fs # array of time points -numpnts = len(t) # Number of points in signals (N=800 for this case) - -f = 10e3 # sine wave frequency -dt = np.random.normal(5e-6, 10e-6, numpnts) # time offset -x = np.sin(2 * np.pi * f * t) -y = np.sin(2 * np.pi * f * (t + dt)) - -nperseg = 2000 - -# ============================================================================= -# Begin code copied from CrossSignal class -signal1_seg = [] -signal2_seg = [] -nseg = numpnts // nperseg # Number of segments -for i in range(nseg): - start_i = i * nperseg - signal1_seg.append(x[start_i:start_i + nperseg]) - signal2_seg.append(y[start_i:start_i + nperseg]) -signal1_seg = np.array(signal1_seg) -signal2_seg = np.array(signal2_seg) - -xcorr = np.zeros((nseg, 2 * nperseg - 1)) -autocorr1 = np.zeros((nseg, 2 * nperseg - 1)) -autocorr2 = np.zeros((nseg, 2 * nperseg - 1)) -xcorr_coef = np.zeros((nseg, 2 * nperseg - 1)) -for i in range(nseg): - - # Subtract mean from each segment - signal1_seg[i, :] -= np.mean(signal1_seg, axis=1)[i] - signal2_seg[i, :] -= np.mean(signal2_seg, axis=1)[i] - - # Calculate cross-correlation for each segment - # The second input is reversed to change the convolution to a - # cross-correlation of the form Sum[x[i] * y[i - k]]. The - # output is then reversed to put the cross-correlation into - # the more standard form Sum[x[i] * y[i +k]] - xcorr[i, :] = fftconvolve(signal1_seg[i, :], - signal2_seg[i, ::-1])[::-1] - - # Calculate autocorrelations for each segment - autocorr1[i, :] = fftconvolve(signal1_seg[i, :], - signal1_seg[i, ::-1])[::-1] - autocorr2[i, :] = fftconvolve(signal2_seg[i, :], - signal2_seg[i, ::-1])[::-1] - - # Calculate correlation coefficient - xcorr_coef[i, :] = xcorr[i, :] / np.sqrt( - autocorr1[i, nperseg - 1] * autocorr2[i, nperseg - 1]) - - # Average over all segments - crosscorrelation = np.mean(xcorr, axis=0) - autocorrelation1 = np.mean(autocorr1, axis=0) - autocorrelation2 = np.mean(autocorr2, axis=0) - correlation_coef = np.mean(xcorr_coef, axis=0) - - # Calculate envelope of correlation using analytic signal method - correlation_coef_envelope = np.absolute( - hilbert(correlation_coef)) - - # Construct time axis for cross correlation - time_delays = np.linspace(-(nperseg - 1), - (nperseg - 1), - 2 * nperseg - 1) / fs - -fig2 = plt.figure() -ax2 = fig2.add_subplot(111) # for some reason this is preferred over fig.gca() -ax2.set_xlim([0, 0.5e-3]) -ax2.set_xlabel('Time') -ax2.set_ylabel('y') -ax2.plot(t, y) - -fig1 = plt.figure() -ax1 = fig1.add_subplot(111) # for some reason this is preferred over fig.gca() -ax1.set_xlim([-10e-6, 10e-6]) -ax1.set_ylim([0.9, 1.0]) -ax1.set_xlabel('Time delay') -ax1.set_ylabel('Cross correlation') -ax1.set_title('CrossSignal method') -ax1.plot(time_delays, correlation_coef) - -# End code copied from CrossSignal class -# ============================================================================= - -# ============================================================================= -# Test stuff written during development of cross-correlation routine -# ============================================================================= -# Calculate cross correlation using integral definition -#cc_integral = np.zeros(2 * N - 1) -# for k in range(len(cc_integral)): -# if k in range(N): # First half is zero and negative time shift -# for j in range(N - 1 - k, N): -# cc_integral[k] += x[j] * y[j + k - (N - 1)] -## cc_integral[k] /= k + 1 -# else: # Second half is positive time shift -# for j in range(0, 2 * (N - 1) - k + 1): -# cc_integral[k] += x[j] * y[j + k - (N - 1)] -## cc_integral[k] /= 2 * (N - 1) - k + 1 -#cc_integral = correlate(x,y) -#cc_timeaxis = np.linspace(-(N - 1), N - 1, 2 * N - 1) / fs -# -# Calculate cross correlation using fft method -# cc_fft = fftconvolve(x, y[::-1]) # Reverse y to compute correlation instead of convolve -# -# Plot results -#fig1 = plt.figure() -# ax1 = fig1.add_subplot(111) # for some reason this is preferred over fig.gca() -#ax1.set_xlim([-100e-6, 100e-6]) -#ax1.set_xlabel('Time delay') -#ax1.set_ylabel('Cross correlation') -#ax1.set_title('Integral method') -#ax1.plot(cc_timeaxis, cc_integral) -# -#fig2 = plt.figure() -#ax2 = fig2.add_subplot(111) -#ax2.set_xlim([-100e-6, 100e-6]) -#ax2.set_xlabel('Time delay') -#ax2.set_ylabel('Cross correlation') -#ax2.set_title('FFT method') -#ax2.plot(cc_timeaxis, cc_fft) diff --git a/test_old/testEmptySignal.py b/test_old/testEmptySignal.py deleted file mode 100644 index ce48c3c..0000000 --- a/test_old/testEmptySignal.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sat Jul 9 19:50:42 2016 - -@author: drsmith -""" - -import unittest -import fdp -from setup import SetupNstxu - -print('running tests in {}'.format(__file__)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test_old/testEmptyTree.py b/test_old/testEmptyTree.py deleted file mode 100644 index ce48c3c..0000000 --- a/test_old/testEmptyTree.py +++ /dev/null @@ -1,16 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sat Jul 9 19:50:42 2016 - -@author: drsmith -""" - -import unittest -import fdp -from setup import SetupNstxu - -print('running tests in {}'.format(__file__)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test_old/testFilter.py b/test_old/testFilter.py deleted file mode 100644 index 6e7dd66..0000000 --- a/test_old/testFilter.py +++ /dev/null @@ -1,99 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Thu Sep 22 19:00:31 2016 - -@author: dkriete -""" - -from __future__ import division -import copy -from fdp.classes.fdp_globals import FdpError -import numpy as np -import matplotlib.pyplot as plt -from scipy.signal import firwin, filtfilt, freqz - - -def filter_signal(signal, fNyq, fmin=None, fmax=None, numfilttaps=None): - 'Band pass filter the input data' - - # Check to see if either filter frequency has been set. If not, then - # don't filter the data - if fmin is not None or fmax is not None: - - # Set default values for unspecified frequencies and convert units - # of specified frequencies from kHz to Hz - if fmin is not None and fmax is not None: - filttype = 'bandpass' - - if fmin is None: - filttype = 'lowpass' - fmin = fNyq / 2 # Placeholder valid frequency - else: - fmin *= 1000 - - if fmax is None: - filttype = 'highpass' - fmax = fNyq / 2 # Placeholder valid frequency - else: - fmax *= 1000 - - # Verify that frequencies are valid - if fmin <= 0 or fmin >= fNyq: - raise FdpError('fmin is outside valid range') - if fmax <= 0 or fmax >= fNyq: - raise FdpError('fmax is outside valid range') - if fmax < fmin: - raise FdpError('fmin is larger than fmax') - - # Filter data using FIR filter generated using window - # method (Hamming window) - numpnts = len(signal) - if numfilttaps is None: - numtaps = 2 * (numpnts // 2) - 1 - else: - numtaps = numfilttaps - - if filttype == 'lowpass': - h = firwin(numtaps, fmax, nyq=fNyq) - elif filttype == 'highpass': - h = firwin(numtaps, fmin, pass_zero=False, nyq=fNyq) - else: # bandpass - h = firwin(numtaps, [fmin, fmax], pass_zero=False, nyq=fNyq) - - w, b = freqz(h, worN=2000) - fig = plt.figure() - ax = fig.add_subplot(111) - ax.plot(w * fNyq / np.pi, 20 * np.log10(abs(b))) - ax.set_xlabel('Frequency (Hz)') - ax.set_ylabel('Amplitude (dB)') - - return filtfilt(h, 1.0, signal, padlen=numtaps) - else: - return signal - - -# ============================================================================= -# Start of test -# ============================================================================= -T = 0.01 # width of time window -fs = 2e6 # sampling frequency -fNyq = fs / 2 - -t = np.arange(int(fs * T)) / fs # time array -x = np.sin(2 * np.pi * 100 * t) + 0.2 * np.sin(2 * np.pi * - 1e3 * t) + 0.1 * np.sin(2 * np.pi * 10e3 * t) - -fmin = 0.5 -fmax = 2. - -x_filt = filter_signal(x, fNyq, fmin=fmin, fmax=fmax) - -fig1 = plt.figure() -ax1 = fig1.add_subplot(111) -ax1.plot(t, x) -ax1.set_title('Unfiltered') - -fig2 = plt.figure() -ax2 = fig2.add_subplot(111) -ax2.plot(t, x_filt) -ax2.set_title('Filtered') diff --git a/test_old/testNstxu.py b/test_old/testNstxu.py deleted file mode 100644 index 26a7325..0000000 --- a/test_old/testNstxu.py +++ /dev/null @@ -1,89 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sat Jun 25 14:12:13 2016 - -@author: drsmith -""" - -import unittest -import MDSplus as mds -import pymssql -import fdp -from setup import SetupNstxu - -print('running tests in {}'.format(__file__)) - - -class TestNstxu(SetupNstxu): - - def testNstxuMachine(self): - """ - Assert fdp has 'nstx' and 'nstxu' attributes. - Assert fdp.nstxu is subclass of Machine. - """ - self.assertTrue(hasattr(fdp, 'nstxu'), 'fdp.nstxu() missing') - self.assertTrue(hasattr(fdp, 'nstx'), 'fdp.nstx() missing') - self.assertTrue(isinstance(self.nstxu, fdp.classes.machine.Machine), - 'fdp.nstxu() does not return machine.Machine instance') - - def testS0Attribute(self): - """ - Assert nstxu has 's0' attribute - """ - self.assertTrue(hasattr(self.nstxu, 's0')) - - def testDiagnosticContainers(self): - """ - Assert nstxu.s0 has diagnostic attributes - Assert that diagnostic attributes are subclasses of container.Container - """ - containers = ['bes', - 'usxr', - 'mse', - 'chers', - 'mpts', - 'magnetics', - 'equilibria', - 'filterscopes', - 'nbi', - 'neutrons'] - for containername in containers: - self.assertTrue(hasattr(self.nstxu.s0, containername), - 'nstxu.s0 missing {} attribute'.format( - containername)) - container = getattr(self.nstxu.s0, containername) - self.assertTrue(issubclass(type(container), - fdp.classes.container.Container), - '{} is not container.Container subclass'.format( - repr(container))) - - def testLogbookConnection(self): - """ - Assert Logbook object - Assert logbook connection is not none - """ - logbook = self.nstxu._logbook - self.assertTrue(isinstance(logbook, fdp.classes.logbook.Logbook), - 'nstxu._logbook is not logbook.Logbook instance') - logbook._make_logbook_connection() - self.assertIsNotNone(logbook._logbook_connection, - 'nstxu._logbook._logbook_connection is None') - self.assertTrue(isinstance(logbook._logbook_connection, - pymssql.Connection), - 'nstxu._logbook._logbook_connection \ - is not pymssql.Connection instance') - - def testMdsConnection(self): - """ - Assert that self._connections is list of mds.Connection objects - """ - self.assertTrue(isinstance(self.nstxu._connections[0], mds.Connection), - 'nstxu._connections[0] is not mds.Connection instance') - self.assertIsNotNone(self.nstxu._connections[0].socket, - 'nstxu._connections[0].socket is None') - self.assertIsNotNone(self.nstxu._connections[0].hostspec, - 'nstxu._connections[0].hostspec is None') - - -if __name__ == '__main__': - unittest.main() diff --git a/test_old/testNstxuBes.py b/test_old/testNstxuBes.py deleted file mode 100644 index af5758b..0000000 --- a/test_old/testNstxuBes.py +++ /dev/null @@ -1,29 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sat Jun 25 21:14:25 2016 - -@author: drsmith -""" - -import unittest -import fdp -from setup import SetupNstxu - -print('running tests in {}'.format(__file__)) - - -class TestBes(SetupNstxu): - - def testContainerClass(self): - self.assertTrue(hasattr(self.shot, 'bes')) - self.assertTrue(isinstance(self.shot.bes, - fdp.classes.container.Container)) - - def testSignalClass(self): - self.assertTrue(hasattr(self.shot.bes, 'ch01')) - self.assertTrue(isinstance(self.shot.bes.ch01, - fdp.classes.fdpsignal.Signal)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test_old/testNstxuDiagnostics.py b/test_old/testNstxuDiagnostics.py deleted file mode 100644 index 1af7974..0000000 --- a/test_old/testNstxuDiagnostics.py +++ /dev/null @@ -1,62 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Mon Jul 11 16:21:19 2016 - -@author: drsmith -""" - -import unittest -import fdp -from fdp.classes.utilities import isContainer, isSignal, isAxis -from setup import SetupNstxu - -print('running tests in {}'.format(__file__)) - - -class TestNstxuDiagnostics(SetupNstxu): - - def testSignalAxes(self, container=None): - """ - Recursively parse tree - Assert all signals contain 'axes' attribute - Assert all signals contain 'time' attribute - Assert all 'axes' elements are axis objects - Assert all axis attributes are in 'axes' - """ - if not container: - container = self.shot - if not isinstance(container, fdp.classes.shot.Shot): - if isinstance(container._parent, fdp.classes.shot.Shot): - print('Parsing {}'.format(container._name)) - else: - print('Parsing {}.{}'.format( - container._parent._name, container._name)) - for attrname in dir(container): - attr = getattr(container, attrname) - if isContainer(attr): - self.testSignalAxes(attr) - elif isSignal(attr): - self.assertTrue(hasattr(attr, 'axes'), - "Signal {} does not have 'axes' attr".format(attr._name)) - self.assertTrue(hasattr(attr, 'time'), - "Signal {} does not have 'time' attr".format(attr._name)) - self.assertTrue(isAxis(getattr(attr, 'time')), - "'time' attr is not axis object for signal {}".format(attr._name)) - for axisname in attr.axes: - self.assertTrue(hasattr(attr, axisname), - "'axes' element {} not an attribute for signal {}".format( - axisname, attr._name)) - axis = getattr(attr, axisname) - self.assertTrue(isAxis(axis), - "'axes' element {} is not axis object for signal {}".format( - axisname, attr._name)) - for sigattrname in dir(attr): - sigattr = getattr(attr, sigattrname) - if isAxis(sigattr): - self.assertIn(sigattrname, attr.axes, - "{} is axis but not in 'axes' attr for signal {}".format( - sigattrname, attr._name)) - - -if __name__ == '__main__': - unittest.main() diff --git a/test_old/testNstxuShot.py b/test_old/testNstxuShot.py deleted file mode 100644 index d198350..0000000 --- a/test_old/testNstxuShot.py +++ /dev/null @@ -1,48 +0,0 @@ -# -*- coding: utf-8 -*- -""" -Created on Sun Jul 10 00:29:32 2016 - -@author: drsmith -""" - -import unittest -import fdp -from setup import SetupNstxu - -print('running tests in {}'.format(__file__)) - - -class TestNstxuShot(SetupNstxu): - - def testShotClass(self): - shotattrname = 's' + repr(self.shotnumber) - self.assertTrue(hasattr(self.nstxu, shotattrname), - 'nstxu does not have {} attribute'.format(shotattrname)) - self.assertTrue(issubclass(type(self.shot), fdp.classes.shot.Shot), - '{} is not shot.Shot subclass'.format(repr(self.shot))) - - def testDiagnsticContainers(self): - """ - Assert all shot attributes are containers - """ - diagnostics = dir(self.shot) - for diagnostic in diagnostics: - diag = getattr(self.shot, diagnostic) - self.assertTrue(issubclass(type(diag), fdp.classes.container.Container), - '{} is not subclass of container.Container'.format(repr(diag))) - - def testLogbook(self): - """ - Assert logbook entries - """ - pass - - def testTestShot(self): - """ - Assert test shot with <6 digits - """ - pass - - -if __name__ == '__main__': - unittest.main() From dea305b5a74f983a22cfa1788fbe52961943365d Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 14:19:54 -0400 Subject: [PATCH 78/82] changed fdp_globals import --- fdp/classes/gui.py | 8 ++++---- fdp/methods/nstxu/bes/movie.py | 4 ++-- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/fdp/classes/gui.py b/fdp/classes/gui.py index 8a03dc5..d989176 100644 --- a/fdp/classes/gui.py +++ b/fdp/classes/gui.py @@ -19,7 +19,7 @@ # mpl.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from . import fdp_globals +from .fdp_globals import TKROOT, FdpWarning class BaseGui(threading.Thread): @@ -44,9 +44,9 @@ def __init__(self, obj, title='FDP GUI', parent=None, self.start() def run(self): - if not fdp_globals.TKROOT: + if not TKROOT: self.topwindow = tk.Tk() - fdp_globals.TKROOT = self.topwindow + TKROOT = self.topwindow else: self.topwindow = tk.Toplevel() self.topwindow.title(self.title) @@ -106,7 +106,7 @@ def addShot(self): try: shot = int(self.shotEntry.get()) except ValueError: - warn('Shot value is invalid', fdp_globals.FdpWarning) + warn('Shot value is invalid', FdpWarning) return with self.machinelock: self.machine.addshot(shot) diff --git a/fdp/methods/nstxu/bes/movie.py b/fdp/methods/nstxu/bes/movie.py index d6cedb9..a654614 100644 --- a/fdp/methods/nstxu/bes/movie.py +++ b/fdp/methods/nstxu/bes/movie.py @@ -13,8 +13,8 @@ from matplotlib import animation import matplotlib.pyplot as plt -from fdp.classes.fdp_globals import FdpError -from fdp.classes.utilities import isContainer +from ....classes.fdp_globals import FdpError +from ....classes.utilities import isContainer from . import utilities as UT From 6564d4c4220c9f28787eff1d01f0f703e260c184 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 16:01:56 -0400 Subject: [PATCH 79/82] changed 'fdp_globals' to 'globals' throughout repo --- docs/source/developer_guide.rst | 4 ++-- examples/big_test.py | 2 +- fdp/classes/container.py | 2 +- fdp/classes/crosssignal.py | 2 +- fdp/classes/datasources.py | 2 +- fdp/classes/fdp.py | 2 +- fdp/classes/fft.py | 2 +- fdp/classes/{fdp_globals.py => globals.py} | 0 fdp/classes/gui.py | 2 +- fdp/classes/logbook.py | 2 +- fdp/classes/machine.py | 2 +- fdp/classes/parse.py | 2 +- fdp/classes/shot.py | 2 +- fdp/classes/signal.py | 2 +- fdp/methods/fft.py | 2 +- fdp/methods/nstxu/bes/animation.py | 2 +- fdp/methods/nstxu/bes/configuration.py | 4 ++-- fdp/methods/nstxu/bes/crosspower.py | 2 +- fdp/methods/nstxu/bes/fft.py | 2 +- fdp/methods/nstxu/bes/movie.py | 2 +- fdp/methods/nstxu/bes/utilities.py | 2 +- fdp/methods/nstxu/equilibria/utilities.py | 2 +- fdp/methods/plot.py | 2 +- test/test_nstx/test_exceptions.py | 2 +- 24 files changed, 25 insertions(+), 25 deletions(-) rename fdp/classes/{fdp_globals.py => globals.py} (100%) diff --git a/docs/source/developer_guide.rst b/docs/source/developer_guide.rst index c286cae..1285c34 100755 --- a/docs/source/developer_guide.rst +++ b/docs/source/developer_guide.rst @@ -220,9 +220,9 @@ Class ``Node`` .. autoclass:: fdp.classes.node.Node :members: -Module ``fdp.classes.fdp_globals`` +Module ``fdp.classes.globals`` ==================================== -.. automodule:: fdp.classes.fdp_globals +.. automodule:: fdp.classes.globals :members: Module ``fdp.classes.factory`` diff --git a/examples/big_test.py b/examples/big_test.py index b9d4ce0..ceb5cef 100644 --- a/examples/big_test.py +++ b/examples/big_test.py @@ -5,7 +5,7 @@ @author: drsmith """ -#from fdp.classes.fdp_globals import VERBOSE +#from fdp.classes.globals import VERBOSE #VERBOSE = True import fdp diff --git a/fdp/classes/container.py b/fdp/classes/container.py index 79722ff..0af9ecf 100755 --- a/fdp/classes/container.py +++ b/fdp/classes/container.py @@ -10,7 +10,7 @@ import numpy as np import xml.etree.ElementTree as ET -from .fdp_globals import FDP_DIR, VERBOSE +from .globals import FDP_DIR, VERBOSE from . import parse from .node import Node from .signal import Signal diff --git a/fdp/classes/crosssignal.py b/fdp/classes/crosssignal.py index e2bdbef..1aea5a0 100644 --- a/fdp/classes/crosssignal.py +++ b/fdp/classes/crosssignal.py @@ -10,7 +10,7 @@ from scipy.signal.spectral import _spectral_helper from scipy.stats import linregress import numpy as np -from .fdp_globals import FdpError, FdpWarning +from .globals import FdpError, FdpWarning class CrossSignal(object): diff --git a/fdp/classes/datasources.py b/fdp/classes/datasources.py index 5033655..d75ce8d 100644 --- a/fdp/classes/datasources.py +++ b/fdp/classes/datasources.py @@ -7,7 +7,7 @@ """ import os -from .fdp_globals import FdpError +from .globals import FdpError MACHINES = ['nstxu', 'diiid', 'cmod'] diff --git a/fdp/classes/fdp.py b/fdp/classes/fdp.py index fbcc07e..eb8f920 100755 --- a/fdp/classes/fdp.py +++ b/fdp/classes/fdp.py @@ -7,7 +7,7 @@ from .machine import Machine from .parse import parse_method -from .fdp_globals import VERBOSE, FdpError +from .globals import VERBOSE, FdpError from .datasources import machineAlias, MACHINES diff --git a/fdp/classes/fft.py b/fdp/classes/fft.py index b3f8515..7586535 100644 --- a/fdp/classes/fft.py +++ b/fdp/classes/fft.py @@ -7,7 +7,7 @@ import numpy as np from scipy import fftpack -from .fdp_globals import FdpError +from .globals import FdpError class Fft(object): diff --git a/fdp/classes/fdp_globals.py b/fdp/classes/globals.py similarity index 100% rename from fdp/classes/fdp_globals.py rename to fdp/classes/globals.py diff --git a/fdp/classes/gui.py b/fdp/classes/gui.py index d989176..4f0fde9 100644 --- a/fdp/classes/gui.py +++ b/fdp/classes/gui.py @@ -19,7 +19,7 @@ # mpl.use('TkAgg') from matplotlib.backends.backend_tkagg import FigureCanvasTkAgg -from .fdp_globals import TKROOT, FdpWarning +from .globals import TKROOT, FdpWarning class BaseGui(threading.Thread): diff --git a/fdp/classes/logbook.py b/fdp/classes/logbook.py index d0d3c01..810d092 100755 --- a/fdp/classes/logbook.py +++ b/fdp/classes/logbook.py @@ -7,7 +7,7 @@ import datetime import numpy as np import pymssql -from .fdp_globals import FdpError +from .globals import FdpError from .datasources import LOGBOOK_CREDENTIALS diff --git a/fdp/classes/machine.py b/fdp/classes/machine.py index 72154ea..2678b39 100755 --- a/fdp/classes/machine.py +++ b/fdp/classes/machine.py @@ -11,7 +11,7 @@ import MDSplus as mds from .logbook import Logbook from .shot import Shot -from .fdp_globals import FDP_DIR, FdpError, FdpWarning, VERBOSE +from .globals import FDP_DIR, FdpError, FdpWarning, VERBOSE from .datasources import machineAlias, MDS_SERVERS, EVENT_SERVERS diff --git a/fdp/classes/parse.py b/fdp/classes/parse.py index a8d9f41..6b44097 100755 --- a/fdp/classes/parse.py +++ b/fdp/classes/parse.py @@ -6,7 +6,7 @@ import os import numpy as np -from .fdp_globals import FDP_DIR, VERBOSE +from .globals import FDP_DIR, VERBOSE def parse_method(obj, level=None): diff --git a/fdp/classes/shot.py b/fdp/classes/shot.py index ddc2ac0..3b752ee 100755 --- a/fdp/classes/shot.py +++ b/fdp/classes/shot.py @@ -9,7 +9,7 @@ import numpy as np from collections import MutableMapping from . import container -from .fdp_globals import VERBOSE +from .globals import VERBOSE class Shot(MutableMapping): diff --git a/fdp/classes/signal.py b/fdp/classes/signal.py index b19270a..2d6d2d4 100755 --- a/fdp/classes/signal.py +++ b/fdp/classes/signal.py @@ -17,7 +17,7 @@ import inspect import types import numpy as np -from .fdp_globals import FdpError, VERBOSE +from .globals import FdpError, VERBOSE class Signal(np.ndarray): diff --git a/fdp/methods/fft.py b/fdp/methods/fft.py index 218ccf8..fc67347 100644 --- a/fdp/methods/fft.py +++ b/fdp/methods/fft.py @@ -10,7 +10,7 @@ import matplotlib.pyplot as plt from ..classes.utilities import isSignal, isContainer -from ..classes.fdp_globals import FdpWarning +from ..classes.globals import FdpWarning from ..classes.fft import Fft from .listmethods import listSignals diff --git a/fdp/methods/nstxu/bes/animation.py b/fdp/methods/nstxu/bes/animation.py index 9f8fe71..b5848de 100644 --- a/fdp/methods/nstxu/bes/animation.py +++ b/fdp/methods/nstxu/bes/animation.py @@ -13,7 +13,7 @@ from matplotlib import animation import matplotlib.pyplot as plt -from ....classes.fdp_globals import FdpError +from ....classes.globals import FdpError from ....classes.utilities import isContainer diff --git a/fdp/methods/nstxu/bes/configuration.py b/fdp/methods/nstxu/bes/configuration.py index 04bb642..b5341b6 100644 --- a/fdp/methods/nstxu/bes/configuration.py +++ b/fdp/methods/nstxu/bes/configuration.py @@ -9,9 +9,9 @@ import xml.etree.ElementTree as ET from warnings import warn -from ....classes.fdp_globals import FdpError +from ....classes.globals import FdpError from ....classes.utilities import isContainer -from ....classes.fdp_globals import FdpWarning +from ....classes.globals import FdpWarning def loadConfig(container=None): diff --git a/fdp/methods/nstxu/bes/crosspower.py b/fdp/methods/nstxu/bes/crosspower.py index 30955b7..8d2477e 100644 --- a/fdp/methods/nstxu/bes/crosspower.py +++ b/fdp/methods/nstxu/bes/crosspower.py @@ -12,7 +12,7 @@ from ....classes.crosssignal import CrossSignal from ....classes.utilities import isContainer -from ....classes.fdp_globals import FdpWarning +from ....classes.globals import FdpWarning def crosssignal(container, sig1name='ch01', sig2name='ch02', diff --git a/fdp/methods/nstxu/bes/fft.py b/fdp/methods/nstxu/bes/fft.py index 043297f..260fdf4 100644 --- a/fdp/methods/nstxu/bes/fft.py +++ b/fdp/methods/nstxu/bes/fft.py @@ -6,7 +6,7 @@ import matplotlib.pyplot as plt from ....classes.utilities import isSignal, isContainer -from ....classes.fdp_globals import FdpWarning +from ....classes.globals import FdpWarning from ....classes.fft import Fft diff --git a/fdp/methods/nstxu/bes/movie.py b/fdp/methods/nstxu/bes/movie.py index a654614..e0a192d 100644 --- a/fdp/methods/nstxu/bes/movie.py +++ b/fdp/methods/nstxu/bes/movie.py @@ -13,7 +13,7 @@ from matplotlib import animation import matplotlib.pyplot as plt -from ....classes.fdp_globals import FdpError +from ....classes.globals import FdpError from ....classes.utilities import isContainer from . import utilities as UT diff --git a/fdp/methods/nstxu/bes/utilities.py b/fdp/methods/nstxu/bes/utilities.py index 7938d30..1107ff4 100644 --- a/fdp/methods/nstxu/bes/utilities.py +++ b/fdp/methods/nstxu/bes/utilities.py @@ -5,7 +5,7 @@ @author: drsmith """ -from ....classes.fdp_globals import FdpError +from ....classes.globals import FdpError from ....classes.utilities import isSignal, isContainer diff --git a/fdp/methods/nstxu/equilibria/utilities.py b/fdp/methods/nstxu/equilibria/utilities.py index 6585555..9e1e7be 100644 --- a/fdp/methods/nstxu/equilibria/utilities.py +++ b/fdp/methods/nstxu/equilibria/utilities.py @@ -8,7 +8,7 @@ import xml.etree.ElementTree as ET import os -from ....classes.fdp_globals import FDP_DIR +from ....classes.globals import FDP_DIR from ....classes.container import Container, _tree_dict, init_class diff --git a/fdp/methods/plot.py b/fdp/methods/plot.py index 038fd0f..b355847 100755 --- a/fdp/methods/plot.py +++ b/fdp/methods/plot.py @@ -15,7 +15,7 @@ import matplotlib.pyplot as plt #import pyqtgraph as pg -from ..classes.fdp_globals import FdpWarning +from ..classes.globals import FdpWarning # pg.mkQApp() diff --git a/test/test_nstx/test_exceptions.py b/test/test_nstx/test_exceptions.py index e78fca0..fefb756 100644 --- a/test/test_nstx/test_exceptions.py +++ b/test/test_nstx/test_exceptions.py @@ -1,7 +1,7 @@ from warnings import warn import pytest -from fdp.classes.fdp_globals import FdpError, FdpWarning +from fdp.classes.globals import FdpError, FdpWarning def test_exceptions(): with pytest.raises(FdpError): From 4abf46b7dbc0b3369a97b50c59405d8801f46622 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 22:10:57 -0400 Subject: [PATCH 80/82] tests --- .coveragerc | 2 +- fdp/classes/container.py | 14 -------------- fdp/classes/signal.py | 2 -- test/test_nstx/test_crossphase.py | 5 +++++ test/test_nstx/test_shot.py | 4 +++- test/test_nstx/test_signal.py | 13 ++++++++++++- 6 files changed, 21 insertions(+), 19 deletions(-) create mode 100644 test/test_nstx/test_crossphase.py diff --git a/.coveragerc b/.coveragerc index a1498db..a01654a 100644 --- a/.coveragerc +++ b/.coveragerc @@ -1,6 +1,6 @@ [run] source = fdp -branch = True +branch = False [report] show_missing = True diff --git a/fdp/classes/container.py b/fdp/classes/container.py index 0af9ecf..88b4b04 100755 --- a/fdp/classes/container.py +++ b/fdp/classes/container.py @@ -184,14 +184,9 @@ def __init__(self, module_tree, top=False, **kwargs): print(' {}.__init__() End module parsing'.format(self._name)) def __getattr__(self, attribute): - if VERBOSE: - print(' {}.__getattr__({})'.format(self._name, attribute)) try: if self._dynamic_containers[attribute] is None: branch_path = '.'.join([self._get_branch(), attribute]) - if VERBOSE: - print(' {}.__getattr__({}) calling Factory()'. - format(self._name, attribute)) self._dynamic_containers[attribute] = \ Factory(branch_path, root=self._root, shot=self.shot, parent=self) @@ -199,28 +194,19 @@ def __getattr__(self, attribute): return self._dynamic_containers[attribute] except KeyError: pass - if not hasattr(self, '_parent') or self._parent is None: raise AttributeError("Attribute '{}' not found".format(attribute)) - if hasattr(self._parent, '_signals') and \ attribute in self._parent._signals: raise AttributeError("Attribute '{}' not found".format(attribute)) - attr = getattr(self._parent, attribute) if 'Shot' in str(type(attr)): raise AttributeError("Attribute '{}' not found".format(attribute)) if Container in attr.__class__.mro() and attribute[0] is not '_': raise AttributeError("Attribute '{}' not found".format(attribute)) if inspect.ismethod(attr): - if VERBOSE: - print(' {}.__getattr__({}) returning parent method'. - format(self._name, attribute)) return types.MethodType(attr.__func__, self) else: - if VERBOSE: - print(' {}.__getattr__({}) returning parent attr'. - format(self._name, attribute)) return attr def _get_dynamic_containers(self): diff --git a/fdp/classes/signal.py b/fdp/classes/signal.py index 2d6d2d4..3eaa43d 100755 --- a/fdp/classes/signal.py +++ b/fdp/classes/signal.py @@ -319,8 +319,6 @@ def __getslice__(self, start, stop): return self.__getitem__(slice(start, stop)) def __call__(self, **kwargs): - if VERBOSE: - print(' {}.__call__ BEGIN'.format(self._name)) try: slc = [slice(None)] * len(self.axes) except TypeError: diff --git a/test/test_nstx/test_crossphase.py b/test/test_nstx/test_crossphase.py new file mode 100644 index 0000000..8c65215 --- /dev/null +++ b/test/test_nstx/test_crossphase.py @@ -0,0 +1,5 @@ + +def test_crossphase(setup_nstx): + nstx = setup_nstx + bes = nstx.s204990.bes + bes.plotcrossphase('ch42','ch46',tmin=0.3,tmax=0.4,nperseg=2000,spectrum=False) \ No newline at end of file diff --git a/test/test_nstx/test_shot.py b/test/test_nstx/test_shot.py index 027551b..17e8af3 100644 --- a/test/test_nstx/test_shot.py +++ b/test/test_nstx/test_shot.py @@ -9,4 +9,6 @@ def test_shot(setup_shot): getattr(shot, 'chers') shot.logbook() shot.get_logbook() - shot.check_efit() \ No newline at end of file + shot.check_efit() + dir(shot.chers) + dir(shot.chers.spline) \ No newline at end of file diff --git a/test/test_nstx/test_signal.py b/test/test_nstx/test_signal.py index f8a0df0..3e00326 100644 --- a/test/test_nstx/test_signal.py +++ b/test/test_nstx/test_signal.py @@ -10,10 +10,21 @@ def test_1d_signals(setup_shot): shot.rwm.irwm1] for signal in signals: signal[:] + assert signal assert hasattr(signal, 'size') assert signal.size > 0 assert hasattr(signal, 'time') assert signal.time.size > 0 signal.plot() print(signal[0:9]) - signal.axes \ No newline at end of file + signal.axes + signal(time=[0.1,0.2]) + +def test_2d_signals(setup_shot): + shot = setup_shot + signals = [shot.mpts.te, + shot.chers.ti] + for signal in signals: + signal[:] + signal.plot() + signal[0,0:9] \ No newline at end of file From 1ae8d4bb3eb38681ad2fb0a5a9fbfe4574a08a67 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 22:14:30 -0400 Subject: [PATCH 81/82] updated CHANGELOG.txt and AUTHORS.txt --- AUTHORS.txt | 2 +- CHANGELOG.txt | 28 ++++++++++++++++++++++++++++ 2 files changed, 29 insertions(+), 1 deletion(-) diff --git a/AUTHORS.txt b/AUTHORS.txt index ca61988..a9921fe 100644 --- a/AUTHORS.txt +++ b/AUTHORS.txt @@ -3,7 +3,7 @@ Lead developers: Kevin Tritz Howard Yuh Commits from authors: - 204 David R. Smith + 277 David R. Smith 37 ktritz 22 dmkriete 2 hyyuh diff --git a/CHANGELOG.txt b/CHANGELOG.txt index ad9a8db..8795b8f 100644 --- a/CHANGELOG.txt +++ b/CHANGELOG.txt @@ -1,3 +1,31 @@ +Release v0.2.0 -- 2017-04-19\n +4abf46b tests +6564d4c changed 'fdp_globals' to 'globals' throughout repo +dea305b changed fdp_globals import +ea12a72 tests +54cb3a7 Merge branch 'drs-dev' of github.com:drsmith48/fdp into drs-dev +74c271f tests +ff08bd2 tests +63ce140 tests +af97cda testing for logbook.py and machine.py +8fbaf30 pytest setup +534f00a created new test directory and configured for pytest; run 'pytest' or 'make test' +3f59f74 minor +be1449c minor +a8e38e3 fixed axis removal from multi-dim signals +9400ca8 Merge branch 'master' into drs-dev +8e2d471 Merge pull request #54 from drsmith48/plotpsirz +33c025e debugging eq.plotrz.plot() +7adfae2 bfield() method for equilibria +ddd16a5 minor fixes +ea8852b changed 'zero level' indices to floats +09f779a changed iteritems to iter() +7d32fd6 docs +bab6bbc docs +fa1a1fb docs +17e9578 removed pushes from bumps in Makefile +a06ac9b run 'authors' recipe prior to 'bump-*' recipes in Makefile +\n Release v0.1.4 -- 2017-04-07 a2842c8 added automatic CHANGELOG.txt updates with 'bump-*' recipes in Makefile From 4490335da873e75f0a441715f2c5e9259ba1f661 Mon Sep 17 00:00:00 2001 From: "David R. Smith" Date: Wed, 19 Apr 2017 22:14:33 -0400 Subject: [PATCH 82/82] =?UTF-8?q?Bump=20version:=200.1.4=20=E2=86=92=200.2?= =?UTF-8?q?.0?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- .bumpversion.cfg | 2 +- docs/source/conf.py | 2 +- fdp/__init__.py | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/.bumpversion.cfg b/.bumpversion.cfg index 4daf757..f23119c 100644 --- a/.bumpversion.cfg +++ b/.bumpversion.cfg @@ -1,5 +1,5 @@ [bumpversion] -current_version = 0.1.4 +current_version = 0.2.0 commit = True tag = True verbose = True diff --git a/docs/source/conf.py b/docs/source/conf.py index 16ea139..6204753 100755 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -66,7 +66,7 @@ # built documents. # # The short X.Y version. -version = '0.1.4' +version = '0.2.0' # The full version, including alpha/beta/rc tags. release = version diff --git a/fdp/__init__.py b/fdp/__init__.py index 8dc4b24..483a7e0 100755 --- a/fdp/__init__.py +++ b/fdp/__init__.py @@ -7,7 +7,7 @@ from .classes import fdp -__version__ = '0.1.4' +__version__ = '0.2.0' def nstxu(*args, **kwargs):