################################################################################
# Spectral Python (SPy) package change log
################################################################################

2013-01-22	tboggs <tboggs@users.sourceforge.net>

    * __init__.py: Incremented __version__ to '0.9'

2013-01-22	tboggs <tboggs@users.sourceforge.net>

    * algorithms/algorithms.py
      (TrainingClass.transform): Remove superfluous `if` block from previous
        commit.
    * algorithms/transforms.py: doc string changes
    * algorithms/__init__.py: import MatchedFilter from detectors module.

2013-01-21	tboggs <tboggs@users.sourceforge.net>

    LinearTransform objects can now be chained together and can be passed a
    specific dtype for output.  They also have dim_in and dim_out members.
    `transform_image` optionally accepts LinearTransform arg instead of an
    ndarray.

    * io/spyfile.py
      (transform_image): Alternately accept a LinearTransform as arg.
      (TransformedImage.__init__): Alternately acccept a LinearTransform as arg.
        Store the transform as a LinearTransform object.
      (TransformedImage.__getitem__): Use the `transform` member.
      (TransformedImage.read_pixel): Use the `transform` member.
      (TransformedImage.load): Use the `transform` member.
      (TransformedImage.read_subregion): Use the `transform` member.
      (TransformedImage.read_subimage): Use the `transform` member.
      (TransformedImage.read_datum): Use the `transform` member.
      (TransformedImage.read_bands): Use the `transform` member.
    * algorithms/transforms.py
      (LinearTransform.__init__): Added dim_in, dim_out, and dtype members.
      (LinearTransform.__call__): Cast transformed data to appropriate type.
      (LinearTransform.chain): New method to chain two transforms together.
    * algorithms/algorithms.py
      (TrainingClass.transform): Explicitly use LinearTransform.

2013-01-19	tboggs <tboggs@users.sourceforge.net>

    Added a FisherLinearDiscriminant class, fixed doc strings, and handle
    LinearTransformation objects in TrainingClass.transform.

    * algorithsm/algorithms.py
      (FisherLinearDiscriminant): New class.
      (linear_discriminant): Returns a FisherLinearDiscriminant object instead
        of a tuple.
      (reduce_eigenvectors): Function removed (replaced by method in
        PrincipleComponents class).
      (TrainingClass.transform): Also accept a LinearTransform as arg.
      (TrainingClassSet.transform): Get nbands from one of the classes.
    * algorithms/detectors.py (MatchedFilter): Fixed latex markup in doc string.
    * algorithms/transforms.py (LinearTransform): Fixed doc string.
    * algorithms/__init__.py: Removed reduce_eigenvectors from imports
    
2013-01-17	tboggs <tboggs@users.sourceforge.net>

    Added a matched filter function and created a PrincipalComponents object.
    
    * graphics/ndwindow.py
      (WxNDWindowFrame.create_axes_list): Call glutInit to prevent error if
        `ndwindow` is called without class labels.
    * algorithms/algorithms.py
      (mean_cov): Use 64-bit floats for covariance calculation.
      (PrincipalComponents): New class.
      (principal_components): Function now returns a PrincipalComponents object
        instead of a tuple.
    * algorithms/detectors.py: New file. Contains MatchedFilter class.
    * algorithms/transforms.py: New file. Contains LinearTransform class.
    * algorithms/spymath.py: New file.  Contains matrix_sqrt function.

2012-07-08	tboggs <tboggs@users.sourceforge.net>

    Added a right-click meny to the `WxNDWindowFrame` for pixel class
    reassignment.  `ndwindow` now returns a proxy object by which client code
    can access the current value of the `classes` array associated with the
    displayed data.

    * graphics/graphics.py
      (_next_window_data_proxy_id): Module-level counter for data proxy IDs.
      (_window_data_proxies): Module-level dict of window data objects.
      (WindowData): New base class for window data objects.
      (WindowDataProxy): New proxy base class for accessing WindowData objects.
      (create_window_data_proxy_id): Returns a new WindowDataProxy ID and
        adds an associated entry in _window_data_proxies.
    * graphics/ndwindow.py:
      (MouseMenu): New class for implementing a right-click menu.
      (WxNDWindowFrame.__init__): Take proxy ID as an argument.
      (WxNDWindowFrame.on_event_close): New method for updating proxy data prior
        to closing the window.
      (WxNDWindowFrame.right_click): New method to pop up the right-click menu.
      (WxNDWindowFrame.on_char):
      * Call `on_event_close` when closing the window.
      * Only allow single-octant mode if fewer than six features are available.
      (WxNDWindowFrame.reassign_selection): If pixels were reassigned to the max
        class, increment the max class so a new empty class will be available
	next time the mouse menu is opened.
      (WxNDWindowFrame.set_data): Only allow single-octant mode if fewer than
        six features are available.
      (NDWindowData): New class for holding returnable client data.
      (NDWindowDataProxy): New data proxy used by client (calling) code.
      (NDWindowFunctor.__init__): Take proxy ID argument.
      (NDWindowFunctor.__call__): Pass proxy ID to window constructor.
      (validate_args): New function to validate args passed to `ndwindow`.
      (ndwindow): Return a proxy object to allow client code to access updated
        values of `classes` array. Call `validate_args`. Added doc string.
    * graphics/hypercube.py: Code cleanup.
      
