Skip to content

Commit

Permalink
Merge pull request #612 from grlee77/release-notes-1_2
Browse files Browse the repository at this point in the history
Release notes for v1.2.0
  • Loading branch information
rgommers committed Nov 8, 2021
2 parents 9996424 + a6cc244 commit 0f911ad
Show file tree
Hide file tree
Showing 4 changed files with 248 additions and 71 deletions.
1 change: 1 addition & 0 deletions .mailmap
Original file line number Diff line number Diff line change
Expand Up @@ -9,5 +9,6 @@ Holger Nahrstaedt <holgernahrstaedt@gmx.de> Holger Nahrstaedt <holgern@users.nor
Kai Wohlfahrt <kai.wohlfahrt@gmail.com> <kai.scorpio@gmail.com>
Kai Wohlfahrt <kai.wohlfahrt@gmail.com> <kjw53@cam.ac.uk>
Kai Wohlfahrt <kai.wohlfahrt@gmail.com> Kai <kai.scorpio@gmail.com>
Pavle Boškoski <pavleb+git@gmail.com> pavleb <pavleb+git@gmail.com>
Ralf Gommers <ralf.gommers@gmail.com> <ralf.gommers@googlemail.com>
Sylvain Lannuzel <sylvain.lannuzel@student.ecp.fr> SylvainLan <sylvain.lannuzel@student.ecp.fr>
69 changes: 68 additions & 1 deletion doc/release/1.2.0-notes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -6,12 +6,30 @@ PyWavelets 1.2.0 Release Notes

We are very pleased to announce the release of PyWavelets 1.2.

PyWavelets now requires Python 3.7+.
This release has new discrete wavelet transforms features incleading a series
of multiresolution analysis functions (details below).

PyWavelets has dropped support for Python 3.5 and 3.6 and now supports
Python 3.7-3.10.

We also now provide aarch64 linux wheels as well as universal2 and arm64
wheels that are compatible with Apple's M1 processors.


New features
============

- There is a new series of multilevel stationary wavelet transforms (``mra``,
``mra2`` and ``mran``) suited for multiresolution analysis of 1D, 2D or nD
signals, respectively. This MRA analysis is also known as the additive wavelet decomposition because the corresponding inverse functions (``imra``, ``imra2``
or ``imran``) reconstruct the original signal by simple addition of the
components. These are a good alternative to the use of the existing SWT
functions when it is important to have features aligned across wavelet scales
(see the new demo in ``demo/mra_vs_swt.py``).

- There is now an n-dimensional implementation available for the wavelet packet
transforms (see class `WaveletPacketND`).


Backwards incompatible changes
==============================
Expand All @@ -25,6 +43,9 @@ Backwards incompatible changes
Bugs Fixed
==========

- Add input length check in `dwt_single` for reflect modes.
- Demos were updated for compatibility with recent Matplotlib versions.
- Removed deprecated import from ``imp``.

Other changes
=============
Expand All @@ -33,3 +54,49 @@ Other changes

Authors
=======

* ElConno +
* Ralf Gommers
* Gregory R. Lee
* Jakub Mandula +
* nperraud +
* ossdev07 +

A total of 6 people contributed to this release.
People with a "+" by their names contributed a patch for the first time.
This list of names is automatically generated, and may not be fully complete.


Issues closed for v1.2
----------------------

* `#235 <https://github.com/PyWavelets/pywt/issues/235>`__: Build issue: cython not recognized
* `#545 <https://github.com/PyWavelets/pywt/issues/545>`__: Request: add __reduce__ method for WaveletPacket object
* `#554 <https://github.com/PyWavelets/pywt/issues/554>`__: imp is deprecated


Pull requests for v1.2
----------------------

