================================================================================
SPy 0.22
================================================================================
Release date: 2020.08.01

New Features (thanks to @kormang)
---------------------------------

* Continuum computation and removal

  * See functions `spectral_continuum`, `remove_continuum`, `continuum_points`

* Support for USGS spectral library (`spectral.USGSDatabase`)

* SMACC algorithm for endmember extraction (`spectral.algorithms.smacc`)

Bug Fixes
---------

* [Issue #113] `orthogonalize` was broken in release 0.21.


================================================================================
SPy 0.21
================================================================================
Release date: 2020.04.26

Changes
-------

* As of version 0.21, Spectral Python (SPy) is released under the MIT License.

* Switched most console `print` statements to logging statements for finer
  control of module output.

* Cleaned up a lot of code to put imports at module (file) level.

Bug Fixes
---------

* [Issue #99] matplotlib's "cmap" keyword now works again with `spy.imshow`.

* [Issue #102] Creating a `SpectralLibrary` no longer fails when some
  optional band parameters are not provided.


================================================================================
SPy 0.20
================================================================================
Release date: 2019.10.06

New Features
------------

* Support for ECOSTRESS spectral library (supercedes ASTER library).

* Accept "mask" and "bg" keywords in `imshow` and `get_rgb` (affects color
  scaling).

* Denoising methods added to `PrincipalComponents` (issue #91) added by
  @gemmaellen.

* Added "raw" to list of checked ENVI data file extensions.

Changes
-------

* Increase speed of `spectral_angles` computation by ~30x using `einsum`.

* Eliminate `tostring` deprecation warnings by migrating to `tobytes`.

Bug Fixes
---------

* Support parsing ENV bbl values as floats (issue #67).

* Removed "scale" keyword to handle TransformedImage objects in
  `envi.save_image` (issue #83).

================================================================================
SPy 0.19
================================================================================
Release date: 2017.06.04

New Features
------------

* Rendering functions accept an "ignore" keyword to indicate a bad data value
  that will be ignored when calculating color histogram stretches.

* Added `iterator_ij` to iterate over all pixel coordinates for a given
  image mask.

* Added `expand_binary_mask_for_window` to expand an image mask to include
  all pixels within a fixed size window around each masked pixel.

* Added support for bad band lists (bbl) in ENVI headers and suppress display
  of bad bands in spectral plots

* Added optional support for non-lowercase ENVI header parameter names.

Changes
-------

* `principal_components` also accepts a `GaussianStats` object, which can
  avoid the need to recompute image/class statistics.

* Added a `SpyException` base class for package-specific exceptions.

* Added "raw" to the list of checked ENVI image data file extensions.

Bug Fixes
---------

* Fixed a bug that potentially produced incorrect results in `map_class_ids`
  (issue #53).

* Removed unecessary import that cause python3 compatibility error in
  `aviris.open` (issue #54).

* Removed `has_key` call breaking python3 compatibility (issue #56).

================================================================================
SPy 0.18
================================================================================
Release date: 2016.06.18

Changes
-------

* Improved handling of ENVI header files:

  * If "header offset" is missing, assume the offset is 0.

  * Stricter check for "ENVI" in the first line of the file.

  * [Issue #42] More-informative exceptions are raised when a problem is
    encountered while reading and ENVI header.

  * [Issue #46] No longer defaulting `band_quantity` to "Wavelength".

Bug Fixes
---------

* [Issue #38 and #39] The `tostring` method has been deprecated in newer
  versions of PIL/Pillow. Using `tobytes` now and falling back to `tostring`
  if it fails.

* [Issue #40] An exception was raised when trying to get a pixel's row/col
  by CTRL-SHIFT-clicking in the ND window display.

* [Issue #44] Matplotlib was being set to interactive mode even if no SPy
  windows were displayed. This would affect behavior of other code using
  Matplotlib. Interactive mode is now set only once the first display is
  requested.

* [Issue #49] `GaussianClassifier` and `MahalanobisDistanceClassifier` method
  `classify_image` was failing when applied to an object that was not a
  numpy.ndarray (e.g., a `SpyFile` or `TransformedImage`).

================================================================================
SPy 0.17
================================================================================
Release date: 2015.11.11

New Features
------------

* Functions `map_class_ids` and `map_classes` were added for mapping class
  indices between images.

* `view_nd` now accepts custom axis labels.

* `ImageArray` and `SpyFile` have `asarray` method that provides numpy
  array interface.

Changes
-------

* ENVI header parameter names are case insensitive (converted to lower-case
  after being read).

* `ImageArray` objects have additional `SpyFile` methods/attributes and
  indexing behavior is now like `SpyFile`'s.

* An exception is now raised when attempting to open or save an image in
  ENVI format with nonzero major or minor frame offsets (see issue #35).

Bug Fixes
---------

* [Issue #27] ImageView.__str__ failed if image did not have "bands" in
  metadata.

================================================================================
SPy 0.16.2
================================================================================
Release date: 2015.04.27

Bug_Fix release.

Bug Fixes
---------

* [Issue #19] Fixed handling of intereave keyword.

* [Issue #20] envi.save_image fails when interleave keyword is provided for
  single-band images.

* [Issue #21] offset keyword has not effect in envi.create_image.

* [Issue #22] setup.py fails if numpy is not already installed.

* [Issue #24] save_rgb fails when format keyword is given.

* [Issue #25] view_cube fails in HypercubeWindow.load_textures.

* [Issue #26] Too few colors in view_cube side faces.

================================================================================
SPy 0.16.1
================================================================================
Release date: 2014.10.18

Bug_Fix release.

Bug Fixes
---------

* [Issue #18] Missing import statements for pixel iterators.

================================================================================
SPy 0.16.0
================================================================================
Release date: 2014.10.18

New Features
------------

* Adaptive Coherence/Cosine Estimator (ACE) target detector

* Pixel Purity Index (PPI)

* Adjustable linear color stretches (based on data limits or cumulative histogram)

* Ability to save ENVI Classification files (thanks to @ohspite)

* `ImageView` class has `set_title` method

Changes
-------

* `imshow` image displays use a linear 2% color stretch by default (can
  override this in `spectral.settings`)

* Limited Python 3 compatibility (all functions except `view_cube` and `view_nd`) supported

* `get_rgb` handles bands with no variation (color set to min value)

* Modified `view_nd` to support change in PyOpenGL API

Bug Fixes
---------

* [Issue #16] Incorrect handling of alternate file extensions in `envi.save_image`

* [Issue #11] Incorrect handling of unsigned byte data type in ENVI files

* [Issue #13] As of version 1.9, `numpy` no longer provides `oldnumeric` submodule

================================================================================
SPy 0.15.0
================================================================================
Release date: 2014.06.04

New Features
------------

* Added Minimum Noise Fraction (`mnf`) algorithm (a.k.a., Noise-Adjusted
  Principal Components). An associated `noise_from_diffs` function enables
  estimation of image noise from a homogeneous region of the image.


Changes
-------

* When calling `envi.save_image`, assume an ndarray with two dimensions is
  a single-band image (i.e., don't require an explicit third dimension).

* [Issue #9] All SpyFile subclass read methods now have an optional
  `use_memmap` argument to indicate whether the memmap interface should be
  used (vice direct file read) on a per-call basis. Default values are
  specific to the particular method and file interleave.

Bug Fixes
---------

* [Issue #7] Handle recognize comment lines in ENVI headers and accept blank
  parameter values in the header. Thanks to Don March (http://ohspite.net)

* [Issue #2] Garbage results were being generated for several algorithms when
  a NaN value was present in the image data. Reasonable checks are now
  performed in several algorithms and an optional `allow_nan` argument (False
  by default) was added to `calc_stats`.

* [Issue #1] For images with more rows than columns, the row/col of the pixel
  under the mouse cursor did not display if the row index was greater than
  the image width.


Performance Improvements
------------------------

* [Issue #5] Improved BilFile.read_bands performance. Thanks to Don March
  (http://ohspite.net)

* [Issue #8] Faster creation/display of RGB images for display. Thanks to
  Don March (http://ohspite.net)

================================================================================
SPy 0.14.0
================================================================================
Release date: 2014.02.22

Changes
-------

* Attempt to use Pillow fork of PIL, if available, rather than older PIL.

* `view_cube` now uses common color scale limits on all side faces.

* When creating an `AsterDatabase` instance, directories in the `SPECTRAL_DATA`
  environment variable are search for the specified file (after the current
  directory).

* `spectral.imshow` accepts an optional `fignum` argument to render to an
  existing figure.

* Class labels in a `spectral.imshow` window can be reassigned even when class
  labels were not provided in the function call (all pixels will start with
  class 0).

* File `spectral/algorithms/perceptron.py` can be used independently of the
  rest of the package.

Bug Fixes
---------

* Front and left sides of the image cube displayed by `view_cube` were
  mirrored left-right. Cube aspect ratio was being computed incorrectly for
  non-square images. These bugs were introduced by a recent release.

* Global covariance was not being scaled properly in the
  `MahalanobisDistanceClassifier`. Mathematically, it does not affect results
  and did not affect results on the test data but for large covariance with
  many classes, it could have cause rounding/truncation that would affect
  results.

* PerceptronClassifier constructor was failing due to recent changes in
  base class code. Unit tests have been added to ensure it continues to work
  properly.


Performance Improvements
------------------------

* PerceptronClassifier is roughly an order of magnitude faster due to better
  use of numpy. Inputs are now scaled and weights are initialized withing the
  data limits, which usually results in fewer iterations for convergence.

================================================================================
SPy 0.13
================================================================================
Release date: 2014.01.05

New Features
------------

* New features for image displays:

  * Image rasters can be switched between *data*, *class*, and *class overlay*
    view, using adjustable class alpha transparency.

  * Image pixel regions can be interactively assigned to new classes using
    mouse/keyboard click & drag interaction.

  * A "zoom" window can be opened from an image view by pressing "z". The zoom
    window center point can be panned to a new location by holding CONTROL and
    left-clicking in the original window.

  * Image pixel interpolation can be switched between the module default and
    *nearest* (by pressing "i").

* The `view_nd` window can open a class map raster view (by pressing "c") that
  dynamically shows changed class values.

* Added a `matched_filter` function, which wraps the `MatchedFilter` class and
  allows using local background stats using an inner/outer window.

* `rx` accepts an optional *cov* argument, which specifies a global background
  covariance. When this argument is given, the background mean will be computed
  using a moving inner/outer window but the covariance will be fixed.

* Function `cov_avg` computes covariance averaged over multiple classes (using
  the mean of each class.

* Added `msam` (Modified SAM) function by Oshigami et al (code was contributed
  by Christian Mielke).

* `matrix_sqrt` optionally returns the square root of the matrix inverse.

* Created the `WindowedGaussianBackgroundMapper` to easily apply any pixel-based
  estimator to an image using local background stats computed for an inner/outer
  window.

Performance Improvements
------------------------

* Significant speedup for sevaral algorithms using ndarray inputs:

  * 14x speedup for GMCL

  * 7x speedup for Mahalanobis distance classification

  * 3x speedup for `kmeans`

* Windowed `rx` is significanty faster from using cached covariance.

* `matrix_sqrt` accepts an optional *eigs* arguments that makes square root
  calculation significantly faster.

* `GaussianStats` object caches eigen-decomposition, make calculation of other
  covariance-derived stats much faster.

Changes
-------

* Eigenvectors in `PrincipalComponents` objects (returned by `principal_components`)
  are now stored in columns (they were in rows) to be consistent with numpy.
  An explicit check is not performed to ensure eigenvalues are in descending
  order.

* Converted `GaussianStats` constructor keyword args to optional positional args.

* Added numerouse new unit tests.

* Simplified the unit testing interface, eliminating the need for `test_method`
  decorator and `TestCase` subclass `run` methods.

* Converted `SpySettings` object attributes to class attributes.

* Removed `save_training_sets`. Use `TrainingClassSet.save` instead.

Bug Fixes
---------

* Exception occured when *bands* argument was not provided to `imshow`.

* *stretch_all* parameter for `get_rgb` was sometimes being used when set to
  False or 0 (because it was not None).

* Fixed broken implementation of `load_training_sets`. `save_training_sets` was
  also fixed (but implementation is replaced by TrainingClassSet.save`.

* Fixed a scaling error in `linear_discriminant` and divide by N-1 to get
  unbiased estimate of *cov_b*.

================================================================================
SPy 0.12
================================================================================
Release date: 2013.09.06

New Features
------------

* Added a wrapper around matplotlib's `imshow` to easily display HSI data.

* A new memmap interface is provided for SpyFile objects
  (via the `open_memmap` method), including the ability to open writable
  memmaps.

* Algorithm progress display can be enabled/disabled via the settings object.

* RX anomaly detection can be performed using local statistics by specifying
  an inner/outer window.

* A custom background color can be specified when calling `view_cube`.

* Summary statistics are printed for unit test execution.

Changes
-------

* `get_image_display_data` has been renamed `get_rgb`.

* `view_cube` will also accept an ndaray as the "top" keyword.

* If present, image band info is saved when `envi.save_image` is called.

* Allow calling :func:`~spectral.oi.envi.create_image` using keyword args
  instead of ENVI-specific header paramter names.

* `save_rgb` automatically determines the output file type, based on the
  filename extension.

* Results of several ImageArray methods will be cast to an ndarray.

* The Image base class is now a new-style class.


Bug Fixes
---------

* Eliminated texture-wrapping display artifact near edges of displayed image
  cubes (called via `view_cube`).

* RX.__call__ was failing when image statistics were not provided to class
  constructor.

* Applied Ferdinand Deger's bugfix for `envi.create_image`.

* `ImageView` objects raised an exception when the *data* constructor arg was
  a `SpyFile` object.

* `wx.NewId` occasionally returns a weird number (large negative value), which
  raises an exception in wx. Now caching `NDWindow` right-click menu ID values
  to avoid this wx bug.

================================================================================
SPy 0.11
================================================================================
Release date: 2013.04.03

New Features
------------

* RX anomaly detector.

* Ability to save and create images in ENVI format.

* Added `GaussianStats` class (returned by `calc_stats`). This class can be
  transformed by a `LinearTransform`.  It has a `get_whitening_transform`
  method that returns a callable transform to whiten image data.

* Added a unit-testing sub-package (`spectral.tests`)

Changes
-------

* Changed severals function to accept GaussianStats objects instead of
  sepaarate mean & covariance.

* Changed names of several functions for consistency:

  - `open_image` replaces `image`.

  - `save_rgb` replaces `save_image`

* Improved support for additional data types by reading byte strings into
  numpy arrays with dtypes instead of using builtin array module.

Bug Fixes
---------

* 32-bit integer image data  was not being read properly.

================================================================================
SPy 0.10.1
================================================================================
Release date: 2013.02.23

This is a bug-fix release that corrects the spectrum displayed when double-
clicking on a raster display.  Version 0.10 introduced a bug that had the
row/column swapped, resulting in either the wrong pixel being plotted or an
exception raised.

================================================================================
SPy 0.10
================================================================================
Release date: 2013.02.17

As of this release, SPy now uses IPython for non-blocking GUI windows. IPython
should be started in "--pylab" mode with the appropriate backend set (see
:ref:`starting_ipython`). The standard python interpreter can still be used if
GUI functions are not being called.

New Features
------------

* `LinearTransform` and `transform_image` now handle scalar transforms.

* All functions opening a GUI window will now return a proxy object to enable
  access to any associated data (e.g., accessing changed class values in an
  N-D data display).

* GUI functions are now aware of differences in wxWidgets versions
  (2.8.x vs. 2.9.x).

Changes
-------

* SPy no longer requires explicit creation of a new wx thread.  Instead,
  running SPy interactively with GUI functions now requires using IPython
  in "pylab" mode.

* A few functions have been renamed for consistency:

  * `hypercube` is now `view_cube`.
  
  * `ndwindow is now `view_nd`.

* numpy is used for more covariance calculations (e.g., class-specific
  covariance) to improve performance on multi-core systems.

* Two new parameters have been added to the `spectral.settings` object:

  1. `START_WX_APP` : If this parameter is True and no wx App exists when a
     GUI function is called, then an App will be started to prevent an error.
     
  2. `WX_GL_DEPTH_SIZE` : If the default GL_DEPTH_SIZE is not supported by the
     host system (resulting in a blank GLCanvas in `view_cube` or `view_nd`),
     this parameter can be reduced (e.g., to 24 or 16) to enable OpenGL
     rendering.
  
Bug Fixes
---------

* Spectral plotting failed when double-clicking a transformed image due to
  band info being unavailable.  A check is now performed to prevent this.

* OpenGL-related calls will no longer fail if GLUT or an associated font is
  not available.

================================================================================
SPy 0.9
================================================================================
Release date: 2013.01.23

- New Features

  - Added a linear target detector (MatchedFilter).

  - Added a class for linear transformations (LinearTransform).

- Changes

  - `principal_components` function now returns a object, which contains return
     values previously in a tuple, , as well as the associated linear transform,
     and a `reduce` method.
  
  - `linear_discriminant` function now returns an object, which contains return
    values previously in a tuple, as well as the associated linear transform.
  
  - Covariance calculation is now performed using 64-bit floats.

- Bug Fixes

  - Fixed a bug causing `ndwindow` to fail when no class mask is passed as a
    keyword arg.

================================================================================
SPy 0.8 Release Notes
================================================================================
Release date: 2012.07.15

- New Features

  - The :func:`~spectral.graphics.ndwindow.ndwindow` function enables viewing of
    high-dimensional images in a 3D display. See :ref:`nd_displays` for details.

- Changes

  - Hypercube display now uses mouse control for pan/zoom/rotate.

- Bug Fixes

  - Fixed a bug in several deprecation warnings that caused infinte recursion.

  - Fixed mismatch in parameter names in kmeans_ndarray.

================================================================================
SPy 0.7 Release Notes
================================================================================
Release date: 2012.02.19

- Changes

  - Changed many function/method names to be more consistent with external
    packages.  Use of most old names will generate a deprecation warning but
    some will require immediate changes to client code.

  - :func:`spectral.kmeans` runs about 10 times faster now for loaded images.


- Bug Fixes

  - The Erdas LAN file interface was modified because the previous reference
    file had mixed endian between header and data sections.  If you are using
    the old sample file "92AV3C", then start using the "92AV3C.lan" file
    available on the web site (see Intro section of the user's guide). This file
    has consistent endian-ness between header and image data sections

  - Fixed a few bugs that potentially caused problems with the BIP and BSQ file
    interfaces.  The specific methods fixed are:
    
    * BipFile.read_bands
    * BsqFile.read_subregion
    * BsqFile.read_subimage
 

================================================================================
SPy 0.6 Release Notes
================================================================================
Release date: 2011.01.17

- New Features:

  - Support for parsing & loading spectra from the ASTER Spectral Library.
  
  - Ability to save ENVI spectral library files.

  - :meth:`spectral.kmeans` will accept a :exc:`KeyboardInterrupt` exception
    (i.e., CTRL-C) and return the results as of the previous iteration.

  - Documention is now online via Sphinx.

- Changes

  - Major changes to module/sub-module layout. Biggest change is that the top-
    level module is now "spectral" instead of "Spectra" (capitalization). Many
    functions/classes have moved between files and sub-modules but that should
    be transparent to most users since the most obvious names are automatically
    imported into the top-level module namespace.

  - Additional ENVI data file extensions are now searched (.bil, .bsq, .bip,)

  - Changed default colors in :obj:`spectral.spyColors`, which is the default
    color palette used by :meth:`spectral.viewIndexed`.

  - :meth:`spectral.transformImage` is now the means to apply a linear transform
    to an image (rather than creating a :class:`spectral.TransformedImage`
    directly) because it handles both :class:`spectral.SpyFile` and
    :class:`numpy.ndarray` objects.

  - 64-bit floats are now used for covariance matrices.

  - Changed SPECTRAL_DATA path delimiter from semi-colon to colon.
    
- Bug fixes

  - Fixed a bug preventing successful reading of ENVI header files where an
    equal ("=") symbol appears in a parameter value.

  - Fixed bug where a ColorScale might return an incorrect color if the scale
    contained negative values.

  - :meth:`cluster` would fail if only 2 clusters were requested.
  
  - :meth:`kmeans` was reporting an incorrect number of pixels reassigned
    between iterations (did not affect final convergence).

  - :meth:`logDeterminant` was crashing when receiving negative values.
  
  - Missing a potential byte swap in :meth:`spectral.io.bilfileBilFile.readDatum`.