2012-06-20	tboggs <tboggs@users.sourceforge.net>

    Initial ND window capability.  Automatically initialize display thread when
    `hypercube` is called, if needed.  Removed global import of OpenGL namespace
    from hypercube.py.
    
    * graphics/__init__.py: Import `hypercube` and `ndwindow` functions.
    * graphics/hypercube.py: Eliminated global import of OpenGL namespace.
      (hypercube): Automatically call `init_graphics`, if needed.
    * graphics/ndwindow.py: New file for ND window display.
    * graphics/spywxpython.py: Init module-level `viewer` to None.
    
2012-06-17	tboggs <tboggs@users.sourceforge.net>

    Fixed broken deprecation warnings that cause infinite recursion
    
    * spectral.py: Fixed deprection warnings for `tileImage`,
      `saveTrainingSets`, and `loadTrainingSets`.

2012-06-17	tboggs <tboggs@users.sourceforge.net>

    * graphics/hypercube.py: Added mouse control for hypercube display.

2012-06-14	tboggs <tboggs@users.sourceforge.net>

    Fixed mismatch in parameter names in kmeans_ndarray.
    
    * spectral/algorithms/clustering.py(kmeans_ndarray): Changed `startClusters`
      to `start_clusters`.


2012-05-30	tboggs <tboggs@users.sourceforge.net>

    Fixed bad search/replace that caused infinite recursion in some read funcs.
    
    * spectral.py(ImageArray):
      (read_band): Mislabled readBand warning caused infinite recursion.
      (read_bands): Mislabled readBands warning caused infinite recursion.
      (read_pixel): Mislabled readPixel warning caused infinite recursion.
      (read_datum): Mislabled readDatum warning caused infinite recursion.
    * io/spyfile.py: Fixed doc string
    
2012-02-23	tboggs <tboggs@users.sourceforge.net>

    Added numpy.memmap objects to SpyFile instances.  This improves read speed
    by about a factor of 10 (although algorithms are still about 10 times faster
    when using in-memory arrays).
    
    * io/bilfile.py:
      (BilFile.__init__): Set memmmap member for buffered input.
      (BilFile.read_band, read_bands, read_pixel, read_subregion, read_subimage,
       read_datum): Use memmap for reading file, if available.
    * io/bipfile.py:
      (BipFile.__init__): Set memmmap member for buffered input.
      (BipFile.read_band, read_bands, read_pixel, read_subregion, read_subimage,
       read_datum): Use memmap for reading file, if available.
    * io/bsqfile.py:
      (BsqFile.__init__): Set memmmap member for buffered input.
      (BsqFile.read_band, read_bands, read_pixel, read_subregion, read_subimage,
       read_datum): Use memmap for reading file, if available.

2012-02-19	tboggs <tboggs@users.sourceforge.net>

    Updated version number to '0.7' in __init__.py