* `#393 <https://github.com/PyWavelets/pywt/pull/393>`__: Wavelet packets: extend to nD and support subsets of the axes
* `#525 <https://github.com/PyWavelets/pywt/pull/525>`__: WIP: test against Python 3.8
* `#527 <https://github.com/PyWavelets/pywt/pull/527>`__: Multiresolution Analysis
* `#540 <https://github.com/PyWavelets/pywt/pull/540>`__: remove unused distutils import from __init__.py
* `#546 <https://github.com/PyWavelets/pywt/pull/546>`__: ENH: make Wavelet, WaveletPacket, WaveletPacket2D and ContinuousWavelet...
* `#547 <https://github.com/PyWavelets/pywt/pull/547>`__: ContinuousWavelet: add tests for dtype and remove unused \*\*kwargs
* `#552 <https://github.com/PyWavelets/pywt/pull/552>`__: Cython 3.0 compatibility: explicitly call import_array()
* `#559 <https://github.com/PyWavelets/pywt/pull/559>`__: MAINT: bump minimum Python version to 3.7
* `#567 <https://github.com/PyWavelets/pywt/pull/567>`__: Documentation about trim_approx in swt2 is wrong
* `#571 <https://github.com/PyWavelets/pywt/pull/571>`__: improve documentation of padding in coeffs_to_array
* `#572 <https://github.com/PyWavelets/pywt/pull/572>`__: Replace camera image with a CC0-licensed equivalent
* `#573 <https://github.com/PyWavelets/pywt/pull/573>`__: switch from terrify to multibuild for OS X setup on Travis
* `#578 <https://github.com/PyWavelets/pywt/pull/578>`__: Add Python 3.9 to CI and classifiers
* `#584 <https://github.com/PyWavelets/pywt/pull/584>`__: MAINT: remove use of deprecated np.int/float aliases
* `#598 <https://github.com/PyWavelets/pywt/pull/598>`__: Add input length check in dwt_single for reflect modes
* `#601 <https://github.com/PyWavelets/pywt/pull/601>`__: Add wheel building and deployment via GitHub Actions and cibuildwheel
* `#604 <https://github.com/PyWavelets/pywt/pull/604>`__: MAINT: update pyproject.toml and setup.py for Python 3.10
* `#608 <https://github.com/PyWavelets/pywt/pull/608>`__: BLD: update Cython build dependency to recent release and <3.0
* `#609 <https://github.com/PyWavelets/pywt/pull/609>`__: MAINT: fix \`origin='image'\` calls that Matplotlib no longer...
* `#610 <https://github.com/PyWavelets/pywt/pull/610>`__: Update GitHub Actions workflow to build Python 3.10 wheels
* `#611 <https://github.com/PyWavelets/pywt/pull/611>`__: MAINT: fix doc build issues

