; docformat = 'rst' ; ; NAME: ; cgScaleVector ; ; PURPOSE: ; This is a utility routine to scale the elements of a vector or an array into a ; given data range. ; ;******************************************************************************************; ; ; ; Copyright (c) 1998-2013, by Fanning Software Consulting, Inc. All rights reserved. ; ; ; ; Redistribution and use in source and binary forms, with or without ; ; modification, are permitted provided that the following conditions are met: ; ; ; ; * Redistributions of source code must retain the above copyright ; ; notice, this list of conditions and the following disclaimer. ; ; * Redistributions in binary form must reproduce the above copyright ; ; notice, this list of conditions and the following disclaimer in the ; ; documentation and/or other materials provided with the distribution. ; ; * Neither the name of Fanning Software Consulting, Inc. nor the names of its ; ; contributors may be used to endorse or promote products derived from this ; ; software without specific prior written permission. ; ; ; ; THIS SOFTWARE IS PROVIDED BY FANNING SOFTWARE CONSULTING, INC. ''AS IS'' AND ANY ; ; EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES ; ; OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT ; ; SHALL FANNING SOFTWARE CONSULTING, INC. BE LIABLE FOR ANY DIRECT, INDIRECT, ; ; INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED ; ; TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; ; ; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ; ; ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT ; ; (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS ; ; SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. ; ;******************************************************************************************; ; ;+ ; This is a utility routine to scale the elements of a vector or an array into a ; given data range. ; ; :Categories: ; Utilities ; ; :Returns: ; A vector or array of the same size as the input, scaled into the data range given ; by `minRange` and `maxRange'. The input vector is confined to the data range set ; by `MinValue` and `MaxValue` before scaling occurs. ; ; :Params: ; maxRange: in, optional, type=varies, default=1 ; The maximum output value of the scaled vector. Set to 1 by default. ; minRange: in, optional, type=varies, default=0 ; The minimum output value of the scaled vector. Set to 0 by default. ; vector: in, required ; The input vector or array to be scaled. ; ; :Keywords: ; double: in, optional, type=boolean, default=0 ; Set this keyword to perform scaling in double precision. Otherwise, scaling ; is done in floating point precision. ; maxvalue: in, optional ; Set this value to the maximum value of the vector, before scaling (vector < maxvalue). ; The default value is Max(vector). ; minvalue: in, optional ; Set this value to the mimimum value of the vector, before scaling (minvalue < vector). ; The default value is Min(vector). ; nan: in, optional, type=boolean, default=0 ; Set this keyword to enable not-a-number checking. NANs in vector will be ignored. ; preserve_type: in, optional, type=boolean, default=0 ; Set this keyword to preserve the input data type in the output. ; ; :Examples: ; Simple example of scaling a vector:: ; ; IDL> x = [3, 5, 0, 10] ; IDL> xscaled = cgScaleVector(x, -50, 50) ; IDL> Print, xscaled ; -20.0000 0.000000 -50.0000 50.0000 ; Suppose your image has a minimum value of -1.7 and a maximum value = 2.5. ; You wish to scale this data into the range 0 to 255, but you want to use ; a diverging color table. Thus, you want to make sure value 0.0 is scaled to 128. ; You proceed like this:: ; ; scaledImage = cgScaleVector(image, 0, 255, MINVALUE=-2.5, MAXVALUE=2.5) ; ; :Author: ; FANNING SOFTWARE CONSULTING:: ; David W. Fanning ; 1645 Sheely Drive ; Fort Collins, CO 80526 USA ; Phone: 970-221-0438 ; E-mail: david@idlcoyote.com ; Coyote's Guide to IDL Programming: http://www.idlcoyote.com ; ; :History: ; Change History:: ; Written by: David W. Fanning, 12 Dec 1998. ; Added MAXVALUE and MINVALUE keywords. 5 Dec 1999. DWF. ; Added NAN keyword. 18 Sept 2000. DWF. ; Removed check that made minRange less than maxRange to allow ranges to be ; reversed on axes, etc. 28 Dec 2003. DWF. ; Added PRESERVE_TYPE and DOUBLE keywords. 19 February 2006. DWF. ; Added FPUFIX to cut down on floating underflow errors. 11 March 2006. DWF. ; Renamed Scale_Vector to cgScaleVector, 16 May 2013. DWF. ; ; :Copyright: ; Copyright (c) 1998-2013, Fanning Software Consulting, Inc. ;- FUNCTION cgScaleVector, vector, minRange, maxRange, $ DOUBLE=double, $ MAXVALUE=vectorMax, $ MINVALUE=vectorMin, $ NAN=nan, $ PRESERVE_TYPE=preserve_type ; Error handling. Catch, theError IF theError NE 0 THEN BEGIN Catch, /Cancel void = cgErrorMsg() RETURN, vector ENDIF ; Check positional parameters. CASE N_Params() OF 0: Message, 'Incorrect number of arguments.' 1: BEGIN IF Keyword_Set(double) THEN BEGIN minRange = 0.0D maxRange = 1.0D ENDIF ELSE BEGIN minRange = 0.0 maxRange = 1.0 ENDELSE ENDCASE 2: BEGIN IF Keyword_Set(double) THEN maxRange = 1.0D > (minRange + 0.0001D) ELSE $ maxRange = 1.0 > (minRange + 0.0001) ENDCASE ELSE: ENDCASE ; If input data type is DOUBLE and DOUBLE keyword is not set, then set it. IF Size(FPUFIX(vector), /TNAME) EQ 'DOUBLE' AND N_Elements(double) EQ 0 THEN double = 1 ; Make sure we are working with at least floating point numbers. IF Keyword_Set(double) THEN minRange = DOUBLE( minRange ) ELSE minRange = FLOAT( minRange ) IF Keyword_Set(double) THEN maxRange = DOUBLE( maxRange ) ELSE maxRange = FLOAT( maxRange ) ; Make sure we have a valid range. IF maxRange EQ minRange THEN Message, 'Range max and min are coincidental' ; Check keyword parameters. IF Keyword_Set(double) THEN BEGIN IF N_Elements(vectorMin) EQ 0 THEN vectorMin = Double( Min(FPUFIX(vector), NAN=1) ) $ ELSE vectorMin = Double(vectorMin) IF N_Elements(vectorMax) EQ 0 THEN vectorMax = DOUBLE( Max(FPUFIX(vector), NAN=1) ) $ ELSE vectorMax = DOUBLE( vectorMax ) ENDIF ELSE BEGIN IF N_Elements(vectorMin) EQ 0 THEN vectorMin = FLOAT( Min(FPUFIX(vector), NAN=1) ) $ ELSE vectorMin = FLOAT( vectorMin ) IF N_Elements(vectorMax) EQ 0 THEN vectorMax = FLOAT( Max(FPUFIX(vector), NAN=Keyword_Set(nan)) ) $ ELSE vectorMax = FLOAT( vectorMax ) ENDELSE ; Trim vector before scaling. index = Where(Finite(vector) EQ 1, count) IF count NE 0 THEN BEGIN IF Keyword_Set(double) THEN trimVector = Double(vector) ELSE trimVector = Float(vector) trimVector[index] = vectorMin > vector[index] < vectorMax ENDIF ELSE BEGIN IF Keyword_Set(double) THEN trimVector = vectorMin > Double(vector) < vectorMax ELSE $ trimVector = vectorMin > Float(vector) < vectorMax ENDELSE ; Calculate the scaling factors. scaleFactor = [((minRange * vectorMax)-(maxRange * vectorMin)) / $ (vectorMax - vectorMin), (maxRange - minRange) / (vectorMax - vectorMin)] ; Clear math errors. void = Check_Math() ; Return the scaled vector. IF Keyword_Set(preserve_type) THEN BEGIN RETURN, FPUFIX(Convert_To_Type(trimVector * scaleFactor[1] + scaleFactor[0], Size(vector, /TNAME))) ENDIF ELSE BEGIN RETURN, FPUFIX(trimVector * scaleFactor[1] + scaleFactor[0]) ENDELSE END