2012-02-19	tboggs <tboggs@users.sourceforge.net>

    Changed many method and function names to be consitent with external
    modules (this affects almost every file so I won't list them here). Fixed
    several bugs affecting file reading for several formats.
    
    * io/bipfile.py (BipFile.read_bands): convert tuple to list to prevent
      an exception.
    * io/bsqfile:
      (BsqFile.read_subregion):  Fixed a bug that caused reading wrong section
      of data when lower row limit is non-zero.
      (BsqFile.read_subimage):  Fixed a bug that caused reading wrong data
      values when lower row limit is non-zero.

2011-01-28	tboggs <tboggs@users.sourceforge.net>

    Updated ERDAS/LAN file interface to handle either endian, regardless of host
    byte order.  The handler previously assumed little endian header parameters
    and big endian image data because the sample image previously used was a
    mixed endian file.  The handler will no longer work as expected with that
    image (`92AV3C`) because it is considered a badly formatted file.  To use
    that file, open it as normal, then toggle the value of ``img.swap`` (change
    from 0 to 1 or 1 to 0).

    * io/erdas.py:
      (open): Read header as little endian.  If that fails, try big endian.
      (readErdasLanHeader): Accept parameter specifying byte order of file.
      Assume header and image data have same byte order.
    
    A specialized version of the kmeans function was created for numpy ndarrays
    (kmeans_ndarray).  For in-memory images, this function is about 10 times
    faster than the original function (about 100 times faster than using SpyFile
    objects). The specialized version of the function is automatically called by
    kmeans if the image argument is an instance of a numpy.ndarray. Several
    positional arguments of kmeans are now keyword arguments and the default
    distance measure is L2 (Euclidean) distance.  If initial cluster centers are
    not passed as a keyword argument, they will be initialized evenly along the
    diagonal of the image data bounding box.
    
    * algorithms/clustering.py:
      (L2): Don't force type of difference operator.
      (kmeans): Several arguments changed to keywords.  Default distance is L2.
      Default for initial cluster centers is along diagonal of image data
      bounding box.  If image argument is an ndarray, call kmeans_ndarray.
      (kmeans_ndarray): New function - a version of kmeans specialized for
    
    Improved status display output.
    
    * utilities/status.py (StatusDisplay): Call sys.stdout.flush() after
      printing status output.
      

2011-01-17	tboggs <tboggs@users.sourceforge.net>

    * __init__.py: Import names from database submodule.
    * graphics/__init__.py: import ColorScale from colorscale.py
    
    * io/spyfile.py (findFilePath): SPECTRAL_DATA directory changed to ":".

    * Changed doc strings to sphinx format:
	* graphics/graphics.py
	* graphics/colorscale.py
	* graphics/hypercube.py
	* database/aster.py
	* spectral.py
	* io/bipfile.py
	* io/spyfile.py
	* io/aviris.py
	* io/erdas.py
	* io/envi.py
	* io/bsqfile.py
	* io/bilfile.py
	* algorithms/algorithms.py
	* algorithms/clustering.py
	* algorithms/perceptron.py
	* algorithms/resampling.py
	* algorithms/classifiers.py

2011-01-11	tboggs <tboggs@users.sourceforge.net>

    * io/bilfile.py (BilFile.readDatum): Add missing byte swap (if needed)
    * io/bipfile.py (BipFile.readDatum): Add missing byte swap (if needed)

2011-01-10	tboggs <tboggs@users.sourceforge.net>

    * algorithms/algorithms.py (unmix, spectralAngles): Fixed import statements.

2011-01-09	tboggs <tboggs@users.sourceforge.net>

    * __init__.py: import AsterDatabase into main module namespace.
    * database/aster.py
      (AsterDatabase.query): Now returns result set instead of string
      (AsterDatabase.printQuery): New method that prints results of a query
       (what query used to do).

2011-01-05	tboggs <tboggs@users.sourceforge.net>

    * algorithms/__init__.py: import BandResampler.
    * algorithms/resampling.py (BandResampler.__init__): Allow BandInfo objects
      to be passed as arguments

2011-01-02	tboggs <tboggs@users.sourceforge.net>

    * algorithms/clustering.py (kmeans): Allow keyboard interrupt (CTRL-c) to
      terminate k-means algorithm.

2010-12-13	tboggs <tboggs@users.sourceforge.net>

    * algorithms/algorithms.py (mean_cov): Use 64 bit float for covariance.
    * algorithms/perceptron(PerceptronClassifier.train): Raise Exception, not
      string.

2010-12-09	tboggs <tboggs@users.sourceforge.net>

    * io/spyfile.py:
      (transformImage): New function to apply a linear transform to either as
        numpy.ndarray, ImageArray, or SpyFile object.
      (TransformedImage.__init__): raise Exception objects instead of strings.
    * algorithms/algorithms.py (TrainingClass.transform): Catch all exceptions
      when calculating log of determinant of covariance.  Call transformImage
      instead of creating a TransformedImage object.

2010-12-05	tboggs <tboggs@users.sourceforge.net>

    * spectral.py: Changed default colors in spyColors.
    * io/envi.py (open): Fixed bug causing open to miss images with no extension.
    * io/aviris.py (readAvirisBands) Use findFilePath to locate cal files.

2010-11-28	tboggs <tboggs@users.sourceforge.net>

    * algorithms/algorithms.py (logDeterminant): Don't sum negative values.

2010-11-14	tboggs <tboggs@users.sourceforge.net>

    cluster algorithm modified to handle cases with only 2 clusters.  Fixed
    reported number of reassigned pixels in kmeans.

    * algorithms/clustering.py:
      (kmeans)
      - Use "cluster" function to initialize clusters if none supplied in args.
      - Corrected calculation of number of reassigned pixels (note: the error
        reported incorrect value to stdout but didn't affect stopping criteria).
      - Fixed default param value in doc string.
      (OnePassClusterer.calcDistances): Force distance matrix to be float type.
      (OnePassClusterer.findNextToGo): Now handles cases with only 2 clusters.
      
    * graphics/graphics.py (getImageDisplayData): Raise Exception object instead
      of string.

2010-11-09	tboggs <tboggs@users.sourceforge.net>

    Fixed several bugs revealed when producing ENVI spectral libraries from
    the Aster database.

    * algorithms/resampling.py (BandResampler.__init__): Compare args to None
      to avoid errors with numpy arrays in logical expressions.
    * io/envi.py
      (SpectralLibrary.save): Fixed call to writeEnviHdr.
      (_writeHeaderParam): Replace commas in parameter values with dashes to
        prevent read errors.
      (writeEnviHdr): Fixed call to _writeHeaderParam.
    * io/spyfile.py (findFilePath): Add missing param to exception string.

2010-10-26	tboggs <tboggs@users.sourceforge.net>

    * algorithms/clustering.py (OnePassClusterer.classifyImage): Fixed typo
      in module import statement

2010-10-18	tboggs <tboggs@users.sourceforge.net>

    Fixed typo in ENVI import and color scale bug.
    
    * graphics/colorscale.py (__init__): Fixed bug when color scale contains
      negative values.
    * io/envi.py (open): Fixed typo when importing bilfile modules.

2010-09-17	tboggs <tboggs@users.sourceforge.net>

    Improved support for ENVI header parameters.  Added search for image file
    names with interleave as extension (e.g., ".bsq").
    
    * io/envi.py
      (readEnviHdr): Modified parsing code to handle text parameters with "=" in
      the parameter value.  Thanks to Robin Wilson for a patch.
      (open): Search for image files with interleave as extension (.bsq, .bil,
      or .bip).
      
    Automatically recognize host byet order.

    * __init__.py: Determine host byte order and set in SPy package.
    
    
2010-09-09	tboggs <tboggs@users.sourceforge.net>

    Added creation of ENVI spectral libraries from the ASTER database and the
    ability to save ENVI spectral libraries to files.
    
    * database/aster.py (AsterDatabase.create) New method to create an ENVI
      spectral library from a list of ASTER spectrum IDs.
    * io/aviris.py (readAvirisBands): Set band unit to "nm".
    * io/envi.py
      (SpectralLibrary.__init__): Import header vals and set ignored value to "NaN".
      (SpectralLibrary.save): New method to save the library to a file.
      (writeEnviHdr): New method to write an ENVI header file.
      (_writeHeaderParam): New method to write an ENVI header file parameter.
      
2010-08-21	tboggs <tboggs@users.sourceforge.net>

    * graphics/hypercube.py (WxHypercubeFrame.LoadTextures): Made name change
      overlooked during package/module name migration.

2010-08-19	tboggs <tboggs@users.sourceforge.net>

    Added a sub-package for ASTER spectral library support. This enables parsing
    ASTER data files & metadata and putting the data into an sqlite database.
    
    * database: New sub-package.
    * database/__init__: New file.
    * database/aster.py: New file for importing & managing ASTER data
    
    * __init__.py: Import BandInfo into top-level spectral namespace.
    
2010-08-17	tboggs <tboggs@users.sourceforge.net>

    * Changed package/module names.  Top-level package is now "spectral" instead
      of "Spectral" (note capitalization).  Sub-packages/modules have also been
      changed but that should be transparent to most users.  Almost all files
      are affected.

2010-07-10	tboggs <tboggs@users.sourceforge.net>

    * Spectral.py (ImageArray.__getitem__): Added method to ensure that data
      extracted is returned as numpy array and not another ImageArray object.

    * __init__.py: Import spyColors from Spectral.py (accidentally removed with
      previous commit).
    
    * Algorithms/Cluster.py (kmeans): Fixed typo in status message.

2010-07-10	tboggs <tboggs@users.sourceforge.net>

    Move GUI-related functions into the Graphics sub-package.  Also, no longer
    attempt to initialize NumTut for image display if wx fails since NumTut no
    longer exists.
    
      * __init__.py: Import GUI functions from Graphics instead of Spectral
      * Spectral.py (initGraphics, initWxPython, initWxPython, initNumTut, view,
        viewIndexed, makePilImage, saveImage): Moved functions from Spectral.py to Graphics.py
      * Graphics/__init__.py: Explicitly import names from the Graphics module.
      * Graphics/Graphics.py(initGraphics, initWxPython, initWxPython, initNumTut,
        view, viewIndexed, makePilImage, saveImage): Moved functions from
	Spectral.py to Graphics.py
      * Graphics/SpyGnuplot.py (plot): Take "source" keyword as argument (although
        it is unused because Gnuplot module is deprecated.)
      * Graphics/Hypercube.py: Import GUI functions from Graphics insted of Spectral.
      
2010-07-10	tboggs <tboggs@users.sourceforge.net>

    * Io/Envi.py (SpectralLibrary): New class for handling spectra read from
      spectral library files in ENVI .hdr./sli format.
      
    * Spectral.py:
      (view, viewIndexed): If GUI thread hasn't been initialized yet,
      try to initialize it.
      (makePilImage): Changed how getImageDisplayData is imported from Graphics.
    
    * Algorithms/Resampling.py: New file for spectral band resampling functions.  

    * Graphics/Graphics.py (getImageDisplayData): Fix data types that were missed
      when removing old Numeric module references.
      
    * Io/SpyFile.py (load): read static member of ImageArray class to decide which
      numeric type to use for loaded data arrays.
      
    * Algorithms/Clustering (kmeans, KmeansClusterer): Changed default number of
      clusters to 10 (to be consistent with the cluster function).

    Create common interface for opening files from different Io modules.
    
      * Spectral.py (image) Use "open" function in I/O modules.
      * Io/__init__.py: Import Aviris, Erdas, and Envi sub-packages.
      * Io/Avris.py (open): New name for the openAviris function.
        (readAvirisBands): Explicitly use __builtin__.open for opening file.
      * Io/Erdas.py (open): New name for the ErdasLan function.
        (readErdasLanHeader): Changed name from ReadErdasLanHeader. Also, explicitly
	use __builtin__.open for opening file.
      * Io/Envi.py (readEnviHdr): Name changed from ReadEnviHdr.
        (open): New name for EnviHdr function.   Now also handles opening spectral
	libraries in ENVI .hdr/.sli format.
	
    Explicityly import names from sub-packages/modules to avoid polluting the
    top-level namespace.
    
      * __init__.py: Explicitly import sub-package/module names.
      * Algorithms/__init__.py: Explicitly import sub-package/module names.
      
2010-07-08	tboggs <tboggs@users.sourceforge.net>

    * Io/Envi.py (EnviHdr): Added support for additional image data types.

2010-07-05	tboggs <tboggs@users.sourceforge.net>

    Updated TransformedImage class to support being initialized from an
    ImageArray object.
    
	* Spectral.py (Image.params): New method.  Some of the content of
	  SpyFile.params has been moved here.
	  (ImageArray.format): New static variable specifying the numpy array type.
	* Io/SpyFile.py:
	  (SpyFile.load): Use ImageArray.format to define array type.
	  (SpyFile.params): Call Image.params and only add parameters not set there.
	  (TransformedImage): Class now derived from Image instead of SpyFile.
	  Added _typecode class varialble to specify type of returned numpy arrays.
	  (TransformedImage.__getitem__): __getitem__, readSubImage, and readSubRegion
	  now handle case when TransformedImage is defined relative to an ImageArray object.
	  (TransformedImage.typecode): New method.

2010-07-03	tboggs <tboggs@users.sourceforge.net>

    The isoCluster function has been re-named k-means, which is a more accurate
    description of the algorithm.
    
	* Algorithms/__init__.py: Explicitly import functions from Clustering
	* Algorithms/Cluster.py:
	  (IsoClusterer): Class renamed KmeansClusterer
	  (isoCluster): Function renamed kmeans. The isoCluster function is now
	  a pass-through to the kmeans function and issues a deprecation warning.

2010-07-02	tboggs <tboggs@users.sourceforge.net>

    Added an Image base class from which SpyFile and the new ImageArray class are
    derived.  ImageArray is also derived from numpy.ndarray - It is used when
    loading an entire image and can be treated like a numpy array but also has
    much of the additional info that was contained in the SpyFile class.
    
    SpyFile objects now have a scaleFactor member which represents a multiplier
    for data in HSI files.  When data are read from a file, they are divided by
    scale factor to return the actual reflectance (or other quantity).
    
	* Spectral/Spectral.py:
	  (BandInfo): New class to characterize spectral bands for an image.
	  (Image): A base class for hyperspectral image classes. Some of the
	  image metadata formerly contained in the SpyFile class (now derived
	  from Image) has been moved here.
	  (ImageArray): A new class derived from Spectral.Image and Spectral.SpyFile.
	  It contains data loaded from a file refered-to by a SpyFile object.
	  (image): Aviris function was renamed to openAviris.
	* __init__.py: import openAviris function.
	* Io/BilFile.py (readBand, readBands, readPixel, readSubRegion, readSubImage, readDatum):
	  Divide data by scaleFactor before returning.
	* Io/BipFile.py: Ditto
	* Io/BsqFile.py: Ditto
	* Io/SpyFile: (__init__): initialize scaleFactor member
	  (load): divide data by scaleFactor before returning.
	* Io/Aviris.py (Aviris): Function renamed to openAviris.  Read band info if
	  spectral calibration file is specified.
	  (readAvirisBands): New function to read AVIRIS spectral calibration file.
	* Io/Envi.py (EnviHdr): Set scale factor and add spectral band info if present.
    
    Updated graphics code to plot spectra for double-clicks on generic Image
    objects and plot spectral bands along with data for pixel spectrum plots.

	* Graphics/Graphics.py:
	  (getImageDisplayData): Removed references to oldnumeric data types.
	  Support generic Spectral.Image objects (not just SpyFile objects).
	  (doubleClick): Unused method removed.
	* Graphics/SpyPylab.py (plot): If available, plot data against spectral
	  bands associated with the band and display band unit in x-label.
	* Graphics/SpyWxPythonThread.py (WxImageFrame.leftDoubleClick): Support
	  generic Spectral.Image objects (not just SpyFile objects).

2010-06-28	tboggs <tboggs@users.sourceforge.net>

    Added ImageArray class to handle data loaded from SpyFile objects.

	* Spectral.py (Image, ImageArray): New classes.
	* Io/SpyFile.py (SpyFile): Now derived from Spectral.Image class.
	  (__init__): Call base class setParams before SpyFile.setParams.
	  (setParams): Only initialize params not handled by base class.
	  (load): New method to read all data into a Spectral.ImageArray object.
	  Graphics/SpyWxPython.py (view): Associate data source when requesting
	  spectrum plot for an ImageArray object.
	
    * Io/Envi.py(ReadEnviHdr): Don't skip first parameter in file.
    
    * Io/BilFile.py(readBand, readBands, readSubRegion, readSubImage): Removed
      unecessary code for Numeric compatibility.

2010-06-21	tboggs <tboggs@users.sourceforge.net>

    Migrating from Gnuplot to Pylab (Matplotlib)

	* Spectral.py (viewIndexed): Updated for new viewer interface introduced
	  with previous commit.

2010-06-03	tboggs <tboggs@users.sourceforge.net>

    Migrating from Gnuplot to Pylab (Matplotlib)

	* Spectral.py (initWxPython, initNumTut, initGraphics, view, viewIndexed):
	  Use package-level settings object to specify viewer and plotter.
	* Graphics/Hypercube.py (WxHypercubeFrame.__init__): Handle case when
	  window name is not passed as kwarg.
	* Graphics/SpyGnuplot.py (plot) Updated line style for new Gnuplot syntax.
	* Graphics/SpyPylab.py: New file for Pylab interface.
	* Graphics/SpyWxPythonThread.py:
	  (WxImageFrame.leftDoubleClick): Import generic plotter
	* __init__.py: Do not set "qp" or "plot" variable.  Instead, use "settings"
	  object that is imported from Spectral.py.
	  
    Removing CVSROOT directory since we are now using Subversion
        * CVSROOT/*: Deleted

2010-05-21	tboggs <tboggs@users.sourceforge.net>

    Changes to handle migration of Set to built-in type and Numeric-NumPy changes.

	* Spectral.py (initGraphics): prevent multiple initializations of graphics handlers
	* Io/SpyFile (typecode): Return appropriate typecode for NumPy arrays.
	* Algorithms/Algorithms.py:
	  Set correct numpy array typecodes
	  (createTrainingClasses): Handle migration of Set to built-in type.
	* Algorithms/Classifiers (MahalanobisDistanceClassifier.train):
	  numpy.Float changed to numpy.float

	* Algorithms/Perceptron.py: Major rewrite to fix bug in perceptron bias
	   and to support arbitrary number of hidden layers.

2009-12-12	tboggs <tboggs@users.sourceforge.net>

    Changed SpyGnuplot.py for python 2.6 compatibility.

	* Graphics/SpyGnuplot.py: Removed "with" parameter from function calls.

2008-02-28	tboggs <tboggs@users.sourceforge.net>

    Massive updates to upgrade SPy to Python 2.5, NumPy, and wxPython 2.8.

	* __init__.py: Changed import from Numeric to numpy
	* Spectral.py: Updated copyright.  Converted to numpy import.
	  (makePilImage): Converted to numpy.
	  (tileImage): Converted to numpy.
	* Algorithms/Algorithms.py: Updated copyright. Converted to numpy import.
	  (ImageIterator.__iter__): Removed unecessary typecode variable.
	  (ImageMaskIterator): Converted to numpy.
	  (iterator): Converted to numpy.
	  (mean_cov): Converted to numpy.
	  (principalComponents): Converted to numpy.  Note that eigenvectors
	    returned by numpy are in columns (not rows like Numeric).
	  (linearDiscriminant): Converted to numpy.  Note that eigenvectors
	    returned by numpy are in columns (not rows like Numeric).
	  (reduceEigenvectors): Converted to numpy.
	  (logDeterminant): Converted to numpy.
	  (TrainingClass.size): Converted to numpy.
	  (TrainingClass.calcStatistics): Converted to numpy. Calculate
	    invCov and logDetCov.
	  (TrainingClass.transform): Converted to numpy.
	  (TrainingClassSet.__item__): Renamed method __getitem__.
	  (createTrainingClasses): Converted to numpy.
	  (ndvi): Converted to numpy.
	  (bDistanceTerms): Corrected to use values in stats objects of
	    training class objects.
	  (transformImage): Converted to numpy.
	  (orthogonalize): Converted to numpy.
	  (unmix): Converted to numpy.
	  (spectralAngles): Converted to numpy.
	* Algorithms/Classifiers.py: Updated copyright.
	  (Classifier.classifyImage): Converted to numpy.
	  (GaussianClassifier.train): Converted to numpy.
	  (GaussianClassifier.classifySpectrum): Converted to numpy.
	  (MahalanobisDistanceClassifier.train): Converted to numpy.
	  (MahalanobisDistanceClassifier.classifySpectrum): Converted to numpy.
	* Algorithms/Cluster.py: Updated copyright.
	  (L1): Converted to numpy.
	  (L2): Converted to numpy. Return distance instead of distance^2.
	  (isoCluster): Converted to numpy.
	  (clusterOnePass): Converted to numpy.
	  (OnePassClusterer): Converted to numpy.
	* Algorithms/Perceptron.py: Updated copyright.
	  (Perceptron.__init__): Converted to numpy.
	  (Perceptron.input): Converted to numpy.
	  (Perceptron.train): Converted to numpy.
	  (MultiLayerPerceptron.input): Converted to numpy.
	  (MultiLayerPerceptron.train): Converted to numpy.
	  (MultiLayerPerceptron.resetCorrections): Converted to numpy.
	  (PerceptronClassifier.classifySpectrum): Converted to numpy.
	  (PerceptronClassifier.initializeWeights): Converted to numpy.
	* Graphics/ColorScale.py: Updated copyright.
	  (ColorScale.__init__): Converted to numpy.
	  (ColorScale.createDefaultColorScale): Converted to numpy.
	* Graphics/Graphics.py: Updated copyright.
	  (getImageDisplayData): Converted to numpy.
	* Graphics/Hypercube.py: Massive rewrite to accomdate changes in wx and switch
	  to numpy.  Updated copyright.
	* SpyGnuplot.py: Updated copyright.
	  (plot): Converted to numpy.
	* Graphics/SpyNumTut.py: Updated copyright.
	  (view): Converted to numpy.
	* Graphics/SpyWxPython.py: Updated copyright.
	  (SpyWxPythonThreadStarter.view): wx 2.8 syntax change. Converted to numpy.
	* Graphics/SpyWxPythonThread.py: Updated copyright. Handle numpy and wx changes.
	  (ViewImageRequest.__init__): wx 2.8 syntax change.
	  (HiddenCatcher): wx 2.8 syntax change.
	  (HiddenCatcher.__init__): wx 2.8 syntax change.
	  (HiddenCatcher.viewImage): wx 2.8 syntax change.
	  (WxImageFrame): wx 2.8 syntax change.
	  (WxImageFrame.__init__): wx 2.8 syntax change.
	  (WxImageFrame.viewImage): wx 2.8 syntax change.
	  (WxImageFrame.OnPaint): wx 2.8 syntax change.
	  (WxImageServer): wx 2.8 syntax change.
	  (WxImageServer.OnInit): wx 2.8 syntax change.
	* Io/Aviris.py: Updated copyright.
	  (Aviris): Changed typecode for numpy.
	* Io/BilFile.py: Updated copyright.
	  (BilFile.readBand): Converted to numpy.
	  (BilFile.readBands): Converted to numpy - Using dtype instead of typecode.
	  (BilFile.readPixel): Converted to numpy.
	  (BilFile.readSubRegion): Converted to numpy - Using dtype instead of typecode.
	  (BilFile.readSubImage): Converted to numpy - Using dtype instead of typecode.
	* Io/BipFile.py: Updated copyright.
	  (BipFile.readBand): Converted to numpy.
	  (BipFile.readBands): Converted to numpy - Using dtype instead of typecode.
	  (BipFile.readPixel): Converted to numpy.
	  (BipFile.readSubRegion): Converted to numpy - Using dtype instead of typecode.
	  (BipFile.readSubImage): Converted to numpy - Using dtype instead of typecode.
	* Io/BdsqFile.py: Updated copyright.
	  (BsqFile.readBand): Converted to numpy.
	  (BsqFile.readBands): Converted to numpy - Using dtype instead of typecode.
	  (BsqFile.readPixel): Converted to numpy.
	  (BsqFile.readSubRegion): Converted to numpy - Using dtype instead of typecode.
	  (BsqFile.readSubImage): Converted to numpy - Using dtype instead of typecode.
	* Io/Erdas.py: Updated copyright.
	  (ErdasLan): Converted to numpy - Using dtype instead of typecode.
	  (ReadErdasLanHeader): Converted to numpy - Using dtype instead of typecode.
	* Io/Envi.py: Updated copyright.
	  (EnviHdr): Converted to numpy - Using dtype instead of typecode.
	* Io/SpyFile.py: Updated copyright.
	  (SpyFile.__str__): Fixed bug incorrectly accessing typecode.
	  (TransformedImage.__init__): Converted to numpy.
	  (TransformedImage.__getitem__): Converted to numpy.
	  (TransformedImage.readPixel): Converted to numpy.
	  (TransformedImage.readSubRegion): Converted to numpy.
	  (TransformedImage.readSubImage): Converted to numpy.
	  (TransformedImage.readDatum): Converted to numpy.
	  (TransformedImage.readBands): New function.




2006-07-16	tboggs <tboggs@users.sourceforge.net>

    Documentation:

	* Algorithms/Classifiers.py: Added module-level doc string.
	* Algorithms/Cluster.py: Added module-level doc string.
	* Io/SpyFile.py:  Added module-level doc string.

	* Algorithms/Algorithms.py
	  (linearDiscriminant, bDistanceTerms, orthogonalize): Fixed doc string.


2006-07-14	tboggs <tboggs@users.sourceforge.net>

    Implemented formal TrainingClassSet class to hold training classes.

    Renamed canonicalAnalysis to proper linearDiscriminant.

    Added several sample iterator classes.

	* Algorithms/Algorithms.py
	  (ImageMaskIterator.__iter__): Handle case where shape of sample is
	    rank-3 instead of rank-1.
	  (canonicalAnalysis): Renamed to linearDiscriminant.
	  (TrainingClass): Added numBands member. Added sample iteration.
	    Renamed transformStatistics to simply transform.
	  (SampleIterator): New class.
	  (TrainingClassSet): New class.
	* Algorithms/Classifiers.py:
	  (GaussianClassifier.classifySpectrum): Handling TrainingClassSet
	    objects now instead of lists of TrainingClass objects.
	  MahalanobisDistanceClassifier.classifySpectrum): Ditto.

    Added Multi-Layer Perceptron neural network classifier.

	* Algorithms/__init__.py: Importing PerceptronClassifier.
	* Algorithms/Perceptron.py: New file containing multi-layer Perceptron
	  classifier.

    Fixed bug where glGenTextures was returning bad numbers under linux

	* Graphics/Hypercube.py(WxHypercubeWindow): Wait to load textures
          until after window is initialized.


2006-06-24	tboggs <tboggs@users.sourceforge.net>

    Added code for rendering interactive hypercubes.

	* Graphics/ColorScale.py: New file for creating color scales.
	* Graphics/Hypercube.py: New file for rendering hypercubes.
	* Graphics/SpyWxPython.py:
	  Updated copyright header.
	  (SpyWxPythonThreadStarter.view) - Converted kwargs to **kwargs.
	  (view) - Converted kwargs to **kwargs.
	* Graphics/SpyWxPythonThread.py:
	  Updated copyright header.
	  (ViewImageRequest.__init__): Converted kwargs from arg to **kwargs.
	  (HiddenCatcher.viewImage):  Now accepts an arbitrary functor (that
	    returns a wxFrame) to perform window construction and rendering.
	  (WxImageFrame.__init__): Converted kwargs from arg to **kwargs.
	  (WxImageServer.OnInit): Settting app reference in HiddenCatcher.

    Fixed bug in file exception handling code.

	* Io/SpyFile.py:
	  Updated copyright header.
	  (findFilePath): Fixed [ironic] error in exception handling code.

    Searching for additional ENVI file extensions.

	* Io/Envi.py (EnviHdr): Look for .dat and .DAT file extensions.

    Prevent import warnings.

	* Io/BipFile.py:
	  (BipFile.readSubRegion): Avoid method-level import *.
	  (BipFile.readSubImage): Avoid method-level import *.


2006-06-20	tboggs <tboggs@users.sourceforge.net>

    Functions that open data files now search for the files in directories
    specified in the SPECTRAL_DATA environment variable. SPECTRAL_DATA contains
    a semi-colon delimited list of directories.  cwd is always searched first.

	* Io/Erdas.py (ErdasLan): Modified to search SPECTRAL_DATA directories. 
	* Spectral.py (image): Ditto.
	* Io/Envi.py (EnviHdr): Ditto
	* Io/Aviris.py (Aviris): Ditto
	* Io/SpyFile.py (SpyFile.setParams): Ditto.
	*   (findFilePath): New function to determine data file path.

    * __init__.py : Updated __version__ to 0.3

2006-06-16	tboggs <tboggs@users.sourceforge.net>

    * Converted clustering functions into Classifier classes.
    * Added Mahalanobis Classifier.
    * Corrected several copyright headers.

	* Algorithms/__init__.py: Corrected copyright header.
	* Algorithms/Algorithms.py:
	  (mean_cov): Corrected doc string. Removed unused time import.
	* Algorithms/Classifiers.py: Added copyright header.
	  (Classifier.classifiyImage): Changed typecode of classification map.
	  (MahalanobisDistanceClassifier): New class
	* Algorithms/Cluster.py:
	  (cluster): Modified to use new OnePassClusterer class.
	  (IsoClusterer.): New class
	  (OnePassClusterer): New class replacing OnePassClusterEngine.
	* Io/BsqFile.py: Corrected copyright header.
	* Utilities/Status.py: Corrected copyright header.

2006-05-25	tboggs <tboggs@users.sourceforge.net>

    * Created new directories for Algorithms and Utilities.
    * Encapsulated classification algorithms into classes.
    * Added status display object for cleaner status output.

	* __init__.py:
	  Changed several imports due to package restructuring.
	  Setting package-level status member.
	  Incremented SPy version to 0.2
	* Spectral.py (tileImage): Now reads SubImages instead of SubRegions.
	* Algorithms/Algorithms.py : Moved file from Spectral/.
	  Added iterator classes and functions for generic iteration over image
	    pixels.
	  (mean_cov): Now additionally returns number of pixels used in
	    calculating the mean and std dev.
	  (TrainingSet) Several changes and is renamed TrainingClass.
	* Algorithms/__init__.py: New file.
	* Algorithms/Classifiers.py: New file.
	* Algorithms/Cluster.py: Moved from Spectral/.
	* Io/BilFile.py (readSubRegion): Upper bound is now exclusive to match
	  python slice syntax
	* Io/BipFile.py: ditto
	* Io/BsqFile.py: ditto
	* Io/SpyFile.py (TransformedImage): Fixed broken logic for reading
	  data from TransformedImage objects.
	* Utilities/__init__.py: New file.
	* Utilities/Status.py: New file containing StatusDisplay class that
	  provides pretty output for status messages.