83 changes: 56 additions & 27 deletions util/authors.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,39 +5,29 @@
List the authors who contributed within a given revision interval.
To change the name mapping, edit .mailmap on the top-level of the
repository.
"""
# Author: Pauli Virtanen <pav@iki.fi>. This script is in the public domain.

from __future__ import division, print_function, absolute_import

import optparse
import re
import sys
import os
import io
import subprocess


from scipy._lib.six import u, PY3
if PY3:
stdout_b = sys.stdout.buffer
else:
stdout_b = sys.stdout


NAME_MAP = {
u('Gregory Lee'): u('Gregory R. Lee'),
u('Daniel M Pelt'): u('Daniel M. Pelt'),
u('Helder'): u('Helder Oliveira'),
u('Kai'): u('Kai Wohlfahrt'),
u('asnt'): u('Alexandre Saint'),
u('pavleb'): u('Pavle Boškoski'),
}
stdout_b = sys.stdout.buffer
MAILMAP_FILE = os.path.join(os.path.dirname(__file__), "..", ".mailmap")


def main():
p = optparse.OptionParser(__doc__.strip())
p.add_option("-d", "--debug", action="store_true",
help="print debug output")
p.add_option("-n", "--new", action="store_true",
help="print debug output")
options, args = p.parse_args()

if len(args) != 1:
Expand All @@ -48,6 +38,8 @@ def main():
except ValueError:
p.error("argument is not a revision range")

NAME_MAP = load_name_map(MAILMAP_FILE)

# Analyze log data
all_authors = set()
authors = set()
Expand All @@ -56,7 +48,7 @@ def analyze_line(line, names, disp=False):
line = line.strip().decode('utf-8')

# Check the commit author name
m = re.match(u('^@@@([^@]*)@@@'), line)
m = re.match(u'^@@@([^@]*)@@@', line)
if m:
name = m.group(1)
line = line[m.end():]
Expand All @@ -67,17 +59,17 @@ def analyze_line(line, names, disp=False):
names.add(name)

# Look for "thanks to" messages in the commit log
m = re.search(u(r'([Tt]hanks to|[Cc]ourtesy of) ([A-Z][A-Za-z]*? [A-Z][A-Za-z]*? [A-Z][A-Za-z]*|[A-Z][A-Za-z]*? [A-Z]\. [A-Z][A-Za-z]*|[A-Z][A-Za-z ]*? [A-Z][A-Za-z]*|[a-z0-9]+)($|\.| )'), line)
m = re.search(r'([Tt]hanks to|[Cc]ourtesy of) ([A-Z][A-Za-z]*? [A-Z][A-Za-z]*? [A-Z][A-Za-z]*|[A-Z][A-Za-z]*? [A-Z]\. [A-Z][A-Za-z]*|[A-Z][A-Za-z ]*? [A-Z][A-Za-z]*|[a-z0-9]+)($|\.| )', line)
if m:
name = m.group(2)
if name not in (u('this'),):
if name not in (u'this',):
if disp:
stdout_b.write(" - Log : %s\n" % line.strip().encode('utf-8'))
name = NAME_MAP.get(name, name)
names.add(name)

line = line[m.end():].strip()
line = re.sub(u(r'^(and|, and|, ) '), u('Thanks to '), line)
line = re.sub(r'^(and|, and|, ) ', u'Thanks to ', line)
analyze_line(line.encode('utf-8'), names)

# Find all authors before the named range
Expand All @@ -92,22 +84,34 @@ def analyze_line(line, names, disp=False):

# Sort
def name_key(fullname):
m = re.search(u(' [a-z ]*[A-Za-z-\']+$'), fullname)
m = re.search(u' [a-z ]*[A-Za-z-]+$', fullname)
if m:
forename = fullname[:m.start()].strip()
surname = fullname[m.start():].strip()
else:
forename = ""
surname = fullname.strip()
surname = surname.replace('\'', '')
if surname.startswith(u('van der ')):
if surname.startswith(u'van der '):
surname = surname[8:]
if surname.startswith(u('de ')):
if surname.startswith(u'de '):
surname = surname[3:]
if surname.startswith(u('von ')):
if surname.startswith(u'von '):
surname = surname[4:]
return (surname.lower(), forename.lower())

# generate set of all new authors
if vars(options)['new']:
new_authors = authors.difference(all_authors)
n_authors = list(new_authors)
n_authors.sort(key=name_key)
# Print some empty lines to separate
stdout_b.write(("\n\n").encode('utf-8'))
for author in n_authors:
stdout_b.write(("- %s\n" % author).encode('utf-8'))
# return for early exit so we only print new authors
return

authors = list(authors)
authors.sort(key=name_key)

Expand All @@ -134,11 +138,35 @@ def name_key(fullname):
stdout_b.write(("\nNOTE: Check this list manually! It is automatically generated "
"and some names\n may be missing.\n").encode('utf-8'))


def load_name_map(filename):
name_map = {}

with io.open(filename, 'r', encoding='utf-8') as f:
for line in f:
line = line.strip()
if line.startswith(u"#") or not line:
continue

m = re.match(r'^(.*?)\s*<(.*?)>(.*?)\s*<(.*?)>\s*$', line)
if not m:
print("Invalid line in .mailmap: '{!r}'".format(line), file=sys.stderr)
sys.exit(1)

new_name = m.group(1).strip()
old_name = m.group(3).strip()

if old_name and new_name:
name_map[old_name] = new_name

return name_map


#------------------------------------------------------------------------------
# Communicating with Git
#------------------------------------------------------------------------------

class Cmd(object):
class Cmd:
executable = None

def __init__(self, executable):
Expand Down Expand Up @@ -190,6 +218,7 @@ def test(self, command, *a, **kw):
call=True, **kw)
return (ret == 0)


git = Cmd("git")

#------------------------------------------------------------------------------
Expand Down

0 comments on commit 0f911ad

Please sign in to comment.