Local IDL Routines

This page was created by a MODIFICATION of the IDL library routine mk_html_help. For more information on this routine, refer to this page or type:

     doc_library, 'mk_html_help'

at the IDL command line prompt.

List Last updated: Tue Jul 7 13:06:27 2015.


NOTE: Non-PPPL employees may access these routines by following procedure GEN-034 .


Routines by Category

[Alphabetical Listing of Routines]


Routine Descriptions


Category: 2-D Plotting

[List of Routines]


DRAWCIRCLE

[Next Routine] [List of Routines]
 NAME:
  	drawcircle

 PURPOSE:
  	draw a circle centered on [x0, y0]. 
  	YOU HAVE TO HAVE YOUR AXES ESTABLISHED BEFORE CALLING THIS.
  	Return out arrays for later drawing on a surface, too. These are in two
	parts, so you won't have a line down the middle when drawing.

 CATEGORY:
       2-D Plotting,

 CALLING SEQUENCE:
	IDL> (some plot command to estable coordinates)
	IDL> drawcircle, x0, y0, radius

  INPUTS:
	x0,y0 - origin of circle
	radius - radius of circle

  KEYWORDS:
    Inputs:
	color - 
	dashed - if set, will draw curve with dashed line
	angle1 - angle in radians to start drawing arc
	angle2 - angle in radians to stop drawing arc
	deg1 - angle in degrees to start drawing arc
	deg2 - angle in degrees to stop drawing arc
	bottom - draw arc in bottom of circle
    Outputs:
	outX1 - X1 output for other ploting
	outY1 - Y1  "
	outX2 - X2  "
	outY2 - Y2  "
	npts - # of points to use for drawing circle (all the way around)
		(default may be too coarse, so curve not smooth)
  EXAMPLE:
	IDL> x = findgen(100)  & y = x
	IDL> Right_Aspect, x, y, IN_POS=[.1,.1,.9,.9], POSITION=position
	IDL> plot, findgen(100), /nodata, POSITION=position
	IDL> drawcircle, 40, 60, 20
	IDL> drawcircle, 40, 60, 15, /dashed
	IDL> drawcircle, 40, 60, 15, deg1=-60,deg2=-30, /bot
  LIMITATIONS:
	angle1 & angle2 can't cross over 0 or !PI
	ANGLES NEED FIXING (determine where starting from)

  04-Feb-2010 - added angle1 & angle2 keywords (in radians), bottom and npts
  WRITTEN by Bill Davis


DRAWELLIPSE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	drawellipse

 PURPOSE:
  	draw an ellipse centered on [x0, y0]. 
  	YOU HAVE TO HAVE YOUR AXES ESTABLISHED BEFORE CALLING THIS.

 CATEGORY:
       2-D Plotting

 CALLING SEQUENCE:
	IDL> (some plot command to estable coordinates)
	IDL> drawellipse, x0, y0, radius1, radius2, tilt=tilt

 INPUTS:
	x0,y0 - origin of circle/ellipse
	radius1 - Ellipse semi axis 1
	radius2 - Ellipse semi axis 2

 KEYWORDS:
    Inputs:
	tilt - Ellipse rotation angle (radians, unless /deg set)
	       Clockwise; zero is horizontal, to the left
	degrees - if set, tilt is in degrees
	convention - if set, zero is to the right, CCW is positive,
		     with 90 straight up and -90 down 
	color - an index into the color table, or 'red', 'blue', etc.
	dashed - if set, will draw curve with dashed line
	npts - # of pts used in drawing (will be made > 100)
    Outputs:
	xout - x pts in outline
	yout - y pts in outline
 EXAMPLE:
	IDL> x = findgen(100)  & y = x
	IDL> Right_Aspect, x, y, IN_POS=[.1,.1,.9,.9], POSITION=position
	IDL> plot, findgen(100), /nodata, POSITION=position
	IDL> drawellipse, 40, 60, 20, 10
	IDL> drawellipse, 40, 60, 15, 10, /dashed
	IDL> drawellipse, 40, 60, 15, 10, tilt=-1
	IDL> drawellipse, 40, 60, 15, 10, tilt=60, /deg
	IDL> drawellipse, 40, 60, 15, 10, tilt=30, /deg
	IDL> drawellipse, 40, 60, 15, 10, tilt=10, /deg
	IDL> drawellipse, 40, 60, 15, 10, tilt=-10, /deg
	IDL> drawellipse, 40, 60, 15, 10, tilt=60, /deg, /conv
	IDL> drawellipse, 40, 60, 15, 10, tilt=30, /deg, /conv
	IDL> drawellipse, 40, 60, 15, 10, tilt=10, /deg, /conv

	IDL> drawellipse, 40, 60, 15, 5, tilt=20, /deg, /con
	IDL> drawellipse, 40, 60, 15, 5, tilt=30, /deg, /con
	IDL> drawellipse, 40, 60, 15, 5, tilt=40, /deg, /con
	IDL> drawellipse, 40, 60, 15, 5, tilt=50, /deg, /con
	IDL> drawellipse, 40, 60, 15, 5, tilt=60, /deg, /con
	IDL> drawellipse, 40, 60, 15, 5, tilt=-10, /deg, /con
	IDL> drawellipse, 40, 60, 15, 5, tilt=-30, /deg, /con

       IDL> tilt = 10
       IDL> tilt = tilt+20 & drawellipse, 40, 60, 15, 10, tilt=tilt, /deg

    to get the points back:
	IDL> drawellipse, 40, 60, 15, 10, tilt=1, /noPlot, xout=xout, yout=yout

 LIMITATIONS:
 MODIFICATION HISTORY:
	30-Oct-2013 added height keyword
	15-Jan-2013 added "convention" keyword to have tilt angle be like Jr. High
	19-Sep-2012 used polyfill for filled ellipses
	12-Sep-2012 added thick and fill keywords (fill is faked)
	WRITTEN by Bill Davis, 30-Aug-2011


FINDRATZ

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	findRatZ

 PURPOSE:
       find the r of desired Z, but on the outer part of curve, if there
	is more than one point that would cross Z=desiredZ. Use spline 
	interpolation.

 CATEGORY:
       2-D Plotting, EFIT

 CALLING SEQUENCE:
	IDL> desiredR = findRatZ( r, z, desiredZ )

 INPUTS:
	r - radius of plasma edge, (can be an array)
	z - Z of plasma edge, (can be an array of same dimension as r)
	desiredZ - Z at which you want R value on the outer edge returned
		   can be

 KEYWORD PARAMETERS:
	inner - if set, will return the inner value rather than the outer
	plot - if set, will plot inputs and results
	test - if set, will restore test values for inputs
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed

  EXAMPLE:
	IDL> desiredR = findRatZ( r, z, desiredZ, /test, /debug, /plot )

  WRITTEN 18-Feb-2010 by Bill Davis


FOLLOWCONTOUR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	followcontour 

 PURPOSE:
	Follow a contour line to find where it intersects a desired Y and
	return the X value. I.e., where the 2D input array has the same value as
	at specified coordinates. This is used to find the R value at Z=0 with
	the same Psi value as a specified point on the flux surface. So, it can
	be used for plotting things in relation to flux surfaces.
	
 CATEGORY:
       2-D Plotting, Normalized Psi

 CALLING SEQUENCE:
       IDL> xWant = followcontour( data2d [, x, y], xpt=xpt, ypt=ypt [, yWant=yWant])

 INPUTS:
	data2d - 2D array, e.g., flux values
	x - X values (defaults to indices)
	y - Y values (defaults to indices)	 
	xpt - X value at which to get flux (will linearly interpolate)
	ypt - Y value at which to get flux (will linearly interpolate)	 
	yWant - Y value at which to determine X with same flux value [Def=0]
     
 KEYWORD PARAMETERS:
	outer - if set will return largest value, else will return all
		(closed contours may intersect a constant Y line in two,
		 or more, locations)
	inner - if set will return smallest value, else will retrun all
	level - contour/value you want to follow (else determined by xpt & ypt)
	exact - if set will interpolate to get level, rather than use nearest data pt
	plot - if set will plot contours and input point and found point
	_extra - passed to the contour routine
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed

 OUTPUTS:
	xWant - X value where Y=yWant and data2D has same value as at [xpt,ypt]
		(finds the nearest point)

 EXAMPLE:
	IDL> restore, '/u/bdavis/contfollowtest.sav'
	IDL> xWant = followcontour( data2d, x, y, xpt=xpt, ypt=ypt, /plot )

		; where psiRZ, R, Z are from EFIT/LRDfit at a particular time:
	IDL> RatZ0 = followContour( psiRZ, R, Z, xpt=Rwant, ypt=Zwant, $
                                   yWant=0.0, /OUTER, /EXACT )
  19-Nov-2010 added SAME keyword for speed when looking up a lot of points
  WRITTEN 15-Feb-2010 by Bill Davis


OPLOTDASH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       oplotdash
 PURPOSE:
       Overplot a variety of dashed lines, even if terminal
	emulator  doesn't for different linestyles
	
 CATEGORY:
       2-D Plotting
 CALLING SEQUENCE:
       IDL> oplotdash, x, y, dashfracdashfrac=, blankfrac=blankfrac
 INPUTS:
       x - x data to overplot
	y - y data to overplot
 KEYWORD PARAMETERS:
    Optional:
	dashfrac -  fraction of distance (0-1) dash will be (def=0.01)
	blankfrac -  fraction of distance (0-1) blank will be
	smallFrac - fraction of distance (0-1) for a small dash, or a dot.
 OUTPUTS:
       
 COMMON BLOCKS:
       NONE
 NOTES:
	This will probably be slow for large numbers of points.
 EXAMPLE:
	x = findgen(100)
	y = sin(x/5)
	plot, x, y, title='My Plot', xtitle='Seconds', ytitle='Function', $
		charsize=1.5
	oplotdash, x, y/2, dashfrac=.02, blankfrac=.01

	TVIMAGE, bytscl(dist(100,50)), x, y, POSITION=thisPosition, $
		/KEEP_ASPECT_RATIO
	oplotdash, x, y/2, dashfrac=.02, blankfrac=.01

 MODIFICATION HISTORY:
	06-Mar-2013 made to work when other graph type drawn first
	16-Apr-2012 Written by Bill Davis, PPPL


PLOT3_MPTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       plot3_mpts

 PURPOSE:
  	Make 3 Multi-point Thomson Scattering Plots: 2-D plots of 
	electron Temp  and Density and a time history.
	
 CATEGORY:
       2-D Plotting, MPTS, GPI

 CALLING SEQUENCE:
       IDL> plot3_mpts, shot

 INPUTS:
       shot = NSTX shot number 
	
 KEYWORD PARAMETERS:
    Inputs:
	Plot_IP - if=0, do not have Ip plot on graph
	Tplot = vector of times to plot profiles (default = all times)
		(if multiple shots only first time point is used)
	Temax	= value of maximum Te to plot [ keV]
	Nemax	= value of maximum Ne to plot [1e13 /cm^3]
	Pemax	= value of maximum Pe to plot [kPa]
	Nelmax	= value of maximum NeL to plot [1e15 /cm^2]
	Temin	= value of minimum Te to plot [ keV]
	Nemin	= value of minimum Ne to plot [1e13 /cm^3]
	Pemin	= value of minimum Pe to plot [kPa]
	Nelmin	= value of minimum NeL to plot [1e15 /cm^2]
	CHI	= if set, changes plotting defaults to values appropriate 
		  to lower temperature plasmas
	Nospline = set to connect data with straight lines instead of splines.
	Rrange  = two element vector to set radial range of plot [Rmin, Rmax]
	Fancy   = sets Font to Triplex Roman
	Tmin    = minimum time to plot (def=0)
	Tmax	= set maximum value of time in plot
	Pk	= set Te(t) to peak value of spline
	Efit    = value of EFIT tree to use '1,2,3,4,5'
	GPI     = if set, will add trace of average light vs. time from GPI 
		  camera frames.
	NB      = if set, add neutral beam power to time history plot 
	RF      = if set, add HHFW power to time history plot
 	MHD     = if set, add Mirnov trace to time history
	Vloop   = if set, add loop voltage to time history plot
	Mld     = if set, add microwave line density to time history
	HA      = if set, add hydrogen alpha signal to time history
	USXR    = if set, add ultra-soft x-ray signal to time history
	Wmhd    = if set, add EFIT Total energy (Wmhd) to time history
	Tf      = if set, add TF current to time history
	Qmin    = if set, add qmin to time history
	Q95     = if set, add q95 to time history
	noTimeLines - if set, will draw dotted lines on color contours showing
		      times of Thomson data
       box -            
       c_colors - contour colors      
       charsize - sets size of characters in plot
       contour - draw contour lines over color contours       
       ctb - the IDL color table (defaults to 3, hot metal)           
       deltaT -         
       efileType -      
       emailPsAddress - 
       fit - type of fit for separatrix plot
       GPI - if set, plot GPI average in bottom plot           
       interp -         
       lastPoint -      
       lastTime -       
       mailPsFile -     
       nospline -       
       PlotsDesired -   
       psFileName -     
       r1 -             
       r2 -             
       rescale -        
       rf -             
       sep -            
       sh2 -            
       surf -           
       t1 -             
       t2 -             
       tRange -         
       xmargin - sent to plot command       
       XOR_cont - use XOR for color of contour lines      
       xpos -sent to plot command           
       xRange -         
       xsize -          
       ymargin - sent to plot command
       ypos - sent to plot command          
       ysize -          

 OUTPUTS:
       opt = returned value                 			out
 COMMON BLOCKS:
       NONE
  EXAMPLE:
  To add GPI average to lowest plot:
	IDL> plot3_mpts, 138846, /GPI,/box
	IDL> wset, 32
	IDL> plot3_mpts, 138846, /GPI,tmin=.45, tmax=.85, r1=1.2,r2=1.56, $
			 /contour, Plot_ip=0

		; for Stewart's paper Fig. 3:
	IDL> !p.font=0
	IDL> setup_ps,'MPTS_138844.ps', printer='postscript color'
	IDL> plot3_mpts, 138844, /GPI,tmin=.45, tmax=.85, $
			 Temax=1.2, Line_TeMax=2, Nemax=8, /NoBigLabels, $
			 /contour, Plot_ip=0, /Plot_NeL, /Plot_Te, $
			charsize=1.5, BARSZ_CHARS=3, /magAxis
	IDL> unsetup_ps

	IDL> !p.font=0
	IDL> setup_ps,'MPTS_138843.ps', printer='postscript color'
	IDL> plot3_mpts, 138843, tmin=.45, tmax=.85, $
			 Temax=1.2, Line_TeMax=2, Nemax=8, /NoBigLabels, $
			 /contour, Plot_ip=0, /Plot_NeL, /Plot_Te, $
			charsize=1.5, BARSZ_CHARS=3, /magAxis
	IDL> unsetup_ps

	IDL> for shot=138844,138847 do plot3_mpts, shot, /GPI, $
		tmin=.45, tmax=.85, r1=1.2,r2=1.56, /contour, Plot_ip=0, $
		efile='PDF'

	IDL> for shot=138844,138847 do $
		plot3_mpts, shot, /GPI, /Sep, $
		tmin=.3, tmax=.9, r1=1.25,r2=1.5, /contour, $
		Plot_ip=0, c_colors=[115,110,100,50,30,20,10], /debug

	IDL> for shot=138844,138847 do $
		plot3_mpts, shot, /GPI, /Sep, $
		tmin=.45, tmax=.85, r1=1.35,r2=1.5, /contour, $
		Plot_ip=0, c_colors=[115,110,100,50,30,20,10], /debug

    to make a post script plot:
	IDL> !p.font=0
	IDL> setup_ps,'Plot3_MPTS.ps', printer='postscript color'
	IDL> plot3_mpts, 138846, /GPI,tmin=.45, tmax=.85, r1=1.2, r2=1.56, $
	                 /contour
	IDL> unsetup_ps

 NOTES:
 MODIFICATION HISTORY:
	06-May-2014 added MagAxis keyword to allow like for magnetic axis 
	10-Oct-2013 EFIT keyword was not getting to sepvstime for edge
	09-Oct-2013 if just GPI in bottom frame, make smaller than other 2
	30-May-2013 added GPI option for Stewart Zweben
	31-Aug-2010 moved PNB read to end, because opening tree takes ~12s !
	29-Jul-2010 added LastPoint and lastTime keywords
	15-Jul-2010 added xmargin keyword for wall display
	05-Nov-2009 handle no times or deltaT entered.
	14-Apr-06 Added default to mail PDF file if e-mail checked and user specified.
  	26-Jan-06 No longer e-mail to 'USER' if username not specified
		  Tidy up screen message for postscript output
	19-Jul-04 Added emailPsFile and emailPsAddress keywords
	WRITTEN November, 2003, by Bill Davis.


PLOTDASH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       plotdash
 PURPOSE:
       Plot a variety of dashed lines, even if terminal emulator doesn't for
	different linestyles
 CATEGORY:
       2-D Plotting
 CALLING SEQUENCE:
       IDL> plotdash, x, y, dashfracdashfrac=, blankfrac=blankfrac
 INPUTS:
       x - x data to plot
	y - y data to plot
 KEYWORD PARAMETERS:
    Optional:
	dashfrac -  fraction of distance (0-1) dash will be (def=0.01)
	blankfrac -  fraction of distance (0-1) blank will be
	smallFrac - fraction of distance (0-1) for a small dash, or a dot.
 OUTPUTS:
       
 COMMON BLOCKS:
       NONE
 NOTES:
	This will probably be slow for large numbers of points.
 EXAMPLE:
	x = findgen(100)
	y = sin(x/5)
	plotdash, x, y

	plotdash, x, y, dashfrac=.02, blankfrac=.01
	oplotdash, x, y/2, dashfrac=.02, blankfrac=.01, color=mk_color('red')

	y = randomu(seed,100)
	plotdash, x, y

	plotdash, x, y, dashfrac=.02, smallFrac=0.005, blankfrac=.002
	plotdash, x, y, dashfrac=.02, smallFrac=0.002, blankfrac=.005

 MODIFICATION HISTORY:
	17-Apr-2012 added smallFrac keyword, so can have dot-dash style lines
       16-Apr-2012 Written by Bill Davis, PPPL


SHADE_SURFRANGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       shade_surfrange
 PURPOSE:
       make SHADE_SURF plots with x & y ranges (correctly)
 CATEGORY:
	2-D Plotting
 CALLING SEQUENCE:
        shade_surfrange, f, x, y, XRANGE=xrange, YRANGE=yrange, _EXTRA =_extra
 INPUTS:
       f, x & y are just as for surf      in
 KEYWORD PARAMETERS 
	Input:
	  XRANGE - array containing min x & max x
	  YRANGE - array containing min y & max y
	  ZRANGE - array containing min y & max y
	  _EXTRA - standard idl EXTRA keyworrd
 OUTPUTS:
	none
 EXAMPLE:
	x=findgen(100)
	y=x 
	f=DIST(100)
	_EXTRA = { title: 'My Title', $		; pass any extra SHADE_SURF keywords here
	           xtitle: 'seconds', $
		   ax : 40  }
	shade_surfrange, f, x, y, xrange=[20,40], yrange=[50,70],  _EXTRA =_EXTRA
 COMMON BLOCKS:
 NOTES:
	If your are using color tables with reserved colors at the the top,
	e.g., if you use mk_color, you should first call:
	  IDL> dum=mk_color(n_nonfixed=ncolors)
	  IDL> set_shading, values=[0,ncolors-1]

	skirt doesn't seem to work
 MODIFICATION HISTORY:
     09-Jul-02 Handle when yrange or xrange reversed (i.e., first > last)
     17-Aug-01 Handle correctly when !z.range set
     17-Oct-00 Written by Bill Davis


SHOW3M

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	SHOW3m

 PURPOSE:
	Show a 2D array three ways in a display that combines SURFACE, 
	CONTOUR, and an image (color/gray scale pixels).

 CATEGORY:
	2-D Plotting, Graphics, Image Processing.

 CALLING SEQUENCE:
	SHOW3m, Image [, INTERP = Interp, SSCALE = Sscale]

 INPUTS:
	Image:	The 2-dimensional array to display.

 OPTIONAL INPUTS:
	X = a vector containing the X values of each column of Image.
		If omitted, columns have X values 0, 1, ..., Ncolumns-1.
	Y = a vector containing the Y values of each row of Image.
		If omitted, columns have Y values 0, 1, ..., Nrows-1.
 KEYWORD PARAMETERS:
	INTERP:	Set this keyword to use bilinear interpolation on the pixel 
		display.  This technique is slightly slower, but for small 
		images, it makes a better display.

	SSCALE:	Reduction scale for surface. The default is 1.  If this
		keyword is set to a value other than 1, the array size 
		is reduced by this factor for the surface display.  That is, 
		the number of points used to draw the wire-mesh surface is
		reduced.  If the array dimensions are not an integral multiple
		of SSCALE, the image is reduced to the next smaller multiple.
	E_CONTOUR: a structure containing additional keyword parameters
		that are passed to the CONTOUR procedure.  See the example
		below.
	E_SURFACE: a structure containing additional keyword parameters
		that are passed to the SURFACE procedure.  See the example
		below.
       TITLE: Top plot title
       XTITLE: x-axis title
       YTITLE: y-axis title
       FLOOR: if = 0, will not show color contours on floor
       CHARTHICK;  character thickness on color bar
       DRAWLINES: draw lines to indicate a region of interest
       DRAWBOX : draw box around region of interest
       BOXYMID: y-mid point of box, an line location (default=0.1)
       BOXXMID: x-mid point of box, an line location (default=1)
       BOXWIDTH: width of box (default=0.1)
       BAR: if = 0, will not draw color bar
       C_COLOR:   colors for contours
 OUTPUTS:
	No explicit outputs.

 EXAMPLE:
	IDL> gp, '/u/bdavis/MarthRedi/kineticballooning.txt'

 SIDE EFFECTS:
	A new plot is generated.

 RESTRICTIONS:
	The display gets too "busy" when displaying larger (say 50 by 50),
	images, especially if they are noisy.  It can be helpful to use
	the SSCALE keyword or the SMOOTH and/or REBIN functions to smooth the 
	surface plot.

	You might want to modify the calls to CONTOUR and SURFACE slightly
	to customize the display to your tastes, i.e., with different colors,
	skirts, linestyles, contour levels, etc.

 PROCEDURE:
	First, do a SURFACE with no data to establish the 3D to 2D scaling.
	Then convert the coordinates of the corner pixels of the array to
	2D.  Use POLYWARP to get the warping polynomial to warp the
	2D image into the area underneath the SURFACE plot.  Output the image,
	output the surface (with data) and then output the contour plot at
	the top (z=1).

 EXAMPLES:
	A = BESELJ(SHIFT(DIST(30,20), 15, 10)/2.,0)  ;Array for example
	SHOW3, A		;Show it with default display.
	SHOW3, A, SQRT(FINDGEN(30))  ;Make X axis proportional to sqrt
	SHOW3, A, E_CONTOUR={C_CHARSIZE:2, DONW:1} ;Label CONTOUR lines with
		double size characters, and include downhill tick marks.
	SHOW3, A, E_SURFACE={SKIRT:-1, ZRANGE:[-2,2]}  ;Draw a surface with
		a skirt and scale Z axis from -2 to 2.
 MODIFICATION HISTORY:
	DMS. Jan, 1988.
	Added fudges for PostScript, April, 1988.
	Fixed bug where contour plot was occasionally clipped. Dec, 1990.
	Added optional axis variables, and _EXTRA keywords for CONTOUR,
		and SURFACE.  Jan, 1996.
	DD.  Added code to ignore !ORDER for the TV of the image.  Mar 1997.
       SJL  Fixed bug from scaling with polywarp. July, 1998.
	DD.  Add better support for TrueColor devices.
	     Honor !P.BACKGROUND (rather than assuming black or white
            background).  Sept, 2000.
    	Feb/2005 hacked by Bill Davis for Martha Redi:
	     better scaling of bottom image. Added lines and a square to indicate region.
	     When bottom values are zero, make white (transparent). Add color bar.


SURFRANGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       surfrange
 PURPOSE:
       make SURF plots with x & y ranges (correctly)
 CATEGORY:
	2-D Plotting
 CALLING SEQUENCE:
        surfrange, f, x, y, XRANGE=xrange, YRANGE=yrange, _EXTRA =_extra
 INPUTS:
       f, x & y are just as for surf      in
 KEYWORD PARAMETERS 
	Input:
	  XRANGE - array containing min x & max x
	  YRANGE - array containing min y & max y
	  ZRANGE - array containing min y & max y
	  _EXTRA - standard idl EXTRA keyworrd
 OUTPUTS:
	none
 EXAMPLE:
	x=findgen(100)
	y=x 
	f=DIST(100)
	_EXTRA = { title: 'My Title', $		; pass any extra SURF keywords here
	           xtitle: 'seconds', $
		   ax : 40  }
	surfrange, f, x, y, xrange=[20,40], yrange=[50,70],  _EXTRA =_EXTRA
 COMMON BLOCKS:
 NOTES:
	logic is still not perfect. See, e.g., 
	AUSER4:[BDAVIS.TEST.NDD]NDD3D.PRO for a working example of overlaying
	surface plot on a shaded surface plot with ranges set.
 MODIFICATION HISTORY:
     09-Jul-02 Handle when yrange or xrange reversed (i.e., first > last)
     17-Aug-01 Handle correctly when !z.range set
     17-Oct-00 Written by Bill Davis


TH_IMAGE_CONT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       TH_IMAGE_CONT
 PURPOSE:
       Plot contours of Images with both contour lines and colors
 CATEGORY:
	2-D Plotting
 USAGE:
******************** HIGH FREQUENCY RADAR DIVISION, SRL **********************
*************************** Ionospheric Effects ******************************
HELP
1 TH_IMAGE_CONT
	Overlays an image and a contour plot and optionally adds a scale bar.
	Based on the IDL USERLIB routine IMAGE_CONT. This routine supersedes 
	the USERLIB one, having far more functionality, yet capable of EXACTLY
	reproducing the effect of IMAGE_CONT. Scale bar appears on the 
	right-hand-side unless /NOBAR is set. NB: the scale bar is
	automatically created by a recursive call to this routine using the
	same color and image parameters 

 Format:
	In its simplest form (allowing all parameters to default)

    IDL> TH_IMAGE_CONT, IMAGE

	or,

    IDL> TH_IMAGE_CONT, IMAGE, X, Y

	And in its most complex form, specifying ALL parameter

    IDL> TH_IMAGE_CONT, IMAGE, $
		ASPECT=aspect, $
		BADPTS=badpts,$
     		BAR_LABEL_LENGTH=bar_label_length, $
		BAR_RANGE=bar_range, $
		BAR_SEPARATION=bar_separation, $
		BAR_TICKLEN=bar_ticklen, $
		BAR_TICKNAME=bar_tickname, $
		BAR_TICKS=bar_ticks, $
		BAR_TICKV=bar_tickv,$
		BARSZ_CHARS=barsz_chars, $
		BOTTOMcolor=bottomcolor,$
		C_COLORS=c_colors,$
		C_LINESTYLE=c_linestyle, $
		C_THICK=c_thick, $
		CONGRID=congrid, $
		CONT=cont, $
		CRANGE=crange, $
		CT=ct, $
		CUBIC=cubic, $
		DEBUG=debug, $
		EXACT=exact, $
		RAISE_PTITLE=raise_ptitle
		IMAGE_WINDOW=image_window, $
		INTERP=interp,$
		LEVELS=levels,$
		MAX_VALUE=max_value, $
		NLEVELS=nlevels, $
		NOBAR=nobar, $
		NOCONT=nocont, $
		NOERASE=noerase,$
		TOPcolor=topcolor,$
		TSIZE=tsize, $
		WINDOW_SCALE=window_scale, $
		XRANGE=xrange, $
		YRANGE=yrange
 
2	IMAGE
		2-dimensional array to display as an image.

2	/ASPECT
		set to retain image's aspect ratio.  Assumes square
		pixels.  If /WINDOW_SCALE is set, the aspect ratio is retained.

2	BADPTS
		indices into IMAGE data which define the bad points.
		These will not be contoured

2 BAR_LABEL_LENGTH
     the space, in characters (default = 2), for the bar label
2	Btitle 
		Bar title
2	BAR_RANGE	
	 	set the range limits for the color scale bar
		(same as CRANGE, defaults to autoscaling if
		 BAR_TICKV not set)

2	BAR_SEPARATION	
		the separation, in characters (default = 2), between the scale
		bar and the image. Note that the |y-ticklength| will be added
		to this value if y-ticklength < 0.
		Both the image and the color bar need to fit 
		into the space allowed for the plot window, otherwise an
		informative message will be printed and unpredictable results
		may occur for the displayed image 

2	BAR_TICKS
		set the number of tick intervals for the labelling
		of the scale bar 
		(defaults to !z.ticks)

2	BAR_TICKV
		the values to label on the scale bar. If this is set
		then the scale bar will have AT LEAST this range
		(defaults to !z.tickv)

2	BAR_TICKNAME
		the labels to use on the scale bar 
		(defaults to !z.range)

2	BAR_TICKLEN
		the length of the ticks on the scale bar  in fractions of tick
		bar window, (defaults to !z.ticklen)

2	BARSZ_CHARS
		the size of the scale bar in characters (default = 2). 
		Both the image and the color bar need to fit 
		into the space allowed for the plot window, otherwise an
		informative message will be printed and unpredictable results
		may occur for the displayed image. If the value of this
		keyword is <=0 then no bar will be displayed BUT the scaling
		and window size will be calculated as those a color bar is to
		be used. This is useful when doing multiple plots per page
		where only some scale bars are not required but you want the
		plots to all be the same size. Set BARSZ_CHARS = -#chars to
		allow room for a bar of #chars size but not to put a scale bar
		on the plot. Then set BARSZ_CHARS = +#chars to plot the bar on
		alongside another plot, to end up with images of the same
		size. Useful in collaboration with the SIDES procedure (which
		will set flags for when the plot is on the Left,Right,Top and
		Bottom of the plot window).


2	BOTTOMcolor
		Set this keyword to the color index of the desired bottom
		color (range from 0 to TOPcolor-1).
		Note that the default value for this keyword is 1,
		which allows the color of the image to
		be independent of the background and axes colors
		(!P.background and !P.color). If the user sets this keyword
		then allowance should be made for these colors as they are
		generally swapped for POSTSCRIPT and X-Window devices

2	/CONGRID 	
		if the image has to be resampled then use the USERLIB CONGRID
		routine 

2	/CONT 	
		only do the contouring (no image)

2	CRANGE	
		set the range limits for the color scale bar
		(same as BAR_RANGE, defaults to autoscaling if
		 BAR_TICKV not set)

2	CT	
		load a color table (uses LOADCT via MK_COLOR)

2	/CUBIC	
		if the image has to be resampled AND interpolated then use the
		CUBIC interpolation rather than the bi-linear (see INTERP
		Keyword) 

2	/DEBUG	
		write out some inforamtion as it goes


2	/EXACT
 
		When set this will force the contour routine to fit to the
		exact positions relative to the image.
		When data is displayed as an image each datum is expanded out
		to fill a pixel of finite dimensions. The assignment of where
		the "data value" resides within this space is open to debate,
		but is most appropriately (to this author) assigned to the
		geometric centre of the pixel. Most defaults assign this
		position to be at the bottom left-hand corner of the
		pixel. Contour will fit to the 2-d plane assuming that the
		data value is associated with the bottom left-hand corner. To
		reconcile this with the notion of the value being in the
		middle of the pixel the contour call is made with the x/y
		values and ranges for the image adjusted (effectively by half
		a pixel in the x/y directions). This is the EXACT mapping. By
		default, the mapping will be the default contour one.

2	RAISE_PTITLE
		Raise the plot title by this many character units above the
		plot to allow room to put a label on the top x-axis. Default
		is raise by 1 char. If not called then the default y-position
		is 1 char unit above plot (allowing room for xticks, and
		scaled by !P.charsize)

2	IMAGE_WINDOW
		the position of the image window. Can be used to set
		!p.position so you can over-plot the image.
		(Only useful when the scale-bar has been used)

2	/INTERP 
		set to bi-linear interpolate if image is resampled.
		(see also the CUBIC keyword)

2	/NOBAR 
		dont put a scale bar on the right-hand-side

2	/NOCONT
		only do the imaging (no contours)

2	/NOERASE
		dont erase the previous plot
       /NOLOAD
		if set, do not load color table

2	TOPcolor
		Set this keyword to the color index of the desired bottom
		color (range from BOTTOMcolor+1 to !D.n_colors-1). Note that
		the default value for this keyword is !D.n_colors-2, which
		allows the color of the image to be independent of the
		background and axes colors (!P.background and !P.color). If
		the user sets this keyword then allowance should be made for
		these colors as they are generally swapped for POSTSCRIPT and
		X-Window devices 

2	TSIZE	
		size of the plot title (default = 1)
 
2	/WINDOW_SCALE
		set to scale the window size to the image size,
		otherwise the image size is scaled to the window size.
		Ignored when outputting to devices with scalable pixels.

2	XRANGE
		will set the ranges for the x-axes labelling

2	YRANGE
		will set the ranges for the y-axes labelling

2	Contour
		most of the CONTOUR parameters are passed directly

2 Examples
 IDL>   th_image_cont, image

 IDL>	th_image_cont, image, /nocont, /nobar

 IDL>	!p.title = "!17 This is an example of what can be done!3"
 IDL>	!x.title = "X Title"	& !y.title = "Y Title"	& !z.title = "Z Title"
 IDL>	!x.ticklen = -0.02	& !y.ticklen = -0.02	& !z.ticklen = -0.02
 IDL>	!p.charsize = 1.5
 IDL>	levels = findgen(5)*2
 IDL>	image = findgen(20,20)/40.
 IDL>	th_image_cont, image, crange=[0,10], /follow, level=levels, $
			tsize=1.5*!p.charsize, bar_tickv=levels

2 Error_responses
 Returns to the calling procedure on an error

2 Limitations/Assumptions 
	The currently selected display is affected.
	If the device has scalable pixels then the image is written over
	the plot window.
	As with all TV style image displays, the axes range is independent of 
	the image, so it is up to the user the ensure correct labelling of the
	axes.
	NOTE: if the user aborts while this routine is processing then the 
	system variables (in particular !p.position) will have 
	been changed, causing subsequent plots to appear different. Issue the 
	command "resetplt,/all" to reset all the system variables back to the 
	startup state.

	NOTE: if x or y does not have a constant interval, the image will be
		wrong. Instead, use contour, /fill...
2 References 
 	See USERLIB IMAGE_CONT

2 Keywords
	Graphics images contours

2 MODIFICATIONS:
  -------------
  12-Dec-2013 added barlabel keyword
  05-Sep-2013 if /NoLoad set, use values in common block from mk_colors (if set)
		for max values
  07-Jun-2013 make /EXACT the default
  27-Jul-2012 tweeked color table handling. Add rainbow keyword.
  07-Jan-2010 print error if input not 2-D array
  06-Jun-2006 several changes including adding x & ytickformat keywords
  06-Apr-2006 limit max dimension of interpolated postscript plots to 2000 pixels
  14-Mar-2006 added zrange keyword [BD]
  25-Oct-01 Made Contours work when /ASPECT set. Made Contours work when
	     XRANGE or YRANGE set.
  18-Apr-00 Made interpolated image align with data. /EXACT does not give
	     an exact representation. Warn if style=2
  06-Dec-99 Added another pixel to TV image size, so it fills the grid square
  23-Aug-99 Allow Contour, Z, X, Y format. Use MK_COLOR
  07-Jan-98 BD allow more space at the bottom and right-hand side for text
               (keyword BAR_LABEL_LENGTH added)
  07-Aug-97 Bill Davis- v. 2.24
                [1] added _extra call to main CONTOUR and removed
                    it from those making the bar.
 (more modifications in file)


TVIMAGE_CONGRID

[Previous Routine] [Next Routine] [List of Routines]

 NAME:
  TVIMAGE_CONGRID

 PURPOSE:
       Shrink or expand the size of an array by an arbitrary amount.
       This IDL procedure simulates the action of the VAX/VMS
       CONGRID/CONGRIDI function.

  This function is similar to "REBIN" in that it can resize a
       one, two, or three dimensional array.   "REBIN", however,
       requires that the new array size must be an integer multiple
       of the original size.   CONGRID will resize an array to any
       arbitrary size (REBIN is somewhat faster, however).
       REBIN averages multiple points when shrinking an array,
       while CONGRID just resamples the array.

 CATEGORY:
       2-D Plotting

 CALLING SEQUENCE:
  array = TVIMAGE_CONGRID(array, x, y, z)

 INPUTS:
       array:  A 1, 2, or 3 dimensional array to resize.
               Data Type : Any type except string or structure.

       x:      The new X dimension of the resized array.
               Data Type : Int or Long (greater than or equal to 2).

 OPTIONAL INPUTS:
       y:      The new Y dimension of the resized array.   If the original
               array has only 1 dimension then y is ignored.   If the
               original array has 2 or 3 dimensions then y MUST be present.

       z:      The new Z dimension of the resized array.   If the original
               array has only 1 or 2 dimensions then z is ignored.   If the
               original array has 3 dimensions then z MUST be present.

 KEYWORD PARAMETERS:
       INTERP: If set, causes linear interpolation to be used.
               Otherwise, the nearest-neighbor method is used.

       CUBIC:  If set, uses "Cubic convolution" interpolation.  A more
               accurate, but more time-consuming, form of interpolation.
               CUBIC has no effect when used with 3 dimensional arrays.

       MINUS_ONE:
               If set, will prevent CONGRID from extrapolating one row or
               column beyond the bounds of the input array.   For example,
               If the input array has the dimensions (i, j) and the
               output array has the dimensions (x, y), then by
               default the array is resampled by a factor of (i/x)
               in the X direction and (j/y) in the Y direction.
               If MINUS_ONE is present (AND IS NON-ZERO) then the array
               will be resampled by the factors (i-1)/(x-1) and
               (j-1)/(y-1).

       HALF_HALF:
               If set, will tell CONGRID to extrapolate a *half* row
               and column on either side, rather than the default of
               one full row/column at the ends of the array.  If you
               are interpolating images with few rows, then the
               output will be more consistent with this technique.
               This keyword is intended as a replacement for
               MINUS_ONE, and both keywords probably should not be
               used in the same call to CONGRID.

 OUTPUTS:
  The returned array has the same number of dimensions as the original
       array and is of the same data type.   The returned array will have
       the dimensions (x), (x, y), or (x, y, z) depending on how many
       dimensions the input array had.

 PROCEDURE:
       IF the input array has three dimensions, or if INTERP is set,
       then the IDL interpolate function is used to interpolate the
       data values.
       If the input array has two dimensions, and INTERP is NOT set,
       then the IDL POLY_2D function is used for nearest neighbor sampling.
       If the input array has one dimension, and INTERP is NOT set,
       then nearest neighbor sampling is used.

 EXAMPLE:
       ; vol is a 3-D array with the dimensions (80, 100, 57)
       ; Resize vol to be a (90, 90, 80) array
       vol = TVIMAGE_CONGRID(vol, 90, 90, 80)

 MODIFICATION HISTORY:
       DMS, Sept. 1988.
       DMS, Added the MINUS_ONE keyword, Sept. 1992.
  Daniel Carr. Re-wrote to handle one and three dimensional arrays
                    using INTERPOLATE function.
  DMS, RSI, Nov, 1993.  Added CUBIC keyword.
       Craig Markwardt, Dec, 1997.  Added halfhalf keyword to
                        more evenly distribute "dead" pixel row
       Use uniformly spaced grid points for half_half W. Landsman   Feb. 2000
              (and slightly modified by C. Markwardt 14 Feb 2000)
  DWF, FSC, 22 Apr 2007. Modified the program so that 3D arrays use nearest-neighbor
       interpolation unless the INTERP keyword is set.
  DWF, FSC, 22 Apr 2007. Function renamed from CMCONGRID to TVIMAGE_CONGRID on
       recommendation of Craig Markwardt as he wants no part of this. :-)


VECTORSURF

[Previous Routine] [List of Routines]
 NAME:
       vectorsurf

 PURPOSE:
       Shows a fancy way to plot irregulary spaced data from x,y & z vectors.

 CATEGORY:
	2-D Plotting, Example

 CALLING SEQUENCE:
        vectorsurf, x, y, z

 INPUTS:
       tag - MDSplus tag or node name      in

 KEYWORD PARAMETERS 
    Input:
	DRAWXSIZE = drawXsize
	DRAWYSIZE = drawYsize
       BG_COLOR = bg_color

 OUTPUTS:
	none

  EXAMPLE:
     IDL> x=[4,6,1,7,1,8,5,2,4]
     IDL> y=[3,3,1,6,4,5,6,8,1]
     IDL> z=sqrt((x-3)^2+(y-2)^2)+randomn(seed)+2 
     IDL> vectorsurf, x, y, z

  MODIFICATION HISTORY:
       05-Sep-97 Written by Bill Davis
                 from IDL's d_mathstat.pro in the IDL 5.0 release
                 Written by:  DC, RSI,  1995


Category: Animation

[List of Routines]


ALPHAMOVIE10

[Next Routine] [List of Routines]
 NAME:
       alphamovie10
 PURPOSE:
       Plot every 10th frame in time, and overlay
       10 d-alpha traces. Have a marching vertical line indicating time 
	in a plot indicating the Strike Point Radius.

 CATEGORY:
       Animation, NSTX

 CALLING SEQUENCE:
	IDL> d=alphamovie10( 138000, tStart=tStart, tEnd=tEnd )

 INPUTS:
       shot = NSTX shot number 
 KEYWORD PARAMETERS:
    Inputs:
	tStart - 
	tEnd - 
	rMin -  minimum time to display (DEFAULT: 25 )
	rMax -  minimum time to display (DEFAULT: 85 )
	inc - how many D-alpha traces to put on a plot
	efit - 
	xsize - horizontal size of X window (DEFAULT: 600 )
	ysize - vertical size of X window (DEFAULT: 450 )
	xpos - initial X position of lower left of X window in pixels
	ypos - initial Y position of lower left of X window in pixels
	charsize - size of characters on plot (Default: 1.5)
	verbose - if set, will print many informational messages
	debug - if set, will stop before returning
 OUTPUTS:
       MPEGS can be saved from the IDL Animation Widget interface
 EXAMPLE:
	IDL> d=alphamovie10( 138000, /verb )

 NOTES:
       This routine uses X-memory, so too many frames can cause X errors.
	Try reducing the number of frames or xsize and ysize.
 MODIFICATION HISTORY:
	19-Jul-2010 put into xinteranimate by Bill Davis
	20-Apr-2010 written by Josh Kallman. cam4_fy10 written by Vlad.


ANIM2CINE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
    anim2cine

 PURPOSE:
    Create an mpeg or avi movie from two .cin files from Phantom Cameras.
    The data can be color or monochrome

 CATEGORY:
    animation

 CALLING SEQUENCE:
    anim2cine, CineFile1, CineFile2, movieFile=movieFile, t1=t1, t2=t2

 INPUTS:
	CineFile1 - cine file
	CineFile2 - (optional)
	 - 
 OPTIONAL KEYWORD PARAMETERS:
	movieFile - name of output MPEG or QuickTime file (will default to a nice name), or 
	prefix - what would precede _shot_t1_t2 (in msec) in the output filename
	t1 - start time of animation in seconds
	t2 - end time of animation in seconds
	VIEW - if set, just displays images, and does not make an mpeg
   	ndups - if given means repeat every image 'ndups' times
   	despeckle - if set call despeckle routine (slow, but less "intrusive" 
		    than median)
	nSmooth - number input to median smoothing routine for camera data
	sigSmooth - number input to median smoothing routine for signal data
	topPixels -
	botPixels - 
	charsize - character size for plots. Default=2
	ctb - color table for non-color image 
	label1 - label on plot for CineFile1 (default='Monochrome')
	label2 -  label on plot for CineFile2 (default='Color')
	gamma1 - gamma setting for camera 1
	gamma2 - gamma setting for camera 2
	saturation1 - saturation setting for camera 1, if color 
	saturation2 - saturation setting for camera 2, if color 
	min1 - minimum value for bytescaling camera 1
	min2 - minimum value for bytescaling camera 2
	max1 - maximum value for bytescaling camera 1
	max2 - maximum value for bytescaling camera 2
	region1 - crop region to display for camera 1    
	region2 - crop region to display for camera 2     
	byteScale - if set, will scale 
	sigName - if set, will not show Fast Camera images, but this
		  signal vs. time (defaults to \passivespec::BAYC_DALF_HAIFA)
	sigT1 - starting time of signal vs. time plot
	sigT2 - ending time of signal vs. time plot
	sigTitle - if set, will be displayed above sigName plot,
		   else tries to get label from MDSplus
	verbose - if set will print out info as it works
 OUTPUTS: 
	an MPEG file named by movieFile keyword

 EXAMPLE:
    
    anim2cine,camera1="Phantom710-9206", camera2="Phantom73-6663", shot=138767, $
		 sig1='\wf::ip',sig2='\wf::nel', t1=.405, t2=.406,  $
		 gamma1=.37,  min1=20, max1=1442, $
		 gamma2=.8, sat2=.3, max2=1440, rot2=1                               ,/debug

    anim2cine,camera1="Phantom710-9206", camera2="Miro2-7988", shot=138767, $
		 sig1='\wf::ip',sig2='\wf::nel', t1=.405, t2=.406,  $
		 gamma1=.37,  min1=20, max1=1442, $
		 gamma2=.3, sat2=.3, max2=255                                 ,/debug

    f1=findcamfiles('nstx_1_135258.cin')
    f2=findcamfiles('Miro_135258.cin')
    anim2cine,f1,f2,t1=.17,t2=.53, inc=10, mag1=2, mag2=3,  $
	       region1=[.08,.05,1,1], region2=[.1,.0, 1.0,.9], $
	       sig1='\operations::mi_h908_01:input_03*(-1.6)', sig2='\wf::prf', $
	       Units1='mTor', /QUICKTIME, sigLabel1='Antenna Power', /debug

    anim2cine, camera1='Phantom710-9206', camera2='Miro2-7988',  $
	        shot=140000, t1=0.2, t2=0.3, sigT1=0.0, sigT2=1.0, $
		sig1='\wf::ip', sig2='\wf::pnb',  nSmooth=5,  /verbose  , /debug

    anim2cine, 'NSTX_130387.cin', $
		'MIRO_130387.cin', $
		t1=0.1, t2=1.4, sig1='\wf::ip', sigTitle='Plasma Current', /verbose                      

    anim2cine, shot=130370, t1=0.5, t2=0.58, /verbose, /view    , /debug

    f1=findcamfiles('nstx_1_135254.cin')
    f2=findcamfiles('Miro_135254.cin')
    anim2cine,f1,f2,t1=.180,t2=.580, inc=10, $
              movieFile='NSTX_135254_180-580ms.mpg', mag1=2, mag2=3    , /debug
    	  
    f1='/p/nstxcam-archive/Phantom71-5040/2009/nstx_1_135254.cin'
    f2='/p/nstxcam-archive/Miro2-7988/2009/Miro_135254.cin'
    anim2cine,f1,f2,t1=.180,t2=.580, inc=10, $
		region1=[.08,.05,1,1], region2=[.1,.0, 1.0,.9], $
              movieFile='NSTX_135254_180-580ms.mpg', mag1=2, mag2=3    , /debug

    f1=findcamfiles('nstx_1_136159.cin')	; fastest one
    f2=findcamfiles('Miro_136159.cin')
    anim2cine, f1,f2,  mag2=2,  $
		label1='Full', label2='Dropper View', $
		gamma1=0.096,  min1=65,  max1=4095, $
		gamma2=1.188, min2=1114, max2=11075                 , /debug

   mv files to /w/nstx.pppl.gov/htdocs/nstx/Software/Diagnostics/FC2008
   (or whatever year) for web viewing at
   http://nstx.pppl.gov/nstx/Software/Diagnostics/

 MODIFICATION HISTORY:
	08-Dec-2011 added flip1 and flip2 keywords (also made work with just 1 file)
	31-Aug-2010 lots of changes to allow to work off web tool nstxmovie.html
	01-Jul-2010 added region1 and region2 keywords and allow different 
		    magnifications for different cameras
	08-Oct-2009 updates for 2009 cameras. Extract shot # from filenames, 
			if not input
	12-Nov-2008 mods because cineload now assuming frame 0 is beginning of data
	16-Jul-2008 Use Z-buffer, even when viewing, for smoother displays
	15-Jul-2008 Written by Bill Davis


ANIMXYPLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       animxyplot
 PURPOSE:
       Animate X-Y plot of a 2-D array
 CATEGORY:
       Animation
 CALLING SEQUENCE:
       IDL> animxyplot, data2d, x, time [, ....]
 INPUTS:
       data2d - 2 d array (1st dimension like x, 2nd like time)
	x - array for x-axis of x-yplot
	time
 KEYWORD PARAMETERS:
	(can have any keywords used in PLOT command -- will be passed on)
 	mpeg - if set, will create an mpeg of animation
	filename - name of mpeg file (default =  'plotanimation.mpg')
	rep - # number of times to repeat frames (to slow down mpeg) default=0
	t1 - time to start animation (indexes into time array) (default=start)
	t2 - time to end animation (default=end)
	xtitle -    
	ytitle -    
	xsize - xsize of window in pixels
	ysize - ysize of window in pixels 
	flip - if set, will flip mpeg image    
	timeTitle - appended to indication of time on plot (def='Sec.')
	pause - # of seconds to pause between plotted frames when creating
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
 OUTPUTS:
       NONE; just the mpeg file, if specified
 EXAMPLE:
	nframes = 20
	nPts = 1000
	data2d = fltarr(npts, nframes)
	time = findgen(nFrames)/1000 +0.2
	x =findgen(npts)/npts*150 + 50
	for i=0,nframes-1 do data2d[0,i]=sin(x*5/max(x)+i/10.)*exp(1.-x/100-i/10.)
	animxyplot, data2d, x, time, xtitle='Radii', ytitle='Value', /mpeg
 NOTES:
 MODIFICATION HISTORY:
       18-Jan-2008 Written by Bill Davis, PPPL


CINE2MPEG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
    cine2mpeg

 PURPOSE:
    Create a movie from a .cin files from Phantom Fast Cameras.
    Will default to writing jpegs and spawning jmovie to create a
    QuickTime movie. If /MPEGout keyword set, will write an MPEG.
    The data can be color or monochrome,

 CATEGORY:
    animation

 CALLING SEQUENCE:
      cine2mpeg, CineFile1, outFile=outfile, t1=t1, t2=t2, ndups=ndups
   or
      cine2mpeg, shot=shot, t1=t1, t2=t2, /verbose

 INPUTS:
	CineFile1 - a cine filename

	shot - if used instead of filename, it will search appropriate directories.

 OPTIONAL KEYWORD PARAMETERS:
	outFile - name of output MPEG file (will default to a nice name), or 
	prefix - what would precede _shot_t1_t2 (in msec) in the output filename
	t1 - start time of animation in msec
	t2 - end time of animation in msec
	MPEGout - if set will create an MPEG movie
	FramesOut - if=0, will not create QuickTime movie
	VIEW - if set, just displays images, and does not make an mpeg
   	ndups - if given means repeat every image 'ndups' times
   	despeckle - if set call despeckle routine (slow, but less "intrusive" 
		    than median)
	badValue - if data is this or above, replace with median of surrounding pixels
	nSmooth - number input to median smoothing routine
	gamma - gamma correction. (Default=1, which is no correction). 
		0.5 probably better for Miro
	saturation - As in HSV color representation, for color camera. 
		Default is 0.3.
	topPixels -
	botPixels - 
	AveT1 - start time of range for Average Frame in msec
	AveT2 - end time oof range for Average Frame in msec
	manifold - if set, will draw line for manifold positon
	charsize - character size for labels. Default=1.5
	ctb - color table for non-color image 
	label - label on plot 
	horizontal_flip - if set, flip images horizontally
	vertical_flip - if set, flip images vertically
	byteScale - if set, will scale 
	minVal - if this and byteScale set, will use this as minimum value
	maxVal - if this and byteScale set, will use this as maximum value
	inc - default 1o 1; use every "inc"th frame
	noCaption - do not put text on or above image
	Rotate - integer from 0-3, passed to IDL ROTATE function
	verbose - if set will print out info here and there
 OUTPUTS: 
	an MPEG file named by outFile keyword

 NOTES:
	*** you have to be careful with MAXVAL. If too big, all frames will be black
 EXAMPLE:

    cine2mpeg, '/p/nstxcam-archive/Miro2-7988/2008/MIRO_130389.cin', $
		t1=0.02, t2=0.0300, /verbose                                 , /debug

    cine2mpeg, shot=130277, t1=0.100, t2=0.200, /verbose, /view    , /debug

    cine2mpeg, GETENV("NSTXUSR")+'/phantom4/GDNex10usFps27000DC110maP1.98torr-1.cin', $
		outfile='Ne110us.mpg', t1=.0007, t2=0.0017, ndups=4, mag=3

	minHt and maxChi2 are the most useful to adjust:
   blobCriteria = { minHt : 1.2,  $
		     maxChi2 : 3.,  $
		     maxFrames : 1,  $
		     maxJump : 10,  $
		     minArea : 9,  $
		     minLifetime : 3,	$
		     maxAreaChange : 100,  $
		     minRise : 0.02  $
		   }
  cine2mpeg,'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138234.cin',$
           aveT1=0.530, aveT2=0.550,  t1=0.532, t2= 0.5326, /blobs, $
            blobCriteria=blobCriteria, $
           colorTable=3, min=256, /surface, /RotCC, /arrow		     , /view,/debug

  cine2mpeg,'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138234.cin',$
           aveT1=0.530, aveT2=0.550,  t1=0.530, t2= 0.5302, /blobs, $
           colorTable=3, minWidth=256, /surface, /horiz, /RotCC, /arrow     , /view,/debug

     ; to test drawing plasma EDGE and limiter shadow:
  cine2mpeg,'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138234.cin',$
           aveT1=0.530, aveT2=0.550,  t1=0.530, t2= 0.5301,  $
           colorTable=3, minWidth=256, /horiz, /RotCC, /arrow, /EDGE  	     , /view,/debug

   mv files to /w/nstx.pppl.gov/htdocs/nstx/Software/Diagnostics/Miro/GlobalMPEGs 
	for web viewing at
       http://nstx.pppl.gov/nstx/Software/Diagnostics/Miro/GlobalMPEGs

     for Stewart's FY15 GPI paper:

   IDL> cinethumbnails, /edge,  $
	    nSmooth=3, Rotation=1, /horiz, xSize=668*10./8+80, ySize=652*.666, $
	    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_140395.cin',       $
	    /rainbow, border=3, /ellip, nWanted=10, nrows=2, howFar=.1, /norm, $
	    bytescale=0, aveT1=.5505, aveT2=.5515, minVal=0.405, maxVal=2.159, $
	    /colorbar, t1=.550929, t2=.551029, label=0,/verbose

  cine2mpeg,'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_140395.cin',  $
           aveT1=550.5, aveT2=551.5,  t1=550.929, t2=550.95, $	;;;t2= 551.019,  $
           /ellip, /horiz, /rotccw, howFar=0.1, $
           ctb=3, minWidth=256	   ;;;,  /view


 MODIFICATION HISTORY:
	09-Apr-2015 added ellipses keyword for Stewart Zweben GPI paper
	04-Feb-2015 using cgImage and cgSnapshot instead of TV and TVRD so color
		    JPEGS easy.
	12-Mar-2014 added Fit keyword for separatrix calculation
	15-Oct-2013 BIG CHANGE: Bytescale with minVal & maxVal, unless showMax
			defined
	08-Oct-2013 added manifold-showing option. New limiter position
	06-Mar-2013 black out top and bottom after drawing separatrix
	05-Mar-2013 if bytescale set, don't use maxVal and minVal to scale image
       25-Oct-2012 added showNumbers, xvals, and yvals, for suppressing blob #s and
		    having surface axes in cm.
	27-Mar-2012 use fastcam_times and fastcam_frame so can support HDF files from simulation
	12-mar-2012 moved smoothing out of cine2mpeg, and let be done in findblobs,
		    like other apps doing. Have time inputs in msec. Default to Gaussian smoothing
	24-Feb-2012 added gaussian smoothing option
	23-Feb-2012 many adjustments for showing CMOD data, especially when window size
		    not optimal.
	31-Aug-2011 added Surface option for better Blob tracking
	07-Apr-2011 added NoCaption keyword for NOVA work.
	10-Aug-2010 added option to make .mov files from Eliots Java code that uses 
		    jpegs
	09-Jun-2010 made do loops start with LONG so can handle > 32K frames
	27-Aug-2009 added /horizontal_flip and /vertical_flip
 	22-Jul-2009 if not MIRO, and maxVal not specified, scale each frame to it's max.
		    added NORMALIZE keyword (default) to read through all frames
		    and get the max value for use in BYTSCL.
	24-Jun-2009 added showMin and showMax keywords.
	12-Nov-2008 mods because cineload now assuming frame 0 is beginning of data
	18-Sep-2008 mods to magnify keyword
	05-Aug-2008 Written by Bill Davis


CINEAVE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	cineave

 PURPOSE:
       Produce an average frame from a time ranged from .cin files from 
       Phantom  Fast Cameras. This frame is typically used to divide GPI
       images  by to get normalized image.

 CATEGORY:
	animation

 CALLING SEQUENCE:
      
	IDL> a=cineave( CineFile, aveT1=aveT1_in, aveT2=aveT2_in, aveInt=aveInt )

 INPUTS:
	CineFile - a cine filename

  	aveT1 - start time for averaging (seconds)
  	aveT2 - end time for averaging

	nsmooth - # of points for median smoothing on individual frames
   	despeckle - if set call despeckle routine (slow, but less "intrusive" 
		    than median)
	badValue - if data is this or above, replace with median of surrounding pixels
	inc - default 1o 1; use every "inc"th frame
	FrameOffset - if set, subtract this (like a baseline) from all pixels
	FrameAveMin - if set, make close-to-zero pixels this number, 
		      so when dividing into data, as in normalizing, result is near zero

  OUTPUTS:
	maxInt - the maximum intensity anywhere in the frame vs. time
	aveInt - the average intensity anywhere in the frame vs. time
	maxVal - maximum value over interval
	minVal - minimum value over interval
	maxNorm - max value of normalized images over that the same time range
	times - times used to create this average frame
	status - odd if OK

 EAXMPLES:

  filename='/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216029.cin'

 or filename='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_142000.cin'

	IDL> t0=systime(1) & a=cineave( filename, aveInt=aveInt ) & print, systime(1)-t0

  Without finding AveInt, took 6.5 sec for nstx_1_142000.cin. 
  When finding average, 33.6 seconds .

 MODIFICATION HISTORY:
  05-Mar-2014 added keywords fr1 & fr2 for files with whacky times
  05-Sep-2012 added keywords FrameOffset and FrameAveMin
  04-Sep-2012 fixed bug where was dividing by n-1 rather than n.
  27-Mar-2012 use fastcam_times and fastcam_frame so can support HDF files from simulation
  01-Sep-2011 added nsmooth, inc, despeckle & badvalue keywords
  27-Jul-2011 made max intensity at a pixel be the 99.9% pixel value so bad pixels
		don't form max (as Ricky Macqueda did)
  25-Jul-2011 added keyword maxInt to return maximum intensity vs. time
  22-Jul-2011 default aveT1 and aveT2 to entire file and option to return
	       average intensity vs. time [BD]
  18-Jan-2011 added minAll and maxAll keywords
  WRITTEN Jan-2011 by Bill Davis for Stewart Zweben


DISPLAYFCTIFFS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       displayfctiffs

 PURPOSE:
	Animate Fast Camera images with the time overlayed

 CATEGORY:
       Animation

 CALLING SEQUENCE:

	IDL> displayfctiffs, shot
 INPUTS:
       shot = nstx shot number  

 KEYWORD PARAMETERS:
    Keywords:
	minmsec - min time in msec to include
	maxmsec - max time in msec to include
	loop - number of times to loop through animation (default=1)
	pause - time in seconds to pause between frames (default=0)
	minToPlot - min value for bytscl of image
	maxToPlot - max value for bytscl of image
	skip - frames to skip between those displayed (default=0)
	magnify - magnification factor ( note that bigger movies are slower)
	charThick - 
	charsize -  
	debug -  
  	mpg - 
	mds - if set, look for data in MDS plus (little there as of Jul/04)
 OUTPUTS:
       none

 LIMITATIONS:
       MPEG movies created from widget are poor.
 EXAMPLE:
	IDL> displayfctiffs,shot=113723,minms=140,maxms=170

 MODIFICATION HISTORY:
	16-Mar-05 Only read in times within times requested
	29-Jul-04 access /v/kodak area from Unix
	22-Jul-04 Added mpg creation [DM]
      Written by Bill Davis, PPPL


FCDCMOVIES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	fcdcmovies

 PURPOSE:
       Plot Fast Camera and Divertor Camera images along with EFIT field 
	lines, and, optionally, Thomson Scattering Density and Temperature. 
	You may also plot H-alpha (or another) signal vs. time.

 CATEGORY:
        Animation, NSTX, EFIT, Thomson Scattering

 CALLING SEQUENCE:

	IDL> fcdcmovies, 114333,time=[.008,.012],thom=0, sigT1=.005,sigT2=.020

	   To get a postscript frame printed:
	IDL>fcdcmovies,114333,time=0.01,thom=0,sigT1=.005,sigT2=.02,anim=0,/postscript

   if the FC images are too light, you can make them 4 times as bright:
	IDL> fcdcmovies, 112608, FCimgScale=4

   to get an animation with no more than 40 frames between 50 and 317 msec:
	IDL> fcdcmovies, shot, time=[0.05,0.317],max=40
 
 INPUTS:
       shot = nstx shot number  
	diverter camera data must be moved manually to linux. Examples are
	at $NSTXUSR/uppercam/114333 and $NSTXUSR/divcam/114333.
	A .cih file must also be in each directory for the timing information
 KEYWORD PARAMETERS:
    Keywords:
	half - if set, only show left half of fast camera image
	time - 2-element array for animation; single value for one frame
	thomson - if set to 0, will NOT plot Thomson Te and Ne below EFIT contours
	animate - if set to 0, will NOT make a movie in an IDL XINTERANIMATE window.
	maxFrames - max # of frames over time range -- necessary if X-memory
	imSmooth - amount to median smooth images (default=3)
		    is limited (default is 200).
	sigName - if set, will not show Fast Camera images, but this
		  signal vs. time (defaults to \passivespec::BAYC_DALF_HAIFA)
	sigT1 - starting time of signal vs. time plot
	sigT2 - ending time of signal vs. time plot
	sigTitle - if set, will be displayed above sigName plot,
		   else tries to get label from MDSplus
 OUTPUTS:
       none

 LIMITATIONS:
       MPEG movies created from widget are poor.
	All Fast Camera data is on VMS, but can be mounted from petrel084 to
	petrel092. Only what has been moved manually 
	is on Unix. 
 NOTES:

   you need to use /save to get Mpeg  quality=100 (but it's not clear there's
	any improvement in the Mpeg.

   to get tiff files from the fastcamera system into the right taurus directory:
	scp them from the KODAK directory, or one of it's subdirectories, on VMS

	Postscript files can be huge; may try making separate one with only Fast Camera image.

 MODIFICATION HISTORY:
  	05-Jan-2015 BD added shot, so can draw NSTX-U tiles 
		       Devon Battaglia modified code in plot_tiles_nstxu
       03-Sep-04 Fixed bug in times of Thomson when animating partial shot
	05-Aug-2004 Added two Hiroshima cameras
	23-Jul-04 added ExtendEFITtime keyword to continue animation after efit
	15-Jul-04 Make default to do animation and include Thomson data
	13-Jul-04 Made the default be to show whole fast camera image
	05-May-04 Adapted from EfitMovies for Fast Camera data plus x-y plots
	Original EFIT animation written by Dave Gates


FCTIFFSVCR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       fctiffsvcr

 PURPOSE:
	animate Fast Camera tiffs with VCR-like controls.
	from the resulting widget, you may write an Mpeg file

 CATEGORY:
       Animation

 CALLING SEQUENCE:

	IDL> fctiffsvcr, shot
 INPUTS:
       shot = nstx shot number  (Optional - you can navigate for a shot)

 KEYWORD PARAMETERS:
    Keywords:
	minmsec - min time in msec to include
	maxmsec - max time in msec to include
	minToPlot - min value for bytscl of image
	maxToPlot - max value for bytscl of image
	skip - frames to skip between those displayed (default=0)
	magnify - magnification factor ( note that bigger movies are slower)
	InitPath - Initial Path of Fast Camera data
	rate - initial display rate
	verbose - if set, will print info as it progresses
	charThick - 
	charsize -  
	debug -  
	mds - if set, look for data in MDS plus (little there as of Jul/04)
 OUTPUTS:
       none

 LIMITATIONS:
  	as of 29-Jul-2004, FC data just available on NSTX Petrels,
	the VMS cluster.
       MPEG movies created from widget are poor.
 EXAMPLE:
	IDL> fctiffsvcr,shot=113723,minms=140,maxms=170
	IDL> fctiffsvcr, frame1=1000, skip=5, maxframes=100, $
		files='/p/camdata/dust/120325_TIFF/*.tif', mag=3, /debug

 MODIFICATION HISTORY:
      29-Jul-2004 Written by Bill Davis, PPPL


FCVCR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	fcvcr

 PURPOSE:
       Plot Fast Camera images with a VCR-like interface

 CATEGORY:
       Animation, Fast Camera

 CALLING SEQUENCE:

   to get an animation with a maximum of 40 frames (spaced with time selection):
	IDL> fcvcr, 128030, time=[0.05,0.317], max=40

   to see what shots have fast camera data in the tree:
 	IDL> MDSnodeChanges,'\fc3d', shot1=119120, shot2=119330, tree='cameras'
 INPUTS:
       shot = nstx shot number  

 KEYWORD PARAMETERS:
    Keywords:
	sigName - MDSplus signal name of 3-D signal
	tree - MDSplus tree of signal (defaults to cameras2)
	bytescale - if set, will scale each frame to 0-255
	ndups - number of times each frame of movie is duplicated (default=0)
	time - 2-element array for animation; single value for one frame
	animate - if set to 0, will plot individual frames instead of movie.
	maxFrames - max # of frames over time range -- necessary if X-memory
		    is limited (default is 200).
	pixMap - if set, will not send each frame to the screen (faster)
	maxVal - maximum value to use when byte scaling
	minVal - minimum value to use when byte scaling
	camt0 - time of first frame (overrides what is in MDSplus)
	camdt - time between frames (overrides what is in MDSplus)
 OUTPUTS:
       calls XIA, from which you can save pictures of frames, or an mpeg file
 EXAMPLES:
	IDL> fcvcr, 138116, signal='\cameras2::top.edge_neutral.rawdata.data', mag=2
	IDL> fcvcr, 138178, signal='\cameras2::fastsoftxray:frames', ndecimals=5, mag=5
 LIMITATIONS:
 NOTES:
 MODIFICATION HISTORY:
	08-Jun-2010 use amedian, so edges of images get filtered
	03-Jun-2010 added handling of time outside of shot, and overrides
	02-Jun-2010 added keywords maxVal, minVal, bytescale (does all data at once)
	28-Mar-2008 written by Bill Davis


MK_MPEG

[Previous Routine] [Next Routine] [List of Routines]
 NAME: 
    mk_mpeg

 PURPOSE: 
    Write a sequence of images from a 3-D array, or a series of tiff
    files, as an mpeg movie.

 CATEGORY: 
    animation

 CALLING SEQUENCE:
    mk_mpeg, 'movie.mpg' ,ims
	or
    mk_mpeg, 'movie.mpg', files=files

 INPUTS:
     ims: sequence of images as a 3D array with dimensions [sx, sy, nims]
          where sx = xsize of images
                sy = ysize of images
                nims = number of images

 OPTIONAL INPUTS:

 KEYWORD PARAMETERS:
	delafter:  if set delete temporary array after movie was created
                you should actually always do it otherwise you get
                problems with permissions on multiuser machines (since
                /tmp normally has the sticky bit set)
	rep:     if given means repeat every image 'rep' times
                (as a workaround to modify replay speed). i.e., if = 2, make 2 copies of
		 each frame.
	files:   file list. If just one value, needs to include a wild card
	justone: just plot D-alpha
	despeckle : if set call despeckle routine (slow, but less "intrusive" than median)
 OUTPUTS: None

 OPTIONAL OUTPUTS:

 COMMON BLOCKS:

 SIDE EFFECTS:
	creates some files in TMPDIR which are only removed when
	the delafter keyword is used

 RESTRICTIONS:
	depends on the program mpeg_encode from University of
	California, Berkeley, which must be installed in /usr/local/bin

 PROCEDURE:
	writes a parameter file based on the dimensions of the image
	array + the sequence of images in ppm format into a
	temporary directory; finally spawns mpeg_encode to build the
	movie

 EXAMPLE:
 	IDL> shot = 111840
 	IDL> f = file_search( GETENV("NSTXUSR")+'/divcam/'+strtrim(shot,2)+'/*.tif')
 	IDL> mk_mpeg, strtrim(shot,2)+'_divcam'+'.mpg',files=f,shot=shot,/fliphoriz

 LIMITATIONS:
	mpeg_encode must be in your path (not currently on PPPL Linux)

 MODIFICATION HISTORY:
	22-Apr-04 lots of kludges to make nice movies of camera data
		  from Hiroshima University on NSTX. [BD]
	29-Apr-02 Modified write_mpeg to accept a filelist or wildcard spec [BD].
	Mon Nov 18 13:13:53 1996, Christian Soeller
	

	grabbed original from the net and made slight modifications


MPEG_FROM_SCREEN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	mpeg_from_screen

 PURPOSE:
       Example of creating a color Mpeg animation with text overlayed.
	Works on both 8-bit and 24-bit monitors. Can read from files, but those
	returning 24-bit data will not have the text overlaying option.

 CATEGORY:
       Animation

 CALLING SEQUENCE:
	IDL> mpeg_from_screen
    or
	IDL> mpeg_from_screen, data3d=data3D, mpeg_filename='mymovie.mpg'
    or
	IDL> mpeg_from_screen, ndups=5,  $
		files=['out1.jpg','out2.jpg','out3.jpg','out4.jpg','out5.jpg']
 INPUTS:
       none required 

 KEYWORD PARAMETERS:
    All optional inputs:
	data3D - optional 3-D array ( nx, ny, nFrames )
	nFrames - # of frames when using dummy data.
	files - a string array of filenames. 
		Can be of type 'jpg','tif','tif','bmp','jpeg,'png', or 'gif'
	mpeg_filename - output filename for mpeg movie
	ndups - number of times each frame of movie is duplicated (default=3)
	showFrame - if =0, will not show frame around image (irrelevant for rgb files)
	useScreen - if=0, don't bother using screen for output (i.e., no text to overlay)
			(irrelevant for rgb files)
	border - # of pixels around data (default=25)
	ctb - color table to use (default=39)
	charsize - character size (default=1.5)
	charthick - character thickness (default=2)
	pixMap - if = 0, will write and read each frame from screen (much slower)

 OUTPUTS:
       mpeg file

 MODIFICATION HISTORY:
	20-Oct-2004 Optionally operate off a list of files
	15-Oct-2004 Written by Bill Davis


MPTSCAM

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mptscam
 PURPOSE:
	Animate several plots, including MPTS variables
 CATEGORY:
	Animation, MPTS
 CALLING SEQUENCE:
    IDL>  mptscam, shot, xSize=xSize, ySize=ySize, sideSigs=sideSigs, $   
    		    MAX_COLORS_TO_USE = max_colors_to_use, dirs=dirs, $  	   
    		    noSides=noSides, colortable=colortable, $		   
    		    mpegFile=mpegFile, rf=rf, nb=nb, pixMap=pixMap, $	   
    		    gaps=gaps						   
 INPUTS:
	shot - NSTX shot # to display
 KEYWORD PARAMETERS:
    Optional Inputs:
	...
	dirs - directories to search. If not set, typical NSTX camera  
		is set to 'none', no camera file will be used
	directories will be searched.
	defPath - path to find most recent "Miro*.cin" file for default selection
	first - if set, will just return the first match (for speed)
	pick - if set, and more than one match found, will pop a dialog
		box for user to pick one.
	bigger - DEFAULT=1, so will reduce other graphs on left, so camera image is 
		 bigger.
	nSmooth - # of pixels to median smooth over (3 is great for bit noise)
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
 OUTPUTS:
       VCR-like widget; can create mpegs
 EXAMPLE: for output example, see 
	http://nstx.pppl.gov/nstx/Software/Diagnostics/MPTS/mptsdata.html

	IDL> mptscam, 130376, dir='/p/nstxcam-archive/Miro2-7988/2008/'
	IDL> mptscam, 140300, dir='/p/nstxcam/Phantom73-8032/2010/'

	IDL> f=findcamfiles(141833, /pick)	; select camera from those available
	IDL> fdecomp, f, disk, dir, name
	IDL> mptscam, 141833, dir=dir

	IDL> mptscam, 141833, dir='/p/nstxcam/Phantom4-6878/2010/'

 NOTES:
	This routine has not been tested for many combinations of signals
	Logic for making movies with less than the full time needs improving.

 MODIFICATION HISTORY:
	12-Oct-2010 cleaned up for new camera searching, and added /bigger keyword
	18-Aug-2009 limit radial plots from 18-160 cm per Adam McLean.
	14-Aug-2009 major changes for new camera data locations
  	16-Nov-01 Fine tuned for xsize=600, ysize=400 (for publication)
       Written by Bill Davis


WRITE_MPEG

[Previous Routine] [Next Routine] [List of Routines]
+
 NAME: 
        WRITE_MPEG

 PURPOSE: 
        Write a sequence of images as an mpeg movie

 CATEGORY: 
	animation

 CALLING SEQUENCE:
        WRITE_MPEG,'movie.mpg',ims

 INPUTS:
     ims: sequence of images as a 3D array with dimensions [sx, sy, nims]
 	   where sx = xsize of images
 		 sy = ysize of images
 		 nims = number of images

 OPTIONAL INPUTS:

 KEYWORD PARAMETERS:
     delaft:   if set delete temporary array after movie was created
               you should actually always do it otherwise you get
               problems with permissions on multiuser machines (since
               /tmp normally has the sticky bit set)
     rep:      if given means repeat every image 'rep' times
               (as a workaround to modify replay speed)

 OUTPUTS: None
 OPTIONAL OUTPUTS:

 COMMON BLOCKS:

 SIDE EFFECTS:
      creates some files in TMPDIR which are only removed when
      the DELAFT keyword is used

 RESTRICTIONS:
     depends on the program mpeg_encode from University of
     California, Berkeley, which must be installed in /usr/local/bin

 PROCEDURE:
     writes a parameter file based on the dimensions of the image
     array + the sequence of images in ppm format into a
     temporary directory; finally spawns mpeg_encode to build the
     movie

 EXAMPLE:
    IDL> s=openmdsshot('efit',112800)
    IDL> data3d=mdsvalue('\efit01::psirz')
    IDL> write_mpeg, 'efit_112800.mpg', bytscl(congrid(data3d,65*8,65*8,128))
  or 
    IDL>write_mpeg,'test.mpg',reform([[dist(100)],[dist(100)],[dist(100)]],100,100,3)

 MODIFICATION HISTORY:
     15-Jul-04 warn if file not 3d [BD]
     Mon Nov 18 13:13:53 1996, Christian Soeller
     

     grabbed original from the net and made slight modifications


XANIMJPEG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	 XanimJpeg

 PURPOSE:
       animate jpegs (or other image files) in a VCR-like widget, 
	which can make an MPEG Movie.

 CATEGORY:
       Animation, MPEG, jpegs

 KEYWORDS:
       jpegDir - directory containing files to animate
       ext - extension of files to animate (DEFAULT='jpg')
	showTime - if set, try to show time on image
       times - times of images in msec
       increment - for file list, ie., to skip frames, set > 1
	maxFrames - max # of frames to load (to many can cause an X-window problem)
	prefix - prefix of files for search. Default='*'
	byteScale - if set, will scale individual frames from 0-255
	minVal - if this and byteScale set, will use this as minimum value
	maxVal - if this and byteScale set, will use this as maximum value
       ctb - color table to load (not sure makes a difference) DEFAULT=3
       mag - magnification factor for images

 EXAMPLE:
   IDL> xanimjpeg, jpegDir='~bdavis/ShockWaveOutput/Output'

   IDL> jpegDir='/p/gyro/wgutten/gyro-9.0wg/sim/NSTX_120968A02_560/nonlin/ra60/franklin_runs/x80y60_n8r200ob8v6/jpeg_files/'
   IDL> xanimjpeg, jpegDir=jpegDir, prefix='frame06', maxframes=10

   IDL> xanimjpeg, jpegDir='~bdavis/DustTracking/Data/130388/Cam2_NO'

  NOTE: 
	this routine requires substantial "X memory" so, Exceed on a Mac,
	may need more memory; an X-terminal may give a "toolkit error".

 MODIFICATIONS:
  	13-Jul-2010 use XIA & other features
	WRITTEN by Bill Davis


XEASYANIM

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	XeasyAnim 

 PURPOSE:
       animate 3-D array and optionally make MPEG Movie

 CATEGORY:
       Animation, MPEG

 KEYWORDS:
	nreps - number of frames to repeat when creating mpeg (1 means no dups)
	xSize - 
	ySize - 
	rate -            
	MAX_COLORS_TO_USE  - 
	magnification - 
	xpos - 
	ypos - 
	colortable - color table for movie
	ctbFile - color table file (for personal color tables)
	noLoad - if set, do not load any color table 
	SCALEEACHFRAME - 
	bottom -  if set, then position window at bottom of screen
	despeckle - 
	XWIN - 
	YWIN - 
	STDEV_MULT
	ctbfile - color table file (for personal color tables)
 EXAMPLE:
	IDL> Array3D_In = [DIST(200,200),DIST(200,200)*1.2,DIST(200,200)*1.4]
	IDL> Array3D_In = bytscl(reform( Array3D_In, 200, 200, 3 ))
	IDL> XEasyAnim, Array3D_In,  /bottom

    you may wish to the following:

	IDL> dum=MK_COLOR(N_NONFIXED=ncolors)
	IDL> Array3D = BYTSCL( Array3D, TOP=ncolors )
	IDL> XEasyAnim, Array3D
 Modifications:
	12-May-2008 added noLoad and ctbFile keywords
	02-Aug-2007 add gamma keyword [BD]
	02-May-06 added nreps keyword
	14-Apr-06 added xpos & ypos keywords
	06-Mar-02 Added printing, resizing of array, added despeckling [BD]


XIA

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
		XIA

 PURPOSE:
	Display an animated sequence of images using X-windows Pixmaps.
	The speed and direction of the display can be adjusted using 
	the widget interface.

 CATEGORY:
	Animation, Image display, widgets.

 CALLING SEQUENCE:
	To initialize:
		XIA, SET = [Sizex, Sizey, Nframes]

	To load a single image:
		XIA, IMAGE = Image, FRAME = Frame_Index

	To load a single image that is already displayed in an existing window:
		XIA, FRAME = Frame_index, $
			WINDOW = [Window_Number [, X0, Y0, Sx, Sy]]
	(This technique is much faster than reading back from the window.)

	To display the animation after all the images have been loaded:
		XIA [, Rate] 

	To close and deallocate the pixmap/buffer (which also takes place
	automatically when the user presses the "Done With Animation"
	button or closes the window with the window manager):
		XIA, /CLOSE

 OPTIONAL INPUTS:
	Rate:	A value between 0 and 100 that represents the speed of the 
		animation as a percentage of the maximum display rate.
		The fastest animation is with a value of 100 and the slowest
		is with a value of 0.  The default animation rate is 100.  
		The animation must be initialized using the SET
		keyword before calling XIA with a rate value.

 KEYWORD PARAMETERS:
	BOTTOM: If set, window will be at bottom of screen or parent window
	CLOSE:	Set this keyword to delete the offscreen pixwins and Widget, 
		freeing storage.

	CYCLE: If set, cycle.  Normally, frames are displayed going either
		forward or backwards.  If CYCLE is set, reverse direction
		after the last frame in either direction is displayed.
		Provide this keyword with the SET keyword.

	FRAME:	The frame number when loading frames.  This keyword only has
		an effect when used in conjunction with the SET keyword.
		FRAME must be set to a number in the range 0 to Nframes-1.

	GROUP:	The widget ID of the widget that calls XIA.  When 
		this ID is specified, the death of the caller results in the 
		death of XIA.

	IMAGE:	A single image to be loaded at the animation position given 
		by FRAME.  The keyword parameter FRAME must also be specified.

	KEEP_PIXMAPS: If TRUE, XIA doesn't destroy the animation
		pixmaps when it is killed. Calling it again without
		going through the SET and LOAD steps will cause the same
		animation to play without the overhead of creating
		the pixmaps.
	BLOCK:  Set this keyword to have XMANAGER block when this
		application is registered.  By default the Xmanager
               keyword NO_BLOCK is set to 1 to provide access to the
               command line if active command 	line processing is available.
               Note that setting BLOCK for this application will cause
		all widget applications to block, not only this
		application.  For more information see the NO_BLOCK keyword
		to XMANAGER.
	ORDER:	Set this keyword to display images from the top down instead
		of the default bottom up.  This keyword is only used when 
		loading images.
       MODAL:  If set, then XIA runs in "modal" mode, meaning that
               all other widgets are blocked until the user quits
               XIA.
       MPEG_FILENAME: Set this keyword equal to a string for the desired
               MPEG filename.  If not set, idl.mpg is used.
       MPEG_CLOSE: Set this keyword to write the MPEG file.
	NREPS - number of frames to repeat when creating mpeg (1 means no dups)
       SHOWLOAD: Set this keyword (in conjunction with the SET keyword) to 
		display each frame and update the frame slider as frames are 
		loaded.

	SET:	This keyword initializes XIA.  SET should be equated
		to a 3-element integer vector containing the following 
		parameters:
		  Sizex, Sizey:	The width and height of the images to be 
				displayed, in pixels.

		  Nframes:	The number of frames in the animated sequence 
				(since XIA is an animation routine, 
				Nframes must be at least 2 frames).

	TITLE:	A string to be used as the title of the widget.  If this 
		keyword is not specified, the title is set to "XIA" 
		This keyword has an effect only when used in conjunction with
		the SET keyword).

	TRACK: If set, the frame slider tracks the current frame.  Default
		is not to track.  Provide this keyword with the SET keyword.

	WINDOW:	When this keyword is specified, an image is copied from an 
		existing window to the animation pixmap.  When using X 
		windows, this technique is much faster than reading
		from the display and then calling XIA with a 2D 
		array.

		The value of this parameter is either an IDL window
		number (in which case the entire window is copied),
		or a vector containing the window index and the rectangular 
		bounds of the area to be copied, for example:
		WINDOW = [Window_Number, X0, Y0, Sx, Sy]

      XOFFSET:	The horizontal offset, in pixels from the left of the frame, 
		of the image in the destination window.

      YOFFSET:	The vertical offset, in pixels from the bottom of the frame,
		of the image in the destination window.

 OUTPUTS:
	No explicit outputs.

 COMMON BLOCKS:
	XIA_COM: a private common block.

 SIDE EFFECTS:
	A pixmap and widget are created.

 RESTRICTIONS:
	Only a single copy of XIA can run at a time.

 PROCEDURE:
	When initialized, this procedure creates an approximately square
	pixmap or memory buffer, large enough to contain Nframes of
	the requested size.  Once the images are loaded, using the 
	IMAGE and FRAME keywords, they are displayed by copying the images 
	from the pixmap or buffer to the visible draw widget.

 EXAMPLE:
	Enter the following commands to open the file ABNORM.DAT (a series
	of images of a human heart) and animate the images it contains using
	XIA.  For a more detailed example of using XIA, 
	see the example in the "Using IDL Widgets" chapter of "IDL Basics".
	Read the images into the variable H by entering:

	   OPENR, 1, FILEPATH('abnorm.dat', SUBDIR = 'examples/data')	 
	   H = BYTARR(64, 64, 16)					 
	   READU, 1, H  						 
	   CLOSE, 1							 
	   H = REBIN(H, 128, 128, 16)					 

	   XIA, SET=[128, 128, 16], /SHOWLOAD				 
	
	   FOR I=0,15 DO XIA, FRAME = I, IMAGE = H[*,*,I]		 
	   XIA  							 

 MODIFICATION HISTORY:
	02-May-06 added nreps keyword
	14-Apr-06 added xpos & ypos, bottom & right keywords
	02-Aug-01 modified XInterAnimate to have printing [Bill Davis]


XYANIM

[Previous Routine] [List of Routines]
 NAME:
       xyanim
 PURPOSE:
	Animate a series of X-Y plots.
       Makes an animation in a XINTERANIMATE window. An MPEG file
	can then be saved, or the movie can be played with VCR-like 
	controls
 CATEGORY:
       Animation
 CALLING SEQUENCE:
       IDL> xyanim, Radii, YvsT, times, xSize=xSize, ySize=ySize
 INPUTS:
       Radii - 1-D array of Radii (for example)
       YvsT  - 2-D array of Independent axis vs. time
	times - times for which an x-y plot will be made (defaults to 1/frame)
 KEYWORD PARAMETERS:
       Keywords:
	  xSize - x size of resulting output frame (default=400)
	  ySize - y size of resulting output frame (default=xSize)
 OUTPUTS:
       just the XinterAnimate window. MPEGs can be made from that widget.
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	See /u/bdavis/cvs/idl_cvs/testxyanim.pro 
 MODIFICATION HISTORY:
       12-Jun-01 Written by Bill Davis, PPPL


Category: Bits

[List of Routines]


BITS

[Next Routine] [List of Routines]
 NAME:
       bits
 PURPOSE:
       Given a byte or integer, return a vector of 8 or 16 values
       which are the binary representation of the value.
 CATEGORY:
       bits, hardware
 INPUT:
       invalue - The byte or integer value to check
 OUTPUT:
       bitarr  - The 8-element array with values set
                 if the bit is set
 EXAMPLE:
	IDL> BITS, invalue, BITARR
 HISTORY:
       Written 1988 by M.Morrison
       13-Nov-92 (MDM) - Modified to allow integer*2 values
                         and to allow an array of values.
        7-Apr-94 (MDM) - Allow integer*4 values
       15-Aug-94 (MDM) - Corrected error from 7-Apr-94 mod which
                         did not allow an array of inputs


BTEST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
    BTEST       

 PURPOSE:
    To test bit N in FIX(X)

 CATEGORY:
    Bits, Hardware

 CALLING SEQUENCE:
    YesNo = btest( X, N )

 PARAMETERS:  
    Inputs:
    	X      (REQ) (I) (0 1) (I  F)
           	X is the variable to be tested
   
    	N      (REQ) (I) (0) (I)
           	The bit of X to be tested
     Returned:
    	YESNO  (REQ) (O) (0 1) (I)
           	The result of the test. 1(true) if bit N is set, 0(false)
           	otherwise.

 EXAMPLES:

        YESNO = btest( !X.STYLE, 4 )
        IF YESNO THEN PRINT,'X-axis suppressed' $
                 ELSE PRINT,'Draw X-axis'

        To find points in NEWSIPS which are outside calibrated region:
        YESNO = btest( ABS(NU),1 )             ; look for nu flag = -2
        IND = WHERE (YESNO EQ 0)            ; keep points where yesno = 0
        PLOT,W(IND),F(IND)                  ; plot calibrated points
        
 NOTES:

     Note that negative integers are stored in twos complement form.
     Therefore, the left-most bits are ON rather than OFF as they are for 
     positive numbers. Input the absolute value of X is negative numbers 
     to avoid this problem. 

     This procedure can be used to check the values of complex
     IDL system variables such as ![XYZ].STYLE.

 PROCEDURE:

     Checks whether (FIX(X) OR (NOT 2^N)) = -1 to set the output
     flag YESNO.

 MODIFICATION HISTORY:
	26-Oct-99 Convert from btest to make a function (like FORTRAN)
     Mar  6 1983 RJP GSFC initial program
     Aug 24 1987 RWT GSFC add PARCHECK
     Mar  7 1988 CAG GSFC all VAX RDAF-style prolog
     Jul 13 1990 RWT GSFC Sun mods: use examples pertinent to SUN IDL
                 and add listing of procedure call statement
     Jun 19 1991 PJL GSFC cleaned up; tested on SUN and VAX; updated prolog
     Mar  8 1993 RWT GSFC modify to allow X & YESNO to be vectors and 
                 add documentation about negative numbers.


DECODE_GRAY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       DECODE_GRAY
 PURPOSE:
  	Convert a gray-code value to an integer
 CATEGORY:
       Bits, CAMAC, Hardware, Stepper Motor Control
 CALLING SEQUENCE:
       IDL> int = DECODE_GRAY(grayCode)
 INPUTS:
       grayCode = number in gray code.  
 KEYWORD PARAMETERS:
     Optional Input:
	  NBits - # of bits to decode; defaults to 8
 OUTPUTS:
       int = returned integer                 			out
 COMMON BLOCKS:
       NONE
 EXAMPLES:
	IDL> print,DECODE_GRAY(1)
	       1
	IDL> print,DECODE_GRAY(2)
	       3
	IDL> print,DECODE_GRAY(255)
	     170
	IDL> print,DECODE_GRAY(255+512)
	     170
	IDL> print,DECODE_GRAY(255+512,nbits=16)
	     853
 NOTES:
	This can probably be sped up considerably.
 MODIFICATION HISTORY:
       26-Oct-99 Written by Bill Davis, PPPL


MK_BITARRAY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mk_bitarray
 PURPOSE:
       Create an array of 1's & 0's corresponding to input bits set
	(works for negative numbers, too, unlike similar routines)
 CATEGORY:
       Bits
 CALLING SEQUENCE:
       IDL> array= mk_bitarray( input )
       IDL> array= mk_bitarray( input, nbits=5 )
 INPUTS:
       input = whatever; might be something like !X.STYLE  
 KEYWORD PARAMETERS:
	NBITS=nbits - length of returned array (default to input type)
	PRINT - if set, will print bits in groups of fours.
 OUTPUTS:
       Byte array containing 1's and 0's               	out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> print,mk_bitarray(3, nbits=8)
	   1   1   0   0   0   0   0   0
	IDL> dum = mk_bitarray( 1025, /print )'
	 1 0 0 0   0 0 0 0   0 0 1 0   0 0 0 0
 LIMITATION:
	Only works on a scalar.
 MODIFICATION HISTORY:
	05-Jun-00 default nbits to input type. add print keyword.
       30-Mar-99 Written by Bill Davis, PPPL


SHOWBITS

[Previous Routine] [List of Routines]
  NAME:
       showbits
  PURPOSE:
       Given a byte or integer, return a vector of 8 or 16 values
       which are the binary representation of the value.
  CATEGORY:             
	Bits, Hardware
  USAGE:
	bitarr = SHOWBITS( invalue, /print )
  INPUT:
       invalue - The byte or integer value to check
  OUTPUT:
       bitarr  - The 8-element array with values set
                 if the bit is set
  KEYWORDS:
    (Optional)
	NtoShow - # of bits to show
  HISTORY:
	29-Oct-99 Converted to Function by Bill Davis, ntoshow added
       Written 1988 by M.Morrison
       13-Nov-92 (MDM) - Modified to allow integer*2 values
                         and to allow an array of values.
        7-Apr-94 (MDM) - Allow integer*4 values
       15-Aug-94 (MDM) - Corrected error from 7-Apr-94 mod which
                         did not allow an array of inputs
  LIMITATIONS:
	Only works for non-negative, fixed-point numbers


Category: blobs

[List of Routines]


BLOBBINRANGES

[Next Routine] [List of Routines]
 NAME:
 	blobbinranges

 PURPOSE:
	plot bins of one variable vs another from blob database and draws
       ranges, of say 90%, in Y for each binned point. Uses color filled
	contours for square bin values.
       See http://nstx.pppl.gov/nstx/Software/Applications/blobDBdefs.txt
	for an explanation of variables and units of database variables.

 CATEGORY:
       Blobs

 CALLING SEQUENCE:
	IDL> blobBinRanges, filename

  INPUTS:
  ------
	filename - file saved from DbAccess

  KEYWORDS:
  --------
	xVar - Column in DbAccess for independent variable (default='topNorm')
	yVar - Column in DbAccess for dependent variable (default='xVel')
		Note: velocities are in Km/sec. Most other things are in pixels.
	x1 - starting pixel in horizontal direction to consider
	x2 - ending pixel in horizontal direction to consider
	t1 - starting pixel in vertical direction to consider     
	t2 - ending pixel in vertical direction to consider        
	percent - % of data points to draw bars over (Default=90, but 95% might be better)
	binSize - length of bin (on X axis)
	nBins - if set, will set binsize so this # of bins cover range of X data
	minHt - min value of topNorm
	maxHt - max value of topNorm
	saveFile - if=1, will save a JPEG file
	plotFile - file name to save JPEG to
	position - bounding box in normalized coords (def=[.1,.1,.95, .9])
	xrange - the x limits of the plot (set !x.style=1 before running for exact)
	yrange - the y limits of the plot (set !y.style=1 before running for exact)
	explain - include in the legend an explanation of bars and numbers
	ctb - color table for color contours (default=3, hot metal)
	interp - if set, will interpolate colors indicating blobs per bin

  EXAMPLES:
  --------
    IDL> blobBinRanges, '/u/bdavis/cvs/database/DBoutSH141741.txt', $
	     x1=10, x2=50, charsize=1.5,  $    
    	     xtitle='Normalized Blob Brightness',  $
	     ytitle='Radial Velocity (Km/s)',  $  
    	     title='Shot 141741; 212-216 msec', $    
    	     percent=90, yrange=[-2,4], xrange=[1,7], /contours, /rainbow		  
  
    IDL> blobBinRanges, '/u/bdavis/cvs/database/DBoutSH139286.txt', $
	     x1=10, x2=50, charsize=1.5,  $    
    	     xtitle='Normalized Blob Brightness',  $
	     ytitle='Radial Velocity (Km/s)',  $  
    	     title='Shot 139286; 312-316 msec', $    
    	     percent=90, yrange=[-2,4], xrange=[1,7], /contours, /rainbow		  
  
    IDL> blobBinRanges, '/u/bdavis/cvs/idl_cvs/DBoutSH142000.txt', /debug	  

    IDL> blobBinRanges, '/u/bdavis/cvs/idl_cvs/DBoutSH142000.txt', $
	     x1=40, charsize=1.5,  $    
    	     xtitle='Normalized Blob Brightness',  $
	     ytitle='Radial Velocity (Km/s)',  $  
    	     title='Shot 142000; 240-270 msec', legend='Outside Separatrix', $    
    	     percent=90, yrange=[-2,4], xrange=[1,7], /contours, /rainbow		  
 

    IDL> blobBinRanges, '/u/mko/testfile_142000.txt', x1=40, charsize=1.5,  $    
    	     xtitle='Normalized Blob Brightness',  $
	     ytitle='Radial Velocity (Km/s)',  $  
    	     title='Shot 142000; 240-270 msec', legend='Outside Separatrix', $    
    	     percent=90, yrange=[-2,4], xrange=[1,7], /contours, /rainbow		  
	
  MODIFICATION HISTORY:
  --------------------
	29-Oct-2013 change order of columns read to fit (new?) DbAccess files.
  	WRITTEN 26-Jul-2012 by Bill Davis


BLOBTRAILS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        blobtrails

 PURPOSE:
        draw trails of blob trajectories that go through a certain region of the image. 
        Data comes from a database of blob characteristics for a given shot, and perhaps
        just part of a shot (see populateblobs.pro).
      
 CATEGORY:
       Blobs

 CALLING SEQUENCE:
       IDL> blobtrails, table=table, xpt=xpt, ypt=ypt, box=box, minht=minht

 INPUTS:
 -------
      database - SQL database (server maintained by Tom Carroll) for blobs, DEF='BLOBS'
      table - table name in database of blobs for a period within a shot, or
      shot - will assume table is named 'SH'+shot

      xpt - horizontal center of region from which trajectories start
      ypt - vertical center of region from which trajectories start
      boxradius - # of pixels around [xpt, ypt] to allow for start of trajectories
      minHt - min height of blob in normalized image. (when blob passes through box) 
      lifeRequired -  lifetime required in seconds (after passing through box) , or
      needed - number of frames needed (after passing through box) to bother with
      t1 - (optional) 1st time to consider (seconds)
      t2 - (optional) last time to consider (seconds)
      timeOffSet - amount needed to be added to camera time to get to shot time
      rainbow - if set, will use "betterrainbow" pallette, rather than hot metal.
      nSmooth - smoothing to be applied before track is plotted (default=3)
      maxJump - max # of pixel to change per frame to be considered same blob
                 (DEF=10)
      msec - if set, display times in millisec
      ellipse - if set, draw ellipses where fit was made
      symWidth - if <=0 then draw ellipses in realistic shapes
      scale - if realistic blob sizes drawn, scale their size by this factor
      xplot1 - starting x pixel for plot
      xplot2 - ending x pixel for plot
      yplot1 - starting y pixel for plot
      yplot2 - ending y pixel for plot
      verbose - if set, lots of information output listed
      debug - if set, will output even more and may stop at some spots
          "rise" was the difference from the max of a blob (after normalizing frame) 
              and the lowest closed contour line that enclosed it. 

 EXAMPLES:
      IDL> blobtrails, 32,32, box=2, /rainbow, minht=1.1, /list, /debug

      IDL> blobtrails, 25,25, box=2, /rainbow, shot=138234, ny=80, /list     , /debug

      IDL> maxJump=5
      IDL> blobtrails, table='SH138234',xpt='32',ypt='32',boxRadius='2',minHt='2', $
                       maxJump=maxJump, needed='3',t1='0',t2='20', ctb='-1', ListTimes='on', $
                       eFileType='None',psfilename='blobtrails',emailPsAddress='', /deb

      IDL> blobtrails, table='SH1091216028', x1=39, x2=41, y1=2,y2=62, psym=4, minHt='1.5', $
                       maxJump=10, needed='3',t1='0',t2='20', ctb='-1', ListTimes='on',   $
                       xplot1=30, xplot2=60,  /msec,  chimax=5, nSmooth=3, $
                       eFileType='None',psfilename='blobtrails',emailPsAddress='', /deb

         blobtrails, table='SH138234',xpt='20',ypt='20',boxRadius='3', minHt='2', $
                   maxJump=maxJump, needed='3',ctb='-1',  $
                    t1=530, t2=550, $
                   xplot1=10, xplot2=50, yplot1=10, yplot2=80, charsize=1.5, /ellip          , /deb

         blobtrails, table='SH138234',x1=15, x2=30, y1=20, y2=22,  minHt='2.5', $
                   maxJump=maxJump, needed='3',ctb='-1',  $
                    t1=530, t2=550, $
                   xplot1=15, xplot2=50, yplot1=10, yplot2=80, charsize=1.5, /ellip          , /deb

         blobtrails, 20, 20, boxRadius=3, shot=138234,  $
                     minHt=2.2, t1=530, t2=550, xSize=500, ySize=600, $
                     /ListTimes, charsize=1.8, psym=4, symSize=2,$
                     xplot1=10, xplot2=40, yplot1=0, yplot2=30

   to get a track of just one blob:
         blobtrails, 8, 40, boxRadius=4, shot=138234,  $
                     minHt=2.2, t1=534, t2=535, xSize=500, ySize=600, $
                     /ListTimes, charsize=1.6, psym=4, symSize=2,$
                     xplot1=-10, xplot2=40   ;;;, yplot1=0, yplot2=30

   to make plots for Stewart's 2014 paper:
   IDL> !p.font=0
   IDL> setup_ps, 'bt_140395_1pt5.ps', printer='postscript', /color
   IDL> blobtrails, shot=140395, t1=549.25, t2=550.75, minHt=1.5,  $
		     x1box='0',x2box='63', y1box='0',y2box='79', $
	             limiter='on', charsize=1.8, symbol='none', $
	       	     yplot1='', yplot2='', $
	             efitVersion='EFIT02',  $
	       	     /noYellow, /rainbow,  /first, symwidth=3
   IDL> unsetup_ps 

   IDL> setup_ps, 'bt_141746.ps', printer='postscript', /color
   IDL> blobtrails, shot=141746, t1=213.5 ,t2=214.5, minHt=1.5,  $
		     x1box='0',x2box='63', y1box='0',y2box='79', $
	             limiter='on', charsize=1.8, symbol='none', $
	       	     yplot1='', yplot2='', $
	             efitVersion='EFIT02',  $
	       	     /noYellow, /rainbow, /first, symwidth=3
   IDL> unsetup_ps 
 
   to make plots for Stewart's 2014 paper, but with times printed:
   IDL> blobtrails, shot=140395, t1=549,t2=551, minHt=1.5,  $
		     x1box='0',x2box='63', y1box='0',y2box='79', $
	             limiter='on', charsize=charsize, symbol='none', $
	       	     yplot1='', yplot2='', $
	             efitVersion='EFIT02',  $
	       	     noYellow=noYellow, rainbow=rainbow,  $
	       	     titleChrSz=titleChrSz, /first, symwidth=3, $
		     /ListTimes, Xplot1=-40, Xplot2=50
  
   to make plot for Stewart's 2014 paper, but with just one blob:
   IDL> blobtrails, shot=140395, t1=550.92 ,t2=550.96, minHt=1.5,  $
		     x1box='0',x2box='63', y1box='0',y2box='79', $
	             limiter='on', charsize=1.5, $
	       	     yplot1='', yplot2='', first=0, $
	             efitVersion='EFIT02',  $
	       	     noYellow=noYellow, rainbow=rainbow,  $
	       	     /ellipse, symwidth=3, $
		     /ListTimes, Xplot1=0, Xplot2=50, nskip=3
  
   IDL> blobtrails, shot=141746, t1=213.192 ,t2=213.195, minHt=1.5,  $
		     x1box='0',x2box='63', y1box='0',y2box='79', $
	             limiter='on', charsize=1.5, $
	       	     yplot1='', yplot2='', first=0, $
	             efitVersion='EFIT02',  $
	       	     noYellow=noYellow, rainbow=rainbow,  $
	       	     /ellipse, symwidth=3, /ListTimes, $
		     Xplot1=-20, Xplot2=50, nskip=3
  
 MODIFICATION HISTORY:
	29-Jul-2014 add /degrees to call to drawellipse, since the tilts in 
		    the database are degrees (zero left, 90 straight up, 
		    180 to right). Also added nskip factor for when drawing
		    all locations for a single track
       16-Jul-2014 add noYellow keyword
	01-Oct-2012 colors for single tracks was broken; fixed.
		    Now, both blob positions and separatrix (and limiter) are plotted
		    physical coordinates when plotting in cm. Previously, and still when
		    plotting vs. pixels, the "rhomboid" shape of the fiber bundle is
		    not accounted for.
	28-Sep-2012 when axesInCm set, use actual R & Z values for blob positions, and 
		    plot separtrix from actual R & Zs.
	13-Sep-2012 added EveryOther, suppress, noTitle keywords
  	18-Jul-2012 adjust for plot area not all the pixels
	26-Mar-2012 option to draw separatrix
       22-Mar-2012 Use HM values for ellipse shapes (have an option for size, too)
       01-Dec-2011 fixed duplication of first and last blob indices
       17-Jun-2011 fixed for Database time in msec
       08-Mar-2011 added wholeLife field to database, so "needed" makes more sense
                    (the blob has to have persisted for that many frames to be considered)
       WRITTEN 2-Feb-2011 by Bill Davis for Stewart Zweben


GENNETCDFBLOBS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	gennetcdfblobs

 PURPOSE:
  	Write NetCDF files of dummy Blob data for code validation. 
  	Files with  known blob velocities are generated. This code
  	prints out  these average x- and y-velocities, as as writing
  	the averages to a  variable in the file (although, as of Nov.
  	4, 2013, an array was written for  those variables and only
  	the first value represents the averages).
  
 CATEGORY:
       Blobs

 CALLING SEQUENCE:
       IDL> gennetcdfblobs, type,  nframes=nframes, speed=speed,  $
                 plot=plot, radius1=radius1, radius2=radius2, $
         	  tilt=tilt, noise=noise, x0=x0, y0=y0,   $
	 	  base=base, top=top, nblobs=nblobs, $
		  times=times
  OUTPUTS:
  	files

  	The files have an _#, where # ends up being the shot number in the 
  	database table. 

  filenames 
  ---------
 'circoneup_1.nc'    one circular blob moving upwards
  	xVel & yVel = 0        3 pixels/frame
		      0.000    0.009489 Km/s

 'circoneout_2.nc'   one circular blob moving outwards
  	xVel & yVel = 3        0 pixels/frame
		      0.01116  0.00000 Km/s

 'circmany_3.nc'     many circular blobs moving in different directions
  	xVel & yVel = 0.60     0.378 pixels/frame
		      0.00223  0.001195 Km/s

 'elipseone_4.nc'    one circular blob moving upwards and slowly outwards
  	xVel & yVel = 1        3 pixels/frame
		      0.00372  0.009489 Km/s

 'elipsemany_5.nc'   many eliptical blobs moving outwards, but up and down
  	xVel & yVel = 1.50     0.333 pixels/frame
		      0.00558  0.001054 Km/s

  (note that these speeds are much smaller than typical blobs, because
   the time between frames is only 1ms instead of 2.2usec.)

  EXAMPLES
  --------             
	IDL> gennetcdfblobs, 2, /plot, /debug

	IDL> for i=1,5 do gennetcdfblobs, i

	files can be read by IDL> img = readnetcdfblobs(filename, framenumber)

	Once they are loaded into a database (with loadblobs.pro), speeds can
	be checked by running checkvaves.pro.

 MODIFICATION HISTORY:
	WRITTEN 31-Oct-2013 by Bill Davis, PPPL, for Stewart Zweben


GPICONT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        gpicont

 PURPOSE:
        plot GPI data (an average of a center strip vs. time) as a 
        color contour with the separatrix overlayed

 CATEGORY:
        Blobs, Cameras, GPI, MDSplus, NSTX, edge

 CALLING SEQUENCE:
        IDL> gpicont, shot

 INPUT PARAMETERS:
        shot - MDSplus shot #

 KEYWORD PARAMETERS:
        t1 - start time (Def=0.3 s)
        t2 - end time (Def=0.9 s)     
        maxtimes - max number of points in time to plot (def=100000)
	     nTimes - the final number of times on the color contours
	     moreSmooth - after smoothing is done in the time dimension
			when reducing the # of times plotted, this 
			is used for the whole image (with edges handled)
	 fit - e.g., 'LRDfit04'. Defaults to "EFIT02"
        XSIZE - initial horizontal size of graphics window 
        YSIZE - initial vertical size of graphics window 
        charsize -  size of characters on plot (Def=2)
        sep - if=0, will not show separatrix
	     jpeg - if set, will make a jpeg of a screen dump
	     ps - if set, will save a postscript file
	     pdf - if set and ps set, will save a pdf file
	     new - forces rereading and saving data, even if times have 
		    been done before
	 frac - if = 1, then plot the fraction inside the separatrix
        verbose - if set, will print many informational messages
        debug - if set, debug output will be printed
               

 EXAMPLE:
   IDL> gpicont, 138844    

   IDL> gpicont, 138846, /new, t1=0.59, t2=0.67

   IDL> for i=138844, 138846 do gpicont, i, t1=0.59, t2=0.67, $
					/psout, /pdf

 MODIFICATION HISTORY:
	02-Dec-2013 option to draw +/- 5ms band around peak GPI data
			(if bandCenter present)
	28-Oct-2013 if times not specified, get from file containing peak time
	10-Oct-2013 added fit keyword, so doesn't always use "best fit"
	18-Sep-2013 from efit edge points was using nearest point
		    to the camera middle. Now interpolate edge values
		    using sepatmidgpi.
  	14-Aug-2013 Written by Bill Davis for Stewart Zweben.


GPIMOUNTAIN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        gpimountain

 PURPOSE:
        plot GPI data (an average of a center strip vs. time) as a surface
        with the separatrix overlayed

 CATEGORY:
        Blobs, 3-D Plotting, MDSplus, NSTX, GPI, edge

 CALLING SEQUENCE:
        IDL> gpimountain, shot

 INPUT PARAMETERS:
        shot - MDSplus shot #

 KEYWORD PARAMETERS:
        t1 - start time (Def=0.3 s)
        t2 - end time (Def=0.9 s)     
        maxtimes - max number of points in time to plot (def=1000)
        az - degrees to rotate around Z axis (def=30)      
        ax - degrees to rotate around X axis (def=30)     
        XSIZE - initial horizontal size of graphics window 
        YSIZE - initial vertical size of graphics window 
        charsize -  size of characters on plot (Def=2)
        sep - if=0, will not show separatrix
        nudge - amount to nudge separatrix line up, so shows above surface
                Def=30
        fence - height to draw top of fence where separatrix is.
	        Def=100. If=0, no fence will be drawn.   
        verbose - if set, will print many informational messages
        debug - if set, debug output will be printed
               
 LIMITATIONS:
        To show the separatrix on the surface, you have to find the right
        Z, which is hard without lots of interpolation. The work around is
        to nudge the Z values up so they will show above the surface even
        if it isn't quite right.

 EXAMPLE:
        IDL> gpimountain, 138844, az=50, ax=40, nudge=10, $
		           position=[.15,.1,.85,.85], nSmooth=5, nTimes=100	 

        IDL> gpimountain, 138846, az=50, ax=40, nudge=10, /new, $
		           position=[.15,.1,.85,.85], nSmooth=5, nTimes=1000	 

 MODIFICATION HISTORY:
  	 11-Jun-2013 Written by Bill Davis for Stewart Zweben.


LOADBLOBS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   loadblobs

 PURPOSE:
	calls many routines used for loading blob tracking info into a 
	database and making plots and output files

 CATEGORY:
	blobs

 CALLING SEQUENCE:
       IDL> loadblobs, filename

	if you want to load many shots from a list in a file, use something 
	like /u/bdavis/GPI/call_loaddb.pro
 INPUTS:
       filename - a .cin or .hdf file containing plasma images
	
 KEYWORD PARAMETERS:
	filename - cine file to analyze
	outfilename - output of text with blob info (default formed from inputs)
	t1 - start time desired in terms of times in .cin file (in sec)
	t2 - end time desired in terms of times in .cin file (in sec)
       aveT1 - start for averaging frame (DEF=t1) if normalize=1
       aveT2 - ending time for averaging frame (DEF=t2)   
	horiz - if=0, do not flip frames horizontally
	RotCCW - if set, will rotate frame Counter-clockwise (after horizontal flip)
		default for NSTX, but not for CMOD
	BlobCriteria - structure for blob criteria, like min normalized height, etc.
	normalize - normalize images (divide by average frame) before looking for 
		blobs.
	deleteFirst - if = 0, will NOT first delete the existing database table.
	dbOut - if=0, will not write to an SQL database
	outDBfile - if set, will write database info to this filename, rather than db
       table - if not set, will write to table SH+
	database - if not set, will write to database 'BLOBS'
	nSmooth - amount to smooth image before looking for blobs
	GaussSmooth - if set, will do "gaussian" smoothing (sort of a double smooth)
		      instead of boxcar smoothing
	velSmooth -  amount to smooth velocity tracks before putting into database
	FrameOffset - if set, subtract this (like a baseline) from all pixels
	FrameAveMin - if set, make close-to-zero pixels this number, 
		      so when dividing into data, as in normalizing, result is near zero
	AveFrameSmooth - smoothing for the averaged frame(s)
	verbose - if set, lots of information output listed
	debug - if set, will output even more and may stop at some spots

 NOTES:
	see CheckBlobVel.txt for validation case
	see /u/bdavis/w3_html/swdoc/Blob_Tilt_Calcs.txt for other facts.
   
	populateblobs.pro reads a file of blob characteristics created from fcplayer.pro
	or saveblobs.pro, which is usually called, together with populateblobs, from
	loadblobs.pro. I.e.,
       
	--loadblobs
	  --saveblobs
	    --findblobs
	      --fcfitellipse (returns tilts in radians, clockwise from zero to left)
	        --mpfitellipse
	      --blobfilewrite (writes file with tilts in radians, CW zero to left)
	  --populateblobs (reads file, and converts tilts to degrees)
	
 EXAMPLES:

	   ; for test blobs
 	loadblobs, 'circoneup_1.nc', t1=0., t2=0.010, horiz=0, norm=0
 	loadblobs, 'circoneout_2.nc', t1=0., t2=0.010, horiz=0, norm=0
 	loadblobs, 'circmany_3.nc', t1=0., t2=0.010, horiz=0, norm=0
 	loadblobs, 'elipseone_4.nc', t1=0., t2=0.010, horiz=0, norm=0
 	loadblobs, 'elipsemany_5.nc', t1=0., t2=0.010, horiz=0, norm=0

 	camDir = '/p/nstxcam-archive/Phantom710-9205/2010/'
 	loadblobs, camdir+'nstx_5_139286.cin', t1=0.312, t2=0.316

   ; NB scan
 loadblobs, T1=0.500, T2=0.510, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139481.cin' 

 loadblobs, T1=0.500, T2=0.510, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139482.cin' 

 loadblobs, T1=0.500, T2=0.510, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139483.cin' 

   ; Li scan
 loadblobs, T1=0.580, T2=0.590, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141319.cin' 

 loadblobs, T1=0.580, T2=0.590, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141326.cin' 

 loadblobs, T1=0.530, T2=0.540, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141320.cin' 

 loadblobs, T1=0.530, T2=0.540, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141324.cin' 

 loadblobs, T1=0.530, T2=0.540, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141322.cin' 

 loadblobs, T1=0.480, T2=0.490, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141307.cin' 

    ; two CMOD cameras for same shot 
	(when data retrieved from MDSplus at MIT, times are shot times):

 loadblobs, T1=1.089, T2=1.091, /verb,  table='SH1120224030x',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224030x_blobs_1116-1118ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       'shot_1120224030.cine'

 loadblobs, T1=1.089, T2=1.091, /verb,  table='SH1120224030m',   $	; cam near mid-plane
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224030m_blobs_1116-1118ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       'shot_1120224030.cin'


  shot='1120224009'  &  t1=0.701    &  t2=t1+0.005
  shot='1120224015'  &  t1=0.801    &  t2=t1+0.004
  shot='1120224022'  &  t1=1.044    &  t2=t1+0.004	; 
  shot='1120224023'  &  t1=1.113    &  t2=t1+0.003
  shot='1120224024'  &  t1=1.130    &  t2=t1+0.005
  shot='1120224027'  &  t1=1.144    &  t2=t1+0.004

  shot='1120712026'  &  t1=1.144    &  t2=t1+0.004
  shot='1120712027'  &  t1=1.144    &  t2=t1+0.004
  shot='1120712028'  &  t1=1.144    &  t2=t1+0.005	; 
  shot='1120712029'  &  t1=1.144    &  t2=t1+0.003

  shot='1120815018'  &  t1=1.270    &  t2=t1+0.004
  shot='1120815021'  &  t1=1.190    &  t2=t1+0.003
  shot='1120815030'  &  t1=1.260    &  t2=t1+0.004
  shot='1120815034'  &  t1=1.150    &  t2=t1+0.003

 st1 = strtrim( string(t1*1000,format='(I4.4)'), 2)
 st2 = strtrim( string(t2*1000,format='(I4.4)'), 2)
 loadblobs, T1=t1, T2=t2, table='SH'+shot+'x',   $	; cam near X-pt
       /horiz, /RotCW, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_'+shot+'x_blobs_'+st1+'-'+st2+'ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, FrameAveDeltaMS=0, $
       'shot_'+shot+'.cine', /verb

 loadblobs, T1=t1, T2=t2, table='SH'+shot+'m',   $	; cam near midplane
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_'+shot+'m_blobs_'+st1+'-'+st2+'ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, FrameAveDeltaMS=0, $
       'shot_'+shot+'.cin', /verb	; midplane camera file does not end in e


    ; for fake blobs covering whole center of image:
 ; and tilts
 .r getfakeblobs
 loadblobs, T1=0.080, T2=0.080+.002, /verb,  table='FakeShotXall',   $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021FakeX_blobs_80-80ms.txt',  $
       norm=0,  horiz=0,  minHt=3, velSmooth=0,  $
       '/p/gpi/szweben/Phantom2_Data/2012_shots/1120815/shot_1120815021.cine'

 loadblobs, T1=0.080, T2=0.080+.0055, /verb,  table='FakeShotM',   $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021FakeM_blobs_80-80ms.txt',  $
       norm=0,  horiz=0,  minHt=3, velSmooth=0,  $
       '/p/gpi/szweben/Phantom_Data/2012_data/1120815/shot_1120815021.cin'

 loadblobs, T1=0.080, T2=0.080+.0055, /verb,  table='FakeShotXT',   $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021FakeXT_blobs_80-80ms.txt',  $
       norm=0,  horiz=0,  minHt=3, velSmooth=0, $
       '/p/gpi/szweben/Phantom2_Data/2012_shots/1120815/shot_1120815021.cine'

 loadblobs, T1=0.080, T2=0.080+.0055, /verb,  table='FakeShotXT30',   $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021FakeXT30_blobs_80-80ms.txt',  $
       norm=0,  horiz=0,  minHt=3, velSmooth=0, $
       '/p/gpi/szweben/Phantom2_Data/2012_shots/1120815/shot_1120815021.cine'



    ; two CMOD cameras for same shot:

 loadblobs, T1=1.086, T2=1.088, /verb,  table='SH1120224029x',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224029x_blobs_1086-1088ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       'shot_1120224029.cine'

 loadblobs, T1=1.086, T2=1.088, /verb,  table='SH1120224029m',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224029m_blobs_1086-1088ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       'shot_1120224029.cin'



    ; two CMOD cameras for same shot 
	(stewarts Movie is from 1.116-1.118, but stuff starts happening at 1.117):

 loadblobs, T1=1.115, T2=1.117, /verb,  table='SH1120224022x',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224022x_blobs_1116-1118ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       'shot_1120224022.cine'

 loadblobs, T1=1.115, T2=1.117, /verb,  table='SH1120224022m',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224022m_blobs_1116-1118ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       'shot_1120224022.cin'



 loadblobs, T1=0.080, T2=0.090, /verb,  table='SH1120815021xN',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021xN_blobs_80-90ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       '/p/gpi/szweben/Phantom2_Data/2012_shots/1120815/shot_1120815021.cine'

 loadblobs, T1=0.080, T2=0.090, /verb, table='SH1120815021mN',    $	; midplane cam
       /horiz, minHt=0.33, minRise=0.04, Chi=5, velSmooth=0,  $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021mN_blobs_80-90ms.txt', $
       AveFrameSmooth=0, FrameAveMin=25, FrameOffset=25, $
      '/p/gpi/szweben/Phantom_Data/2012_data/1120815/shot_1120815021.cin'


 loadblobs, T1=0.080, T2=0.090, /verb,  table='SH1120224022xN',   $	; cam near X-pt
       /horiz, minHt=0.5, minRise=0.06, Chi=5,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224022x_blobs_80-90ms.txt',  $
       AveFrameSmooth=0, FrameAveMin=25, $
       '/p/gpi/szweben/Phantom2_Data/2012_shots/1120224/shot_1120224022.cine'

 loadblobs, T1=0.080, T2=0.090, /verb, table='SH1120224022mN',    $	; midplane cam
       /horiz, minHt=0.33, minRise=0.04, Chi=5, velSmooth=0,  $
       nSmooth=3, /GaussSmooth, outFile='shot_1120224022m_blobs_80-90ms.txt', $
       AveFrameSmooth=0, FrameAveMin=25, FrameOffset=25, $
      '/p/gpi/szweben/Phantom_Data/2012_data/1120224/shot_1120224022.cin'





    ; two CMOD cameras for same shot -- try without normalization
 loadblobs, T1=0.020, T2=0.040, /verb,  table='SH1120815021x',   $	; cam near X-pt
       /horiz, minHt=20, norm=0, minRise=4, Chi=8,  velSmooth=0, $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021x_blobs_20-40ms.txt',  $
       '/p/gpi/szweben/Phantom2_Data/2012_shots/1120815/shot_1120815021.cine'

 loadblobs, T1=0.020, T2=0.040, /verb, table='SH1120815021m',    $
       /horiz, minHt=20, norm=0, minRise=4, Chi=8, velSmooth=0,  $
       nSmooth=3, /GaussSmooth, outFile='shot_1120815021m_blobs_20-40ms.txt', $
   '/p/gpi/szweben/Phantom_Data/2012_data/1120815/shot_1120815021.cin'

   ; try that shot with normal params
 loadblobs, T1=0.020, T2=0.040, /verb, table='SH1120815021',    $
       /horiz, outFile='shot_1120815021_blobs_20-40ms.txt', $
   '/p/gpi/szweben/Phantom_Data/2012_data/1120815/shot_1120815021.cin'

   ; defaults work pretty well when normalizing:

 loadblobs, T1=0, T2=0.020, /verb,    $
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216017.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216018.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216019.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216023.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216025.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216026.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216028.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216029.cin'
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216030.cin'
   
 loadblobs, T1=0.050, T2=0.070, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2010_data/1100120/shot_1100120025.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100120/shot_1100120026.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100120/shot_1100120027.cin'
   
 loadblobs, T1=0.050, T2=0.070, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2010_data/1100803/shot_1100803005.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100803/shot_1100803008.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100803/shot_1100803011.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100803/shot_1100803015.cin'

 loadblobs, T1=0.060, T2=0.080, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2010_data/1100824/shot_1100824017.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100824/shot_1100824019.cin'
    '/p/gpi/szweben/Phantom_Data/2010_data/1100824/shot_1100824021.cin'
   
 loadblobs, T1=0, T2=0.020, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2011_data/1110114/shot_1110114023.cin'
    '/p/gpi/szweben/Phantom_Data/2011_data/1110114/shot_1110114026.cin'
    '/p/gpi/szweben/Phantom_Data/2011_data/1110114/shot_1110114027.cin'
   
 loadblobs, T1=0.017, T2=0.027, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2011_data/1110114/shot_1110114032.cin'

	For Matt:
 loadblobs, T1=0.24, T2=0.27, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_142000.cin' 

 loadblobs, T1=0.219, T2=0.229, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138120.cin' 

 loadblobs, T1=0.225, T2=0.235, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138114.cin' 

 ; APS NB
 loadblobs, T1=0.280, T2=0.300, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138119.cin' 

 loadblobs, T1=0.290, T2=0.300, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138128.cin' 

 loadblobs, T1=0.280, T2=0.300, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_142220.cin' 

 loadblobs, T1=0.530, T2=0.550, /verb, FrameAveDeltaMS=0, table='SH138234z',  $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138234.cin' 

 loadblobs, T1=0.268, T2=0.288, /verb, table='SH139432',  $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139432.cin' 

 loadblobs, T1=0.258, T2=0.278, /verb, table='SH139444',  $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139444.cin' 

 loadblobs, T1=0.200, T2=0.220, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141751.cin'

 loadblobs, T1=0.210, T2=0.230, /verb,   $
    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141752.cin'    , /deb

 loadblobs, T1=0.021, T2=0.031, /verb, '/p/nstxcam/CMOD/shot_1120223031.cin'    , /deb

    to load a file, but not a database:
 loadblobs, '/u/bdavis/Blobs/solt_012_3.5b.hdf', shot=99901203, dbout=0, $
		outDBfile='solt_012_3.5b.txt', normalize=0, minHt=0.01, minRise=0.01

  27-Feb-2012 added smoothing options, since default in findblobs now=0

 MODIFICATION HISTORY:
	30-Jun-2015 changed default of velSmooth to 0, so manual checks work
		    had no effect since 
	28-Mar-2014 added camera keyword
	12-Mar-2014 made EFIT02 the default for separatrix calc
	12-Nov-2012 made default GaussSmooth=1, to be consistent with FCplayer.
	17-May-2012 several updates to pass parameters to saveblobs for file output
	WRITTEN by Bill Davis, PPPL, for Stewart Zweben


PLOTBLOBVYVSBIN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	plotblobvyvsbin

 PURPOSE:
	plot a series of vertical velocity traces vs. time
	from the blob database. Each trace will be from a horizontal 
	range

 CATEGORY:
       Blobs

 CALLING SEQUENCE:
       IDL> plotblobvyvsbin, shot=shot

 KEYWORDS:
	shot - shot (has to be in the database)
	table - table in the database (name can be created from shot)
	database - SQL database (default='blobs')
	xBinSize - # of pixels to bin over in X (default=6)
	tBinSize - time width over which to average velocities (default=0)
	nSmooth - number of time points to smooth over before plotting
		(default=21)
	minHt - minimum normalized height for blobs to count (default=1.2)
	needed - # of frames for which blob exists to count (default=2)
	x1 - pixel location to start binning (defaults to min of center in data)
	x2 - pixel location to stop binning
	t1 - time to start data bining (default to start of times in database)
	t2 - time to end binning (default to end of times in database)
	VyMin - plot min (auto scales otherwise)
	VyMax - plot max
	colors - color indices for lines
	charsize - character size for plot labels
	yTitle - title for vertical axis
       timeOffSet - time to add to camera times to get shot times (ms)
       	     (can be automatically read from file for some shots)
	jpeg - if set makes a jpeg in your home directory and prints the name

 OUTPUTS:
	just plotting

 NOTES:
	keywords for the PLOT command will be passed along

 EXAMPLE:
	IDL> plotblobvyvsbin, shot=1110114032, nSmooth=21 
	IDL> colors=[49,53,51,56,50,52]
       IDL> plotblobvyvsbin, shot=1110114032, xbinsize=6, tBinSize=0.025,  $
			VyMin=-2, VyMax=3, xrange=[21,23],colors=colors, x1=25 

	IDL> plotblobvyvsbin, shot=1110114032, xbinsize=7, nsmooth=5, tbin=0.025,  $
			VyMin=-1, VyMax=1, xrange=[21,23],colors=colors, x1=25

       IDL> plotblobvyvsbin, shot=1120223031, xbinsize=8, nsmooth=31, x1=32, /jpeg

  WRITTEN 03-May-2012 by Bill Davis, PPPL, for Stewart Zweben


POPULATEBLOBS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	populateblobs 

 PURPOSE:
      Read a file created from fcplayer.pro with columns of blob 
      characteristics vs time. compute frame-to-frame statistics like x & y
      velocity and duration, based on "reasonableness" factors, like maximum
      movement per frame allowed. Velocities are recomputed after parent-child
      relationships determined, so the velocity tracks can be smoothed.
	     (loadblobs.pro can be used for all the steps needed to populate the 
	      database.)
      
 CATEGORY:
       Blobs

 CALLING SEQUENCE:
       IDL> populateblobs, filename=filename, table=table

 INPUTS:
 -------
      filename - name of input file produced from FCplayer.
      database - SQL database (server maintained by Tom Carroll) for blobs, 
       	  DEF='blobs' 
      make - if set, will try to create datbase table (if already exists, will
              complain, but no harm done)
      table - table name in database of blobs for a period within a shot, or		     
      shot - will assume table is named 'SH'+shot
      maxJump - max # of pixel to change per frame to be considered same blob
       	 (DEF=10)
      minFrames - minimum # of contigous frames blob must be identified to 
       	   be considered (DEF=3)
      maxArea max area change (sq. pixels) per frame to be considered same blob

      outFileName - if present, will write data to a table-delimited file 
       	     rather than an SQL database

	BlobCriteria - structure for blob criteria, like min normalized height, etc.
			(just for writing to the output "database" file.)
      verbose - if set, lots of information output listed
      debug - if set, will output even more and may stop at some spots

 EXAMPLES:
      filename='shot_1120815034m_blobs_1150-1153ms.txt'    
      outfile='shot_1120815034m_out.txt'
      populateblobs, filename=filename, table=table, /deletefirst, $
		      timeoffset=0, shot=1120815034, outfile=outfile, $
			/verb, doRhos=0

      filename='shot_1120224022x_blobs_1044-1048ms.txt'    
      table = 'SH1120224022x'
      populateblobs, filename=filename, table=table, /verb, /deletefirst, $
		      timeoffset=0, shot=1120224022

      filename='/u/bdavis/cvs/idl_cvs/shot_1120815021Fake_blobs_80-80ms.txt'    
      table = 'FakeShot'
      populateblobs, filename=filename, table=table, /verb		  , /make

      filename='/u/bdavis/cvs/idl_cvs/shot_1091216028_blobs_0-20ms.txt'    
      table = 'SH1091216028'
      populateblobs, filename=filename, table=table, /verb		  , /make

      filename='/u/bdavis/cvs/idl_cvs/shot_1091216029_blobs_0-20ms.txt'    
      table = 'SH1091216029'
      populateblobs, filename=filename, table=table, /verb		  , /make

      filename='nstx_5_138234_blobs_530-550ms.txt' 
      table = 'SH138234'
      populateblobs, filename=filename, table=table, /verb		  , /make
 
      filename='nstx_5_138128_blobs_280-300ms.txt' 
      table = 'SH138128'
      populateblobs, filename=filename, table=table, /verb,  /deleteFirst    , /debug
 
      filename='nstx_5_142200_blobs_280-300ms.txt' 
      table = 'SH138128'
      populateblobs, filename=filename, table=table, /verb 	  , /make
 
      filename='nstx_5_141751_blobs_200-220ms.txt' 
      table = 'SH141751'
      populateblobs, filename=filename, table=table, /verb		  , /make
	 
      --- to write out a file that Stewart can read in Kalideograph:
      filename='nstx_5_138234_blobs.txt'   
      populateblobs, filename=filename, out=filename+'OUT', /verb	 
 
 NOTES 
      see CheckBlobVel.txt for validation case.
	see /u/bdavis/w3_html/swdoc/Blob_Tilt_Calcs.txt for other facts.

 MODIFICATION HISTORY:
	29-Jun-2015 BD mk_blobtable now makes the blob # the primary key (Identity)
			was getting warnings on this. Changed.
	24-Jun-2014 BD "wholelife" was -1 for last occurence of blob. Also, when
		       blob just seen in one frame, make wholelife = delta time
	10-Oct-2012 BD compute XfromSep at each time step
	20-Sep-2012 BD back to no negative ellipticity. 
		       Tilt stored in degrees, from PI/2 (straight up) to -Pi/2 (down)
		       and zero tilt is horizontal
	04-Sep-2012 BD changed def of ellipticity, so can have < 1. 
			ellip = Major Radius/Minor Radius, if tilt between pi/4 and
			3pi/4, then make ellipticity negative.
	29-Aug-2012 BD added ellip, ellipHM and Rho (R-Rsep at midplane)
	17-May-2012 BD several updates to receive parameters to output to file
	06-Jan-2012 BD changing velocities from pixels/frame to Km/s. Adding column
			        in databases for x distance to the separatrix.
	WRITTEN 2-Feb-2011 by Bill Davis for Stewart Szweben


SAVEBLOBS

[Previous Routine] [List of Routines]
 NAME:
   	saveblobs

 PURPOSE:
  	Save blob tracks, just like FCplayer, but easier and faster. Usually called from
	LoadBlobs.pro.

 CATEGORY:
	blobs

 CALLING SEQUENCE:
       IDL> saveblobs, filename

 INPUTS:
       filename - a .cin or .hdf file containing plasma images
	
 KEYWORD PARAMETERS:
	filename - cine file to analyze
	outfilename - output of text with blob info (default formed from inputs)
  	t1 & t2 - time range to load (in sec)

       aveT1 - start for averaging frame (DEF=t1) (in sec)
       aveT2 - ending time for averaging frame (DEF=t2)   
	horiz - if=0, do not flip frames horizontally
	RotCCW - if set, will rotate frame Counter-clockwise (after horizontal flip)
		default for NSTX, but not for CMOD
	BlobCriteria - structure for blob criteria, like min normalized height, etc.
	nSmooth - amount to smooth image before looking for blobs
	GaussSmooth - if set, will do "gaussian" smoothing (sort of a double smooth)
		      instead of boxcar smoothing
	FrameOffset - if set, subtract this (like a baseline) from all pixels
	FrameAveMin - if set, make close-to-zero pixels this number, 
		      so when dividing into data, as in normalizing, result is near zero
	AveFrameSmooth - smoothing for the averaged frame(s)
	FrameAveDeltaMS - make frames used for normalizing an average of this many millisec

 EXAMPLES:
 saveblobs, T1=0, T2=20, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216030.cin'

    '/p/gpi/szweben/Phantom_Data/2010_data/1100120/shot_1100120025.cin'

 saveblobs, T1=90, T2=92, /verb,   $
    '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1110114/1110114026.cin' 

 saveblos, '/u/bdavis/Blobs/solt_012_3.5b.hdf', shot=99901203, norm=0

 MODIFICATION HISTORY:
	12-Nov-2012 added FrameAveDeltaMS keyword and feature to have an average for
		    a particular frame just be over this # of milliseconds.q
	17-May-2012 several updates to receive parameters to output to file
       01-Mar-2012 decided not to smooth average frame
       WRITTEN 09-Feb-2012 by Bill Davis, PPPL, for Stewart Zweben


Category: Colors

[List of Routines]


BETTERRAINBOW

[Next Routine] [List of Routines]
 NAME:
       betterrainbow
 PURPOSE:
       Loads a rainbow color palette with 6 evenly-spaced (roughly) colors
 CATEGORY:
      Colors,  Graphics
 CALLING SEQUENCE:
       IDL> betterrainbow
 INPUTS:
       NONE  
 KEYWORD PARAMETERS:
    Optional Keywords:
	BAR - if set, will draw a color bar on plot
	nColors - # of colors to load (Defaults to !D.TABLE_SIZE)
	lessRed - if set, rainbow will have a smaller red region
	WhiteBottom - if set, there will be a white region at the bottom
	topColor - can be an index or 'white' or 'black'
	botColor - can be an index or 'white' or 'black'
	linePlots - if set, top color will be black and bottom color will be white
	noYellow - if set, don't have yellow (because doesn't show up well on white)
 OUTPUTS:
       NONE (color table changed)
 EXAMPLE:
	IDL> betterrainbow, botColor='white', /bar
	IDL> 

 LIMITATIONS:
	always starts at the bottom of color palette.
 MODIFICATION HISTORY:
	13-Aug-2012 mucked with white bottom
	04-Nov-2011 smoothed out corners in green between 180 & 240, so discontinuity not
		    seen in organge
	26-Aug-2011 added smooth parameter, default it to 50. Round off purple to
		    blue transition.
	18-Jun-2008 added NoYellow keyword
	02-Aug-2007 fix bug for /lineplot and ncolors<256; 
		    if /linePlots keyword set, reset !p.color & !p.background
	30-Apr-2007 added linePlots keyword
	26-May-2006 added ncolors and whiteBottom keywords
	14-Feb-2005 add topColor and botColor keywords
       15-Jul-2002 Written by Bill Davis, PPPL


COLORSEARCH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       colorSearch

 PURPOSE:
       Return color index (or closest available) from the color name.

 CATEGORY:
      Colors,  Graphics

 CALLING SEQUENCE:
	index = colorSearch( colorName )

 INPUT:
       colorName: A string with the name of the color. 'WHITE','BLACK','YELLOW',
		'RED','GREEN','BLUE','MAGENTA','YELLOW','ORANGE', 'PURPLE', 
		'DarkGreen','LTBLUE', 'GREY', 'GOLD','GreenYellow','PaleGoldenrod','BROWN',  
               'LightSeaGreen',  'SALMON',  'MediumVioletRed'

       (colorName is NOT case sensitive)

	Synonyms are handled as follows:
         'GREY' = 'GRAY'
         'DARKGRAY' = 'GRAY'
         'CHARCOAL' = 'GRAY'
         'AQUAMARINE' = 'GREEN'
         'SKYBLUE' = 'LTBLUE'
         'LT_BLUE' = 'LTBLUE'
         'CYAN' = 'LTBLUE'
         'DKBLUE' = 'BLUE'
         'DARKBLUE' = 'BLUE'
         'DK_BLUE' = 'BLUE'
         'VIOLET' = 'MAGENTA'

    or, if colorName = 
          'FOREGROUND' then simply return, !p.color
          'BACKGROUND' then simply return, !p.background

 KEYWORD PARAMETERS:
	INIT - if set, will load color table 39 (rainbow with Black and white),
	       and !p.color will be set to black, and !p.background to white.
	       *** NOTE that the SET_PLOT command can change !p.color and !p.background.
 	debug - if set, will print informational messages
	quiet - if set, will not warn if color found is not close to that asked for
	status - if = 1, then color was found, else 0

 RESTRICTIONS:
	If match is not found it will return the index of the "closest" table location, and
	status=0, and, if /quiet is not set, it will print a warning.
	

       Note that the SET_PLOT command (from IDL Help):
          "sets the default color !P.COLOR to the maximum color index minus one or, 
	    in the case of devices with white backgrounds, such as PostScript, to 0 (black)."
	After calling SET_PLOT,'X' or SET_PLOT,'Z' you will have to re-call a=colorSearch( /init )
	to return to plotting black lines on a white background.
 EXAMPLES:
	plot, indgen(10), color=colorSearch( /init )
	oplot, indgen(10)/2, color=colorSearch('red')

       names = colorsearch( /RETURNnames )
	dum = mk_color(table=32)
	plot, indgen(280), ystyle=3, /nodata
	for i=0, n_elements( names )-1 do oplot, [0,255], [colorsearch(names[i]),colorsearch(names[i])], $
					         color=colorsearch(names[i])
	for i=0, n_elements( names )-1 do xyouts, 256,colorsearch(names[i]), names[i], color=colorsearch(names[i])
 
 MODIFICATION HISTORY:
	26-Jan-2007 Written by Bill Davis, PPPL


DECOMPOSEDCOLOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  DECOMPOSEDCOLOR

 PURPOSE:

   This function is used to determine, in a device independent way, if the 
   current graphics device is using color decomposition. The function returns
   a 1 if color decomposition is turned on, and a 0 if it is turned off. When
   color decomposition is turned on, we say the device is using a true-color
   display. If color decomposition is turned off, we say the device is using
   an indexed color display.

 AUTHOR:

   FANNING SOFTWARE CONSULTING
   David Fanning, Ph.D.
   1645 Sheely Drive
   Fort Collins, CO 80526 USA
   Phone: 970-221-0438
   E-mail: davidf@dfanning.com
   Coyote's Guide to IDL Programming: http://www.dfanning.com/

 CATEGORY:

   Colors

 CALLING SEQUENCE:

   result = DecomposedColor()

 RETURN VALUE:

   result:       A 1 if color decomposition is turned on. A 0 if color decomposition is turned off.

 ARGUMENTS:

  device:        The IDL graphics device whose color decomposition state you wish to know the
                 current value of. If undefined, the current graphics device is used.

 KEYWORDRS:

  DEPTH:          An output keyword that returns the depth of the graphics device. Normally,
                  either 8 for index color devices, with color decomposition turned off, or 24
                  for true-color devices with color decomposition turned on.

 EXAMPLE:

  IDL> Print, DecomposedColor()     ; Color decomposition state of current graphics device.
       1
  IDL> Print, DecomposedColor('PS') ; Color decomposition state of PostScript graphics device.
       0

 MODIFICATION HISTORY:

  Written by: David W. Fanning, May 24, 2009.
  Modified the way decomposition was obtained for PostScript devices IDL 7.1 and higher. 12 Dec 2010. DWF.
  Fixed a problem in the CASE statement with ELSE clause and added a NULL device segment. 4 Jan 2011. DWF.
  It now appears 24-bit PostScript support was added in IDL 7.1, although the Get_Decomposed keyword
      didn't work until IDL 7.1.1. 13 January 2011. DWF


MK_COLOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mk_color

 PURPOSE:
       Create color tables with 12 fixed colors at the top. These colors
	can be referenced by name.

 CATEGORY:
      Colors,  Graphics

 CALLING SEQUENCE:
	index = mk_color( color )
	index = mk_color( color, TABLE=5, MAX_COLORS_TO_USE = 128 )
 OPTIONAL INPUTS:
       COLOR: A string with the name of the color. 'WHITE','BLACK','YELLOW',
                 'RED','GREEN','BLUE','MAGENTA','LTBLUE', and (if device
		   supports more than 8 colors) 'GREY' are allowed.
	       Alternately, COLOR may be an integer from 0 - 8.
              If the COLOR input is anything else, or not present, an index
	          for yellow is returned.
 KEYWORD PARAMETERS:
	LOAD:	If set, return a structure containing all 8 colors.
		e.g. IDL> c=MK_COLOR(/load)
		     IDL> plot,x,y,color=c.red
       MAX_COLORS_TO_USE: The maximum number of colors to use for all of
		IDL . The default
		is 64 so IDL doesn't grab all the colors on a 256-color
		monitor. If an IDL window, or a call to LOADCT, was made
		before the first call to mk_color, the number of colors
	        will already have been allocated.
	TABLE: The number of the pre-defined color table to load, from 0 to 40.
	       The same as for LOADCT. The default is 0.
	FILE:  If present, will load color table from this file.
	        These colors will be squeezed into the number of
		colors used for the palette (N_NONFIXED colors).
	N_NONFIXED (returned) number of colors other than the nine fixed ones.
		e.g., MAX_COLORS_TO_USE-12.
	SILENT: If this keyword is set, the Color Table message is suppressed.
	SEARCH - if set, will do a least squares fit to color table to find
		 closest index to color -- good if color table was set outside
	  	 of mk_color
	GAcolors - if set, create a color table with colors beginning at zero, 
		   in the same order as GA color_setup routine.
 COMMON BLOCKS:
       mk_color_local

 SIDE EFFECTS:
       Limits the maximum number of colors for this IDL session.
	(The default is 64 colors).
 RESTRICTIONS:
	Reserving the right number of colors only works if this is called
	before any IDL window is drawn, and before LOADCT is called.

	Good Luck if you try and run with 24-bit color.

	If a device allows less than 12 colors (like Tek), the colors beyond
	the number allowed will not be available.
 EXAMPLES:
    Simply:
	plot,indgen(100),color=mk_color('red'),background=mk_color('white')
    or:
	plot,[0,1],[0,10]-1
	for i=0,8 do oplot,[i,i],color=mk_color(i)	; to see all colors
    x-y overlays:
	PLOT,INDGEN(100),/NODATA, COLOR=MK_COLOR('blue')	; axes in blue
	PLOT,INDGEN(100), COLOR=MK_COLOR('red')			; data in red
	OPLOT,INDGEN(100)/2, COLOR=MK_COLOR('yellow')		; overlay yellow

    Using color contours AND x-y plots:
	array_2D = DIST(150)	; generate a test array
	yellow_index = mk_color( TABLE=5, MAX_COLORS_TO_USE = 128, $
		N_NONFIXED = n_nonfixed)
	WINDOW,  XSIZE=400, YSIZE=250				; make wide window
	TV, BYTSCL( array_2D, TOP = n_nonfixed-1 ), 25, 50  	; plot scaled 2-D image
	PLOT, HISTOGRAM(array_2D), COLOR=mk_color('LtBlue'),  $	; lt. blue axes
	   POSITION=[0.55, 0.15, 0.95, 0.95], /NOERASE, /NODATA
	OPLOT, HISTOGRAM(array_2D) > 10, COLOR=mk_color('Magenta')	; data in magenta
	whatever = mk_color(TABLE=39)	; change colors of contours, but not lines
 NOTES:
	Tek Colors are 0=black, 1=white, 2=red, 3=green, 4=blue,
		5=cyan, 6=magenta, 7=yellow, 8=orange.

	default Green is [0,192,0] so it won't be so light.

 MODIFICATION HISTORY:
	29-Sep-2009 made dark green actually forest green, so shows up better.
		    make green [0,192,0] rather than [0,255,0], so not so bright.
	24-May-04   moved creation of X-window when Z-buffer the device
		    (necessary when mk_color first called with PS or Z.)
	22-Apr-2004 fixed bug when Z-buffer set on first call.
	14-Nov-03 - fixed new bug for Tek colors.
	13-Mar-03 - if requested color not found, try to find black (instead of yellow)
		    if ask for 'FOREGROUND' or 'BACKGROUND' return !p values.
		    GAcolor Keyword for doing colors like GA (same order and position)
	20-Aug-02 - set !p.color & !p.background to previous colors (closest
		    r,g,b value), when called the first time, or when changing
		    color tables.  Add FILE keyword
	07-Mar-02 - Change !d.n_colors to !d.table_size
	08-May-01 - When in Tek, make !p.color=black (was going to index 15)
	23-Apr-01 - added three more colors (orange, purple, darkgreen)
	26-Jan-01 - limit structure returned to !d.n_colors (e.g., when=2).
	28-Sep-00 - Added bottom keyword (passes straight through to loadct)
	24-Jan-00 - If color found at multiple indices, return highest valid one
	02-Jan-00 - Both /LOAD and individual colors return valid indices in
		    24-bit mode.
	05-Oct-99 - BD Synonyms & Structure return as in new D. Fanning routine.
	09-Jun-99 - BD If desired color not found, return index of nearest color.
 	11-May-99 - BD make return valid values for 24-bit (decomposed) color
	28-Jan-99 - BD handle device with less than 9 colors.
	14-Dec-98 - BD allow COLOR input to be an integer from 0-8.
		        Return index of 0 when color not found in table.
	04-Dec-98 - Bill Davis changed GETCOLORS to load color table, return color
			index, etc.  Colors were added.
       GETCOLORS Written by: David Fanning, 10 February 96.


STRETCHSTEPS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       stretchsteps

 PURPOSE:
       stretch parts of the color tables into steps.

 CATEGORY:
       Colors, Image processing

 CALLING SEQUENCE:
       stretchsteps, Low, High, steps=n [, /CHOP]

 INPUTS:
       Low:    The lowest pixel value to use.  If this parameter is omitted,
               0 is assumed.  Appropriate values range from 0 to the number 
               of available colors-1.

       High:   The highest pixel value to use.  If this parameter is omitted,
               the number of colors-1 is assumed.  Appropriate values range 
               from 0 to the number of available colors-1.

 OPTIONAL INPUTS:
       Gamma:  Gamma correction factor.  If this value is omitted, 1.0 is 
               assumed.  Gamma correction works by raising the color indices
               to the Gamma power, assuming they are scaled into the range 
               0 to 1.
       steps:  number of steps/colors of the resulting color table (default=16)
 KEYWORD PARAMETERS:
       CHOP:   If this keyword is set, color values above the upper threshold
               are set to color index 0.  Normally, values above the upper 
               threshold are set to the maximum color index.

 OUTPUTS:
       No explicit outputs.

 COMMON BLOCKS:
       COLORS: The common block that contains R, G, and B color
               tables loaded by LOADCT, HSV, HLS and others.

 SIDE EFFECTS:
       Image display color tables are loaded.

 RESTRICTIONS:
       Common block COLORS must be loaded before calling stretchsteps.

 PROCEDURE:
       New R, G, and B vectors are created by linearly interpolating
       the vectors in the common block from Low to High.  Vectors in the 
       common block are not changed.

       If NO parameters are supplied, the original color tables are
       restored.

 EXAMPLE:
       Load the STD GAMMA-II color table by entering:

               LOADCT, 5

       Create and display and image by entering:

               TVSCL, DIST(300)

       Now adjust the color table with stretchsteps.  Make the entire color table
       fit in the range 0 to 70 by entering:

               stretchsteps, 0, 70

       Notice that pixel values above 70 are now colored white.  Restore the
       original color table by entering:

               stretchsteps

 MODIFICATION HISTORY:
	26-May-2006 Fixed green & blue switch & get color table rather than
		relying on common block [BD]
	18-Dec-2002 Modified RSI STRETCH.PRO [BD]
       DMS, RSI, Dec, 1983.
       DMS, April, 1987.       Changed common.
       DMS, October, 1987.     For unix.
       DMS, RSI, Nov., 1990.   Added GAMMA parameter.


WHITEOUT

[Previous Routine] [List of Routines]
 NAME:
       whiteout
 PURPOSE:
 	white-out a portion of the color table 
	-- defaults to the 5 lowest locs.
 CATEGORY:
      Colors,  Graphics
 CALLING SEQUENCE:
       IDL> whiteout
 INPUTS:
       NONE  
 KEYWORD PARAMETERS:
    Optional Keywords:
	loc - index within color table to start whiting out (Default=0)
	nlocs - number of locations to whiteout (Default=5
 OUTPUTS:
       NONE (color table changed)
 LIMITATIONS:
	Reloading color table will undo this.
 MODIFICATION HISTORY:
	May-2006 Written by Bill Davis, PPPL


Category: Compound widgets

[List of Routines]


CW_BGROUP3_6

[Next Routine] [List of Routines]
 NAME:
	CW_BGROUP3_6

 PURPOSE:
	CW_BGROUP3_6 is a compound widget that simplifies creating
	a base of buttons. It handles the details of creating the
	proper base (standard, exclusive, or non-exclusive) and filling
	in the desired buttons. Events for the individual buttons are
	handled transparently, and a CW_BGROUP3_6 event returned. This
	event can return any one of the following:
		- The Index of the button within the base.
		- The widget ID of the button.
		- The name of the button.
		- An arbitrary value taken from an array of User values.

 CATEGORY:
	Compound widgets.

 CALLING SEQUENCE:
		Widget = CW_BGROUP3_6(Parent, Names)

	To get or set the value of a CW_BGROUP3_6, use the GET_VALUE and
	SET_VALUE keywords to WIDGET_CONTROL. The value of a CW_BGROUP3_6
	is:

		-----------------------------------------------
		Type		Value
		-----------------------------------------------
		normal		None
		exclusive   	Index of currently set button
		non-exclusive	Vector indicating the position
				of each button (1-set, 0-unset)
		-----------------------------------------------


 INPUTS:
       Parent:		The ID of the parent widget.
	Names:		A string array, containing one string per button,
			giving the name of each button.

 KEYWORD PARAMETERS:

	BUTTON_UVALUE:	An array of user values to be associated with
			each button and returned in the event structure.
	COLUMN:		Buttons will be arranged in the number of columns
			specified by this keyword.
	EVENT_FUNCT:	The name of an optional user-supplied event function 
			for buttons. This function is called with the return
			value structure whenever a button is pressed, and 
			follows the conventions for user-written event
			functions.
	EXCLUSIVE:	Buttons will be placed in an exclusive base, with
			only one button allowed to be selected at a time.
	FONT:		The name of the font to be used for the button
			titles. If this keyword is not specified, the default
			font is used.
	FRAME:		Specifies the width of the frame to be drawn around
			the base.
	IDS:		A named variable into which the button IDs will be
			stored, as a longword vector.
	LABEL_LEFT:	Creates a text label to the left of the buttons.
	LABEL_TOP:	Creates a text label above the buttons.
	MAP:		If set, the base will be mapped when the widget
			is realized (the default).
	NONEXCLUSIVE:	Buttons will be placed in an non-exclusive base.
			The buttons will be independent.
	NO_RELEASE:	If set, button release events will not be returned.
	RETURN_ID:	If set, the VALUE field of returned events will be
			the widget ID of the button.
	RETURN_INDEX:	If set, the VALUE field of returned events will be
			the zero-based index of the button within the base.
			THIS IS THE DEFAULT.
	RETURN_NAME:	If set, the VALUE field of returned events will be
			the name of the button within the base.
	ROW:		Buttons will be arranged in the number of rows
			specified by this keyword.
	SCROLL:		If set, the base will include scroll bars to allow
			viewing a large base through a smaller viewport.
	SET_VALUE:	The initial value of the buttons. This is equivalent
			to the later statement:

			WIDGET_CONTROL, widget, set_value=value

	SPACE:		The space, in pixels, to be left around the edges
			of a row or column major base. This keyword is
			ignored if EXCLUSIVE or NONEXCLUSIVE are specified.
	UVALUE:		The user value to be associated with the widget.
	XOFFSET:	The X offset of the widget relative to its parent.
	XPAD:		The horizontal space, in pixels, between children
			of a row or column major base. Ignored if EXCLUSIVE
			or NONEXCLUSIVE are specified.
	XSIZE:		The width of the base. 
	X_SCROLL_SIZE:	The width of the viewport if SCROLL is specified.
	YOFFSET:	The Y offset of the widget relative to its parent.
	YPAD:		The vertical space, in pixels, between children of
			a row or column major base. Ignored if EXCLUSIVE
			or NONEXCLUSIVE are specified.
	YSIZE:		The height of the base. 
	Y_SCROLL_SIZE:	The height of the viewport if SCROLL is specified.

 OUTPUTS:
       The ID of the created widget is returned.

 SIDE EFFECTS:
	This widget generates event structures with the following definition:

		event = { ID:0L, TOP:0L, HANDLER:0L, SELECT:0, VALUE:0 }

	The SELECT field is passed through from the button event. VALUE is
	either the INDEX, ID, NAME, or BUTTON_UVALUE of the button,
	depending on how the widget was created.

 RESTRICTIONS:
	Only buttons with textual names are handled by this widget.
	Bitmaps are not understood.

 MODIFICATION HISTORY:
	15 June 1992, AB
	7 April 1993, AB, Removed state caching.


CW_PDLIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	CW_PDList

 PURPOSE:
	A compound widget that simplifies creating
	pulldown menus. It has a simpler interface than the XPDMENU
	procedure, which it is intended to replace. Events for the
	individual buttons are handled transparently, and a CW_PDList
	event returned. This event can return any one of the following:
               - The Index of the button within the base.
               - The widget ID of the button.
               - The name of the button.
		- The fully qualified name of the button. This allows
		  different sub-menus to contain buttons with the same
		  name in an unambiguous way.


 CATEGORY:
	Compound widgets.

 CALLING SEQUENCE:
	widget = CW_PDList(Parent, Desc)

 INPUTS:
       Parent:	The ID of the parent widget.
	Desc:	An array of strings or structures.  Each element contains
		a menu description with two fields, a flag field, and
		the name of the item.  If a structure, each element
		is defined as follows:
			{ CW_PDList_S, flags:0, name:'' }

		The name tag gives the name of button. The flags
		field is a two-bit bitmask that controls how the button is
		interpreted:

		    Value	   Meaning
		    -------------------------------------------
		     0     This button is neither the beginning
			   nor the end of a pulldown level.
		     1     This button is the root of a
                          sub-pulldown menu. The sub-buttons
			   start with the next button.
		     2     This button is the last button at the
			   current pulldown level. The next button
			   belongs to the same level as the current
			   parent button.
			   If none or empty string is specified as a
			   the name, the button is not created, but
			   the next button belongs to the upward level.
		     3     This button is the root of a sub-pulldown
			   menu, but it is also the last entry of
			   the current level.
		     4     Same as 0, above, except that this button will
			   be preceeded by a separator as with the SEPARATOR
			   keyword to WIDGET_BUTTON.
		     5     Same as 1, above, except that this button will
			   be preceeded by a separator.
		     6     Same as 2, above, except that this button will
			   be preceeded by a separator.
		     7     Same as 3, above, except that this button will
			   be preceeded by a separator.

	If Desc is a string, each element contains the flag field
	followed by a backslash character, followed by the menu item's
	contents.  See the example below.

	EVENT PROCEDURES:  An event procedure may be specified for an
	element and all its children, by including a third field
	in Desc, if Desc is a string array.  Events for buttons without
	an event procedure, are dispatched normally.
	See the example below.

 KEYWORD PARAMETERS:
	DELIMITER:        The character used to separate the parts of a
			  fully qualified name in returned events. The
			  default is to use the '.' character.
	FONT:		  The name of the font to be used for the button
			  titles. If this keyword is not specified, the
			  default font is used.
	HELP:		  If MBAR is specified and one of the buttons on the
			  menubar has the label "help" (case insensitive) then
			  that button is created with the /HELP keyword to
			  give it any special appearance it is supposed to
			  have on a menubar. For example, Motif expects
			  help buttons to be on the right.
	IDS:		  A named variable into which the button IDs will
			  be stored as a longword vector.
	MBAR:		  if constructing a menu-bar pulldown, set this
			  keyword.  In this case, the parent must be the 
			  widget id of the menu bar of a top-level base,
			  returned by WIDGET_BASE(..., MBAR=mbar).
	RETURN_ID:	  If present and non-zero, the VALUE field of returned
			  events will be the widget ID of the button.
	RETURN_INDEX:	  If present and non-zero, the VALUE field of returned
			  events will be the zero-based index of the button
			  within the base. THIS IS THE DEFAULT.
	RETURN_NAME:	  If present and non-zero, the VALUE field of returned
			  events will be the name of the selected button.
	RETURN_FULL_NAME: If present and non-zero, the VALUE field of returned
               	  events will be the fully qualified name of the
			  selected button. This means that the names of all
			  the buttons from the topmost button of the pulldown
			  menu to the selected one are concatenated with the
			  delimiter specified by the DELIMITER keyword. For
			  example, if the top button was named COLORS, the
			  second level button was named BLUE, and the selected
			  button was named LIGHT, the returned value would be

			  COLORS.BLUE.LIGHT

			  This allows different submenus to have buttons with
			  the same name (e.g. COLORS.RED.LIGHT).
	UVALUE:		  The user value to be associated with the widget.
       UNAME:            The user name to be associated with the widget.
	XOFFSET:	  The X offset of the widget relative to its parent.
	YOFFSET:	  The Y offset of the widget relative to its parent.

 OUTPUTS:
       The ID of the top level button is returned.

 SIDE EFFECTS:
	This widget generates event structures with the following definition:

		event = { ID:0L, TOP:0L, HANDLER:0L, VALUE:0 }

	VALUE is either the INDEX, ID, NAME, or FULL_NAME of the button,
	depending on how the widget was created.

 RESTRICTIONS:
	Only buttons with textual names are handled by this widget.
	Bitmaps are not understood.

 EXAMPLE:
	The following is the description of a menu bar with two buttons,
	"Colors" and "Quit". Colors is a pulldown containing the colors
	"Red", "Green", Blue", "Cyan", and "Magenta". Blue is a sub-pulldown
	containing "Light", "Medium", "Dark", "Navy", and "Royal":

		; Make sure CW_PDList_S is defined
		junk = { CW_PDList_S, flags:0, name:'' }

		; The description
		desc = [ { CW_PDList_S, 1, 'Colors' }, $
			     { CW_PDList_S, 0, 'Red' }, $
			     { CW_PDList_S, 0, 'Green' }, $
			     { CW_PDList_S, 5, 'Blue\BLUE_EVENT_PROC' }, $
			         { CW_PDList_S, 0, 'Light' }, $
			         { CW_PDList_S, 0, 'Medium' }, $
			         { CW_PDList_S, 0, 'Dark' }, $
			         { CW_PDList_S, 0, 'Navy' }, $
			         { CW_PDList_S, 2, 'Royal' }, $
			       { CW_PDList_S, 4, 'Cyan' }, $
			       { CW_PDList_S, 2, 'Magenta\MAGENTA_EVENT_PROC' }, $
			 { CW_PDList_S, 2, 'Quit' } ]

	The same menu may be defined as a string by equating the Desc parameter
	to the following string array:
	
	desc =[ '1\Colors' , $
		'0\Red' , $
		'0\Green' , $
		'5\Blue\BLUE_EVENT_PROC' , $
		'0\Light' , $
		'0\Medium' , $
		'0\Dark' , $
		'0\Navy' , $
		'2\Royal' , $
		'4\Cyan' , $
		'2\Magenta\MAGENTA_EVENT_PROC' , $
		'2\Quit'  ]


	The following small program can be used with the above description
	to create the specified menu:


		base = widget_base()
		menu = CW_PDList(base, desc, /RETURN_FULL_NAME)
		WIDGET_CONTROL, /REALIZE, base
		repeat begin
		  ev = WIDGET_EVENT(base)
		  print, ev.value
		end until ev.value eq 'Quit'
		WIDGET_CONTROL, /DESTROY, base
		end

	Note that independent event procedures were specified for
	the multiple Blue buttons (blue_event_proc), and the Magenta button 
	(magenta_event_proc).

 MODIFICATION HISTORY:
	18 June 1992, AB
	16 Jan 1995, DMS, Added MBAR keyword, event procedures,
			and menu descriptor strings.
	2 July 1995, AB, Added HELP keyword.
	3 September 1996, LP, Added button-less end of current level
	Apirl, 2003 copied from CW_PDMENU. added xsize & event_pro keywords.
		    setting showSelection keyword will cause the menu
		    selection to be displayed as the title of the button [BD]


CW_PDMENU

[Previous Routine] [List of Routines]
 NAME:
	CW_PDMENU

 PURPOSE:
	CW_PDMENU is a compound widget that simplifies creating
	pulldown menus. It has a simpler interface than the XPDMENU
	procedure, which it is intended to replace. Events for the
	individual buttons are handled transparently, and a CW_PDMENU
	event returned. This event can return any one of the following:
               - The Index of the button within the base.
               - The widget ID of the button.
               - The name of the button.
		- The fully qualified name of the button. This allows
		  different sub-menus to contain buttons with the same
		  name in an unambiguous way.


 CATEGORY:
	Compound widgets.

 CALLING SEQUENCE:
	widget = CW_PDMENU(Parent, Desc)

 INPUTS:
       Parent:	The ID of the parent widget.
	Desc:	An array of strings or structures.  Each element contains
		a menu description with two fields, a flag field, and
		the name of the item.  If a structure, each element
		is defined as follows:
			{ CW_PDMENU_S, flags:0, name:'' }

		The name tag gives the name of button. The flags
		field is a two-bit bitmask that controls how the button is
		interpreted:

		    Value	   Meaning
		    -------------------------------------------
		     0     This button is neither the beginning
			   nor the end of a pulldown level.
		     1     This button is the root of a
                          sub-pulldown menu. The sub-buttons
			   start with the next button.
		     2     This button is the last button at the
			   current pulldown level. The next button
			   belongs to the same level as the current
			   parent button.
			   If none or empty string is specified as a
			   the name, the button is not created, but
			   the next button belongs to the upward level.
		     3     This button is the root of a sub-pulldown
			   menu, but it is also the last entry of
			   the current level.
		     4     Same as 0, above, except that this button will
			   be preceeded by a separator as with the SEPARATOR
			   keyword to WIDGET_BUTTON.
		     5     Same as 1, above, except that this button will
			   be preceeded by a separator.
		     6     Same as 2, above, except that this button will
			   be preceeded by a separator.
		     7     Same as 3, above, except that this button will
			   be preceeded by a separator.

	If Desc is a string, each element contains the flag field
	followed by a backslash character, followed by the menu item's
	contents.  See the example below.

	EVENT PROCEDURES:  An event procedure may be specified for an
	element and all its children, by including a third field
	in Desc, if Desc is a string array.  Events for buttons without
	an event procedure, are dispatched normally.
	See the example below.

 KEYWORD PARAMETERS:
	DELIMITER:        The character used to separate the parts of a
			  fully qualified name in returned events. The
			  default is to use the '.' character.
	FONT:		  The name of the font to be used for the button
			  titles. If this keyword is not specified, the
			  default font is used.
	HELP:		  If MBAR is specified and one of the buttons on the
			  menubar has the label "help" (case insensitive) then
			  that button is created with the /HELP keyword to
			  give it any special appearance it is supposed to
			  have on a menubar. For example, Motif expects
			  help buttons to be on the right.
	IDS:		  A named variable into which the button IDs will
			  be stored as a longword vector.
	MBAR:		  if constructing a menu-bar pulldown, set this
			  keyword.  In this case, the parent must be the 
			  widget id of the menu bar of a top-level base,
			  returned by WIDGET_BASE(..., MBAR=mbar).
	RETURN_ID:	  If present and non-zero, the VALUE field of returned
			  events will be the widget ID of the button.
	RETURN_INDEX:	  If present and non-zero, the VALUE field of returned
			  events will be the zero-based index of the button
			  within the base. THIS IS THE DEFAULT.
	RETURN_NAME:	  If present and non-zero, the VALUE field of returned
			  events will be the name of the selected button.
	RETURN_FULL_NAME: If present and non-zero, the VALUE field of returned
               	  events will be the fully qualified name of the
			  selected button. This means that the names of all
			  the buttons from the topmost button of the pulldown
			  menu to the selected one are concatenated with the
			  delimiter specified by the DELIMITER keyword. For
			  example, if the top button was named COLORS, the
			  second level button was named BLUE, and the selected
			  button was named LIGHT, the returned value would be

			  COLORS.BLUE.LIGHT

			  This allows different submenus to have buttons with
			  the same name (e.g. COLORS.RED.LIGHT).
	UVALUE:		  The user value to be associated with the widget.
       UNAME:            The user name to be associated with the widget.
	XOFFSET:	  The X offset of the widget relative to its parent.
	YOFFSET:	  The Y offset of the widget relative to its parent.

 OUTPUTS:
       The ID of the top level button is returned.

 SIDE EFFECTS:
	This widget generates event structures with the following definition:

		event = { ID:0L, TOP:0L, HANDLER:0L, VALUE:0 }

	VALUE is either the INDEX, ID, NAME, or FULL_NAME of the button,
	depending on how the widget was created.

 RESTRICTIONS:
	Only buttons with textual names are handled by this widget.
	Bitmaps are not understood.

 EXAMPLE:
	The following is the description of a menu bar with two buttons,
	"Colors" and "Quit". Colors is a pulldown containing the colors
	"Red", "Green", Blue", "Cyan", and "Magenta". Blue is a sub-pulldown
	containing "Light", "Medium", "Dark", "Navy", and "Royal":

		; Make sure CW_PDMENU_S is defined
		junk = { CW_PDMENU_S, flags:0, name:'' }

		; The description
		desc = [ { CW_PDMENU_S, 1, 'Colors' }, $
			     { CW_PDMENU_S, 0, 'Red' }, $
			     { CW_PDMENU_S, 0, 'Green' }, $
			     { CW_PDMENU_S, 5, 'Blue\BLUE_EVENT_PROC' }, $
			         { CW_PDMENU_S, 0, 'Light' }, $
			         { CW_PDMENU_S, 0, 'Medium' }, $
			         { CW_PDMENU_S, 0, 'Dark' }, $
			         { CW_PDMENU_S, 0, 'Navy' }, $
			         { CW_PDMENU_S, 2, 'Royal' }, $
			       { CW_PDMENU_S, 4, 'Cyan' }, $
			       { CW_PDMENU_S, 2, 'Magenta\MAGENTA_EVENT_PROC' }, $
			 { CW_PDMENU_S, 2, 'Quit' } ]

	The same menu may be defined as a string by equating the Desc parameter
	to the following string array:
	
	desc =[ '1\Colors' , $
		'0\Red' , $
		'0\Green' , $
		'5\Blue\BLUE_EVENT_PROC' , $
		'0\Light' , $
		'0\Medium' , $
		'0\Dark' , $
		'0\Navy' , $
		'2\Royal' , $
		'4\Cyan' , $
		'2\Magenta\MAGENTA_EVENT_PROC' , $
		'2\Quit'  ]


	The following small program can be used with the above description
	to create the specified menu:


		base = widget_base()
		menu = cw_pdmenu(base, desc, /RETURN_FULL_NAME)
		WIDGET_CONTROL, /REALIZE, base
		repeat begin
		  ev = WIDGET_EVENT(base)
		  print, ev.value
		end until ev.value eq 'Quit'
		WIDGET_CONTROL, /DESTROY, base
		end

	Note that independent event procedures were specified for
	the multiple Blue buttons (blue_event_proc), and the Magenta button 
	(magenta_event_proc).

 MODIFICATION HISTORY:
	18 June 1992, AB
	16 Jan 1995, DMS, Added MBAR keyword, event procedures,
			and menu descriptor strings.
	2 July 1995, AB, Added HELP keyword.
	3 September 1996, LP, Added button-less end of current level
	Apirl, 2003 added xsize & event_pro keywords. [BD]
	July, 2003 removed setting ids in structure in UVALUE


Category: Database

[List of Routines]


CREATE_LOCUS_TABLE

[Next Routine] [List of Routines]
 NAME:
       create_locus_table
 PURPOSE:
       Create a table in the Locus database following the convention
	of data columns named xx0, xx1, xx2, etc.
 CATEGORY:
       Database, SQL
 CALLING SEQUENCE:
       IDL> create_locus_table, table, nvars
 INPUTS:
	table - table name to create in Locus database
	nvars - number of variable in table (not counting shot & times)
 KEYWORD PARAMETERS:
    Optional Inputs:
	database - if not present, will default to 'locus'
	columns - if not present, will be named 'xx0', 'xx1', 'xx2', etc. as needed
		  by Locus. These are in addition to the required columns, shot, time, etc.
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	status - if odd, then success
 OUTPUTS:
       
 EXAMPLE:  
	IDL> create_locus_table, 'metals', 7
    or
	IDL> columns=['Zn','Ar','Li','Al','C']
	IDL> create_locus_table, 'metals', n_elements(columns), columns=columns

 NOTES:
    You need to have permission to create tables in the database
    (else send email to dbadmin). 
    You will need a file called locus.sybase_login in your home 
    directory -- it can be created with commands similar to those in
    /p/nstxusr/util/setup/mkmdsplusdbfile.csh
 MODIFICATION HISTORY:
       19-Oct-2009 Written by Bill Davis, PPPL


DB_COLUMNS

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
	db_columns

  PURPOSE:
	list database tables and columns in which the column name 
	contains a string.

  CATEGORY:
	Database

  USE: 
       IDL> info = db_columns( wildCard='te')
    or IDL> info = db_columns( 'te', /print)

  KEYWORDS:
	wildCard - string to match 
		  (do not include *'s or other wildcard strings)
	dataBase - database to search. Defaults to nstxlogs.
	print	 - if set, will print tables and columns fitting criteria

  WRITTEN Oct-2002 by Bill Davis


DB_LIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       db_list
 PURPOSE:
       List info from an NSTX Database Table; especially to be displayed
	in output from a Web Tool database, like 
	http://nstx.pppl.gov/nstx/Software/WebTools/searchefitdb.html.
	Searches from a database will be MUCH faster than from MDSplus trees.
 CATEGORY:
       Database, NSTX, Web Tools
 CALLING SEQUENCE:
       IDL> db_list, shot1=shot1, shot2=shot2, runID=runID,  $
		rundate=rundate, username=username,  $
		str1=str1, str2=str2, str3=str3, logical1=logical1, logical2=logical2, $
		database=database, include=include, outFile=outFile
 INPUTS:
	(none required)
 KEYWORD PARAMETERS:
   (all optional)
       shot1 - beginning shot, e.g., 120200
	shot2 - ending shot (if missing, will just search 100 shots before shot1) 
	database - database to query; defaults to 'NSTXLOGS'
	table - table in database to query; defaults to 'EFIT02'
	outFile - string (if not present, data listed to screen)
	_extra - contains all the (arbitrary) parameters for the query. 
		These must be the column names in the table; e.g., gapin1=gapin1
 		qualifiers ending with 1 or 2 are limits for that parameter
 		if value = '*', want to list parameter, but not include in qualifier
 OUTPUTS:
       data to screen or file, if specified. File can be displayed in the calling web page.
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> db_list, shot1=120200		
	IDL> db_list, rundate=20060426	; all shots from Apri. 25, 2006
	IDL> db_list, shot1=120200, shot2=120500, pnbi1=600000
 MODIFICATION HISTORY:
	20-Dec-2007  Written by Bill Davis, PPPL


LOGBOOK_LIST_PLUS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       logbook_list_plus
 PURPOSE:
       List info from the NSTX logbook (to a screen or file)
 CATEGORY:
       Database, NSTX
 CALLING SEQUENCE:
       IDL> logbook_list_plus, shot1=shot1, shot2=shot2, XP=XP,  $
		rundate=rundate, username=username,  $
		str1=str1, str2=str2, str3=str3, logical1=logical1, logical2=logical2, $
		database=database, include=include, outFile=outFile
 INPUTS:
	(none required)
 KEYWORD PARAMETERS:
   (all optional)
	shot1 - beginning shot, e.g., 120200
	shot2 - ending shot (if missing, will just search shot1) 
	XP - Typically the XP #, e.g., 5
	rundate - run date (YYYYMMDD), e.g., 20060426
	username - computer username of person who made the entry, e.g. 'KAYE'
	str1, str2, str3 - strings that must be in the comments for a shot to be included
	logical1, logical2, 'AND' or 'OR' between str1, 2, & 3
	include - if NOT=0 and USERNAME specified then include any entries satisfying 
		other criteria for which TOPIC='PHS OPS' or 'SESSION LEADER'
	database - defaults to 'NSTXLOGS'
	break - if set, lines longer than 72 characters will be broken at an earlier space
	outFile - string (if not present, data listed to screen)
	xsize - horizontal size of plot summary 
	ysize - vertical size of plot summary 
 OUTPUTS:
	data to screen or file, if specified
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> logbook_list_plus, shot1=120200		
	IDL> logbook_list_plus, rundate=20060426	; all shots from April 25, 2006
	IDL> logbook_list_plus, shot1=120200, shot2=130000, username='PAUL'
	IDL> logbook_list_plus, shot1=120200, /verb, /debug, outfile='temp.html'
 MODIFICATION HISTORY:
	29-Jan-2015  moved JPEG directory to /w/nstx.pppl.gov/htdocs/nstx_site.data/Scratch/
		     so it wouldn't get searched from the software web page
	09-Jan-2014  added "lastrundate" keyword, so can get a range of days.
	09-Aug-2013  don't set shot # if blank, but rundate specified.
	11-Jul-2012  make work if just username specified (didn't use %) and allow strings
		     of shot numbers.
	24-Aug-2010  included 'RF' as default entries.
	26-Jul-2010  addes for having checkboxes for topics on weblogplus.html
	15-Jul-2010  made lightning fast by searching subdirectories like 138000s for plot
		     summary files. See mkandmv.pro to make these directories and move files.
	08-Apr-2010  allow pre-existing jpegs to be in subdirectories
	08-Dec-2009  added keywords charsize, xsize, ysize
	14-Jul-2009  Return error if no entries found
	25-Jul-2008  Removed RunID keyword, and added XP [BD]
	10-Jul-2008  Added "order by shot" to query, so all shots shown
	29-Nov-2007  Had to change supersep to wrap long lines
	28-Nov-2007  Written by Bill Davis, PPPL (some code from Josh Stillerman)


LOGBOOK_LIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       logbook_list
 PURPOSE:
       List info from the NSTX logbook (to a screen or file)
 CATEGORY:
       Database, NSTX
 CALLING SEQUENCE:
       IDL> logbook_list, shot1=shot1, shot2=shot2, runID=runID,  $
		rundate=rundate, username=username,  $
		str1=str1, str2=str2, str3=str3, logical1=logical1, logical2=logical2, $
		database=database, include=include, outFile=outFile
 INPUTS:
	(none required)
 KEYWORD PARAMETERS:
   (all optional)
	shot1 - beginning shot, e.g., 120200
	shot2 - ending shot (if missing, will just search shot1) 
	runID - Typically the XP #, e.g., 5
	rundate - run date (YYYYMMDD), e.g., 20060426
	username - computer username of person who made the entry, e.g. 'KAYE'
	str1, str2, str3 - strings that must be in the comments for a shot to be included
	logical1, logical2, 'AND' or 'OR' between str1, 2, & 3
	include - if NOT=0 and USERNAME specified then include any entries satisfying 
		other criteria for which TOPIC='PHS OPS' or 'SESSION LEADER'
	database - defaults to 'NSTXLOGS'
	break - if set, lines longer than 72 characters will be broken at an earlier space
	outFile - string (if not present, data listed to screen)
 OUTPUTS:
	data to screen or file, if specified
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> logbook_list, shot1=120200		
	IDL> logbook_list, rundate=20060426	; all shots from Apri. 25, 2006
	IDL> logbook_list, shot1=120200, shot2=130000, username='PAUL'
 MODIFICATION HISTORY:
	07-Apr-2009  made response better when nothing found
	29-Nov-2007  Had to change supersep to wrap long lines
	28-Nov-2007  Written by Bill Davis, PPPL (some code from Josh Stillerman)


LOGBOOK_OPTIONS (COPIED FROM LOGBOOK_OPTIONS)

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       logbook_options (copied from logbook_options)
 PURPOSE:
       List info from the NSTX logbook (to a screen or file)
 CATEGORY:
       Database, NSTX
 CALLING SEQUENCE:
       IDL> logbook_options, shot1=shot1, shot2=shot2, XP=XP,  $
		rundate=rundate, username=username,  $
		str1=str1, str2=str2, str3=str3, logical1=logical1, logical2=logical2, $
		database=database, include=include, outFile=outFile
 INPUTS:
	(none required)
 KEYWORD PARAMETERS:
   (all optional)
	shot1 - beginning shot, e.g., 120200
	shot2 - ending shot (if missing, will just search shot1) 
	XP - Typically the XP #, e.g., 5
	rundate - run date (YYYYMMDD), e.g., 20060426
	username - computer username of person who made the entry, e.g. 'KAYE'
	str1, str2, str3 - strings that must be in the comments for a shot to be included
	logical1, logical2, 'AND' or 'OR' between str1, 2, & 3
	include - if NOT=0 and USERNAME specified then include any entries satisfying 
		other criteria for which TOPIC='PHS OPS' or 'SESSION LEADER'
	database - defaults to 'NSTXLOGS'
	break - if set, lines longer than 72 characters will be broken at an earlier space
	outFile - string (if not present, data listed to screen)
	xsize - horizontal size of plot summary 
	ysize - vertical size of plot summary 
 OUTPUTS:
	data to screen or file, if specified
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> logbook_options, shot1=120200		
	IDL> logbook_options, rundate=20060426	; all shots from April 25, 2006
	IDL> logbook_options, shot1=120200, shot2=130000, username='PAUL'
	IDL> logbook_options, shot1=120200, /verb, /debug, outfile='temp.html'
 MODIFICATION HISTORY:
	24-Aug-2010  included 'RF' as default entries.
	26-Jul-2010  addes for having checkboxes for topics on weblogplus.html
	15-Jul-2010  made lightning fast by searching subdirectories like 138000s for plot
		     summary files. See mkandmv.pro to make these directories and move files.
	08-Apr-2010  allow pre-existing jpegs to be in subdirectories
	08-Dec-2009  added keywords charsize, xsize, ysize
	14-Jul-2009  Return error if no entries found
	25-Jul-2008  Removed RunID keyword, and added XP [BD]
	10-Jul-2008  Added "order by shot" to query, so all shots shown
	29-Nov-2007  Had to change supersep to wrap long lines
	28-Nov-2007  Written by Bill Davis, PPPL (some code from Josh Stillerman)


SYB_ENTRY

[Previous Routine] [List of Routines]
 NAME: SYB_ENTRY

 PURPOSE : Display/modify/create entries in the NSTX logbook database.

 CATEGORY:
	Database

 CALLING SEQUENCE:  
	IDL> SYB_ENTRY
	IDL> syb_entry, font=find_font(/courier,/bold, size=12)

 KEYWORD PARAMETERS: 
	DEFAULT='save_file' to restore settings.
	FONT = a font
	FSIZE = font size (default=14)
	WARNING - if=0, will not display intial warning of  "RUN_INFO has not been run today"
	INITAL_QUERY - the initial query of the database, e.g. 
		'rundate=20070523 and VOIDED IS NULL'
	        defaults to current user, last day with 
		entries, topic in ('PHYS OPS','SESSION LEADER')) and  VOIDED IS NULL

 LIMITATIONS 

 About

  - ENTRY_DISPLAY is a widget based IDL procedure for
   looking at entries in the LOGBOOK database.  Its primary
   purpose is to display an up-to-date set of logbook entries
   during a run.

   The user specified the record selection criteria

   (Options->Display Options).  Whenever a new logbook
   entry is made, the display is automatically updated to
   include the new record(s) if they meet the criteria 
   (unless one is in a blocking entry widget).

   This tool allows the user to create new logbook entries.
   Chose 'Make Final Entry' from the Entry menu.

   In addition this tool can be used to void and edit
   existing logbook entries.  Select part of an entry in
   main display, and then choose 'Edit Entry' or
   'Void Entry' from the Entry menu.
   NOTE:  you may only void or edit entries which you have
          entered into the database! Send email to dbadmin to have other 
	   entries changed.
 
 NOTES
   To get a white background on text, you need certain commands in a .Xresources
   file. You can have these loaded under the file menu in syb_entry.

   use add_topic_logbook.pro to add topics. 

   to void a topic:
	IDL> cmd = "DELETE FROM topics WHERE topic='BOLOMETERS'"
	IDL> count = DSQL(cmd, stat=stat)

 MODIFICATION HISTORY:
	10-Oct-2013 fill in rundate automatically for entries when shot entered
	02-Aug-2010 added timer to refresh every n seconds (DEFAULT=60)
	04-Jun-2010 increased default max rows to 300
	02-Apr-2010 added help on pattern matching syntax
	12-Mar-2009 use common to pass display options, because structures 
		    within structures have bugs, and are too convoluted. [BD]
	02-Oct-2008 only do an mdsconnect if mds_event_server not defined.
	20-May-2008 fixed Make Entry Options.
	12-May-2008 calling mdssetevent breaks the connection needed for the widget to 
		    recognize events, so now just spawn "setevent".
		    Requires that environmental variable mds_event_target be set.
		    (e.g. to birch.pppl.gov:8501) Tidied up several other issues
		    like consistancy of "Auto Updates" checkbox.
	27-Jul-2007 Added WARNING and INITIAL_QUERY keywords.
		    Added UPDATE button to MAKE_ENTRY widget, so entries can be made
		    in steps. Help added to CUSTOM QUERY window to aid searches.
	02-May-2007 changed default printing to your default printer. Added debug printing
	30-Apr-2007 fixed auto updates on Linux
	09-Apr-2007 Get Current shot from MDSplus, rather getting the largest
		    shot number from the database [BD]
	05-Mar-2007 Allow text with special characters 
		    ('%', '^', '$', '*', '@', '#', '(', '!', ')', '?', ';') to go 
		    into the logbook.
		    added some color buttons. [BD]
	22-Jan-2007 Make sure connect to an event server (default to europa:8501).
	18-Jul-2005 change !version.os to !version.os_family to pick up linux
	05-Mar-2004 Upon startup update the screen with a query [BD]
	02-Mar-2004 Font keyword added, and changed options to ascending order and
		    auto scroll = off (Bill Davis)
       Josh Stillerman 9/20/96  initial version
       Lew Randerson 1999-11-04 Convert from ENTRY_DISPLAY to SYB_ENTRY by 
                                  mimicking Stan Kaye's mods to create VMS SYB_ENTRY
                                ... Convert entry_display to syb_entry (*** default file = $HOME/SybEntry.dat ***)
                                                                       (*** strayed from sk default file handling ***)
                                ... Add GetCurrentDate
       Lew Randerson 1999-11-08 Change 'logbook' to 'nstxlogs'
       Lew Randerson 1999-11-16 Check for os when handling print options
	Lew Randerson 1999-11-17 Add event handling stuff
	Lew Randerson 2000-01-11 Fix typo in get_entry_text parameters
	Lew Randerson 2000-01-11 Put back 'RUN_INFO' check
	Lew Randerson 2000-01-11 Handle unix printing
                                Check hand.key exists


Category: Dates

[List of Routines]


ADDDATE

[Next Routine] [List of Routines]
 NAME:
       addDate
 PURPOSE:
       Add days to a date. Tries to return string in same form as input
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       newDate = addDate(date, ndays)
 INPUTS:
       date = date string, e.g., '6/17/1951', '1951/6/17', or 19510617    
         17 Jun, 1951     Jun 17 1951   1951 Jun 17
         17/Jun/85   17-Jun-1951   85-Jun-17   17 June, 1951.
	nDays - number of days to add (negative number OK)
 KEYWORD PARAMETERS:
	JULIAN - if set, return as Julian day
	LONGYEAR - if set, return year as 4-digits 
 OUTPUTS:
       newDate = Returned date string
 EXAMPLES:
	IDL> print, addDate('6/17/1951', 13)
	06/30/1951

	IDL> print, addDate('June 17, 1951', 13)
	June 30, 1951

	IDL> print, addDate('6/17/51', 365)
	06/16/52				

	IDL> print, addDate('6-17-1951', -30)
	05-18-1951

	IDL> print, addDate('17-Jun-1951', -30)
	18-May-1951

	IDL> print, addDate('20110520', -30)
	20110420

	IDL> print, adddate(systime(),-2)
	28 Jun 11

 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	20-May-2011 fix for longdates
	19-Feb-2010 add LONGYEAR keyword so 4-digit year returned
	17-Aug-2009 Written by Bill Davis


DATE2JD

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       DATE2JD
 PURPOSE:
       Convert a date string to Julian Day number.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       jd = date2jd(date)
 INPUTS:
       date = date string, e.g., '6/17/1951', '1951/6/17', or 19510617    
 KEYWORD PARAMETERS:
 OUTPUTS:
       jd = Returned Julian Day number.   out
 COMMON BLOCKS:
 NOTES:
       Note: date must contain month as a name of 3 or more leeters.
 MODIFICATION HISTORY:
	18-Aug-2009 return 0 if date blank
	12-Feb-2008 handle input date of form 19510617 (yyymmdd)
	27-Nov-2006 Handle date of form 2006/4/28 [Bill Davis, PPPL]
       R. Sterner, 1996 Sep 15

 Copyright (C) 1996, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


DATE2YMD

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       DATE2YMD
 PURPOSE:
       Date text string to the numbers year, month, day.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       date2ymd,date,y,m,d, dateString=dateString
 INPUTS:
       date = date string.             in
 KEYWORD PARAMETERS:
	dateString - (OPTIONAL OUTPUT) of form yyyymmdd (e.g., 20030613)
 OUTPUTS:
       y = year number.                out
       m = month number.               out
       d = day number.         out
 COMMON BLOCKS:
 NOTES:
       Notes: The format of the date is flexible except that the
         month must be month name.
         Dashes, commas, periods, or slashes are allowed.
         Some examples: 23 sep, 1985     sep 23 1985   1985 Sep 23
         23/SEP/85   23-SEP-1985   85-SEP-23   23 September, 1985.
         Doesn't check if month day is valid. Doesn't
         change year number (like 86 does not change to 1986).
         Dates may have only 2 numeric values, year and day. If
         both year & day values are < 31 then day is assumed first.
         systime() can be handled: date2ymd,systime(),y,m,d
         For invalid dates y, m and d are all set to -1.
 MODIFICATION HISTORY:
   29-Jul-2011 handle strings like 7/25/2011-04:46:0-6.538
   12-Feb-2008 handle input date of form 19510617 (yyymmdd)
   17-Apr-2006 - added keyword longDate for return of 20051014.
   14-Oct-2005 - fix to allow dates like 10/14/2005
   13-Jun-2003 - added keyword output of composite string of form
   		    yyyymmdd (e.g., 20030613)
   R. Sterner, 1994 Mar 29 --- Modified to handle arrays.
   RES 18 Sep, 1989 --- converted to SUN.
   25-Nov-1986 --- changed to REPCHR.
   Written by R. Sterner, 29 Oct, 1985.
   Johns Hopkins University Applied Physics Laboratory.

 Copyright (C) 1985, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


FILESHOTDATE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       fileshotdate
 PURPOSE:
       Print time and date of an NSTX shot, but get data from a file
 CATEGORY:
       Dates, MDSplus, Tree Status 
 CALLING SEQUENCE:
       IDL> date = fileshotdate( shot, time=time  )
 INPUTS:
       shot = MDSplus shot number
 KEYWORDS:
    optional output:
	time = time of shot, e.g., 12:25:02.00
 OUTPUT:
	date - e.g., '18-Mar-2010'
 EXAMPLE:
       IDL> date=fileshotdate(136942,time=time)
       IDL> print, date, ' ', time
       18-Mar-2010 13:51:00.00
 COMMON BLOCKS:
       fileshotdate_local
 NOTES:
 LIMITATIONS:
 MODIFICATION HISTORY:
	08-Jul-2013 converted from mdsshotdate by Bill Davis


FILETIME2DBTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       fileTime2dbTime
 PURPOSE:
 	Return times in filetimes format in database format 
 CATEGORY:
	Dates, times
 CALLING SEQUENCE:
       seconds = filetime2dbtime( time )
 INPUTS:
       time - string in military style  '11:04' or '23:59' (no double quotes!)
 KEYWORDS
	addminutes - minutes to add (can be negative, but cannot cross midnight)
 OUTPUT
	time - string with AM or PM after it (no space between). This is the
	       format SQL queries want.
 EXAMPLE: 

	IDL> print,filetime2dbtime( '6:08',addminutes=-10)
	5:58AM
	IDL> print,filetime2dbtime( '13:35')
	1:35PM

 MODIFICATION HISTORY:
 	WRITTEN by 27-Nov-2006 Bill Davis


FROMIDLSECONDS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	fromidlseconds
       
 PURPOSE:
       Convert from IDL-syle time (output from SYSTIME(1),
	to form of '06/14/2004 11:04:52'
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       date_time = fromIdlSeconds( secondsSince )
 INPUTS:
	secondsSince - seconds since 1/1/1970
 KEYWORD PARAMETERS:
	monthString - if set, return dateString as 1-Jan-1970
    optional output:
	datestr - just the date string
 OUTPUTS:
	date_time - string line  '06/14/2004 11:04:52' (no double quotes!)
       
 NOTES:

 EXAMPLE: 
	IDL> print,fromIdlSeconds(1129295443)
	10/14/2005 09:28:10

 MODIFICATION HISTORY:
 	WRITTEN 27-Mar-2009 by Bill Davis


FROMIDLTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	fromidltime
       
 PURPOSE:
       Convert from IDL-syle time (output from SYSTIME(0),
	to form of '06/14/2004 11:04:52'
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       date_time = fromidlTIME( idldatetime )
 INPUTS:
       idldatetime - like Fri Oct 14 09:28:10 2005 (DEFAULTS to now)
 KEYWORD PARAMETERS:
	monthString - if set, return dateString as 1-Jan-1970
    optional output:
	secondsSince - seconds since 1/1/1970
	datestr - just the date string
 OUTPUTS:
	date_time - string line  '06/14/2004 11:04:52' (no double quotes!)
       
 NOTES:

 EXAMPLE: 
	IDL> print,fromidltime('Fri Oct 14 09:28:10 2005')
	10/14/2005 09:28:10

 MODIFICATION HISTORY:

	12-Feb-2008 added secondsSince and monthString keywords
 	WRITTEN 14-Oct-2005 by Bill Davis


GETFILETIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       getfiletime
 PURPOSE:
       return creation date and time of a file
	(not sure atime and ctime are right, for files from a PC)
 CATEGORY:
       Dates, files
 CALLING SEQUENCE:
       IDL> times = getfiletime(files=files)
 INPUT KEYWORDS:
       files - string array of filenames, needed unless list used
       list - alternate way: filename containing a list of files
       dir - if present, is prepended to filenames before finding
       
 KEYWORD PARAMETERS:
	print - if present, will print results
	atime - access time in seconds since 1 January 1970 UTC
	ctime - creation time in seconds since 1 January 1970 UTC 
	mtime - modification time in seconds since 1 January 1970 UTC
 OUTPUTS:
       times - string array of creation date and times of files, 
		e.g., 
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	% /bin/ls -1 * > list.txt
	idl
	IDL> times = getfiletime( list='list.txt',/print )
	camerasbig Tue Oct  2 11:35:37 2007
	cpp Fri Nov  9 16:28:02 2007
	dothis.csh Tue Oct  2 11:33:37 2007
	...
 NOTES:
 MODIFICATION HISTORY:
	03-Mar-2009 added atime, ctime & mtime keywords
       16-Apr-2008 Written by Bill Davis, PPPL


HOURS2TIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       hours2time
 PURPOSE:
 	Return time string like 23:59:05 from floating point hour value
 CATEGORY:
	Dates, times
 CALLING SEQUENCE:
       timeStr = hours2time( hours )
 INPUTS:
       hours - floating pt., from 0-23.9999
 KEYWORDS
    optional outputs:
	hours - integer hours
	minutes - integer minutes
	seconds - floating point seconds
 OUTPUT
	timeStr - string like 23:59:05.123, 03:01:59.777, etc.
 EXAMPLE: 

	IDL> print,hours2time( 3.333333 )
       03:19:59.999
 NOTES:
  	use rgatime2hr() to go the other way

 MODIFICATION HISTORY:
 	07-Jul-2011 WRITTEN by Bill Davis


ISOTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       ISOtime
 PURPOSE:
       Return time in ISO 8601 standard, assuming US East Coast. 
	(handles Daylight Savings time)
 CATEGORY:
       Dates
 CALLING SEQUENCE:
       IDL> timeStr = ISOtime( DateTime )
 INPUTS:
        DateTime - like "06/14/2004 11:04:52"
 KEYWORD PARAMETERS:
       Keywords:
 OUTPUTS:
       timeStr - like 2004-06-14T11:04:52.0-4:00
 COMMON BLOCKS:
       NONE
 EXAMPLE:
   IDL> print,isotime('06/14/2004 11:04:52')
	2004-06-14T11:04:52.0-4:00
 NOTES:
   The ISO standard includes the adjustment to Grenwich Mean Time, so
   you need to know whether Daylight Savings time is in affect.
   This includes routines to find last and first Sunday of a month.
   Assumes no fractions of seconds.
 MODIFICATION HISTORY:
       WRITTEN 19-Jan-2005 by Bill Davis, PPPL


JD2DATE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       JD2DATE
 PURPOSE:
       Convert a Julian Day number to a date string.
 CATEGORY:
	dates
 CALLING SEQUENCE:
       date = jd2date(jd)
 INPUTS:
       jd = Julian Day number.       in
 KEYWORD PARAMETERS:
       Keywords:
         FORMAT = format string.  Allows output date to be customized.
            The following substitutions take place in the format string:
         Y$ = 4 digit year.
         y$ = 2 digit year.
         N$ = full month name.
         n$ = 3 letter month name.
         m$ = 2 digit month number.
         d$ = day of month number.
         0d$ = day of month number as a 2 digit number.
         W$ = full weekday name.
         w$ = 3 letter week day name.
 OUTPUTS:
       date = returned date string.  out
 COMMON BLOCKS:
 NOTES:
       Notes:
         The default format string is 'd$-n$-Y$' giving 24-Sep-1989
         Example: FORMAT='w$ N$ d$, Y$' would give 'Mon 
 MODIFICATION HISTORY:
	17-Aug-2009 added $m option so can get dates like 17-8-2009.
       R. Sterner, 27 Feb, 1991

 Copyright (C) 1991, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


JD2YMD

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       JD2YMD
 PURPOSE:
       Find year, month, day from julian day number.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       jd2ymd, jd, y, m, d, dateString=dateString
 INPUTS:
       jd = Julian day number (like 2447000).     in
 KEYWORD PARAMETERS:
	dateString - (OPTIONAL OUTPUT) of form yyyymmdd (e.g., 20030613)
 OUTPUTS:
       y = year (like 1987).                      out
       m = month number (like 7).                 out
       d = day of month (like 23).                out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	12-Feb-2008 added dateString optional output keyword
       Theo Brauers, 21 Sep, 1997 long loop index i
       R. Sterner, 30 Apr, 1993 --- cleaned up and allowed arrays.
       R. Sterner.  21 Aug, 1986.
       Johns Hopkins Applied Physics Lab.

 Copyright (C) 1986, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


LONG64DATE2STR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       long64date2str
 PURPOSE:
 	Return date from a 64-bit longword, like 1112308040, as returned
	from file_info, in a more conventional format.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       dateString = long64date2str( long64date )
 INPUTS:
       long64date returned from file_info, e.g., 1112308040
 RETURNED:
       dateString - conventional date string, e.g. 02/18/2006
 KEYWORDS
	delim - (string) delimeter used for output (Default is /)
	twoDigitsForYear - if set, year will be last two digits of year
	filetime - time of day of file, e.g. 14:32:59
	year - year of file
	month - numerical month of file
	day - numerical day of file
 EXAMPLES: 

	IDL> print,long64date2str( 1112308040 )
	03/31/2005

	IDL> print,long64date2str( 1112308040, /twoDigitsForYear )
	03/31/05

 MODIFICATION HISTORY:
 	WRITTEN 3-Jan-2007 by Bill Davis


LONGDATE2STR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       longdate2str
 PURPOSE:
 	Return date from a longword, like 20060218, in a more conventional 
	format
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       dateString = longdate2str( longDate )
 INPUTS:
       date in form yyyymmdd, e.g., 20060218
 RETURNED:
       dateString - conventional date string, e.g. 02/18/2006
 KEYWORDS
	delim - (string) delimeter used for output (Default is /)
	twoDigitsForYear - if set, year will be last two digits of year
 EXAMPLES: 

	IDL> print,longdate2str( 20060218 )
	02/18/2006

	IDL> print,longdate2str( 19951229, /twoDigitsForYear )
	12/29/95

 MODIFICATION HISTORY:
 	WRITTEN by 1-May-2006 Bill Davis


MDSSHOTDATE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSshotDate
 PURPOSE:
       Print time and date of an NSTX shot.
 CATEGORY:
       Dates, MDSplus, Tree Status 
 CALLING SEQUENCE:
       IDL> date = MDSshotDate( shot, time=time  )
 INPUTS:
       shot = MDSplus shot number
 KEYWORDS:
    optional output:
	time = time of shot, e.g., 12:25:02
       longDate - returned date in form of yyyymmdd, e.g., 20030613
    optonally returned:
	year
	month
	day
 OUTPUT:
	date - e.g., '11-FEB-2003 15:09:37.60'
 EXAMPLE:
       IDL> date=mdsshotdate(110109,time=time)
       IDL> print, date, ' ', time
       11-FEB-2003 15:09:37.60
 COMMON BLOCKS:
       none
 NOTES:
	This runs fairly quickly, but SQL access is quicker.

	Also see SURVEYDB to quickly see first & last shot of day.
 LIMITATIONS:
 MODIFICATION HISTORY:
	10-Oct-2013 fixed keyword longdate
	22-Apr=2010 added noOpen keyword
	06-Apr-2009 fixed bug with new date format coming from MDSplus & introduced
		    slash keyword, to get date in the form 
	03-Apr-2009 allow for missing value
	14-Jan-2009 Changed node read to be \NSTX::TOP.ACQ_INFO.STATISTICS:STORE_START
	04-Sep-2008 replace openMDSshot with mdsopen
	09-Feb-2004 Added status  (shots before around 104611 don't work)
	03-Jun-02 use \WF::ACQ_START
	03-Oct-00 Written by Bill Davis


MDSTIME2DBTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdsTime2dbTime
 PURPOSE:
 	Convert date & time from MDSplus to database format 
 CATEGORY:
	Dates, times
 CALLING SEQUENCE:
       sqltime = mdsTime2dbTime( time )
 INPUTS:
       time - from MDSplus, e.g. '10-MAR-2008 09:50:46.36'
 KEYWORDS
 OUTPUT
	sqltime - in SQL format, e.g., Mar 10 2008 09:50AM
 EXAMPLE: 

	IDL> print,mdsTime2dbTime( '10-MAR-2008 09:50:46.36')
	MAR 10 2008 09:50AM

 MODIFICATION HISTORY:
 	WRITTEN by 10-Mar-2008 Bill Davis


MDSTIME2VSTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdsTime2vsTime
 PURPOSE:
 	Convert date & time from MDSplus to Visual Studio format 
 CATEGORY:
	Dates, times
 CALLING SEQUENCE:
       vstime = mdsTime2vsTime( time )
 INPUTS:
       time - from MDSplus, e.g. '10-MAR-2008 09:50:46.36'
 KEYWORDS
 OUTPUT
	vstime - in SQL format, e.g., Mar 10 2008 09:50AM
 EXAMPLE: 

	IDL> print,mdsTime2vsTime( '10-MAR-2008 09:50:46.36')
	MAR 10 2008 09:50AM

 MODIFICATION HISTORY:
 	WRITTEN by G. Zimmer Feb '15


MONTHNAMES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MONTHNAMES
 PURPOSE:
       Returns a string array of month names.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       mnam = monthnames()
 INPUTS:
	monthNum - if present, just the name for this month returned
 KEYWORD PARAMETERS:
	nchars - max number of characters in month names
 OUTPUTS:
       mnam = string array of 13 items:     out
         ['Error','January',...'December']
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	28-Jan-2009 Added nchars keyword
	22-Feb-2006 Added monthNum optional input [BD]
       R. Sterner, 18 Sep, 1989

 Copyright (C) 1989, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


MONTHNUMBER

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       monthnumber
 PURPOSE:
       Returns a month number given a month name.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       monthNum = monthnumber(monthStr)
 INPUTS:
	monthStr - e.g., 'Dec', or 'MAR'
 KEYWORD PARAMETERS:
 OUTPUTS:
       monthNum = number of month, 1-12, or -1 if not found     	out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	09-Jul-2013 made to work with an array
       29-Jan-00 Written by Bill Davis


SHOTATTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	shotAtTime 

 PURPOSE:
	find the NSTX shot number closest to a certain time

 CATEGORY:
       Dates, MDSplus

 CALLING SEQUENCE:
       IDL> shot = MDSshotDate( date, time  )

 INPUTS:
  	date - e.g. '2009/2/10' or '15-Oct-2010'
  	time - e.g.,  '12:13'

 OUTPUT:
	shot - NSTX shot number, probably 6 digits

 NOTES:
	Looks up shot range for the year and then does a binary search to find
	the nearest shot number to the input time.

 EXAMPLE:
   IDL> date='2009/2/10'  & time='12:13'
   IDL> print, shotattime( date, time )
	131441

  31-May-2011 WRITTEN by Bill Davis, PPPL, for Doug Darrow


SHOTSOFFILES

[Previous Routine] [Next Routine] [List of Routines]

 >> TIMES RETURNED FROM FILE_INFO AREN'T CORRECT!!!!!!!!

 NAME:
       shotsOfFiles
 PURPOSE:
       Return MDSplus shots (based on creation time) of files
 CATEGORY:
       dates, MDSplus
 CALLING SEQUENCE:
       IDL> shots = shotsOfFiles( rundate )
 INPUTS:
        files - array of files, or scalar string which may contain wild cards
 KEYWORD PARAMETERS:
   	dates - dates (LONG) of files in YYYYMMDD (e.g., 20061231)
   	times - time of day of file, e.g., 23:59:59
   	seconds - seconds since midnight of time of file creation
   	delta_seconds - time of shot minus time of file creation
   	outfiles - files corresponding to shots out (useful when wild cards used)
   	beforeSeconds - seconds before shot to count as that shot (Default=60)
   	verbose - if set, will print informational output
 OUTPUTS:
       shots - array of shot numbers associated with files
 EXAMPLE:
   IDL> shots=shotsOfFiles( '*.dat',dates=dates,times=times,out=outfiles )

   IDL> d=read_cih(filename, shot=120337, filedate=filedate2,filetime=filetime2)
   IDL> print,shotsoffiles( filename)
 NOTES:

   On Windows, in IDL v. 6.2 and before, when running during Daylight Savings time,
   for files created before DST, use keyword addSeconds=-3600

 MODIFICATION HISTORY:
       31-Mar-2006 Written by Bill Davis, PPPL


TIME2SEC

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       time2Sec
 PURPOSE:
 	Return seconds since midnight, if no date given. Otherwise, 
	since Jan. 1, 1970.
 CATEGORY:
	Dates, times
 CALLING SEQUENCE:
       seconds = time2Sec( time )
 INPUTS:
       time - string in military style  '11:04' or '23:59' (no double quotes!)
		or '6:08PM'
		or IDL style, like 'Oct 16 2013 12:56:24'
 KEYWORDS
	none
 OUTPUT
	seconds - seconds (double precision) since midnight, if no date given. 
		Otherwise, since Jan. 1, 1970.
 EXAMPLE: 

	IDL> print,time2Sec( '6:08')
       22080.000
	IDL> print,time2Sec( '6:08PM')
       65280.000
	IDL> print,time2Sec( 'Oct 16 2013 12:56:24')
	1.3819282e+09

 MODIFICATION HISTORY:
	28-Oct-2013 handle array input, and do since 1970, if date specified
 	WRITTEN by 03-Mar-2009 Bill Davis


TIMESOFSHOTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       timesofshots

 PURPOSE:
       return dates and times, like 12:26PM, of NSTX shot

 CATEGORY:
       dates, MDSplus

 CALLING SEQUENCE:
       IDL> times = timesofshots( shot1, shot2, dates=dates )
       IDL> times = timesofshots( year=2010, dates=dates )

 INPUTS:
        shot1 - starting shot
	 shot2 - ending shot

 KEYWORD PARAMETERS:
	year - if set, will find the shots for that year
	dates - dates of files in dd-mon-yyyy (e.g., 07-Jul-2007)
   	longDates - dates (LONG) of files in YYYYMMDD (e.g., 20061231)
   	times - time of day of file, e.g., 23:59:59
   	verbose - if set, will print informational output

 OUTPUTS:
   	times - time of day of file, e.g., '12:05PM'
       
 EXAMPLE:
   IDL> times = timesofshots( year=2010, dates=dates, shots=shots, longd=longd )
   IDL> for i=0,4 do print, shots[i], ' ', dates[i], ' ', times[i]
         136730 23-Feb-2010 12:05PM
         136731 23-Feb-2010 12:17PM
         136732 23-Feb-2010 12:23PM
         136733 23-Feb-2010 12:30PM
         136734 23-Feb-2010 12:40PM

 NOTES:
  	you will need database setup done, as for the NSTX logbook. E.g.,
     	source /p/nstxusr/util/setup/mkmdsplusdbfile.csh

 MODIFICATION HISTORY:
  	08-Jul-2013 added year keyword
  	WRITTEN by Bill Davis, 27-Feb-2009


TOIDLTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	toIdlTime
       
 PURPOSE:
       Convert a date string to IDL time (output from SYSTIME(1),
	i.e., seconds since 1/1/1970
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       seconds = TOIDLTIME( date_time )
 INPUTS:
       date_time - string line  '06/14/2004 11:04:52' (no double quotes!)
 KEYWORD PARAMETERS:
 OUTPUTS:
       seconds since 1/1/1970 (type long64)
 NOTES:

 EXAMPLE: 
	IDL> print, systime(0), long64(systime(1))
       Fri Oct 14 09:10:43 2005            1129295443
	IDL> print, toIdlTime('10/14/2005 09:10:43')
            1129295443

       IDL> print, fromIdlSeconds(1129295443)
	10/14/2005 09:10:43

	IDL> print, toIdlTime('20 Jun 11')

 MODIFICATION HISTORY:

	17-Mar-2010 Handle dates like 'Fri Feb  5 17:04:55 2010', and inputs
		    of Julian dates and Long dates (like 20091231)
 	WRITTEN 14-Oct-2005 by Bill Davis


WEEKDAY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       WEEKDAY
 PURPOSE:
       Compute weekday given year, month, day.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       wd = weekday(y,m,d,[nwd])
 INPUTS:
       y, m, d = Year, month, day (Like 1988, 10, 31).      in
 KEYWORD PARAMETERS:
 OUTPUTS:
       wd = Returned name of weekday.                       out
       nwd = optional Weekday number.                       out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
       R. Sterner. 31 Oct, 1988.
       Johns Hopkins University Applied Physics Laboratory.
       RES 18 Sep, 1989 --- converted to SUN

 Copyright (C) 1988, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


YMD2DATE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       YMD2DATE
 PURPOSE:
       Convert from year, month, day numbers to date string.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       date = ymd2date(Y,M,D)
 INPUTS:
       y = year number (like 1986).                         in
       m = month number (1 - 12).                           in
       d = day of month number (1 - 31).                    in
 KEYWORD PARAMETERS:
       Keywords:
         FORMAT = format string.  Allows output date to be customized.
            The following substitutions take place in the format string:
         Y$ = 4 digit year.
         y$ = 2 digit year.
         N$ = full month name.
         n$ = 3 letter month name.
         m$ = 2 digit month number.
         d$ = day of month number.
         0d$ = day of month number with leading 0 if < 10.
         W$ = full weekday name.
         w$ = 3 letter week day name.
	  dateStr - alternate input, like '20070931'
 OUTPUTS:
       date = returned date string (like 24-May-1986).      out
 COMMON BLOCKS:
 NOTES:
       Notes:
         The default format string is 'd$-n$-Y$' giving 24-Sep-1989
         Example: FORMAT='w$ N$ d$, Y$' would give 'Mon 
 MODIFICATION HISTORY:
	19-Mar-2010 fixed bug for $m meaning minutes in called routines
	17-Aug-2009 added $m option so can get dates like 17-8-2009.
	28-NOV-2007 Added DateStr keyword [ Bill Davis, PPPL ]
       ...
       RES 18 Sep, 1989 --- converted to SUN
       R. Sterner.  16 Jul, 1986.
       Johns Hopkins University Applied Physics Laboratory.

 Copyright (C) 1986, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


YMD2JD

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       YMD2JD
 PURPOSE:
       From Year, Month, and Day compute Julian Day number.
 CATEGORY:
	Dates
 CALLING SEQUENCE:
       jd = ymd2jd(y,m,d)
 INPUTS:
       y = Year (like 1987).                    in
       m = month (like 7 for July).             in
       d = month day (like 23).                 in
 KEYWORD PARAMETERS:
 OUTPUTS:
       jd = Julian Day number (like 2447000).   out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
       R. Sterner,  23 June, 1985 --- converted from FORTRAN.
       Johns Hopkins University Applied Physics Laboratory.
       RES 18 Sep, 1989 --- converted to SUN

 Copyright (C) 1985, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


YRMONTHDAY

[Previous Routine] [List of Routines]
 NAME:
       yrmonthday
 PURPOSE:
       Return a string of YYYYMMDD from a date string.
 CATEGORY:
       Dates
 CALLING SEQUENCE:
       IDL> dateNumberString = yrmonthday(dateString)
 INPUTS:
       dateString = date in one of these formats:
			  '7-jun-2001'
			  'Mon Jan 14 15:22:05 2002'
			  '08Aug2002'
			  'Jun 30 2005'
	   (defaults to today) 
 OUTPUTS:
       dateNumberString = 8-character string of numbers:
		YYYYMMDD
 KEYWORDS
	time - returns time like  08:41:55
	year - year number as string
	month - month number as string
	day - day number  as string
 EXAMPLE:
	IDL> print,yrmonthday()
	20020114
	IDL> print,yrmonthday('5-jun-2001')
	20010605
 NOTES:
 MODIFICATION HISTORY:
       19-Nov-2009 fixed bug returning month number
       31-Mar-06 allow form of 'Jun 30 2005' or 'June 30, 2005'
       16-Nov-04 added time keyword
       15-Aug-02 Modified for UNIX date format by Stan Kaye
       15-Jan-02 Allow for 2-digit years
       14-Jan-02 Written by Bill Davis, PPPL


Category: EFIT

[List of Routines]


CALCBTBP

[Next Routine] [List of Routines]
  NAME:
	calcbtbp

  PURPOSE:
	Calculates toroidal and poloidal magnetic field values (Bt & Bp)
	at desired R & Z and desired time by reading data from the EFIT
	(or similar) MDS+ tree. (Bt is also refered to as B-phi.)

  CATEGORY:
       EFIT, LRDFIT

  CALLING SEQUENCE:
	calcbtbp, shot, index, time, Rwant, Zwant, tree=tree, $
                 BpWant=Bp, BtWant=Bt		; returned
  INPUTS:
	shot - NSTX shot number
	index - number of the run, 1,2,... etc. 
	time - time wanted in seconds
	Rwant - Major radius in meters at which Bt & Bp wanted 
	Zwant - Height in meters at which Bt & Bp wanted 

  RETURNED:
    keywords:
	BpWant - Poloidal magnetic field at desired R & Z at desired time
	BtWant - Toroidal magnetic field at desired R & Z at desired time

  EXAMPLE:
      IDL> .r /u/jmenard/idl/efit/math_routines_jem.pro
      IDL> .r efit_routines_jem.pro
      IDL> calcbtbp, 139444, 4, .27, 1.44, 0., BP=Bp, Bt=Bt
	(will see lots of errors for LRDfits)

      IDL> mdsopen,'LRDFIT04', 139444
      IDL> BTAXP = mdsgetsig( '\BTAXP', xaxis=fittime )
      IDL> print, BTAXP( nearesti( fitTime, 0.27 ) )

  NOTES:
	To see what fits are available, you could:
	   IDL> print, fitsrun(shot)
       or
	   IDL> print, bestFitAvail(shot)
  MODIFICATION HISTORY:
  	WRITTEN 19-Jan-2012 by Bill Davis with Stefan Gerhardt's help
		see /u/sgerhard/NSTX/idl/lib/MSERoutines.pro
	Uses many routines from Jon Menard.


EFITMOVIES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	efitmovies

 PURPOSE:
       Plot EFIT field lines, Thomson Scattering Density and Temperature 
	and, optionally, Fast Camera images. Instead of Fast Camera, can
	plot H-alpha (or another) signal vs. time.

 CATEGORY:
       EFIT, Animation, 2-D Plotting, NSTX, Thomson Scattering

 CALLING SEQUENCE:
   for a nice animated display of the latest shot, with a pick-list displayed for movies:
	IDL> efitmovies, /thom, /summary

   for a movie with a camera looking at the RF limiter and the RF power plotted:
	IDL> efitmovies, 'nstx_1_134625.cin', signame='\wf::prf', time=[.05,.45],  $
		         sigt1=0.1, sigt2=.3, maxframes=1000, $
			 /framesOut, QTmovie='NSTX_134625.mov', /verbose

   to see the strike point plot with EFIT:
	IDL> efitmovies,138000,signame='\EFIT02::RVSOUT',/nofc, sigTitle='Strike Point'

   to get a single frame (with camera image):
	IDL> shot=138000
	IDL> efitmovies, shot, time=0.2, /thom, signame='\wf::ip',  $
                        sigt1=0, sigt2=.4

   to get a single frame with just EFIT
	IDL> efitmovies, 136159,time=.2, /noFC

   to get a single frame with flux surfaces on both sides:
       IDL> efitmovies, 121048, time=.2, /double

   to get a single frame with fast camera (determined from dialog box) image on the left:
       IDL> efitmovies, 138000, time=.2, /pick

   to get an IDL Animation Widget, from which you can write an MPEG:
	IDL> efitmovies, 138000, time=[0.05,0.317], /thom, max=40

   to get an animation with H-alpha time trace instead of Fast Camera images:
	IDL> efitmovies,107314, /thom, time=[.05,.5], /noFC, $
			/signame, sigtitle='H-alpha',max=40

    to see limiter camera (with Lithium dropping):
	IDL> efitmovies, '/p/nstxcam/phantom4/NSTX_135060.cin', /thom, time=[.1,.2]

    to see miro camera (would use nstx_2*138000 in 2010):
	IDL> efitmovies, 'miro*135060', /thom, time=[.1,.12], /summary

    for the Open House:
	IDL> efitmovies, 'miro*135260', /thom,/summ, /noEfit, time=[.18, .55],  $
			maxFrames=400, /press, /fahren, /HMODE

    for full rotation, with just 3 contours outside of plasma:
	IDL> efitmovies, 136159,time=.2, /noFC, outlevels=3, /double, /pdf, /emailPsFile

    for zooming into plot for a single frame:
	IDL> efitmovies, 136159,time=.2, /noFC,xmin=.25,xmax=1.25,ymin=-2,ymax=-1

    to make a movie using jmovie:
	IDL> efitmovies, 138497, time=[.1,.5], /thom, /framesOut, /nofc, anim=0, $
			 QTmovie='NSTX_138000.mov'

   to see what shots have fast camera data in the tree:
 	IDL> MDSnodeChanges,'\fc3d',shot1=119120,shot2=119230,tree='cameras',/after

 INPUTS:
       shot = nstx shot number  

 KEYWORD PARAMETERS:
    Keywords:
	noEfit - if set, do not display EFIT contours
	ndups - number of times each frame of movie is duplicated (default=0)
	time - 2-element array for animation; single value for one frame
	thomson - if set, will plot Thomson Te and Ne below EFIT contours
	animate - if set to 0, will plot individual frames instead of movie.
	maxFrames - max # of frames over time range -- necessary if X-memory
		    is limited (default is 200).
	nDecimalTime - # of decimals to display for time (if in seconds)
	pixMap - if set, will not send each frame to the screen (faster)
 	double - plot efit color contours on both sides of center stack
	sigName - if set, will not show Fast Camera images, but this
		  signal vs. time (defaults to \passivespec::BAYC_DALF_HAIFA)
	sigT1 - starting time of signal vs. time plot
	sigT2 - ending time of signal vs. time plot
	sigTitle - if set, will be displayed above sigName plot,
		   else tries to get label from MDSplus
	overlayTe - overlay Thomson Te and Ne, instead of on left and right
	window - starting window number (default=0)
	efitVersion - the efit version to display. Defaults to the highest
			available less than 5.
	LRDfitVersion - the LRDfit version to display. If non-blank, will override
		        efitVersion keyword used.
       Summary - if set will include a plot summary (Ip, Pinj, D-alpha, Wmhd)
	save - if set, create the MPEG file, but don't bring up the widget
	pick - if set, will let you pick from a menu when more than one Fast Camera
		file matches the specification of the first argument
	warning - if set to 0, will not pop dialog up for messages
 OUTPUTS:
       none

 LIMITATIONS:
       Some reds are green on printer.
 NOTES:
 MODIFICATION HISTORY:
	17-Aug-2010 added WARNING keyword so popping dialog windows can be surpressed
	10-Aug-2010 added option to make MPEGs from Eliots Java code that uses jpegs
	13-Jul-2010 fixed auto-save of mpeg files. Default name has whole time range.
		    Improved finding of camera files. Default to showing Fast Camera
		    when SIGNAMES set.
	01-Jul-2010 added group keyword, and pass to XIA so can be destroyed
		    by a calling program, like efitmovieloop.pro
	04-Jun-2010 many improvements when using frames from MDSplus; have interpolated
		    Thomson profiles extend to adjacent EFIT times before and after
	12-May-2010 added nLevels keyword for # of flux contours
	07-Apr-2010 added noEfit option for Masa
	02-Apr-2010 provided for color movies
	16-Mar-2010 fix for selecting file after no data found for input shot
	17-Dec-2009 made to work with Cine files. Include plot summaries.
	02-May-06 added ndups keyword
  	26-Jan-06 No longer e-mail to 'USER' if username not specified. 
		  Tidy up screen message for postscript output
	27-Sep-2005 fix bug for sub-msec timing for single plots
	19-Aug-2005 improve selection of efit version
	17-Jul-2005 Assure black lines on plots
	03-Sep-04 Better logic for missing Thomson data.
	15-Apr-04 Fixed bug for full time with lots of frames
		  made default max frames 200.
	23-Oct-03 Use spline Te and Ne from Thomson
	23-Aug-03 Adds for efitflux.html
	23-May-03 Added keywords for Web Plotting
	01-May-03 Added /double keyword
       28-May-02 Added /signame keyword and overlayTe
	Original written by Dave Gates


EFIT_TIMES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	efit_times

 PURPOSE:
       Return EFIT times in MDSplus for a shot

 CATEGORY:
       EFIT

 CALLING SEQUENCE:
	IDL> etimes = efit_times(shot, tree=tree)

 INPUTS:
       shot = nstx shot number  

 KEYWORD PARAMETERS:
    Keywords:
	tree - defaults to EFIT02, then tries EFIT01.

 RETURNED:
       returns EFIT times in seconds for this shot for particular tree

 LIMITATIONS:
       
 NOTES:
 MODIFICATION HISTORY:
	06-Jul-2015 written by Bill Davis


GETEFIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME: 
     GETEFIT

 PURPOSE: 
    Procedure to get efit data from A0 and G0 file or from MDSPLUS.  This
    can be used as a front end to the usual reada and readg.  It prints
    out a message if the efit data does not occur for the desired value
    of DELTIME.  It does not return any data unless time window
    requirements are met.
    
 CATEGORY:
       EFIT

 CALLING SEQUENCE: 
    getefit, shot, time, aaa, ggg [,DELTIME=DELTIME] $
              [,ERR=ERR] [,MODE=MODE] [,runID=runID]

 INPUTS: 
     shot    shot number
     time    shot time (sec)

 KEYWORDS: 
      DELTIME - maximum allowable time (sec) for the data to deviate from
        	time.  If two values [t0,t1] are input, the time window is from
        	(time - t0) to (time + t1), otherwise, the time window is from
        	(time - t0) to (time + t0).
      ERR - set to 0 for successful return of efit data; a non-zero
            value means there was a problem getting the efit data
      MODE - read a mode parameter, file or mdsplus
      runID - choose EFIT01 (JT snap file) or EFIT02 (MSE snap file) from
              MDSPlus efit data. Default is EFIT01, the non-MSE automatic
              control room EFIT

 OUTPUTS: 
      aaa     structure from reada routine holds data from A0 file
      ggg     structure from readg routine holds data from G0 file
      err     error code returned from reada ok if err=0

 RESTRICTIONS:
     User can specify source of data as MDSPLUS or a file in the current
     directory, or in a directory given by the environment variable
     MY_EFIT_DIR.

 PROCEDURE: 

 CODE TYPE: modeling, analysis, control

 CODE SUBJECT:  operation, edge, rf, transport, equilibrium, other

 EASE OF USE: can be used with existing documentation

 OPERATING SYSTEMS:  UNIX of all flavors

 EXTERNAL CALLS:  READA, READG

 TO TEST: IDL> getefit, 138000, 0.2, aaa, ggg

	   IDL> getefit, 141010, runID='LRDFIT06', 0.2, aaa, ggg

 MODIFICATION HISTORY:
     Created by Gary D. Porter
     1998.10.20:     Allow for data from a file or MDSPLus by G.D. Porter
     1998.11.03:     Change DELTIME check to allow for 2 values by R.A. Jong
     1999.04.01:     Added runID and removed BLESSED optional keywords
     1999.05.06;     Reset aaa.error=1 when our err parameter=1
     2000.01.03;     Change check on aaa.time and ggg.time to accept data if
                     both are in the acceptable time range, when not equal
     2000.10.19;     Do not cd to MY_EFIT_DIR and send message if mode=MDSPLUS
     2001.10.16;     Fix missing time_range flag in readg call (RAJ)
     06-Aug-2010 [BD] adapted for NSTX for Jose Boedo (note EFIT times on NSTX are
		       in seconds, rather than milliseconds)
     27-nov-2012 [BD] added aaa.shot and ggg.shot tags when getting LRDfit trees.


GETSEP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	getsep

 PURPOSE:
	Get the separatrix (last closed flux surface) R & Z values 
	from EFIT or LRDfit for a particular NSTX or CMOD shot. 
	Interpolate surfaces in time. Can also return R & Z
	of limiter interior. Also works for CMOD shots (tree
	opened elsewhere).

 CATEGORY:
       EFIT, 2-D Plotting, NSTX, CMOD

 CALLING SEQUENCE:
	IDL> getsep, shot, outTime, r_edge=r_edge, z_edge=z_edge,	$
		     xLim=xLim, zLim=zLim

 INPUTS:
	shot - shot number for MDSplus call
	outTimes - times desired in seconds 

 KEYWORD PARAMETERS:
    Optional Inputs:
	efitVersion - 1-6. Defaults to "Best Fit"
	LRDfitVersion - alternate to above
	BestFit - (DEFAULT) if set, will call bestFitAvail, which has preference
		 of LRDFIT04, any other LRDFIT, EFIT02, then highest EFIT.
	outer - if set will just return edge values > median value (default)
	inner  - if set will just return edge values <= median value
	interp - if=0, will not interpolate in time (just take nearest time)
	noOpen - if set will not try to open a tree (assumes already open)
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Returned:
	r_edge - r values of separatrix (edge) points
	z_edge - z values of separatrix points
	rLim - r values of limiter points
	zLim - z values of limiter points

  EXAMPLE:
		; get R & Z of separatrix for CMOD shot
	IDL> getsep, 1120224029, 1.08800,   $
		     r_edge=r_edge, z_edge=z_edge,   $
		     /debug

     to get get R & Z data and limiter location:
	IDL> getsep, 135036, .589, R_edge=R, Z_edge=Z,  $
		     rLim=rLim, zLim=zLim


  MODIFICATION HISTORY:
	05-Mar-2014 added interp keyword, so could get specific points
  	WRITTEN Aug-2012 by Bill Davis for Stewart Zweben


HIGHESTEFITRUN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       highestEfitRun
 PURPOSE:
 	find highest efit version run (in the MDSplus tree)
	Checks up to 5, and contigously after that
 CATEGORY:
       EFIT, MDSplus
 CALLING SEQUENCE:
       IDL> run = highestEfitRun(shot)
 INPUTS:
       shot = shot #  
 KEYWORD PARAMETERS:
	FITTYPE= fit type. Defaults to 'EFIT'. Works for 'LRDFIT', too.
	min2Check - will always check up to this number, and contigously
		    after that. E.g. if there is a EFIT05 and EFIT07, 
		    5 will be declared the highest unless this keyword
		    is 6 or higher.
	max2Check - will stop checking at this fit number
 OUTPUTS:
       integer # representing highest EFIT run in tree
 EXAMPLES:
	IDL> print,fitsrun(123001)
	       EFIT01 EFIT02 EFITRT
	IDL> print,highestefitrun(123001)
		2

	IDL> print,fitsrun(117707)
	EFIT01 EFIT02 EFIT03 EFIT06 EFITRT LRDFIT04 LRDFIT06
	IDL> print,highestefitrun(117707)
	       6
	IDL> print,highestefitrun(117707,FIT='LRDFIT')
	       6
 NOTES:
       When the routine is called with no parameters, or with the
	keyword hlp set, help information is printed.
 MODIFICATIONS:
	13-Apr-2010 added max2Check keyword
	29-Aug-2008 make min2check=20 for LRDfit
 	27-Aug-2007 check at least 5 runs. Add keyword for fit type and
			min2Check.
	Aug-2005 Written by Bill Davis


INTERPEDGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	interpEdge

 PURPOSE:
       Interpolate separatrix in time. From EFIT or LRDfit, find R
       and Z values of last closed flux surface (separatrix) for a
       particular NSTX or CMOD shot.  Can also return R & Z of limiter
       interior. Also works for CMOD shots (tree opened elsewhere).

 CATEGORY:
       EFIT, 2-D Plotting, NSTX, CMOD

 CALLING SEQUENCE:
	IDL> interpEdge, shot, outTime, r_edge=r_edge, z_edge=z_edge,	$
			 xLim=xLim, zLim=zLim,  $
			 /plot, /debug

 INPUTS:
       shot - shot number for MDSplus call
	outTimes - times desired in seconds 

 KEYWORD PARAMETERS:
    Optional Inputs:
	efitVersion - 1-6. Defaults to 2
	LRDfitVersion - alternate to above
	BestFit - (DEFAULT) if set, will call bestFitAvail, which has preference
		 of LRDFIT04, any other LRDFIT, EFIT02, then highest EFIT.
	outer - if set will just return edge values > median value
	inner  - if set will just return edge values <= median value
	interp - if=0, will not interpolate in time (just take nearest time)
	noOpen - if set will not try to open a tree (assumes already open)
	plot - if set will plot data
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Returned:
	r_edge - r values of edge points (in meters)
	z_edge - z values of edge points
	xLim - r values of limiter points
	zLim - z values of limiter points

  EXAMPLE:
	IDL> interpEdge, 130376, .2,   $
			 r_edge=r_edge, z_edge=z_edge,	$
			 /plot, /debug

     to get get R & Z data and limiter location:
	IDL> interpEdge, 135036, .589, R_edge=R, Z_edge=Z,  $
			 xLim=xLim, zLim=zLim

	IDL> interpEdge, 1120815021, 1.15, r_edge=Rsep, z_edge=Zsep, /outer, /plot

  IDL> interpEdge, 138846, .615,r_edge=Rsep,z_edge=Zsep,/outer,/plot, /deb

  MODIFICATION HISTORY:
  --------------------
  12-Mar-2014 added fit keyword
  05-Mar-2014 added interp keyword, so could get specific points
  16-Sep-2013 always have noOpen=0 (bug somewhere)
  04-Mar-2013 don't stop if no radii found greater than average
  30-Aug-2012 add MDSconnect for CMOD; do not assume shot is open
  21-Aug-2012 fixed bug for CMOD
  05-Jan-2012 account for time being first dimension in r & z from CMOD EFITs
  21-Dec-2011 added CMOD support
  15-Dec-2011 added outer and inner keywords
  WRITTEN 12-Dec-2011 by Bill Davis


PECOMP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       PECOMP
 PURPOSE:
       Interactively compare PCS and EFIT signals for a shot
 CATEGORY:
       EFIT, PCS
 CALLING SEQUENCE:
       IDL> pecomp, shot=shot
 INPUTS:
       shot = shot number
 KEYWORD PARAMETERS:
       Keywords:
	  print - print rather than display on screen
         data - can pass in data
         xsize
         ysize
         xrange - of plots
         debug
         bigCharSize
 OUTPUTS:
 COMMON BLOCKS:
       NONE
 EXAMPLE:
		; for NSTX:
	IDL> pecomp2010, shot=130000, bigCharSize=3
	
		; for NSTX-U:
	IDL> pecomp, shot=200005, bigCharSize=2, frac=0.6, /debug
 NOTES:
       Use middle mouse button to select zoom region
 MODIFICATION HISTORY:
	30-Apr-2015 more NSTX-U changes for Dan Boyer
	24-Mar-2015 updating for NSTX-U per Stefan Gerhardt.
	18-Jul-2011 fixed bug in SPA plotted times
	14-Jul-2011 added "SPA Current" and "Loop Voltage Diff" buttons
	14-Jul-2011 removed ["RAI_PF4", "\IPF4"] coils plotting, since bombs
	10-Nov-2008 made to work with skylark defs. 
		    don't keep reading data when not there. [BD]
	21-Feb-2008 Added "RAF_FLPPPU4" & "\F_FLPPPU4" per Dennis & Dave
	14-Feb-2008 Add upper-lower loop voltage difference signals per
		    Dennis Mueller [BD]
       04-Feb-2008 add switch to allow using eng_dev tree [Dana Mastrovito]
	21-Jan-2008 Don't do an MDSconnect (use mdsopen instead of 
		    openMDSshot()) [BD]sigs like \pcs.ra:RAB_LSPPGU1

	12-Feb-2007 Always read shot number field before plotting,  so
		     not necessary. Fix recently introduced errors.		    
       Written by Bill Davis, PPPL, for Dave Gates


PLASMAEDGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	plasmaedge

 PURPOSE:
       From EFIT or LRDfit, find R and Z values of last closed flux surface
	(separatrix) for a particular NSTX shot and time. Optionally save to a 
	file.Also will plot limiters and last closed flux surface with axes.  
	Can also return R & Z of limiter interior.

 CATEGORY:
       EFIT, 2-D Plotting, NSTX

 CALLING SEQUENCE:
	IDL> plasmaEdge, shot, time, /plot, /debug

 INPUTS:
       shot = nstx shot number 
	time - time desired in seconds (will pick closest in tree)

 KEYWORD PARAMETERS:
    Optional Inputs:
	efitVersion - 1-6. Defaults to 2
	LRDfitVersion - alternate to above
	BestFit - (DEFAULT) if set, will call bestFitAvail, which has preference
		 of LRDFIT04, any other LRDFIT, EFIT02, then highest EFIT.
	noOpen - if set will not try to open a tree (assumes already open)
	outfile - Defaults to 'PlasmaEdge___ms.txt', unless='NONE'
	limiter - if set, will print R & Z values for limter shell
	plot - if set will plot data
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Returned:
	r_edge - r values of edge points
	z_edge - z values of edge points
	xLim - r values of limiter points
	zLim - z values of limiter points
	actualTime - actual time used, i.e., nearest EFIT or LRDfit time to
		that requested

  EXAMPLE:
	IDL> plasmaEdge, 130376, .589, /plot, /debug

     to get get R & Z data and limiter location:
	IDL> plasmaEdge, 135036, .589, outfile='NONE', R_edge=R, Z_edge=Z,  $
			xLim=xLim, zLim=zLim

  08-Dec-2011 BD added keyword BestFit, and made that the default!
	          default output file to 'NONE'
  WRITTEN 03-Feb-2010 by Bill Davis


PSIINTERP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	psiinterp

 PURPOSE:
       From EFIT or LRDfit, get psi of a flux surface contour at a 
	particular shot and time and R & Z. Then, find the R position of
	that same psi value at Z=0.

 CATEGORY:
       EFIT, 2-D Plotting, NSTX

 CALLING SEQUENCE:
	IDL> PsiWant = psiinterp( shot, time, Rwant=Rwant, Zwant=Zwant )

 INPUTS:
       shot = nstx shot number 
	time - time desired in seconds (will pick closest in tree)

 OUTPUTS:
	PsiWant - psi at Rwant & Zwant

 KEYWORD PARAMETERS:
    Inputs:
	Rwant & Zwant - arrays of R & Z at which Psi is wanted
	efitVersion - 1-6. Defaults to 2 (if not available, the highest of 
			contiguous versions will be used. E.g., if 1,2,5 are 
			available and 3 is requested, 2 will be used).
	LRDfitVersion - alternate to above
	noOpen - if set will not try to open a tree (assumes already open)
	plot - if set will plot data
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Output:
	RatZ0 - R value at Z=0 of Psis at input R & Z
  EXAMPLE:
	IDL> Rwant = findgen(5)/4*0.5 + 1.1
	IDL> Zwant = findgen(5)/4*0.5 + 0.3
	IDL> PsiWant = psiinterp( 135036, .589, Rwant=Rwant, Zwant=Zwant, $
				  RatZ0=RatZ0, /plot, /debug )
       IDL> XYOUTS, RatZ0, 0, 'X', align=center
     to get get R & Z data:
	IDL> PsiWant = psiinterp( 135036, .589, Rwant=1.4, Zwant=0.4 )

  LIMITATIONS:
	Takes the EFIT/LRDfit at the nearest time. Perhaps an interpolation 
	should be done when the desired time is between computed times.

  06-Sep-2013 set /exact in call to followContour (was getting choppy results)
  WRITTEN 12-Feb-2010 by Bill Davis


SEPVSTIME

[Previous Routine] [List of Routines]
 NAME:
  	sepvstime

 PURPOSE:
	Get the separtrix (last closed flux surface) R & Z values 
	vs. time.
       from EFIT or LRDfit for a particular NSTX or CMOD shot. 
	Can also return R & Z of limiter interior. 

 CATEGORY:
       EFIT, NSTX

 CALLING SEQUENCE:
	IDL> sepvstime, shot, trange=trange, Redge=Redge, Zedge=Zedge

 INPUTS:
       shot - shot number for MDSplus call

 KEYWORD PARAMETERS:
    Optional Inputs:
	tRange - range of times desired (defaults to all available)
	fit - fit desired. Default is "best fit"
	outer - if set will just return edge values > median value (default)
	inner  - if set will just return edge values <= median value
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Returned:
	RedgeVsTime - r values of separatrix (edge) points
	ZedgeVsTime - z values of separatrix points
	used_fit -  the fit used
	tFit - times of the fit
	nPerTime - # of good values in corresponding time element of arrays

  EXAMPLE:

     to get get R & Z data:
	IDL> sepvstime, 138847, RedgeVsTime=R, ZedgeVsTime=Z


  MODIFICATION HISTORY:
	14-Oct-2013 allow fit_desired to be 'BEST'
  	WRITTEN 05-Jun-2013 by Bill Davis for Stewart Zweben


Category: EPICS Channel Access Interface

[List of Routines]


CAGETCOUNTANDTYPE

[Next Routine] [List of Routines]
 NAME:
	caGetCountAndType

 PURPOSE:
	This function returns the number of elements and data type of a
       Channel Access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	Status = caGetCountAndType(pvname, count, type)

 INPUTS:
	pvname:	The name of the process variable for which information is to
               be returned.

 OUTPUTS:
	count:  The number of elements in the process variable. This is 1 for
               scalar process variables and more than 1 for arrays.

       type:   This is a 3 element array containing information about the data
               type of the process variable.
               type(0) = Channel access data type as defined in "cadef.h"
               type(1) = EZCA data type as defined in "ezca.h"
               type(2) = IDL/PV-WAVE data type as defined in size()
               These data types are as follows:

               Name    Channel Access      EZCA        IDL/PVWAVE
               String      0                 1             7
               Short       1                 2             2
               Float       2                 4             4
               Enum        3                 2 (short)     2 (short)
               Byte        4                 0             1
               Long        5                 3             3
               Double      6                 5             5

   The function return value of caGetCountAndType is a status value.  The
   status is 0 if the routine was successful (i.e. the process variable exists)
   and non-zero if the routine failed.

 SIDE EFFECTS:
	This routine will cause a Channel Access search to take place if this is
       the first time this process variable has been referenced.

 RESTRICTIONS:
       The channel access data type enum is mapped to EZCA and IDL short
       data types.  However, application programs can use this routine to
       determine if the native channel access data type is enum, and then
       use caGet(pvname, value, /string) to read the string equivalent of the
       process variable. Programs can also use
       caGetEnumStrings(pvname, strings) to read the strings for the all of
       the possible values of an enum process variable.

 PROCEDURE:
	This routine uses ezcaPvToChid() and then ca_element_count() and
       ca_field_type().
       Note that this routine always returns its values "immediately", even
       if it is called between a caStartGroup and caEndGroup.

 EXAMPLE:
       IDL> status = caGetCountAndType('test_mca1.VAL', count, type)
       IDL> print, status
       0                       ; Status = success
       IDL> print, count
       2048                    ; Array with 2048 elements
       IDL> print, type
           5       3       3   ; Long data type
 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGET

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGet

 PURPOSE:
	This function reads the value of a Channel Access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	Status = caGet(pvname, value, /string, max=n)

 INPUTS:
	pvname:	The name of the process variable for which the value is to
               be returned.

 KEYWORD PARAMETERS:
	STRING:	Set this flag to force caGet to return a string, rather than
               a number.  This flag is particularly useful when the native
               channel access data type is ENUM (3), since the string is
               more descriptive than the number.

	MAX:    This keyword parameter is used to limit the number of
               values returned by caGet. caGet normally returns the native
               element count for a process variable. Setting MAX to a
               number less than this will cause caGet to return only the
               first MAX values in the array.

 OUTPUTS:
	value:  The value of the process variable. By default, caGet returns
               "value" with the native data type and number of elements
               of the process variable. It determines this information by
               calling caGetCountAndType().  Note that if caGet is called
               after calling caStartGroup but before calling caEndGroup then
               the IDL variable "value" is created, but will not actually
               contain the data until caEndGroup is called.

       The function return value of caGet is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.  If caGet is called from
       within an asynchronous group then the status return only indicates
       whether the operation was successfully queued.

 COMMON BLOCKS:
       EZCA_COMMON contains a flag (ingroup) which indicates if we
       are currently in an asynchronous group. This routine tests that flag.

 SIDE EFFECTS:
	This routine will causes a channel access search to take place if
       this is the first time this process variable has been referenced. It
       performs a ca_get, unless called as part of an asynchronous group.

 RESTRICTIONS:
       There are two important restrictions which must be kept in mind when
       calling caGet from inside a "group", i.e. after calling caStartGroup
       and before calling caEndGroup.

       1) The IDL "value" variable (i.e. the second parameter
       passed to caGet) must not be "re-used" or deleted before the call to
       caEndGroup. The reason for this is that EZCA has been passed the
       address of this variable as the location in which the data is to be
       copied when caEndGroup is called. Thus, this location must still
       point to a valid memory location when caEndGroup is called.
       If the "value" variable is re-used then IDL's behavior is
       unpredictable, and bus errors/access violations could occur.

       2) When using caGet to read strings, the data type returned will be
       a byte array, rather than a string.  The reason has to do with the
       manner in which IDL passes strings, which requires that EZCA actually
       be passed pointers to byte arrays. When caGet is called outside of a
       group it automatically converts the byte array to a string before
       returning the value. However when caGet is called inside of a group
       it cannot perform this conversion, since it cannot be done until after
       the data is read, which does not occur until caEndGroup is called.
       Thus, it is the user's responsibility to convert the data from a byte
       array to a string after calling caEndGroup. This is done very simply
       with the string() function. For more information see the example below.

 PROCEDURE:
	This routine uses ezcaGet().

 EXAMPLES:
       IDL> ; The following is an example of a single caGet
       IDL> status = caGet('test_mca1.VAL', value)

       IDL> ; The following is an example of a valid grouped operation
       IDL> ; It also shows how to handle strings.
       IDL> caStartGroup
       IDL> status = caGet('test_mca1.VAL', mca_value)
       IDL> status = caGet('test_vme1.DESC', vme_desc) ; This is a string PV
       IDL> status = caEndGroup()
       IDL> vme_desc = string(vme_desc)    ; Convert from byte array to string

       IDL> ; The following is an example of an INVALID grouped operation
       IDL> caStartGroup
       IDL> status = caGet('test_mca1.VAL', mca_value)
       IDL> status = caGet('test_vme1.VAL', vme_value)
       IDL> mca_value=0
       IDL> ; We have redefined mca_value, so the previous location is
       IDL> ; undefined. NO NOT DO THIS!
       IDL> status = caEndGroup()

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETTIMEOUT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetTimeout

 PURPOSE:
	This function returns the value of the EZCA Timeout parameter. This
       value determines the time parameter passed to ca_pend_io() in EZCA.
       In conjunction with the EZCA RetryCount parameter it determines how
       long EZCA will try to connect to a process variable before giving up.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	timeout = caGetTimeout()

 INPUTS:
	None.

 OUTPUTS:
       The function return value of caGetTimeout is the floating point
       value of the EZCA Timeout parameter, in seconds.

 PROCEDURE:
	This routine uses ezcaGetTimeout().

 EXAMPLES:
       IDL> print, caGetTimeout()
       0.0500000

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CASETTIMEOUT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caSetTimeout

 PURPOSE:
	This procedure sets the value of the EZCA Timeout parameter. This
       value determines the time parameter passed to ca_pend_io() in EZCA.
       In conjunction with the EZCA RetryCount parameter it determines how
       long EZCA will try to connect to a process variable before giving up.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caSetTimeout, timeout

 INPUTS:
	Timeout:  The timeout value in seconds (floating point).

 OUTPUTS:
       None

 PROCEDURE:
	This routine uses ezcaSetTimeout().

 EXAMPLES:
       IDL> caSetTimeout, .001

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETRETRYCOUNT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetRetryCount

 PURPOSE:
	This function returns the value of the EZCA retry count parameter.
       In conjunction with the EZCA Timeout parameter it determines how
       long EZCA will try to connect to a process variable before giving up.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	RetryCount = caGetRetryCount()

 INPUTS:
	None.

 OUTPUTS:
       The function return value of caGetRetryCount is the integer
       value of the EZCA RetryCount parameter.

 PROCEDURE:
	This routine uses ezcaGetRetryCount().

 EXAMPLES:
       IDL> print, caGetRetryCount()
       599

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CASETRETRYCOUNT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caSetRetryCount

 PURPOSE:
	This procedure sets the value of the EZCA RetryCount parameter.
       In conjunction with the EZCA Timeout parameter it determines how
       long EZCA will try to connect to a process variable before giving up.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caSetRetryCount, retrycount

 INPUTS:
	RetryCount: The integer retry count.

 OUTPUTS:
       None

 PROCEDURE:
	This routine uses ezcaSetRetryCount().

 EXAMPLES:
       IDL> caSetRetryCount, 100

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAPUT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caPut

 PURPOSE:
	This procedure writes a new value to a channel access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caPut(pvname, value)

 INPUTS:
	pvname:	The name of the process variable for which the new value
               is to be written

       value:  The new value to be written. In general this can be a scalar
               or array of any data type.  There are of course restrictions
               in that certain strings cannot be written to certain process
               variables, and some process variables cannot be passed arrays.

 KEYWORD PARAMETERS:
	WAIT:	Set this flag to force caPut to wait for a channel access
               callback.  The default is not to wait for a callback, using the
               ezca function ezcaPutOldCa.  The WAIT keyword results in a
               call to ezcaPut, which uses channel access callbacks.

 OUTPUTS:
       The function return value of caPut is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists and a valid value was written) and non-zero if the routine
       failed.

 PROCEDURE:
	This routine uses ezcaPut(). The "nelem" and "type" parameters passed
       to ezcaPut are determined from the IDL data type and number of elements
       of the "value" parameter passed to caPut(). Strings are converted to
       to byte arrays before being passed.

 RESTRICTIONS:
       None.   caPut can be called inside a group, i.e. after calling
               caStartGroup and before calling caEndGroup.  The "value"
               variable passed to caPut can be immediately re-used when
               inside a group, since EZCA copies it to a private location.

 EXAMPLES:
       IDL> ; Put a linear ramp (findgen()) to a waveform process variable.
       IDL> status = caPut('my_waveform.VAL', findgen(100))

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995
       Sept. 16, 1998  Mark Rivers  Added WAIT keyword, made non-callback
                                    version of caput the default


CASTARTGROUP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caStartGroup

 PURPOSE:
	This procedure starts an "asynchronous group".  Within an asynchronous
       group all calls to caGet and caPut are asynchronous, i.e. they queue
       a request and return immediately without waiting for a reply from
       the channel access servers. Calling caEndGroup causes the queue to be
       flushed and waits for the replies. The use of asynchronous
       groups can greatly improve the efficiency of channel access. The user
       must be aware of the restrictions on caGet outlined under the
       description of that routine.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caStartGroup

 INPUTS:
	None.

 OUTPUTS:
       None

 COMMON BLOCKS:
       EZCA_COMMON contains a flag (ingroup) which indicates if we
       are currently in an asynchronous group. This routine sets that flag.

 PROCEDURE:
	This routine uses ezcaStartGroup().

 EXAMPLES:
       IDL> caStartGroup
       IDL> status = caget('test_ao1.SCAN', scan)
       IDL> status = caget('test_mca1.ERTM', ertm)
       IDL> ; Print out values - they will be zero.
       IDL> help, scan, ertm
       IDL> status = caEndGroup()
       IDL> ; Print out values after executing caEndGroup, they are non-zero
       IDL> help, scan, ertm
       Output:
           SCAN            INT       =        0
           ERTM            FLOAT     =      0.000000
           SCAN            INT       =        6
           ERTM            FLOAT     =       7.10000

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAENDGROUP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caEndGroup

 PURPOSE:
	This function ends an "asynchronous group". See caStartGroup for more
       information on asynchronous groups.
       caEndGroup flushes the queue of caGet and caPut calls and waits for
       replies from the channel access servers.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	stat = caEndGroup(status)

 INPUTS:
	None.

 OUTPUTS:
       The function return value is 0 if the operation was successful,
       otherwise it is the first encountered non-successful return code.
       The optional status parameter can be used to return the status code
       of each operation in the group.

 OPTIONAL OUTPUT PARAMETERS:
       status: If this optional parameter is present then it returns a
               array of status information, one for each channel access
               call in the group.

 COMMON BLOCKS:
       EZCA_COMMON contains a flag (ingroup) which indicates if we
       are currently in an asynchronous group. This routine clears that flag.

 PROCEDURE:
	If the status parameter is present then this routine uses
       ezcaEndGroupWithReport().  If the parameter is not present then
       the routine calls ezcaEndGroup().

 RESTRICTIONS:
       When the status parameter is present, and ezcaEndGroupWithReport() is
       called, there is no way to know in advance how many status values
       will be returned.  This routine passes a status array with 1024
       elements, and then truncates it to the actual length.  The maximum
       number of status values which can be retrieved is thus 1024. No errors
       will occur if an asynchronous group has more than 1024 calls, but
       only the first 1024 status values can be obtained.
       This is probably sufficient for most applications!

 EXAMPLES:
       IDL> caStartGroup
       IDL> status = caget('test_ao1.SCAN', scan)
       IDL> status = caget('test_mca1.ERTM', ertm)
       IDL> ; Print out values - they will be zero.
       IDL> help, scan, ertm
       IDL> status = caEndGroup()
       IDL> ; Print out values after executing caEndGroup, they are non-zero
       IDL> help, scan, ertm
       Output:
           SCAN            INT       =        0
           ERTM            FLOAT     =      0.000000
           SCAN            INT       =        6
           ERTM            FLOAT     =       7.10000

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CASETMONITOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caSetMonitor

 PURPOSE:
	This procedure sets a monitor on the specified process variable.
       This causes a channel access callback to execute whenever the value
       of that process variable changes.  Subsequent calls to caGet() after
       calling caSetMonitor will read the values provided by the callbacks,
       rather than reading from the IOC.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caSetMonitor(pvname)

 INPUTS:
	pvname: The name of the process variable on which to set the monitor.

 OUTPUTS:
       The function return value of caSetMonitor is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 PROCEDURE:
	This routine uses ezcaSetMonitor(). The "type" parameter required
       by ezcaSetMonitor is the native EZCA data type as determined
       by caGetCountAndType().

 EXAMPLES:
       IDL> status = caSetMonitor('test_ao1')
       IDL> status = caGet('test_ao1', value)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CACLEARMONITOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caClearMonitor

 PURPOSE:
	This procedure clears a monitor on the specified process variable.
       It cancels the effect of caSetMonitor().

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caClearMonitor(pvname)

 INPUTS:
	pvname: The name of the process variable on which to clear the monitor.

 OUTPUTS:
       The function return value of caClearMonitor is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 PROCEDURE:
	This routine uses ezcaClearMonitor(). The "type" parameter required
       by ezcaClearMonitor is the native EZCA data type as determined
       by caGetCountAndType().

 EXAMPLES:
       IDL> status = caClearMonitor('test_ao1')

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CACHECKMONITOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caCheckMonitor

 PURPOSE:
	This function returns a non-zero value if there is a new (unread)
       monitor for this process variable, otherwise it returns zero.
       This function is particularly useful when a caGet() operation is
       expensive in time, e.g. reading large arrays.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	state = caCheckMonitor(pvname)

 INPUTS:
	pvname: The name of the process variable on which to check the monitor.

 OUTPUTS:
       The function return value is zero if no new monitor value is available,
       and non-zero if a new monitor value is available.

 PROCEDURE:
	This routine uses ezcaNewMonitorValue(). The "type" parameter required
       by ezcaNewMonitorValue() is the native EZCA data type as determined
       by caGetCountAndType().

 EXAMPLES:
       IDL> state = caCheckMonitor('test_ao1',event)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CADEBUG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caDebug

 PURPOSE:
	This procedure turns the EZCA debugging flag on or off. Turning on
       the debugging flag prints lots of information, which is mainly
       useful to developers.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caDebug, state

 INPUTS:
	state:  state=1 turns debugging on, state=0 turns debugging off.

 OUTPUTS:
       None

 PROCEDURE:
	This routine uses ezcaDebugOn() and ezcaDebugOff().

 EXAMPLES:
       IDL> caDebug, 1     ; Turn on debugging
       setting Debug
       IDL> status = caGet('test_ao1', value)
       ca_pend_event(0.000010)
       --start end-of-prologue() report
       ****** Start State:
       AutoErrorMessage T InGroup F Debug T Trace F ErrorLocation LastOnly ListPrint
       LastOnly TimeoutSeconds 0.050000
       Workp : 9cf970 trashme F (nxt 0)
       Channel_avail_hdr 0 :
       ...
       ...
       IDL> caDebug, 0 ; Turn off debugging

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CATRACE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caTrace

 PURPOSE:
	This procedure turns the EZCA trace flag on or off. Turning on
       the trace flag prints lots of information which is mainly useful
       to developers.  Setting the trace flag results in less
       verbose output than setting the debug flag (see caDebug).

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caTrace, state

 INPUTS:
	state:  state=1 turns trace on, state=0 turns trace off.

 OUTPUTS:
       None

 PROCEDURE:
	This routine uses ezcaTraceOn() and ezcaTraceOff().

 EXAMPLES:
       IDL> caTrace, 1     ;Turn on trace
       setting Trace
       IDL> status = caGet('test_ao1', value)
       ca_pend_event(0.000010)
       find_channel() found >test_ao1<
       get_channel(): was able to find_channel()
       ca_pend_event(0.000010)
       ...
       ...
       IDL> caTrace, 0     ; Turn off trace

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETENUMSTRINGS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetEnumStrings

 PURPOSE:
	This function returns all of the choice strings associated with a
       Channel Access "enum" process variable. It is particularly useful
       for building menus of options.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	Status = caGetEnumStrings(pvname, strings)

 INPUTS:
	pvname:	The name of the process variable for which the enum strings
               are to be returned. The native channel access data type of
               this process variable must be enum (3).

 OUTPUTS:
	strings: A string array containing the strings for each possible
               value of the enum variable.

       The function return value of caGetEnumStrings is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists and is of type enum) and non-zero if the routine failed.

 SIDE EFFECTS:
	This routine causes a channel access read. It does not use the
       grouping mechanism of EZCA, i.e. it always executes immediately.

 RESTRICTIONS:
       There must be less than 16 enum strings and they must each be less
       than 26 characters.

 PROCEDURE:
	This routine uses ezcaPvToChid and then ca_get() with a request type
       of DBR_GR_ENUM.  The functionality required by this routine is not
       presently provided directly in EZCA, although it should probably be
       added.

 EXAMPLES:
       IDL> status = caGetEnumStrings('test_mca1.SCAN', strings)
       IDL> for i=0, n_elements(strings)-1 do print, strings(i)
       Passive
       Event
       I/O Intr
       10 second
       5 second
       2 second
       1 second
       .5 second
       .2 second
       .1 second

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETCONTROLLIMITS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetControlLimits

 PURPOSE:
	This procedure reads the control limits for the specified channel
       access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caGetControlLimits(pvname, low, high)

 INPUTS:
	pvname: The name of the process variable from which to read the
               control limits.

 OUTPUTS:
       low:    The low control limit (double).

       high:   The high control limit (double).

       The function return value of caGetControlLimits is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 PROCEDURE:
	This routine uses ezcaGetControlLimits().

 EXAMPLE:
       IDL> status = caGetControlLimits('test_ao1', low, high)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETGRAPHICLIMITS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetGraphicLimits

 PURPOSE:
	This procedure reads the graphic limits for the specified channel
       access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caGetGraphicLimits(pvname, low, high)

 INPUTS:
	pvname: The name of the process variable from which to read the
               graphic limits.

 OUTPUTS:
       low:    The low graphic limit (double).

       high:   The high graphic limit (double).

       The function return value of caGetGraphicLimits is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 PROCEDURE:
	This routine uses ezcaGetGraphicLimits().

 EXAMPLE:
       IDL> status = caGetGraphicLimits('test_ao1', low, high)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETPRECISION

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetPrecision

 PURPOSE:
	This procedure reads the precision for the specified channel
       access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caGetPrecision(pvname, precision)

 INPUTS:
	pvname: The name of the process variable from which to read the
               precision.

 OUTPUTS:
       precision:  The precision (short).

       The function return value of caGetPrecision is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 PROCEDURE:
	This routine uses ezcaGetPrecision().

 EXAMPLE:
       IDL> status = caGetPrecision('test_ao1', precision)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETSTATUS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetStatus

 PURPOSE:
	This procedure reads the status parameters for a channel access
       process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caGetStatus(pvname, timestamp, status, severity)

 INPUTS:
	pvname: The name of the process variable from which to read the
               status parameters.

 OUTPUTS:
       timestamp: The timestamp of the last time the record was processed
               lonarr(2).

       status: The status flag (int).

       severity: The severity flag (int).

       The function return value of caGetStatus is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 PROCEDURE:
	This routine uses ezcaGetStatus().

 EXAMPLE:
       IDL> status = caGetStatus('test_ao1', timestamp, status, severity)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAGETUNITS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetUnits

 PURPOSE:
	This procedure reads the units string for the specified channel
       access process variable.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	status = caGetUnits(pvname, units)

 INPUTS:
	pvname: The name of the process variable from which to read the units.

 OUTPUTS:
       units:  The units (string).

       The function return value of caGetUnits is a status value.  The
       status is 0 if the routine was successful (i.e. the process variable
       exists) and non-zero if the routine failed.

 COMMON BLOCKS:
       EZCA_COMMON contains a flag (ingroup) which indicates if we
       are currently in an asynchronous group. This routine tests that flag.

 PROCEDURE:
	This routine uses ezcaGetUnits().

 EXAMPLE:
       IDL> status = caGetUnits('test_ao1', units)

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAERROR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caError

 PURPOSE:
	This procedure controls error printing and returns error strings.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caError, err_string, /ON, /OFF, /PRINT, prefix=prefix

 INPUTS:
       None

 KEYWORD PARAMETERS:
       /ON
           Setting this switch turns on automatic error message printing
           on stdout.  Automatic printing is initially enabled.

       /OFF
           Setting this switch turns off automatic error message printing
           on stdout.

       /PRINT
           Setting this switch prints the last error message on stdout.

       prefix=prefix
           The prefix keyword can be used to pass a string which is prefixed
           to error messages printed with /PRINT or fetched via the optional
           output parameter.

 OPTIONAL OUTPUT PARAMETERS:
	err_string:
           If this parameter is present then it will contain the text of the
           last error message.

 COMMON BLOCKS:
       EZCA_COMMON contains a flag (ingroup) which indicates if we
       are currently in an asynchronous group. This routine tests that flag.

 PROCEDURE:
	This routine uses ezcaPerror(), ezcaAutoErrorMessageOn(),
       ezcaAutoErrorMessageOff(), and ezcaGetErrorString()

 EXAMPLE:
       IDL> ; Define a prefix and turn on error messages
       IDL> caError, prefix='My program', /ON
       IDL> ; Fetch the last error message
       IDL> caError, err_string

 MODIFICATION HISTORY:
 	Written by:	Mark Rivers
	June 28, 1995


CAVERSION

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       caVersion

 PURPOSE:
       This function returns the string of current version information
       about ezcaIDL

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       string = caVersion()

 INPUTS:
       None.

 OUTPUTS:
       Return the string which gives the version information about
       ezcaIDL, ezca, Ezca, and EPICS base verion number.

 PROCEDURE:
	This routine uses Ezca_version() from the ezcaScan library.

 EXAMPLE:
       IDL> print, caVersion()

 MODIFICATION HISTORY:
       Written by:     Ben-chin Cha   Dec, 1995


CAINIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caInit

 PURPOSE:
	This routine sets the channel access timeout used by list array
       functions defined in ezcaScan library.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caInit [,flag] [,help=help]

 INPUTS:
	flag:	Optional flag, if set to -1  ezcaScan library default timeout
               settings will be used.

 KEYWORD PARAMETERS:
     HELP:  If ,/HELP is set, on-line help will be displayed.

 OUTPUTS:
       None.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine set the channel access timeout values used in the
       ezcaScan library.  This routine set the timeout to 3 seconds for
       lists of process variables, and sets the timeout for
       ca_pend_event to 0.001 second.

       If a value of -1 is specified for the flag, the default value
       of 10 seconds for lists of process variables will be used.

 RESTRICTIONS:
       None.

 PROCEDURE:
	This routine uses Ezca_init() from the ezcaScan library.

 EXAMPLES:
       IDL> caInit

 MODIFICATION HISTORY:
 	Written by:	Ben-chin Cha     Dec, 1995


CAPENDEVENT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caPendEvent

 PURPOSE:
	This function causes the Ezca to call channel access ca_pend_event
       function.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	caPendEvent [,time=0.001] [,help=help]

 INPUTS:
       None.

 KEYWORD PARAMETERS:
       TIME:  This keyword parameter is used to reset the timeout in seconds
              used by ca_pend_event in ezcaScan library.

       HELP:  If ,/HELP is set, on-line help will be displayed.

 OUTPUTS:
       None.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine sets the timeout for event monitor routines used in
       ezcaScan library and calls the ca_pend_event.

 RESTRICTIONS:
	Positive time must be used.

 PROCEDURE:
	This routine uses Ezca_setPendTime() from the ezcaScan library.

 EXAMPLES:
       IDL> caPendEvent, time=0.0001

 MODIFICATION HISTORY:
 	Written by:	Ben-chin Cha      Dec, 1995


CAPENDIO

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caPendIO

 PURPOSE:
	This routine sets the timeout used by ca_pend_io in array get/
       put used in ezcaScan library.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       caPendIO, time=time, list_time=list_time

 INPUTS:
       None.

 KEYWORD PARAMETERS:
	TIME:   Use the TIME=time keyword to set the timeout waiting for
               channel access I/O for single process variable name.

	LIST_TIME: Use the LIST_TIME=list_time keyword to set the timeout
               waiting for channel access I/O for a list of PV names.

       HELP:   If ,/HELP is specified, on line help will be displayed.

 OUTPUTS:
       None.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       These times will be used in array get/put from then on in all
       ca_pend_io calls in ezcaScan library.

 RESTRICTIONS:
       Positive real times should be used in those keywords.

 PROCEDURE:
	This routine uses Ezca_setPendTime() from the ezcaScan library.

 EXAMPLES:
       IDL> caPendIO, time=0.1, list_time=3.
       IDL> caPendIO, /help

 MODIFICATION HISTORY:
 	Written by:	Ben-chin Cha      Dec, 1995


CATIMESTAMP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caTimeStamp

 PURPOSE:
       This function returns the time stamp of corresponding value for
       the specified record name.

 CATEGORY:
	EPICS Channel Access Interface

 CALLING SEQUENCE:
	string = caTimeStamp(pvname)

 INPUTS:
       pvname:	The name of the process variable for which the timestamp is to
               be returned.

 KEYWORD PARAMETERS:
       None.

 OUTPUTS:
	string:  The function returns the time stamp string for the requested
                PV name.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
	This routine will causes a channel access search to take place if
       this is the first time this process variable has been referenced.

 RESTRICTIONS:
       Only single PV name is allowed in input.

 PROCEDURE:
	This routine uses Ezca_timeStamp() from the ezcaScan library.

 EXAMPLES:
       IDL> print,caTimeStamp('chademoai1')

 MODIFICATION HISTORY:
 	Written by:	Ben-chin Cha      Dec, 1995


CASEARCH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caSearch

 PURPOSE:
       This function searches for a list of process variable names.
       It returns 0 if successful, returns -1 if failed.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       Status = caSearch(pvname)

 INPUTS:
      pvname: The variable for a list of process variables for which the
              channel access search to be done.

 KEYWORD PARAMETERS:
       None.

 OUTPUTS:
       None.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine will causes a channel access search to take place if
       this is the first time pvnames has been referenced.

 RESTRICTIONS:
       None.

 PROCEDURE:
       This routine uses Ezca_search_list() from the ezcaScan library.

 EXAMPLES:
       IDL> print,caSearch('chademoai1')
       IDL> x = ['chademoai1','chademoai2']
       IDL> status = caSearch(x)

 MODIFICATION HISTORY:
       Written by:	Ben-chin Cha      Dec, 1995
      04-11-96   bkc   Fix typo error names to name


CAGETERROR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	caGetError

 PURPOSE:
       This function get CA return codes for a list of process variable names.
       Return code can be 0 or -1, 0 for success, -1 for failure.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       Status = caGetError(Pvname,Err)

 INPUTS:
      Pvname: The variable for a list of process variables for which the
              channel access return code to be checked.

 KEYWORD PARAMETERS:
       None.

 OUTPUTS:
       Err:  The corresponding return code(s) for the Pvname(s) are returned.
             Returns array of 0 or 1. 0 indicates success, 1 indicates failed.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine will causes a channel access search to take place if
       this is the first time pvnames has been referenced.

 RESTRICTIONS:
       None.

 PROCEDURE:
       This routine uses Ezca_get_error_array() from the ezcaScan library.

 EXAMPLES:
       IDL> print,caGetError('chademoai1')
       IDL> x = ['chademoai1','chademoai2']
       IDL> status = caGetError(x)

 MODIFICATION HISTORY:
       Written by:	Ben-chin Cha      Dec, 1995


CAGETARRAY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       caGetArray

 PURPOSE:
       This function reads values for a list of Channel Access process
       variable. It returns 0 if successful, returns -1 if failed.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       Status = caGetArray(names,pdata,max=no,type=i,/TYPE,/EVENT)

 INPUTS:
       names:	The variable for a list of channel access PV names for which
               the array of data is to be returned.

 KEYWORD PARAMETERS:
      MAX:    Default to 1 for a list of PV names. If more than one values
              to be returned for a list of array type PV names, this keyword
              must be specified. If the `no' specified is greater than the
              native count, zeros will be padded in the output array.

              If only one PV name is input, then caGetArray returns
              the native element count for the process variable. Setting
              MAX to a number less than the native count this will cause
              caGetArray to return only the first MAX values for the PV.

      TYPE:   This keyword specifies the IDL data type to be returned by
              the output array. If not specified, it defaults to 5, i.e.
              double precision type of data will be returned by the
              output array.

                1 - byte      2 - short       3 - long      4 - float
                5 - double    7 - string

     /TYPE    Instead of type=i a user can use the IDL data type keyword
              directly, the data type keyword supercedes the type=i
              specification. Valid types given below

                            /double
                            /float
                            /string
                            /long
                            /short
                            /byte

    /EVENT    If specified use the ca_array_get_callback otherwise use
              the ca_array_get

 OUTPUTS:
     pdata:  The output variable,  pdata(max,noNames), returns the data
             array for the requested list of PV names. The `max' is the no
             of values specified by the keyword MAX, the `noNames' is the
             number of PV names in the input variable names.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine will causes a channel access search to take place if
       this is the first time this process variable has been referenced.

 RESTRICTIONS:
       Only one type of data can be requested for a list of PV names.

 PROCEDURE:
	This routine uses Ezca_getArray() from the ezcaScan library.

 EXAMPLES:
       Three examples are given below.
       The first caGetArray call returns only the first value for each PV
       name, the second and third caGetArray call both returns 10 float
       values for each PV name

       IDL> names=['chademowf7','chademowf8']
       IDL> st = caGetArray(names,pdata)
       IDL> st = caGetArray(names,pdata,max=10,/float)
       IDL> st = caGetArray(names,pdata,max=10,type=4)

 MODIFICATION HISTORY:
       Written by:	Ben-chin Cha      Dec, 1995
      04-11-96     bkc    If array get failed, only the pvnames not found are
                          reported
      04-22-96     bkc    Replace caError by caGetError


CAPUTARRAY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       caPutArray

 PURPOSE:
       This function writes an array of data to a list of Channel Access
       process variable. It returns 0 if successful, else retuns -1.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       Status = caPutArray(pvname, pdata, /event)

 INPUTS:
       pvname:	The variable specifies a list of process variables for
               which the input array of data is to be written to IOC.
       pdata:  Input data array. The data array must be consistant with
               the number of PV names defined in the pvname.

 KEYWORD PARAMETERS:
      EVENT:   If specified use the ca_array_put_callback otherwise
               use the ca_array_put.

 OUTPUTS:
      None.

 COMMON BLOCKS:
      None.

 SIDE EFFECTS:
       This routine will causes a channel access search to take place if
       this is the first time this process variable has been referenced.

 RESTRICTIONS:
       Thus, it is the user's responsibility to make sure the adequate
       pdata is provided for the pvname.

 PROCEDURE:
	This routine uses Ezca_putArray() from the ezcaScan library.

 EXAMPLES:
       In the following example write a string value '11' to two PV
       names: chademomask1.VAL  and chademoai2.VAL

       IDL> x = ['chademomask1', 'chademoai2']
       IDL> y = make_array(1, 2, /string)
       IDL> y(0) = '11'
       IDL> y(1) = '11'
       IDL> status = caPutArray(x,y)

       In the following example write values [1,2,3] to two waveform records
       names: chademowf2  and chademowf5

       IDL> x = ['chademowf2','chademowf5']
       IDL> y = make_array(3, 2)
       IDL> y(0,0) = [1,2,3]
       IDL> y(0,1) = [1,2,3]
       IDL> print,caPutArray(x,y)
       IDL> print,caGetArray(x,pd,max=10)
       IDL> print,pd

 MODIFICATION HISTORY:
       Written by:	Ben-chin Cha      Dec, 1995


CASCAN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       caScan

 PURPOSE:
       This function provides add/get/zero/clear monitor features on a
       scan record and a set of PV names.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       Status = caScan(name,pvnames,nonames,npts,vals,op_keyword,max=no)

 INPUTS:
       name:   The name of the process variable which has control of
               triggering scan, e.g. the scan record name.
       pvnames: A list of detector process variables for which the values
                are to be monitored by the trigger name.

 KEYWORD PARAMETERS:
      ADD:     Set this flag /ADD  to add a complete set of monitor for
               name and pvnames.
               Return 0 if successful, -1 if failed, 1 if old monitor
               already existed. If succeeds, the output variable npts
               is set to the number of data to be detected, and the
               nonames is set to the number of PVs in pvnames.

      CLEAR:   Set this flag /CLEAR to clear the monitor set by add.
               Return 0 if successful, -1 if failed.

      GET:     Set this flag /GET to get scan array of monitor values back.
               Return -1 if failed, return 1 if scan is properly set up but
               not triggered yet, return >1 if real data detected.
               If succeeds, the npts is set to the number of data so far
               detected.

      ZERO:    Set this flag /ZERO to zero the allocated space.
               Return 0 for success, -1 for failure.

      MAX:     Specifies the max number of monitor values to be returned.
               If the trigger name is not a scan record, the max=no must
               be provided for this function.

 OUTPUTS:
     nonames:  This variable returns the number of PVs in pvnames.
     npts:     This variable returns the current number of data points
               detected by the scan record.
     vals:     This detector data array buff, vals(nonames,max), stores
               the detected data so far captured.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine will causes a channel access search to take place if
       this is the first time this process variable has been referenced.

 RESTRICTIONS:
       None.

 PROCEDURE:
       This routine uses Ezca_scanAddMonitor(), Ezca_scanClearMonitor(),
       Ezca_scanGetMonitor(), and Ezca_scanZeroMonitor() from the Ezca
       library.

 EXAMPLES:
      For scan record type triggered scan

       IDL> print,caScan('name',pvnames,/add)
       IDL> print,caScan('name',pvnames,nonames,npts,vals,/get)
       IDL> print,caScan('name',pvnames,/zero)
       IDL> print,caScan('name',pvnames,/clear)

      For non-Scan record type triggered scan

       IDL> print,caScan('name',pvnames,/add,max=100)
       IDL> print,caScan('name',pvnames,nonames,npts,vals,/get,max=100)
       IDL> print,caScan('name',pvnames,/zero,max=100)
       IDL> print,caScan('name',pvnames,/clear,max=100)

 MODIFICATION HISTORY:
       Written by:	Ben-chin Cha      Dec, 1995


CAMONITOR

[Previous Routine] [List of Routines]
 NAME:
       caMonitor

 PURPOSE:
       This function provides Add/Get/Check/Clear monitor features on a
       single PV or a list of PV names.

 CATEGORY:
       EPICS Channel Access Interface

 CALLING SEQUENCE:
       Status = caMonitor(name, vals, num, overflow, op_keyword,type_keyword, max=no)

 INPUTS:
       name:	The variable for a PV or a list of PV names.

 KEYWORD PARAMETERS:
     ADD:      Set /ADD to add CA monitor for the specified name.
               Return 0 for success, -1 for failure.

     CLEAR:    Set /CLEAAR to clear CA monitor for the specified name.
               Return 0 for success, -1 for failure.

     CHECK:    Set /CHECK to check for new event for the specified name.
               Return 0 for success, -1 for failure.
               The ouput variable 'vals' contains the return event flags.
                 0 - flags no new event detected
                 1 - flags new event detected

     GET:      Set /GET to get monitor values back for the specified name.
               Different type of monitor returns different vals array.
               If non queue type monitor set, the vals array returns a
               single value for each PV in the name variable.
               If the kewword /QUEUE is specified, in addition of vals,
               both num and overflow variables are also returned.

     QUEUE:	Set /QUEUE flag to queue the value change event for the
               monitored single channel until the user gets them.

     MAXQUEUE: The MAXQUEUE=no must be specified if /QUEUE is specified.

     MODE:     This flag indicates what type of monitor queue is desired.
               The MODE=i where i can be 1/2/3, it defaults to 1. The
               MODE=1 or 2 monitor fills the QUEUE buff until it is fulled.
               If MODE=1, the /GET will clear the QUEUE buff.
               IF MODE=2, the /GET will not clear the QUEUE buff.
               The MODE=3 uses the circulat buffer, it keeps the most
               current MAXQUEUE values in the queue buffer.

               Default Vals returned in double precision form.
     /INT      Return Vals converted to integer
     /LONG     Return Vals converted to long integer
     /BYTE     Return Vals converted to byte type 
     /FLOAT    Return Vals converted to float type 
     /STRING   Return Vals converted to string type

 OUTPUTS:
     vals:     Returns the array of data if either keyword /GET or /CHECK
               is specified

     num:      Returns the real number of data in the vals array for the
               /QUEUE mode

     overflow: Returns the buffer full indicator for the /QUEUE mode
               0 - vals queue buff is not full
               1 - vals queue buff is full

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       This routine will causes a channel access search to take place if
       this is the first time this process variable has been referenced.

 RESTRICTIONS:
       All the PVs are monitored as double values in this function
       unless the PV is a DBR_STRING type then monitored as string type.
       For getting the monitored queue array, only a single PV name can
       be specified.  For non queue type monitor, only the first value
       for a PV can be returned by this function.  Use caGet to get
       array type of values back.

 PROCEDURE:
	This routine uses Ezca_monitorArrayAdd(), Ezca_monitorArrayGet(),
       Ezca_monitorArrayCheck(), Ezca_monitorArrayClear(), Ezca_queueAdd(),
       Ezca_queueGet(),Ezca_queueZero(), and Ezca_queueClear()
       from the ezcaScan library.

 EXAMPLES:
    Single value monitor

       IDL> print,caMonitor('chademoai1',/add)
       IDL> print,caMonitor('chademoai1',vals,/get)
       IDL> print,caMonitor('chademoai1',/clear)

    Use queue array monitor with maxqueue=100

       IDL> print, caMonitor('chademoai1',/add,/queue,maxqueue=100)
       IDL> print, caMonitor('chademoai1',vals,num,overflow,/get,/queue,maxqueue=100)
       IDL> print, caMonitor('chademoai1',/clear,/queue)

 MODIFICATION HISTORY:
       Written by:	Ben-chin Cha      Dec, 1995
       04-12-96    bkc   Modified on line help syntax
       04-07-99    bkc   Return monitor values specification:
                         /byte,/int,/long,/float,/string 


Category: Events

[List of Routines]


EXECONEVENT

[Next Routine] [List of Routines]
 NAME:
       execonevent

 PURPOSE:
       Widget to spawn an executable (with shot as argument) when an 
	MDSplus event occurs. An IDL routine can also be spawned with shot as
	the only  argument, or any IDL command string executed.
	
 CATEGORY:
       Events, MDSplus

 CALLING SEQUENCE:
	IDL> execOnEvent, kickOffEvent='bdtest', executable='/u/bdavis/cvs/idl_cvs/echoarg.exe'
       IDL> execonevent, events=['NSTX_SOC', 'my_event' ]
	IDL> execonevent, emailTo=['vlad@pppl.gov, joeshmoe@pppl.gov'], $
		events=['NSTX_ACQ_DONE', 'CAM1_DONE',  $
			'CAM2_DONE','CAM3_DONE','CAM4_DONE' ]
    to get e-mail when really important events are missed, e.g., :
	IDL>  execonevent,add=['TS_RAW_READY','PHOENIXGO_P1','MPTS_FIT_DONE', $
			       'TFMON_ACQ_DONE'], emailTo='joeshmoe@pppl.gov'
 INPUTS:
       none.  
 KEYWORD PARAMETERS:
    (optional) 
	kickOffEvent - event at which to kick of executable
	executable - executable to spawn
	idljob - spawns subprocess, with current shot number as the only input
	cmd - IDL command string to execute (will wait until returns)
	TEST - if set, appends TEST to all events
       EVENTS_WANTED - Character array of events to watch for.
			defaults to ['NSTX_SOC', 'CAM1_DONE',
			'CAM2_DONE','CAM3_DONE','CAM4_DONE' ]
	EMAIL - email address for message if all events listed not set before next shot..
	NOCLEAR - if set, will not clear events when first event is recognized
	noBox - if set, will not create color box for events 
		(can conflict with plot windows spawned from cmd)
	PRINT - if set, will print messages when events are recognized
	TIME - if set, will display time-of-day when event was declared
	add_events - if set, will add these event(s) to the default
	BIG - if set, fonts are big
	WALL - if set, events of interest for display wall, and big font
       GROUP_LEADER - Group_Leader ID
 OUTPUTS:
       none.
 NOTES:
       The time of day will be printed for the first event, and the other times
       will be cleared. Then the time difference will be printed as mm:ss, 
       so :12 would mean it came 12 seconds after the first event. 
 TESTING
	IDL> execonevent, EVENTS_WANTED=['MY_TEST_EVENT_1','MY_TEST_event_2'], $
			/Shots
	   and from a VMS computer:  
	IDL> SetMDSShotEvent,'MY_TEST_EVENT_1', 999999

	IDL> execonevent, EVENTS='bdtest', cmd='print, "Hi Mom"', /verbose

 ROUTINES USED:
	MK_COLOR, usingXwindows, MDSEVENT
 EXAMPLE:
	  to automatically have MPTS plots come up on Display Wall:
	IDL> execonevent, EVENTS='MPTS_REFRESH', cmd='plot_mpts,shot=0,chrsz=1.5, xmargin=[7,3]'
 LIMITATION:
	Shot numbers are only returned  when running on VMS currently.
 NOTES:
	As the events are declared, the boxes turn color.
 	When the first event in the list is recognized, the other boxes are
	set to yellow (unless /noClear was set). Shot numbers declared with 
	the events may optionally be displayed.
       The status fields are initially the background color.
	A program calling this routine, might want to save !D.WINDOW 
	before the TV commands and restore it immediately afterwards.
 MODIFICATION HISTORY:
	15-Jun-2010 added cmd keyword [BD]
	01-Oct-2008 Removed MDSconnect
	06-Mar-2006 Written by Bill Davis, PPPL


MONEVENTS_NOXMANAGER

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       monevents_noxmanager

 PURPOSE:
       monevents version to run in batch mode. 
	Widget to monitor occurrence of MDSplus events & optional Shot #,
	if passed with the event declaration. The time of the event can also
	be displayed.

 EXPLANATION:
	Lists various events related to an NSTX shot cycle (as a default). 
	As the events are declared, the boxes turn color.
 	When the first event in the list is recognized, the other boxes are
	set to yellow (unless /noClear was set). Shot numbers declared with 
	the events may optionally be displayed.

 CATEGORY:
       Events, MDSplus, Monitoring Widget

 CALLING SEQUENCE:
       IDL> monevents

  to get a small # of key events:
     IDL> monevents, EVENTS_WANTED=['NSTX_SOC',	      $
       	      'NSTX_TMINUS60',  'NSTX_SOD',	      $
       	      'NSTX_ACQ_STARTED' ,'PC_908C16N08_ACQ', $       ; Digitizer that EFIT needs
       	      'MPTS_FIT_DONE', 'NSTX_ACQ_DONE' ,      $
       	      'SFLIP_IN_TREE' ],		      $
       	      /SHOT, /NoClear
  to get Diagnostic events and labels:
     IDL> monevents_noxmanager, file_input='/u/bdavis/cvs/idl_cvs/eventlabelsdiags.txt', $
		      	tabs=0, maxper=12, /shot,  /noclear, /WebGifs, $
			outFile='NSTX_Diagnostic_Status.gif'

     IDL> monevents_noxmanager, file_input='/u/bdavis/cvs/idl_cvs/eventlabelssmall.txt', $
		      	tabs=0, maxper=12, /shot,  /noclear, /WebGifs, $
			outFile='NSTX_Diagnostic_Status_Example.gif'

  to get all MPTS-relevant events:
     IDL>  monevents,/shot,add=['NSTX_ABC', 'MPTS_FORCEFIT', $
             'NSTX_ABS','NSTX_KLC','TS_RAW_READY']
  to see all QCS at once:
     IDL> monevents,/qcs,tabs=0,maxper=22, /shot, clear_event='NSTX_SOC' ,/noclear
  for QCS testing:
     IDL>  monevents,/shot,add=['sflip_files','test2','qcs_test'],tabs=0,/nocle, $
                     logfile='$HOME/ShotCycleEvents.log'
  for watching TF timing:
     IDL>  monevents,/shot,tabs=0,/nocle, $
          EVENTS_WANTED=['NSTX_SOD','PC_908C36N02_ACQ','PC_908C36N06_ACQ',  $
		   'PC_908C36N10_ACQ','PC_908C36N14_ACQ','TFMON_ACQ_DONE'];  for monitoring TF joint events, with a logfile in your home directory:
  for watching EFIT timing:
     IDL> monevents,/shot,/noclear,tabs=0, $
          EVENTS_WANTED=['NSTX_SOD','PC_908C16N08_ACQ', 'FDIA_CALC_DONE', $
                  'OP_H908_01_ACQUIRED', 'OP_H908_02_ACQUIRED', 'OP_H908_04_ACQUIRED',   $
                  'OP_H908_05_ACQUIRED', 'OP_H908_07_ACQUIRED', 'OP_H908_08_ACQUIRED',   $
                  'OP_H908_09_ACQUIRED', 'OP_H908_11_ACQUIRED', 'OP_H908_13_ACQUIRED',   $
		   'PHOENIXGO_P1', 'MPTS_FIT_DONE', 'PHOENIXGO_P2V1',  $
		   'phoenixDone_p1', $
		   'NSTX_ACQ_DONE',   $
		   'phoenixDone_p2' ],  $
       	   logfile='$HOME/EfitEvents.log'

 INPUTS:
       none.  

 KEYWORD PARAMETERS:
    (optional) 
       EVENTS_WANTED - String array of events to watch for
	LABELS - strings array to display instead of events
	FILE_INPUT - a text file of events to watch for (labels can follow each, in quotes)
	   format like:
		NSTX_SOC	       "Start of Cycle"
		BA_L8212_01_ACQ	       "Bolometers"
		GS_908C28N14_ACQ       "Gas Injection"
               ...
	CLEAR_EVENT - event to clear green lights on (default to EVENTS_WANTED[0]
	ADD_EVENTS - these events will be added to default events.
	QCS - if set, will read the file for QCS events, and use all there.
	LogFile - will log events to this file.
	LogEvents - if set, and LogFile not set, will log events to MonEvens.log
	nCols - number of columns wanted. Will default to 15 per column
	maxPerCol - another way to determine # of columns. Default=15.
	tabs - will default to tabs if more than one column. if=0, all on 1.
	NOCLEAR - if set, will not clear text boxes when first event is recognized
	PRINT - if set, will print messages when events are recognized
	SHOWSHOTS - if set, will display shot numbers declared with the events
	TIME - if set, will display time-of-day when event was declared
	BIG - if set, fonts are big
	WALL - if set, events of interest for display wall, and big font
	GIFseconds - seconds between writes of GIF file of window contents
		(good for making web-accessible displays). If not present, don't make files
	WebGifs - if set, will create a gif (to be read from the web) whenever widget is
		  updated (DEFAULT=0)
       GROUP_LEADER - Group_Leader ID
	VERBOSE - if set, lots of information is output

 OUTPUTS:
       none.

 TESTING
	IDL> monevents, EVENTS_WANTED=['MY_TEST_EVENT_1','MY_TEST_event_2'], $
			/Shots
	   and from a VMS computer:  
	IDL> SetMDSShotEvent,'MY_TEST_EVENT_1', 999999

 COMMON BLOCKS:
       none

 ROUTINES USED:
	MK_COLOR, usingXwindows, MDSEVENT

 EXAMPLE:
	IDL> monevents

 LIMITATION:
	Shot numbers are only returned  when running on VMS currently.

 NOTES:
       The time of day will be printed for the first event, and the other times
       will be cleared. Then the time difference will be printed as mm:ss, 
       so :12 would mean it came 12 seconds after the first event. 

       The status fields are initially the background color.
	A real program might want to save !D.WINDOW before the TV commands
	and restore it immediately afterwards.

 MODIFICATION HISTORY:
	01-Oct-2008 Removed mdsconnect [BD]
	18-Aug-2008 Added labels to be displayed instead of events, if desired.
		    added WebGifs & GifSeconds keywords. Add
	10-Jul-2008 made logging of events clearer
	21-Feb-07 added /logevents and logfile as keywords
	08-Feb-06 Added clear_event keyword, and made it show up 1st in list
	09-Nov-05 added tabs and QCS keyword
	03-Feb-04 added wall keyword
	10-Feb-03 added keyword add_event [BD]
	14-Jun-01 Default to showing time
       20-Jul-00 Written by Bill Davis, PPPL


MONEVENTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       monevents
 PURPOSE:
       Widget to monitor occurrence of MDSplus events & optional Shot #,
	if passed with the event declaration. The time of the event can also
	be displayed.
 EXPLANATION:
	Lists various events related to an NSTX shot cycle (as a default). 
	As the events are declared, the boxes turn color.
 	When the first event in the list is recognized, the other boxes are
	set to yellow (unless /noClear was set). Shot numbers declared with 
	the events may optionally be displayed.
 CATEGORY:
       Events, MDSplus, Monitoring Widget
 CALLING SEQUENCE:
       IDL> monevents
  to get a small # of events for Dummy Load testing:
     IDL> monevents, EVENTS_WANTED=[		$
		      'NSTX_SOC',		$
		      'nstx_initphase_done',   	$
       	      'NSTX_SOD', 		$       
		      'NSTX_ACQ_STARTED', 	$  ; Digitizer that EFIT needs
		      'PC_908C16N08_ACQ',  	$
       	      'NSTX_ACQ_DONE' ,      	$
       	      'efitdb_done' ],		$
       	      /SHOT, /NoClear, tabs=0
  to get a small # of key events, starting at SOC:
     IDL> monevents, EVENTS_WANTED=['NSTX_SOC', 'NSTX_TM60', $
       	      'NSTX_SOD', 'PC_908C16N08_ACQ', $       ; Digitizer that EFIT needs
       	      'MPTS_FIT_DONE', 'NSTX_ACQ_DONE' ,      $
       	      'phoenixDone_p1' ],		      $
       	      /SHOT, /NoClear
  to get Diagnostic events and labels:
     IDL> monevents, file_input='/u/bdavis/cvs/idl_cvs/eventlabelsdiags.txt', $
		      tabs=0, maxper=12, /shot,  /noclear, /WebGifs

  to get all MPTS-relevant events:
     IDL>  monevents,/shot,add=['NSTX_ABC', 'MPTS_FORCEFIT', $
             'NSTX_ABS','NSTX_KLC','TS_RAW_READY']
  to see all MEMS at once:
     IDL> monevents,/MEMS,tabs=0, maxper=22, /shot, clear_event='NSTX_SOC' ,/noclear
  for MEMS testing:
     IDL>  monevents,/shot,add=['sflip_files','test2','qcs_test'],tabs=0,/nocle, $
                     logfile='$HOME/ShotCycleEvents.log'
  for watching TF timing:
     IDL>  monevents,/shot,tabs=0,/nocle, $
          EVENTS_WANTED=['NSTX_SOD','PC_908C36N02_ACQ','PC_908C36N06_ACQ',  $
		   'PC_908C36N10_ACQ','PC_908C36N14_ACQ','TFMON_ACQ_DONE'];  for monitoring TF joint events, with a logfile in your home directory:
  for watching EFIT timing:
     IDL> monevents,/shot,/noclear,tabs=0, $
          EVENTS_WANTED=['NSTX_SOD','FDIA_CALC_DONE', $
                  'OP_H908_01_ACQUIRED', 'OP_H908_02_ACQUIRED', 'OP_H908_04_ACQUIRED',   $
                  'OP_H908_05_ACQUIRED', 'OP_H908_07_ACQUIRED', 'OP_H908_08_ACQUIRED',   $
                  'OP_H908_09_ACQUIRED', 'OP_H908_11_ACQUIRED', 'OP_H908_13_ACQUIRED',   $
		   'PHOENIXGO_P1', 'MPTS_FIT_DONE', 'PHOENIXGO_P2V1',  $
		   'phoenixDone_p1', $
		   'NSTX_ACQ_DONE',   $
		   'phoenixDone_p2' ],  $
       	   logfile='$HOME/EfitEvents.log'

 INPUTS:
       none.  
 KEYWORD PARAMETERS:
    (optional) 
	EVENTS_WANTED - String array of events to watch for
	LABELS - strings array to display instead of events
	FILE_INPUT - a text file of events to watch for (labels can follow each, in quotes)
	   format like:
		NSTX_SOC	       "Start of Cycle"
		BA_L8212_01_ACQ	       "Bolometers"
		GS_908C28N14_ACQ       "Gas Injection"
               ...
	CLEAR_EVENT - event to clear green lights on (default to EVENTS_WANTED[0]
	ADD_EVENTS - these events will be added to default events.
	MEMS - if set, will read the file for MEMS events, and use all there.
	LogFile - will log events to this file.
	LogEvents - if set, and LogFile not set, will log events to MonEvens.log
	nCols - number of columns wanted. Will default to 15 per column
	maxPerCol - another way to determine # of columns. Default=15.
	tabs - will default to tabs if more than one column. if=0, all on 1.
	NOCLEAR - if set, will not clear text boxes when first event is recognized
	PRINT - if set, will print messages when events are recognized
	SHOWSHOTS - if set, will display shot numbers declared with the events
	TIME - if set, will display time-of-day when event was declared
	BIG - if set, fonts are big
	WALL - if set, events of interest for display wall, and big font
	GIFseconds - seconds between writes of GIF file of window contents
		(good for making web-accessible displays). If not present, don't make files
	WebGifs - if set, will create a gif (to be read from the web) whenever widget is
		  updated (DEFAULT=0)
	BD - display events favored by a certain programmer.
       GROUP_LEADER - Group_Leader ID
	VERBOSE - if set, lots of information is output
 OUTPUTS:
	none.
 TESTING
	IDL> monevents, EVENTS_WANTED=['MY_TEST_EVENT_1','MY_TEST_event_2'], $
			/Shots
	   and from a VMS computer:  
	IDL> SetMDSShotEvent,'MY_TEST_EVENT_1', 999999
 COMMON BLOCKS:
       none
 ROUTINES USED:
	MK_COLOR, usingXwindows, MDSEVENT
 EXAMPLE:
	IDL> monevents

	IDL> monevents, num=450, prefix='gt', time=0, tab=0, npercol=30, show=0, shot=0
 LIMITATION:
	Shot numbers are only returned  when running on VMS currently.
 NOTES:
	The time of day will be printed for the first event, and the other times
	will be cleared. Then the time difference will be printed as mm:ss, 
	so :12 would mean it came 12 seconds after the first event. 

	The status fields are initially the background color.
	A real program might want to save !D.WINDOW before the TV commands
	and restore it immediately afterwards.
 MODIFICATION HISTORY:
	12-Apr-2010 add num and prefix keywords so can generate event names
	01-Oct-2008 Removed mdsconnect [BD]
	18-Aug-2008 Added labels to be displayed instead of events, if desired.
		    added WebGifs & GifSeconds keywords. Add
	10-Jul-2008 made logging of events clearer
	21-Feb-07 added /logevents and logfile as keywords
	08-Feb-06 Added clear_event keyword, and made it show up 1st in list
	09-Nov-05 added tabs and QCS keyword
	03-Feb-04 added wall keyword
	10-Feb-03 added keyword add_event [BD]
	14-Jun-01 Default to showing time
	20-Jul-00 Written by Bill Davis, PPPL


WATCHEVENTS

[Previous Routine] [List of Routines]
 NAME:
       watchevents
 PURPOSE:
       Widget to monitor occurrence of MDSplus events. 
	If all events do not happen before next occurance of first event, 
	send e-mail.
 CATEGORY:
       Events, MDSplus
 CALLING SEQUENCE:
       IDL> watchevents, events=['NSTX_SOC', 'my_event' ]
	IDL> watchevents, emailTo=['vlad@pppl.gov, joeshmoe@pppl.gov'], $
		events=['NSTX_ACQ_DONE', 'CAM1_DONE',  $
			'CAM2_DONE','CAM3_DONE','CAM4_DONE' ]
    to get all MPTS-relevant events:
	IDL>  watchevents,/shot,/show,add=['NSTX_ABC', 'MPTS_FORCEFIT', $
		'NSTX_ABS','NSTX_KLC','TS_RAW_READY']
 INPUTS:
       none.  
 KEYWORD PARAMETERS:
    (optional) 
	TEST - if set, appends TEST to all events
       EVENTS_WANTED - Character array of events to watch for.
			defaults to ['NSTX_SOC', 'CAM1_DONE',
			'CAM2_DONE','CAM3_DONE','CAM4_DONE' ]
       GROUP_LEADER - Group_Leader ID
	NOCLEAR - if set, will not clear events when first event is recognized
	PRINT - if set, will print messages when events are recognized
	SHOWSHOTS - if set, will display shot numbers declared with the events
	TIME - if set, will display time-of-day when event was declared
	add_events - if set, will add these event(s) to the default
	BIG - if set, fonts are big
	WALL - if set, events of interest for display wall, and big font
 OUTPUTS:
       none.
 NOTES:
       The time of day will be printed for the first event, and the other times
       will be cleared. Then the time difference will be printed as mm:ss, 
       so :12 would mean it came 12 seconds after the first event. 
 TESTING
	IDL> watchevents, EVENTS_WANTED=['MY_TEST_EVENT_1','MY_TEST_event_2'], $
			/Shots
	   and from a VMS computer:  
	IDL> SetMDSShotEvent,'MY_TEST_EVENT_1', 999999
 COMMON BLOCKS:
       none
 ROUTINES USED:
	MK_COLOR, usingXwindows, MDSEVENT
 EXAMPLE:
	IDL> watchevents
 LIMITATION:
	Shot numbers are only returned  when running on VMS currently.
 NOTES:
	As the events are declared, the boxes turn color.
 	When the first event in the list is recognized, the other boxes are
	set to yellow (unless /noClear was set). Shot numbers declared with 
	the events may optionally be displayed.
       The status fields are initially the background color.
	A program calling this routine, might want to save !D.WINDOW 
	before the TV commands and restore it immediately afterwards.
 MODIFICATION HISTORY:
	08-Sep-08 removed mdsconnect.
	10-Jun-05 Converted from Monevents.pro for Vlad.
	03-Feb-04 added wall keyword
	10-Feb-03 added keyword add_event [BD]
	14-Jun-01 Default to showing time
       20-Jul-00 Written by Bill Davis, PPPL


Category: Fast Cameras

[List of Routines]


CINETHUMBNAILS

[Next Routine] [List of Routines]
 NAME:
       cineThumbNails
 PURPOSE:
       Plot thumbnails of many frames from a .cin file
 CATEGORY:
       Fast Cameras
 CALLING SEQUENCE:
       IDL> cinethumbnails, shot
 INPUTS:
       shot - optional alternate to filename; if more than one cine file found
	       you will get a dialog box (if no shot or filename entered, will be prompted)  
 KEYWORD PARAMETERS:
   Inputs:
      (Optional)
	filename - optional name of cine file (fastest when this used)
	t1 - start time of thumbnails (sec.)
	t2 - end time of thumbnails (sec.)
	nWanted - # of thumbnails (defaults to 108)
	edge - if set, will show plasma edge on picture (separatrix) (NOT WORKING)
       fit - type of fit for separatrix plot
	deltaT - time between thumbnails
	minVal - min value to use in byte scaling (default=0)
	maxVal - max value to use in byte scaling (default depends on camera type)
		>>> if = 0, each frame will be byte scaled.
	bytescale - if set, bytescale frames
	gamma - gamma to apply to image (Default=0.55)
	ctb - color table for non-color image 
	saturation - (Default=0.3)
	xsize - horizontal size of plot window (defaults to 640, but will let you manually expand)
	ysize - vertical size of plot window (defaults to 512, but will let you manually expand)
	label - if=0 will not label each frame with time in msec
	title - if=0 will not print file name at top right of frame   
	horizontal_flip - if set, flip images horizontally
	vertical_flip - if set, flip images vertically
       RotCCW - rotate image Counter-ClockWise
	RotCW - rotate image ClockWise
	nRows - # of rows of thumbnails
	top2bottom - if=0, time will go from bottom to top
	border - # of pixels between images (default=1)
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	(none)
 OUTPUTS:
       just plots to graphic window
 EXAMPLES:
     !P.FONT=0
     setup_ps, 'Thumbs_138117.ps', printer = 'postscript color'
  cinethumbnails,  /horiz, /rotccw, ctb=3,  $
	'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138117.cin', $
	minVal=20, maxVal=230, nWanted=40, /edge, $
	t1=0.242,t2=0.248, xsize=900, ysize=580, nsmooth=3, thick=3
     unsetup_ps
  cinethumbnails,  /horiz, /rotccw, ctb=3,  $
	'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139050.cin', $
	t1=0.399,t2=0.455, xsize=900, ysize=580,/debug
   IDL> i = 0
   IDL> i = i+1
   IDL> cinethumbnails, '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138120.cin', $
		t1=0.219+i*0.001, t2=0.219+(i+1)*0.001, /horizontal_flip, /RotCCW, ctb=3, $
		xsize=1024, ysize=780
   IDL> mk_jpeg,'~/sh138120_'+strtrim(219+i,2)+'ms.jpg'

   IDL> cinethumbnails, '/p/nstxcam/Miro2-7988/2010/nstx_2_137600.cin'
   		    (expand window manually)

   IDL> cinethumbnails, 137726, xsize=1600,ysize=1000, t1=.03, t2=.31, nwanted=45
   		    (select the Miro file)

   IDL> cinethumbnails,'/p/nstxcam/Phantom73-6663/2010/nstx_3_137726.cin',maxval=0, $
   		       t1=.100,t2=.274      ; (will byte scale each frame)

   IDL> cinethumbnails,'/p/nstxcam/Phantom710-9206/2010/nstx_1_137726.cin',maxval=2000, $
   			t1=.246,t2=.267,nw=23
  	  ; to test separtrix drawing
   IDL> cinethumbnails, '/p/nstxcam/Phantom710-9205/2010/nstx_5_139444.cin', $
   			 t1=.255,t2=.285, /horizontal_flip, /RotCCW, ctb=3, $
   			 nwanted=20, /bytescale, /edge
  	  ; or from CMOD:
   IDL> cinethumbnails,  $
	   '/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216028.cin', $
   	   t1=.0,t2=.02, /horizontal_flip, ctb=3, nwanted=20, /bytescale, /edge

   IDL> cinethumbnails, 'nstx_5_137582.cin', t1=.32, t2=.37, $
		nSmooth=3, Rotation=1, /horiz, xSize=1300, ySize=900, /edge
		

   IDL> cinethumbnails, '/p/nstxcam/Phantom73-8032/2010/nstx_4_137702.cin'

     for Stewart's FY15 GPI paper:
   IDL> cinethumbnails, t1=.550929, t2=.551029, label=0, /edge,  $
	    nSmooth=3, Rotation=1, /horiz, xSize=668, ySize=652*.666,  $
	    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_140395.cin', $
	    /rainbow, border=3, /ellip, nWanted=8, nrows=2, howFar=.2, /verb

   IDL> !P.FONT=0
   IDL> setup_ps, 'thumbs_140395.ps', printer='postscript', /color
   IDL> cinethumbnails, t1=.550929, t2=.551029, label=0, /edge,  $
	    nSmooth=3, Rotation=1, /horiz, xSize=668*10./8, ySize=652*.666,  $
	    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_140395.cin', $
           aveT1=.5505, aveT2=.5515, showCon=1, nlevs=600, $
	    /rainbow, border=3, /ellip, nWanted=10, nrows=2, howFar=.1, /verb
   IDL> unsetup_up

   IDL> mk_jpeg, 'mythumbs.jpg'    ; make a jpeg file of whatever is plotted
   IDL> cinethumbnails, t1=.550929, t2=.551029, label=0, /edge,  $
	    nSmooth=3, Rotation=1, /horiz, xSize=668*10./8+80, ySize=652*.666, $
	    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_140395.cin',       $
	    /rainbow, border=3, /ellip, nWanted=10, nrows=2, howFar=.1, /norm, $
	    bytescale=0, aveT1=.5505, aveT2=.5515, minVal=0.405, maxVal=2.159, $
	    /colorbar

   IDL> cinethumbnails, /edge,  $
	    nSmooth=3, Rotation=1, /horiz, xSize=668*10./8+80, ySize=652*.666, $
	    '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_140395.cin',       $
	    /rainbow, border=3, /ellip, nWanted=10, nrows=2, howFar=.1, /norm, $
	    bytescale=0, aveT1=.5505, aveT2=.5515, minVal=0.405, maxVal=2.159, $
	    /colorbar, t1=.550929, t2=.551029, label=0,/verbose
 NOTES:
	see http://nstx.pppl.gov/nstx/Software/Applications/cinethumbnails.html
	for examples
 MODIFICATION HISTORY:
   30-Jul-2014 handle white at bottom of color table
   14-Oct-2013 added FIT keyword for separatrix plot
   07-Mar-2013 added keywords top2bot (now default), nrows, and border (def=1)
   26-Feb-2013 mods to work from a web page. Added medsmooth keyword.
   12-Dec-2011 put flip and rotate in for doing blob work. Also adding option to show
		separatrix and limiter shadow
   14-Dec-2010 made to work with monochrome files (not True Color)
   Written by Bill Davis, 12-Apr-2010


LOAD_FC

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       load_fc
 PURPOSE:
       Load summary Waveforms for Phantom Fast Cameras into MDSplus.
 PROCEDURE:
 CATEGORY:
       Fast Cameras, MDSplus
 CALLING SEQUENCE:
	load_fc, shot1, shot2, path=['/p/nstxusr/miro/2009','/p/nstxcam/miro/2009'], $
			       prefix='Miro'
	load_fc, shot1, shot2, path='/p/nstxusr/miro/2008',prefix='Miro'
 INPUTS:
	shot1 = starting shot number to process
	shot2 = (Optional) last shot number to process
 KEYWORDS:
    (Optional)
	test  - doesn't write to MDSplus
	EventDone - if there, will declare this event when all of one shot done
	noDeclare - if set, will declare NO events.
 COMMON BLOCKS:
       NONE
 NOTES:
       YOU NEED PRIVILEGES to write to the MDSplus tree. On skylark:

	IDL> addSigNodes, shot1, shot2, tree='CAMERAS', $
		nodes=['\aveintensity', '\maxintensity', '\ave_r','\ave_g','\ave_b' ], $
		tags =['\aveint', '\maxint','\ave_r','\ave_g','\ave_b']
	    (probably better to do the above in TCL procedure
 LIMITATIONS:
 MODIFICATION HISTORY:
  	09-Mar-2007 WRITTEN by Bill Davis


MKMANYMOVIES

[Previous Routine] [List of Routines]
 NAME:
       MKMANYMOVIES

 PURPOSE:
  	make animations for the Fast Camera data from a shot list

 CATEGORY:
       Fast Cameras

 CALLING SEQUENCE:
       IDL> 

 INPUTS:
       shot = NSTX shot number 
	
 KEYWORD PARAMETERS:
    Inputs:
	infile - filename for shot list
	t1 - start time in msec
	t2 - end time in msec
	outDir -
	shortName -
	minWidth -
	minVal - Min pixel value to show. DEF = 0
	maxVal - Max pixel value to show, DEF = 16383
	Saturation
	fps
	skip - 
	auto - 
	baseDir - 
	overwrite - 
	xsize - horizontal size of X window
	ysize - vertical size of X window
	xpos - initial X position of lower left of X window in pixels
	ypos - initial Y position of lower left of X window in pixels
	charsize - size of characters on plot
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	status - if odd, then success

 OUTPUTS:
       movie files

 EXAMPLE:
	IDL> mkmanymovies, infile='testshots.txt'

		; to just do one shot
	IDL> mkmanymovies, shot=120870

 NOTES:

 MODIFICATION HISTORY:
	04-Feb-2015 Roger wanted files from other years, so adding logic
       29-Jan-2015 Written by Bill Davis, PPPL, for Roger Raman


Category: files

[List of Routines]


FDECOMP

[Next Routine] [List of Routines]
 NAME:
	FDECOMP
 PURPOSE:
	Routine to decompose a file name for any operating system

 CATEGORY:
	Files, OS Specific, Strings
 CALLING SEQENCE:
	FDECOMP, filename, disk, dir, name, qual, version, [OSFamily = ]

 INPUT:
	filename - string file name, scalar

 OUTPUTS:
	All the output parameters are scalar strings
	disk - disk name, always '' on a Unix machine, scalar string
	dir - directory name, scalar string
	name - file name, scalar string
	qual - qualifier, set equal to the characters beyond the last "."
	version - version number, always '' on a non-VMS machine, scalar string

 OPTIONAL INPUT KEYWORD:
	OSFamily - one of the four scalar strings specifying the operating 
		system:  'vms','windows','MacOS' or 'unix'.    If not supplied,
		then OS_FAMILY() is used to determine the operating system.
 EXAMPLES:
	Consider the following file names 

	Unix:    file = '/rsi/idl40/avg.pro' 
	VMS:     file = '$1$dua5:[rsi.idl40]avg.pro;3
	Mac:     file = 'Macintosh HD:Programs:avg.pro'
	Windows: file =  'd:\rsi\idl40\avg.pro'
	
	then IDL> FDECOMP,  file, disk, dir, name, qual, version
	will return the following

		  Disk             Dir          Name        Qual     Version
	Unix:      ''            '/rsi/idl40/'  'avg'       'pro'       ''
	VMS:     '$1$dua5'       '[RSI.IDL40]'  'avg'       'pro'       '3'
	Mac:     'Macintosh HD'  ':Programs:'   'avg'       'pro'       ''
	Windows:    'd:'         \rsi\idl40\    'avg'       'pro'       ''

 NOTES:
	(1) All tokens are removed between
		1) name and qual  (i.e period is removed)
		2) qual and ver   (i.e. VMS semicolon is removed)
	(2) On VMS the filenames "MOTD" and "MOTD." are distinguished by the 
	    fact that qual = '' for the former and qual = ' ' for the latter.

 ROUTINES CALLED:
	Function GETTOK(), OS_FAMILY()
	Users with V4.0 or later can replace OS_FAMILY() with !VERSION.OS_FAMILY
 HISTORY
	version 1  D. Lindler  Oct 1986
	Include VMS DECNET machine name in disk    W. Landsman  HSTX  Feb. 94
	Converted to Mac IDL, I. Freedman HSTX March 1994
          


FILE2STRUCT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	file2struct

 PURPOSE:
 	return a structure where elements are named with column headings, and 
	arrays are the columns

 CATEGORY:
       files

 CALLING SEQUENCE:
       IDL> struct = file2struct(filename)

 INPUTS:
       filename - file name with columns and, preferably, headings
	

 KEYWORDS:
	strip - if set, strip everything from column headings up to
		and including the first period
	FORMAT - scalar string containing a letter specifying an IDL type
		for each column of data to be read.  Allowed letters are 
		A - string data, B - byte, D - double precision, F- floating 
		point, I - integer, L - longword, and X - skip a column.
		(G & E equate to F)

		Columns without a specified format are assumed to be floating 
		point.  Examples of valid values of FMT are

	   'A,B,I'   ;First column to read as 6 character string, then 
	   	      1 column of byte data, 1 column integer data. 'V' for LONG64
	   'L,L,L,L'  ;Four columns will be read as longword arrays.
	   ' '        ;All columns are floating point

	If a FORMAT keyword string is not supplied, then all columns are 
	assumed to be floating point.

	SILENT - Normally, READCOL will display each line that it skips over.
		If SILENT is set and non-zero then these messages will be 
		suppressed.
	DEBUG - If this keyword is non-zero, then additional information is
		 printed as READCOL attempts to read and interpret the file.
	nSkip - Scalar specifying number of lines to skip at the top of file
		before reading.   Default is to start at the first line.
	        Headings for the columns (the last line skipped) will be the tags
		in the structures.
	COMMENT - skip if a line begins with this
	NUMLINE - Scalar specifying number of lines in the file to read.  
		Default is to read the entire file
	LINESSKIPPED - Ascii array of lines skipped
	TABDELIM - If set, then assume columns are delimitted by tabs
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed

 OUTPUTS:
	struct - structure containing the filename and a tag for each column

 EXAMPLES:
	IDL> struct = file2struct( '/u/bdavis/Blobs/readtest.txt', nskip=1, /strip, $
		FORMAT='I,F,F,F,F,F,I,F,F,F,I,F,I,F,F,F,F,F,I,F,F,F,F,F,F,F,F,F,F,F,F,F' )

	IDL> loadblobs,t1=0.18,t2=0.35, dbout='/u/bdavis/Blobs/blobs141751.txt', $
		 '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141751.cin'
	IDL> struct = file2struct( '/u/bdavis/Blobs/blobs141751.txt', nskip=3,  $
		FORMAT='I,F,F,F,F,F,I,F,F,F,I,F,I,F,F,F,F,F,I,F,F,F,F,F,F,F,F,F,F,F,F,F' )

 REVISION HISTORY:
   03-Jul-2012  take the last non-blank line at the top for the column 
   		 headings & tag names
   WRITTEN 02-May-2012 by Bill Davis for Ahmed Diallo


FINDCAMFILES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       findcamfiles
 PURPOSE:
       Find camera files in various directories Environmental/System
       variable FC_DATA_DIR will be used, if set, to  look for files
	containing the string in 'filename'  
 CATEGORY:
       Files
 CALLING SEQUENCE:
       IDL> paths = findcamfiles(shotstr)
 INPUTS:
       shotstr = anything, but usually a shot number.  If not present,
                  a dialog box will pop up.
 KEYWORD PARAMETERS:
        dirs - directories to search. If not set, the known NSTX camera  
                directories will be searched.
        defPath - path to find most recent "*.cin" file for default selection
        first - if set, will just return the first match (for speed)
        pick - if set, and more than one match found, will pop a dialog
                box for user to pick one.
        noPick - Do not offer dialog box, even if no file found
        CASE_SENSITIVE - if not set, search will be case insensitive.
        subDirectories - if NOT set, WILL search subdirectories
	 camera - optional input, if you want cameras with file names including "_n_" 
	 SANfaster - if file is on both /p/nstxcamera and /p/nstxcam, just 
		     offer /p/nstxcam
        verbose - if set, will print many informational messages
        debug - if set, debug output will be printed
 OUTPUTS:
       paths = paths of files matching input in directories searched
 EXAMPLE:
        IDL> print, findcamfiles( '*miro*134180' )
        IDL> print, findcamfiles( 142000 )
        IDL> print, findcamfiles( 'nstx_5_139442' )
 NOTES:
 	if file is on both /p/nstxcamera and /p/nstxcam, in 2010, /p/nstxcam 
	was much faster. if this is not true, set keyword SANfaster to 0.
 MODIFICATION HISTORY:
	10-Jan-2014 fix bug when shot not specified
	27-Feb-2013 - don't modify camera input string
	20-Sep-2012  fixed bug when shotstr_in just a shot number 
  	10-Sep-2012 - Account for data to be read via MDSplus at MIT for CMOD.
		      if shot is > 9, no directory info included, and file not
		      if the current directory, then get from tree at MIT
        08-Dec-2011 added camera keyword
	 25-Jul-2011 don't overwrite shotstr input
	 08-Dec-2010 if file is on both /p/nstxcamera and /p/nstxcam, in 2010, 
		     /p/nstxcam was much faster, so just offer it.
        03-Nov-2010 mods for running on a PC or Mac.
        07-Oct-2010 fixed a bug finding old files, when search string not found in last dir
        16-Jul-2010 added ext keyword, and default to "cin*" so .txt files, etc. don't show
        19-Jan-2010 use getcamdirs() so list of NSTX dirs is in one place.
                    Assuming FILE_SEARCH will include subdirectories if 2 arguments used
                    (this didn't always work in some testing)
        14-Jan-2010 if no files in the default directory, back up a year and check
        06-Nov-2009 Default to case-insensitive searches.
        21-Jul-2009 added other areas (this will probably be pretty slow)
        06-Jul-2009 Written by Bill Davis, PPPL


GETNEXTFILE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       getNextFile
 PURPOSE:
 	get next file in a directory, defaulting to alphabetic search
 CATEGORY:
       Files
 CALLING SEQUENCE:
       IDL> nextFile = getNextFile( inFile )
 INPUTS:
       input = filename with or without directory prefix
 KEYWORD PARAMETERS:
	numeric - if set will try to sort files numerically, so *_9.ext will
		   come before *_10.ext 
	back - if set will go back one in list
 OUTPUTS:
       nextFile               			out
 EXAMPLE:
	IDL> infile='/p/camdata/fastsoftxray/NSTX_119761/Frame_287.tif'
	IDL> nextFile = GetNextFile( inFile)

	IDL> infile='/p/camdata/fast_camera/shot000119681/NSTX000119681_35.tif'
	IDL> print, GetNextFile( inFile, /numeric)
 NOTES:
   	finds all files of the form AAAAAA_*.ext (if no "_" in file, just
	return next in alphabetical order)
 MODIFICATION HISTORY:
	29-Jun-2006 added back keyword
       20-Apr-2006 Written by Bill Davis, PPPL


H5DFROMTEXT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	h5dfromtext 

 PURPOSE:
	create a H5D file from a text file with columns of data

 CATEGORY:
       files

 CALLING SEQUENCE:
       IDL> h5dfromtext, in_filename=in_filename, out_filename=out_filename

 KEYWORD INPUTS:
       in_filename - file name with columns and, preferably, headings
	out_filename - name of H5D file to write (defaults to in_filename with .H5 ext)
	strip - if set, strip everything from column headings up to
		and including the first period
	FORMAT - scalar string containing a letter specifying an IDL type
		for each column of data to be read.  Allowed letters are 
		A - string data, B - byte, D - double precision, F- floating 
		point, I - integer, L - longword, and X - skip a column.
		(G & E equate to F)

		Columns without a specified format are assumed to be floating 
		point.  Examples of valid values of FMT are

	   'A,B,I'   ;First column to read as 6 character string, then 
	   	      1 column of byte data, 1 column integer data. 'V' for LONG64
	   'L,L,L,L'  ;Four columns will be read as longword arrays.
	   ' '        ;All columns are floating point

	If a FORMAT keyword string is not supplied, then all columns are 
	assumed to be floating point.

	SILENT - Normally, READCOL will display each line that it skips over.
		If SILENT is set and non-zero then these messages will be 
		suppressed.
	DEBUG - If this keyword is non-zero, then additional information is
		 printed as READCOL attempts to read and interpret the file.
	nSkip - Scalar specifying number of lines to skip at the top of file
		before reading.   Default is to start at the first line.
	COMMENT - skip if a line begins with this
	NUMLINE - Scalar specifying number of lines in the file to read.  
		Default is to read the entire file
	LINESSKIPPED - Ascii array of lines skipped
	TABDELIM - If set, then assume columns are delimitted by tabs
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed

 OUTPUTS:
	status 
	(file written)

 EXAMPLES:
	IDL> h5dfromtext, in_filename='/u/bdavis/Blobs/readtest.txt', nskip=1, /strip, $
		FORMAT='I,F,F,F,F,F,I,F,F,F,I,F,I,F,F,F,F,F,I,F,F,F,F,F,F,F,F,F,F,F,F,F'

 REVISION HISTORY:
  	WRITTEN 02-May-2012 by Bill Davis for Ahmed Diall0


MKDATEDIR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	mkdatedir
 PURPOSE:
	Make a directory of the form YYYYMMDD (if it doesnt't exist)
	and move files there if the files were last modified on that date. 
 CATEGORY:
	Files, Dates
 CALLING SEQUENCE:
	IDL> mkdatedir, path=path, prefix=prefix, ext=ext, date=date
 INPUTS:
       none
 KEYWORD PARAMETERS:
	PATH - directory
	PREFIX - file prefix for deletion
	EXT - file extension for deletion; file search will be path+prefix+'*.'+ext 
	DATE - date for search, of form yyyymmdd, e.g., 20050617 (default=TODAY)
	ALL - if set, all files will be moved to the right directory (overrides DATE)
	VERBOSE - if set, will print informational output
 OUTPUTS:
	none
 LIMITATIONS
	Only works on Unix/Linux
 MODIFICATION HISTORY:
	03-Feb-2015 changed SpecFit directory so search doesn't get bogged down
	07-Mar-2007 Added keyword all
	22-Aug-2005 Written by Bill Davis, PPPL


MK_FILENAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mk_filename
 PURPOSE:
       File names with system independent symbolic directories.
 CATEGORY:
	Files, OS Specific, File I/O
 CALLING SEQUENCE:
       f = mk_filename(symdir, name)
 INPUTS:
       symdir = symbolic directory name.   in
       name = file name.                   in
 KEYWORD PARAMETERS:
       Keywords:
         /NOSYM means directory given is not a symbolic name.
         OPSYS=os specifiy operating system to over-ride
           actual.  Use VMS, WINDOWS, or MACOS.  UNIX is default.
	  SUBDIR=s  Subdirectory below the symdir, e.g., SUBDIR='dir1/dir2'
         DELIM=c delimiter character between directory and
           file name.  This is returned.
 OUTPUTS:
       f = file name including directory.  out
 COMMON BLOCKS:
 NOTES:
       Notes: symdir is a logical name for VMS and
         an environmental variable for UNIX and WINDOWS.  Ex:
         DEFINE IDL_IDLUSR d0:[publib.idl]  for VMS
         set IDL_IDLUSR=c:\IDL\LIB\IDLUSR   for WINDOWS.
         setenv IDL_IDLUSR /usr/pub/idl     for UNIX.
         Then in IDL: f=mk_filename('IDL_IDLUSR','tmp.tmp')
         will be the name of the file tmp.tmp in IDL_IDLUSR.
 MODIFICATION HISTORY:
       R. Sterner,  4 Feb, 1991
       R. Sterner, 27 Mar, 1991 --- added /NOSYM
       R. Sterner, 21 May, 1991 --- If not a listed opsys assume unix.
       R. Sterner,  4 Jun, 1991 --- added DOS.
       R. Sterner,  2 Jul, 1991 --- added DELIM.
       R. Sterner, 17 Jan, 1992 --- added OPSYS= and avoided double //
       R. Sterner, 1994 Feb 7 --- Added MacOS.
       R. Sterner, 1994 Feb 14 --- Changed DOS to windows.
       B. Davis - nenamed from filename.pro. Added SUBDIR keyword

 Copyright (C) 1991, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


MVSHOTRANGEDIR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mvshotrangedir
 PURPOSE:
       Put files fitting a certain partern into a sub-directory of the form nnnn00s, 
	where nnnn00 represents a shot range,
	e.g., 114100s whould contain shots 114100-114199. 
 CATEGORY:
       Files, Dates
 CALLING SEQUENCE:
       IDL> mvshotrangedir, path=path, prefix=prefix, ext=ext, date=date
 INPUTS:
       none
 KEYWORD PARAMETERS:
       path - directory
       prefix - file prefix for deletion
       ext - file extension for deletion; file search will be path+prefix+'*.'+ext 
       verbose - if set, will print informational output
 OUTPUTS:
       none
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> mvshotrangedir,/verb

	IDL> for i=1408, 1420 do mvshotrangedir, fourDigits=strtrim(i), /verb
 NOTES:
 LIMITATIONS
	Only works on Unix/Linux
 MODIFICATION HISTORY:
	03-Feb-2015 changed SpecFit directory so search doesn't get bogged down
	21-Oct-2010 made work
	23-May-2006 do all files in dir
       15-May-2006 Written by Bill Davis, PPPL


NUMLINES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	NUMLINES

 PURPOSE:
	Return the number of lines in a file

 CATEGORY:
       Files

 CALLING SEQUENCE:
	nl = NUMLINES( filename )

 INPUT:
	filename = name of file, scalar string

 OUTPUT:
	nl = number of lines in the file, scalar longword
	     Set to -1 if the number of lines could not be determined
 METHOD:
	If Unix then spawn to wc; otherwise read 1 line at a time and count

 PROCEDURE CALLS:
	OS_FAMILY() - Determine if a unix system; Users with IDL V4.0 or later
		can replace this with !VERSION.OS_FAMILY

 MODIFICATION HISTORY:
	22-May-2015 BD handle 0 length (because saved from mac)
 	07-Oct-98 BD Added StopOnError Keyword
		     in unix, handle stuff printed from .cshrc when spawning wc
	W. Landsman February 1996


READ_ARRAY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       read_array
 PURPOSE:
	Read a numeric array (1-D) from a text file
 CATEGORY:
       Files
 CALLING SEQUENCE:
       IDL> num_array = read_array(filename)
 INPUTS:
       filename = name of file containing lines of ascii data.
 KEYWORD PARAMETERS:
	nskip    - number of lines to skip before reading
	status - odd, if OK
 OUTPUTS:
       num_array = returned array of floating point values
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> num_array = read_array( filename )
 NOTES:;
 MODIFICATION HISTORY:
       01-Aug-2008 Written by Bill Davis, PPPL


READCOL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	READCOL

 PURPOSE:
	Read a free-format ASCII data file with columns of data into IDL 
	variables.  Lines of data not meeting the specified format (e.g. 
	comments) are ignored.  Columns may be separated by commas or spaces.
	Use READFMT to read a fixed-format ASCII file.   Use RDFLOAT for
	much faster I/O (but less flexibility).

 CATEGORY:
	Files

 CALLING SEQUENCE:
	READCOL, name, v1 [, v2, v3, v4, v5, ...  v25 , status=status, $
             FORMAT = , /DEBUG ,  /SILENT , nSkip = , NUMLINE =, comment= ]

 INPUTS:
	NAME - Name of ASCII data file, scalar string.  In VMS, an extension of 
		.DAT is assumed, if not supplied.

 OPTIONAL INPUT KEYWORDS:
	FORMAT - scalar string containing a letter specifying an IDL type
		for each column of data to be read.  Allowed letters are 
		A - string data, 
		B - byte,  
		D - double precision,  
		F- floating point, 
		I - integer,  
		L - longword, and  
		X - skip a column.
		(G & E equate to F)

		Columns without a specified format are assumed to be floating 
		point.  Examples of valid values of FMT are

	'A,B,I'        ;First column to read as 6 character string, then 
			1 column of byte data, 1 column integer data. 'V' for LONG64
	'L,L,L,L'       ;Four columns will be read as longword arrays.
	' '             ;All columns are floating point

	If a FORMAT keyword string is not supplied, then all columns are 
	assumed to be floating point.

	SILENT - Normally, READCOL will display each line that it skips over.
		If SILENT is set and non-zero then these messages will be 
		suppressed.
	DEBUG - If this keyword is non-zero, then additional information is
		 printed as READCOL attempts to read and interpret the file.
	nSkip - Scalar specifying number of lines to skip at the top of file
		before reading.   Default is to start at the first line.
	COMMENT - skip if a line begins with this
	NUMLINE - Scalar specifying number of lines in the file to read.  
		Default is to read the entire file
	LINESSKIPPED - Ascii array of lines skipped
	TABDELIM - If set, then assume columns are delimitted by tabs
	DELIM - e.g., ",". There can then be blanks within fields

 OUTPUTS:
	V1,V2,V3,...V15 - IDL vectors to contain columns of data.
		Up to 25 columns may be read.  The type of the output vectors
		are as specified by FORMAT.

 EXAMPLES:
	Each row in a file POSITION.DAT contains a star name and 6 columns
	of data giving an RA and Dec in sexigesimal format.   Read into IDL 
	variables.  (NOTE: The star names must not contain internal spaces.)

	IDL> FMT = 'A,I,I,F,I,I,F'
	IDL> READCOL,'POSITION',F=FMT,name,hr,min,sec,deg,dmin,dsec  

	The HR,MIN,DEG, and DMIN variables will be integer vectors.

	Alternatively, all except the first column could be specified as
	floating point.

	IDL> READCOL,'POSITION',F='A',name,hr,min,sec,deg,dmin,dsec 

	To read just the variables HR,MIN,SEC
	IDL> READCOL,'POSITION',F='X,I,I,F',HR,MIN,SEC

 RESTRICTIONS:
	This procedure is designed for generality and not for speed.
	If a large ASCII file is to be read repeatedly, it may be worth
	writing a specialized reader.

	Columns to be read as strings must not contain spaces or commas, 
	since these are interpreted as column delimiters.  
	(UNLESS /TABDELIM is used). Use READFMT to read such files.

	Numeric values are converted to specified format.  For example,
	the value 0.13 read with an 'I' format will be converted to 0.

	When DELIM specified (and not blank), first all blanks are replaced
	with |b, then delimiter characters within quoted strings are replaced
	with a backtick. After the columns are parsed and put into variables,
	the proper characters are put back in.

 PROCEDURES CALLED
	GETTOK(), NUMLINES(), REPCHR(), STRNUMBER(), ZPARCHECK

 REVISION HISTORY:
	20-Feb-2014 added ReplaceTab keyword for when file is tab delimited 
		    and has @'s in it.
	21-Nov-2013 added DELIM keyword. This is especially for columns with 
			spaces in cells. Ignore delimiters within quoted strings.
	14-Apr-2010 added datatype 'V' for LONG64
	16-Oct-2008 added status keyword
	24-Aug-99 Added LINESSKIPPED keyword
    10/99 Added TABDELIM keyword [Bill Davis]
	Written         W. Landsman                 November, 1988
	Modified	     J. Bloch 			June, 1991
	(Fixed problem with over allocation of logical units.)
	Added nSkip and NUMLINE keywords  W. Landsman    March 92
	Read a maximum of 25 cols.  Joan Isensee, Hughes STX Corp., 15-SEP-93.
	Call NUMLINES() function W. Lansdman          Feb. 1996


READ_FLOATS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       read_floats
 PURPOSE:
      Read a list from a text file and return a floating-point array
 CATEGORY:
       Files
 CALLING SEQUENCE:
       IDL> floats = read_floats(filename)
 INPUTS:
       filename = name of file containing lines of ascii data.  
 KEYWORD PARAMETERS:
	HLP - When set, help information is printed.
	nskip - lines to skip 
	status - if even, then read was successful
 OUTPUTS:
       floats = returned array of floats - 1 per line             	out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> floats = read_floats( 'hans.txt', maxlines=500000 )
 NOTES:
 MODIFICATION HISTORY:
	26-Sep-2008 Written by Bill Davis, PPPL


READ_GENERIC

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       read_generic
 PURPOSE:
        read an image from a variety of types of files
 CATEGORY:
       Files, Graphics
 CALLING SEQUENCE:
       IDL> data2D = read_generic( filename )
 INPUTS:
       filename - file name to read in
		can be type 'jpg','tif','tif','bmp','jpeg,'png', 'ppm', 'pgm', or 'gif'
 KEYWORD PARAMETERS:
       Optional output:
	  extension - the file extension, eg., 'jpg'
	  inDim - for .raww files, specify x & y dimensions (Default to [256,128])
	  nBytesPer- for .raww files, specify number of bytes per data point (Default=2)
	  center - if set, will only return center columns (1/2 of data)
 OUTPUTS:
       2-D data array from file               			out
 COMMON BLOCKS:
       NONE
 MODIFICATION HISTORY:
	17-Jul-2013 return bad status if fails in read_image
	15-Apr-2009 added support for .raww type (from Photron cameras)
	30-Sep-2008 added channel keyword
	25-Apr-2007 added colortable keyword
	21-Feb-2007 added ppm file type
	19-Apr-2006 replaced keywords with args R,G,B 
	15-Oct-2004 Written by Bill Davis, PPPL 


READ_LIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       READ_LIST
 PURPOSE:
       Read a list from a text file and return a string array. 
	Will ignore lines beginning with a semicolon, but will
	will return blank lines.
 CATEGORY:
       Files
 CALLING SEQUENCE:
       IDL> str_array = READ_LIST(filename)
 INPUTS:
       filename = name of file containing lines of ascii data.  
 KEYWORD PARAMETERS:
	HLP - When set, help information is printed.
	nskip - lines to skip 
	status - if even, then read was successful
 OUTPUTS:
       str_array = returned array of strings - 1 per line             	out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> str_array = READ_LIST( filename )
 NOTES:
 MODIFICATION HISTORY:
	16-Aug-2008 added skipChar keyword
	01-Aug-2008 added nskip keyword
	13-Apr-2007 added status keyword
	11-Apr-06 added maxlines keyword [BD]
       1-Apr-99 Written by Bill Davis, PPPL


READNETCDFBLOBS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       readnetcdfblobs

 PURPOSE:
  	Read NetCDF files of dummy Blob data for code validation.
  	the files can be generated with gennetcdfblobs.

 CATEGORY:
       files, Fast Cameras

 CALLING SEQUENCE:
	IDL> img = readnetcdfblobs(filename, framenumber, times=times)

 EXAMPLE:
	IDL> img = readnetcdfblobs('circoneup_1.nc', 1)

	IDL> dum=readnetcdfblobs('circmany_3.nc', 1, xvel=xvel, yvel=yvel)
	IDL> print, xvel[0], yvel[0]

	see ncdf_cat.pro for example of reading netcdf files.

 MODIFICATION HISTORY:
	WRITTEN 31-Oct-2013 by Bill Davis, PPPL, for Stewart Zweben


READ_NUMBERS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       read_numbers
 PURPOSE:
	Read a numeric array (1-D) from a text file
 CATEGORY:
       Files
 CALLING SEQUENCE:
       IDL> num_array = read_numbers(filename)
 INPUTS:
       filename = name of file containing lines of ascii data.
 KEYWORD PARAMETERS:
	nskip    - number of lines to skip before reading
	status - odd, if OK
 OUTPUTS:
       num_array = returned array of floating point values
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> num_array = read_numbers( filename )
 NOTES:;
 MODIFICATION HISTORY:
       28-Feb-2002 Written by Bill Davis, PPPL


READ_QUOTED

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
	READ_QUOTED
  PURPOSE:
	Reads a file and returns anything between first two quotes.
 CATEGORY:
       Files
  CALLING SEQUENCE:
	IDL> comments = READ_QUOTED(filename)
 INPUT:        
	filename - e.g., "waveform.DAT"
  RETURNED:
	comments - string array with dimension = # of lines read (& not skipped)
 KEYWORDS
	delim - quote character, defaults to "
	nskip    - number of lines to skip before reading
 RETURNED:
	strings  - string array

 MODIFICATION HISTORY:
	16-Aug-2008 added skipChar & status keywords
 	26-Aug-00 WMD Written


READ_TABLE

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
 	read_table
  PURPOSE:
       Reads a table file, like from a spreadsheet.  

  CATEGORY:
       files

  CALLING SEQUENCE:
   	IDL> data2d = read_table( filename, nskip=nskip, header=header )

  INPUT:        
	filename - e.g., "AMP.DAT"

  OPTIONAL INPUT:
	nskip    - number of lines to skip before reading (will be returned in header)
	nCols - # of data values per line
       maxLines - default=1,000,000
	delim - if not tab-delimited, set this to ' '

  OPTIONAL OUTPUT:
	strings - if set, returns a string array, rather than floats

  RETURNED:
	Data_2D  - nCols x N array

  EXAMPLE:
	IDL> data2d=read_table('/u/bdavis/StrachanDB/HiRadEnergyBal.txt', nskip=1, $
			       header=header, /strings )

  LIMITATIONS:
	Can't handle blanks in fields

  WRITTEN 25-Feb-2011 by Bill Davis for Jim Strachan


RMFILESBYDATE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       rmfilesbydate
 PURPOSE:
       Remove files not modified since a certain date
 CATEGORY:
       Files, Dates
 CALLING SEQUENCE:
       IDL> rmfilesbydate, path=path, prefix=prefix, ext=ext, date=date
 INPUTS:
       none
 KEYWORD PARAMETERS:
       path - directory
       prefix - file prefix for deletion
       ext - file extension for deletion; file search will be path+prefix+'*.'+ext 
       date - date for search, of form yyyymmdd, e.g., 20050617 (default=TODAY)
       daysbefore - optional additional number of days before date
       verbose - if set, will print informational output
       justprint - if set, will not remove files
 OUTPUTS:
       none
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> 
 NOTES:
 	for safety, on Unix, you may wish to create a ~/Trash directory 
	and alias rm to
 	   /bin/mv !* ~/Trash
 LIMITATIONS
 MODIFICATION HISTORY:
       22-Aug-2005 Written by Bill Davis, PPPL


SPEC_DIR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	SPEC_DIR
 PURPOSE:
	Provide a complete file specification by appending a default disk
	or directory if necessary.

 CATEGORY:
	Files, OS Specific, Strings
 CALLING SEQUENCE:                      
	File_spec = SPEC_DIR( filename, [ extension ] )
 INPUT:
	filename - character string giving partial specification of a file
		name.  Examples for different operating systems include the
			following:
		VMS: '$1$DUA5:TEST.DAT','[.SUB]TEST'
		Unix: pro/test.dat, $IDL_HOME/test
		MacOS: ':Programs:test'
		Windows: '\pro\test.dat','d:\pro\test'

 OPTIONAL INPUT:
	exten - string giving a default file name extension to be used if
		filename does not contain one.  Do not include the period.

 OUTPUT:
	File_spec - Complete file specification using default disk or 
		directory when necessary.  

 EXAMPLE:
	IDL> a = spec_dir('test','dat')

	is equivalent to the commands
	IDL> cd, current=cdir
	IDL> a = cdir + delim + 'test.dat'

	where delim is the OS-dependent separator 
 METHOD:
	SPEC_DIR() decomposes the file name using FDECOMP, and appends the 
	default directory (obtained from the CD command) if necessary.   
	Under VMS, SPEC_DIR() will also try to translate disk and directory 
	logical names.

	SPEC_DIR() does not check whether the constructed file name actually
	exists.
 PROCEDURES CALLED:
	FDECOMP, OS_FAMILY()
 REVISION HISTORY:
	Written W. Landsman         STX         July, 1987
	Added Unix compatibility, W.  Landsman, STX   August 1991
	Added Windows and Macintosh compatibility   W. Landsman  September 1995


WRITE_GENERIC

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       write_generic
 PURPOSE:
        write an image to the appropriate type of file, based on 
	file extension
 CATEGORY:
       Files, Graphics
 CALLING SEQUENCE:
       IDL> write_generic, filename, data2D [,  R,G,B]
 INPUTS:
       filename - file name to read in
		can be type 'jpg','tif','tif','bmp','jpeg,'png', 'ppm', 'pgm', or 'gif'
 KEYWORD PARAMETERS:
    Optional inputs:
	extension - the file extension, eg., 'jpg'
	quality - jpeg quality [0-100, default is 75]
	order - JPEG/JFIF images are normally written in top-to-bottom order.
		If the image array is in the standard IDL order (i.e., from
		bottom-to-top) set ORDER to 0, its default value. If the image
		array is in top-to-bottom order, ORDER must be set to 1. 

 OUTPUTS:
       2-D data array from file               			out
 COMMON BLOCKS:
       NONE
 MODIFICATION HISTORY:
	25-Feb-2009 added RGB keyword
	18-Oct-2007 added quality keyword
	25-Apr-2007 added colortable keyword (not used!?!)
	21-Feb-2007 added ppm file type
	19-Apr-2006 replaced keywords with args R,G,B 
	15-Oct-2004 Written by Bill Davis, PPPL 


WRITE_TEXT

[Previous Routine] [List of Routines]
 NAME:
       write_text
 PURPOSE:
       Write data to a text file
 CATEGORY:
       files
 CALLING SEQUENCE:
       IDL> write_text, filename, data, data2, data3, data4, data5, data6
 INPUTS:
	filename - filename for output (DEFAULT='outfile.txt')
	data - array of numbers
	data2, data3, etc., are optional.
 KEYWORD PARAMETERS:
	header - text lines to put at the beginning of file
	tabs - if set, columns will be delimited by a tab characater
	verbose - if set, will echo message to screen with print command
 OUTPUTS:
       none
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> write_text, 'myfilename.txt', findgen(100)

   to write two columns with 1 header line:
	IDL> write_text, 'myfilename.txt', time, data, header='Hello World!'

 NOTES:
 MODIFICATION HISTORY:
	24-Apr-2009 option to write up to 6 columns of data
       12-Jun-2008 Written by Bill Davis, PPPL


Category: GAplot

[List of Routines]


GA_DATA

[Next Routine] [List of Routines]
 NAME:
	GA_Data

 PURPOSE:
	A GA_Data object defines a dataset Y as a function of X. It can
	be drawn on a Plot defined by a GA_Plot object.

 CATEGORY:
	GAplot
 SUPERCLASSES:

 SUBCLASSES:
	GA_Data3
	GA_DataV

 CREATION:
	See GA_Data::Init


GA_DATA::GETXRANGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetXRange

 PURPOSE:
	Retrieves the range of X data.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetXRange()

 ARGUMENTS:

 KEYWORDS:


GA_DATA::GETYRANGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetYRange

 PURPOSE:
	Retrieves the range of Y data.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetYRange([XRANGE])

 ARGUMENTS:
	XRANGE	Returns Y range only for data points within XRANGE.

 KEYWORDS:
	ERRORBAR  Set to retrieve Y range with errorbars included.


GA_DATA::SETPROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::SetProperty

 PURPOSE:
	Sets the value of a property or group of properties for the GA_Data.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Data:]SetProperty

 ARGUMENTS:

 KEYWORDS:
	Any keyword to GA_Data::Init followed by "Set". In addition,
	HIDE		Set to hide this data set in Plot.
	PROPERTIES3D
	SELECTEDPOINT	Index of selected data point.
	STATUS
	XDATA		A vector argument to replace abscissa data X.
	YDATA		A vector argument to replace ordinate data Y.
	fitDegree	Degree of fit to display with data.
			0=none, 1=linear, 2=quadratic, 3=cubic
	fitThruZero	if=1 then fit forced to go through zero

 MODIFICATION HISTORY
	11-Mar-2005 Added fitDegree and fitThruZero keywords


GA_DATA::GETXNAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetXName

 PURPOSE:
	Retrieves the name of X vector.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetXName()

 ARGUMENTS:

 KEYWORDS:


GA_DATA::GETFLAGAUTOLABEL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetFlagAutoLabel

 PURPOSE:
	Retrieves value of FlagAutoLabel

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetFlagAutoLabel()

 ARGUMENTS:

 KEYWORDS:


GA_DATA::GETYNAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetYName

 PURPOSE:
	Retrieves the name of Y vector.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetYName()

 ARGUMENTS:

 KEYWORDS:


GA_DATA::GETLABEL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetLabel

 PURPOSE:
	Retrieves the label of this dataset. If not set, use YName.
	Can be overridden by subclasses to supply automatically generated
	label. FlagAutoLabel is provided to facilitate this.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetLabel()

 ARGUMENTS:

 KEYWORDS:


GA_DATA::GETXDATA

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetXData

 PURPOSE:
	Retrieves abscissa vector X.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetXData()

 ARGUMENTS:

 KEYWORDS:
	MARKER    >0, returns X values of   marked data points.
		  <0, returns X values of unmarked data points.
	RESAMPLE  Set to resample data before returning X.  Data is resampled 
		  to the maximum number of data points specified by member maxpts.


GA_DATA::GETYDATA

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetYData

 PURPOSE:
	Retrieves ordinate vector Y.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetYData()

 ARGUMENTS:

 KEYWORDS:
	MARKER    >0, returns Y values of   marked data points.
		  <0, returns Y values of unmarked data points.
	RESAMPLE  Set to resample data before returning Y.  Data is resampled 
		  to the maxmum number of data points specified by member maxpts.
	ERRORBAR  A vector of same size of Y vector. Returns Y + ERRORBAR/2.


GA_DATA::GETCOLOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetColor

 PURPOSE:
	Retrieves the color index associated with this data set.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetColor()

 ARGUMENTS:

 KEYWORDS:


GA_DATA::GETSYMBOL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetSymbol

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetSymbol()


GA_DATA::GETSYMBOLSIZE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetSymbolSize

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetSymbolSize()


GA_DATA::GETLINESTYLE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetLineStyle

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetLineStyle()


GA_DATA::GETLINESTYLENONE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetLineStyleNone

 PURPOSE:
	Retrieves linestyle index for 'NONE' (no line).

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetLineStyleNone()


GA_DATA::GETPLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::GetPlot

 PURPOSE:
	Retrieves the GA_Plot object that contains this data object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Data::]GetPlot()


GA_DATA::DRAW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::Draw

 PURPOSE:
	Overplots this data set onto a Plot that has been established by
	a GA_Plot object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Data::]Draw

 ARGUMENTS:

 KEYWORDS:
	DRAGOFFSET
	ERASE


GA_DATA::ADD_TEXT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::Add_Text

 PURPOSE:
	Add a text annotation defined by GA_AnnotateText object that will be 
	drawn together with this data object onto the plot object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Data::]Add_Text(XPOS,YPOS,TEXT)

 ARGUMENTS:
	XPOS	X position of the text
	YPOS	Y position of the text
	TEXT	a string

 KEYWORDS:
	DRAW	Set to draw this data object after adding the text.
	USE	Set to 0 to hide or 1 to display this text annotation. Default=1


GA_DATA::DELETE_TEXT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::Delete_Text

 PURPOSE:
	Deletes a text member from the data object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->Delete_Text,dataset

 ARGUMENTS:
	DATASET  Either a text object or the index of text objects starting
		 zero as the first one.

 KEYWORDS:
	DRAW	   Draw the data set upon deletion of the text object.
	NODESTROY  Set to not destroy the text object itself, only remove
		   from this data object. Default to destroy.


GA_DATA::SET_TEXT_PROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::Set_Text_Property

 PURPOSE:
	Sets the parameters associated with a text annotation object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Data::]Set_Text_Property [,TEXTMEMBER]

 ARGUMENTS:
	TEXTMEMBER  Index number of text objects (0 being the first one).
		    If not specified, this methon applies to all text members.

 KEYWORDS:
	DRAW	Draw this data object after setting text properties.
	NOUSE	Set to not display the text.
	TEXT	A string to replace the text content.
	USE	Set to display the text.
	All properties settable by GA_AnnotateText::SetProperty.


GA_DATA::INIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Data::Init

 PURPOSE:
	Initializes the GA_Data object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj = OBJ_NEW('GA_Data',[X,]Y)
	or 
	Result = Obj->[GA_Data::]Init([X,]Y)   (in a subclass' Init method only)

 ARGUMENTS:
	X - A vector or a pointer to a vector. If not specified, Y is defined 
	    as a function of point number starting at zero.  If both arguments 
	    are specified, Y is a function of X, and X and Y have to be of 
	    same data type.
	Y - The ordinate data or a pointer to the ordinate data.

 KEYWORDS:
	Properties retrieveable via GA_Data::Get{PropertyName} are 
	indicated by "Get" following the keyword.  Properties settable via 
	GA_Data::SetProperty are indicated by "Set" following the keyword.

	COLOR (Get,Set)		The color index for plotting this data set. Default=foreground
	DEBUG			Set to turn on debugging.
	ERRORBAR (Set)		A vector of errorbar values (+- errorbar/2).
	INTERPOLATE (Set)	Set to set editmode to interpolate (?)
	FLAGAUTOLABEL (Get,Set)	Set to automatically determine label from method call.
	LABEL (Get,Set)		Legend label
	LINESTYLE (Get,Set)	The linestyle of drawing this data. Default=0 (solid line)
	MARKCOLOR (Get,Set)	Color index for markers
	MARKER (Get,Set)	Set to indicate that data points can be marked.
	MARKFILL (Get,Set)	Set to fill marker symbols.
	MARKLABELS (Get,Set)	Label used for markers.
	MARKSIZE (Get,Set)	Size of mark symbols.
	MARKSYMBOL (Get,Set)	Symbol used for markers.
	PLOT (Get,Set)		The GA_Plot object that contains this object.
	SHIFT (Set)		Set to set editmode to shift (?)
	SYMBOL (Get,Set)	The symbol used for this data set.
	SYMFILL (Get,Set)	Set this keyword to fill the symbols.
	SYMFRAC (Get,Set)	The fraction (0-100) of symbols to plot. Default=0.
	SYMSIZE (Get,Set) 	The size of symbols. Default=1.
	XNAME (Get,Set)		A name associated with X.
	XSCALE (Get,Set)	Two elements arrary for X scaling. X=X*XSCALE[1]+XSCALE[0]
	YNAME (Get,Set)		A name associated with Y.
	YSCALE (Get,Set)	Two elements array for Y scaling. Y=Y*YSCALE[1]+YSCALE[0]


GA_PLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot

 PURPOSE:
	A GA_Plot object draws graphs of its data members. It is a container of
	GA_Data objects.  If it has more than one data object member, the data 
	members are overlayed. A plot object can be thought as a wrapper to 
	IDL's PLOT command, keyword values to the PLOT command are preserved as
	plot object's or data objects' members.  A plot object is plotted on a
	window created by a GA_Plot_Window object which may contain several plot
	objects.

 CATEGORY:
	GAplot
 SUPERCLASSES:

 SUBCLASSES:
	GA_Plot3

 CREATION:
	See GA_Plot::Init

 BASIC METHODS:
	GA_Plot::Add_Data
	GA_Plot::Add_Data_Object
	GA_Plot::Delete_Data
	GA_Plot::Select_Data
	GA_Plot::Set_Data_Property
	GA_Plot::Set_Plot_Property


GA_PLOT::GETDATASELECTED

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::GetDataSelected

 PURPOSE:
	Retrieves the selected data object. A data object can be selected
	by clicking near to the data points with Left-Mouse-Button in
	'Select' mode.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot::]GetDataSelected()

 KEYWORDS:
	INDEX	A named variable to recieve the index of the selected data object


GA_PLOT::SELECT_DATA

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Select_Data

 PURPOSE:
	This method retrieves a particular data object associated with this
	plot object. A data can be selected by name or by index number.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot::]Select_Data([DATASET])

 ARGUMENTS:
	DATASET	  A string specifying the name of the data object, or an
		  integer specifying the index number, 0 being the 1st one.


GA_PLOT::SET_DATA_PROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Set_Data_Property

 PURPOSE:
 	This method allows you to change the parameters associated with a
 	particular data object. You must specify a particular data set by 
	passing the object reference to the data set. (This can be obtained 
	with the GA_Plot::Select_Data method.) If a data set object is not 
	specified as the data member, the first data set is used by default.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Set_Data_Property [,DATAMEMBER]

 ARGUMENTS:
	DATAMEMBER  A GA_Data object associated with this plot object.

 KEYWORDS:
	Any keywords acceptable to GA_Data::SetProperty, and
	AUTORANGE   Set to reset the data range automatically.
	DRAW	    Set to re-draw all datasets.
 EXAMPLES:
	oPlot->Set_Data_Property,oPlot->Select_Data(1),XData=x,Ydata=y

	This resets X and Y vectors for the 2nd dataset in the oPlot object.


GA_PLOT::GET_DATA_PROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Get_Data_Property

 PURPOSE:
 	This method allows you to retrieve the properties of a data member
 	belonging to the plot. Data member is identified by passing its
 	object reference (which can be obtained with the Select_Data method).
 	If a data member is not specified, the first data memeber is used
	as a default.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Get_Data_Property [,DATAMEMBER]

 ARGUMENTS:
	DATAMEMBER   A GA_Data object associated with this plot object.

 KEYWORDS:
	Keywords are named variables to receive retrieved values.
	At least one keyword should be provided.
	COLOR	   The color index of the data member.
	LINESTYLE  The linestyle of the data member.
	MARKER	   Used together with XDATA and/or YDATA.
	           >0 for marked data points, <0 for unmarked data points.
	SYMBOL
	SYMFILL
	SYMFRAC
	SYMSIZE
	XNAME
	XDATA	   Abscissa vector X of the data member.
	YNAME
	YDATA	   Ordinate vector Y of the data member.

 EXAMPLE:
	oPlot->Get_Data_Property,oPlot->Select_Data(1),XData=xdata,Marker=-1

	This retrives X values of the unmarked data points from the 2nd
	data member of this plot and stores the result in variable xdata.


GA_PLOT::ADD_DATA_OBJECT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Add_Data_Object

 PURPOSE:
 	This method allows you to add a GA_DATA or GA_DATA3 object to
 	the plot object. The data object reference is returned.

	See also GA_Plot::Add_Data

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot::]Add_Data_Object, NEWDATA

 ARGUMENTS:
	NEWDATA	  A GA_Data(3) object to be added.

 KEYWORDS:
	DRAW		Set to re-draw all datasets.
	NOAUTORANGE	Set to not reset the data range automatically.


GA_PLOT::ADD_DATA

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Add_Data

 PURPOSE:
 	This method allows you to add another data object to
 	the plot object. Properties of the data object may be set with
 	the method's keywords. Extra carries any keywords acceptable
 	by Ga_Data[3]::Init.  A new data object will be created and
	the reference is returned.

	See also GA_Plot::Add_Data_Object

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->Add_Data([XDATA,] YDATA [,ZDATA]])

 ARGUMENTS:
	XDATA	X vector. If not specified, X will set to a point number
	        array starting at zero.
	YDATA	Y vector as a function of X if ZDATA is not specified.
	        If ZDATA is specified, YDATA is the 2nd independent data.
	ZDATA	A two dimensional array as a function of X and Y.
		If ZDATA is specified, a GA_Data3 will be created.

	See GA_Data::Init and GA_Data3::Init for acceptable inputs.

 KEYWORDS:
	Any keywords acceptable to GA_Data::Init or GA_Data3::Init, and
	DRAW		Set to re-draw all datasets.
	NOAUTORANGE	Set to not reset data ranges automatically.

 HISTORY:
	07-10-2002  Q.Peng - This method shouldn't have worked for adding a
	            GA_Data3 (with XDATA,YDATA,ZDATA) before. The order of 
		    arguments has just been corrected.


GA_PLOT::DELETE_DATA

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Delete_Data

 PURPOSE:
 	This method allows you to delete a data set member from the Plot 
	Object. The data set may be specified by indicating its NAME, by 
	indicating its POSITION (index number), or by the data OBJECT itself. 
	(See the Select_Data method for more details about a data set's
 	NAME and POSITION.)

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Delete_Data, DATASET

 ARGUMENTS:
	DATASET   A string for its name, or an integer for its position
		  (0 being the 1st), or a GA_Data object reference.

 KEYWORDS:
	DRAW		Set to re-draw all datasets.
	NOAUTORANGE	Set to not reset data ranges automatically.
	NODESTROY	Set to not destroy the deleted data object.


GA_PLOT::AUTO_RANGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Auto_Range

 PURPOSE:
	Set data ranges automatically according to data.
	This is needed for multiple data sets.
	Set both xrange and yrange by default.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Auto_Range

 KEYWORDS:
 	OVERRIDE  Set to ALWAYS autoscale both MIN and MAX regardless of 
		  the settings of xautorange and yautorange
	XONLY	  Set to only autoscale X range.
	YONLY	  Set to only autoscale Y range.
	ZONLY	  Set to only autoscale Z range.


GA_PLOT::ADD_TEXT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Add_Text

 PURPOSE:
	This method adds a text annotation to a specified location on
	the plot.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->Add_Text, XPOS, YPOS, TEXT

 ARGUMENTS:
	XPOS	X coordinate of the text.
	YPOS	Y coordinate of the text.
	TEXT	A string.

 KEYWORDS:
	Any keywords acceptable to GA_AnnotateText::Init, and
	DRAW	Set to re-draw all datasets.
	USE	1 - display the text (default), 0 - do not display the text. 


GA_PLOT::SET_TEXT_PROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Set_Text_Property

 PURPOSE:
 	This method allows you to change the parameters associated with a
 	text annotaion object.  The textMember is the index number of the
 	text object.  All text members are used by default if no textMember
 	is specified.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Set_Text_Property [,TEXTMEMBER]

 ARGUMENTS:
	TEXTMEMBER  An integer specifying the index number of the text memeber.
		    0 is the 1st text.  If not specified, all texts are used.

 KEYWORDS:
	DRAW	Set to re-draw all datasets.
	NOUSE	Set to not display the text in the plot.
	TEXT	A string to replace the text value.
	USE	Set to display the text in the plot.
	Any keywords acceptable by GA_AnnotateText::SetProperty


GA_PLOT::DRAW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Draw

 PURPOSE:
 	This method draws the Plot Object, including all of the
 	data members included in the Plot Object. 

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Draw

 KEYWORDS:
	NODATA	If set, only the plot axes and annotation are drawn.
	NOERASE keyword to PLOT.
	


GA_PLOT::SETSLICEMODE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::SetSliceMode

 PURPOSE:
	Set mode for data slicing. For a GA_Plot object, the plot can be used
	as a slicer to slice through other GA_Plot3 objects in the same
	window.  The data in this plot will not be sliced because there is
	no third dimension.

	See also GA_Plot3::SetSliceMode

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]SetSliceMode, MODE

 ARGUMENTS:
	MODE 	'A' - Can be used to slice through the 1st dimension of a
	              GA_Plot3 object with slicemode 'AB', or the 2nd dimension
		      of a GA_Plot3 object with slicemode 'BA'.
		'B' - Can be used to slice through the 2nd dimension of a
		      GA_Plot3 object with slicemode 'AB', or the 2nd dimension
		      of a GA_Plot3 object with slicemode 'AB'.
		'X' - Not a slicer. In 'Slice' mode, when cursor moves into
		      this plot, nothing happens.


GA_PLOT::SET_PLOT_PROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Set_Plot_Property

 PURPOSE:
 	This method allows you to set the standard Plot properties. If
 	the DRAW keyword is set, the plot will be drawn after the new
 	properties are set. (See the Init Method for a more complete
 	explanation of these Plot properties.)

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Set_Plot_Property

 KEYWORDS:
	Any keywords to GA_Plot::Init followed by "Set", and
	DRAW
	LCHARSIZE
	NOXTICKS
	SETXRANGE
	SETYRANGE
	XAUTORANGE
	YAUTORANGE
	WINDOW


GA_PLOT::GET_PLOT_PROPERTY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Get_Plot_Property

 PURPOSE:
 	This method allows you to obtain the standard Plot properties
 	from the Plot Object. (See the Init Method for a more complete
 	explanation of these Plot properties.)

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot::]Get_Plot_Property

 KEYWORDS:
	Keywords are named variables to receive retrieved values.
	Any keywords to GA_Plot::Init followed by "Get", and
	NUMDATASETS
	NUMTEXT
	LCHARSIZE
	NOXTICKS
	SETXRANGE
	SETYRANGE
	XAXIS
	XAUTORANGE
	YAXIS
	YAUTORANGE


GA_PLOT::GETWINDOW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::GetWindow

 PURPOSE:
 	This method returns the GA_Plot_Window object that the plot object 
	belongs to, for EditCallBack purpose.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot::]GetWindow()


GA_PLOT::GETDATAOBJECTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::GetDataObjects

 PURPOSE:
 	The method returns the array of data objects stored in this plot object.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Results = Obj->[GA_Plot::]GetDataObjects()


GA_PLOT::INIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot::Init

 PURPOSE:
 	This method initializes a GA_Plot object. Standard properties
 	are set with positional and keyword parameters. The routine makes 
	GA_DATA objects from the data passed into the method. Use the 
	Add_Data method to add additional data sets and the Delete_Data 
	method to remove data sets from the Plot Object. Data inside the 
	data objects can be modified with the Set_Data_Property method. 
	Think of this initialization routine as a wrapper for the PLOT 
	command. Use keywords appropriate for the PLOT command 
	in making the call.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj = OBJ_NEW('GA_Plot'[,X [,Y]])
	or
	Result = Obj->[GA_Plot::]Init([X [,Y]])   (in a subclass' Init method only)

 ARGUMENTS:
	X - If Y is specified, X, Y are the two arguments to GA_Data::Init
	    If Y is not specified, X can be a GA_Data or GA_DataV object,
	    or it can be the only argument to GA_Data::Init.
	Y - The 2nd argument to GA_Data::Init

 KEYWORDS:
	Properties retrieveable via GA_Plot::Get_Plot_Property are indicated
	by "Get" following the keyword.  Properties settable via
	GA_Plot::Set_Plot_Property are indicated by "Set".

	ASPECT (Get,Set)	Set to keep aspect ratio of plots.
	BACKGROUND (Get,Set)	The color index of background.
	CHARSIZE (Get,Set)	The character size for labels.
	COLOR (Get,Set)		The color index for axes and annotations.
	CONTOUR			Set to do contour plots.
	DATACOLOR		The color for plotting data created here.
	DEBUG(Set)		Set to turn on debugging.
	DEP_DATA_NAME		The name associated with dependent data (Y).
	FLAGLEGEND (Get,Set)	0 = do not show labels, 1 = show labels
	INDEP_DATA_NAME		The name associated with independent data (X).
	GRID (Get,Set)		A two-element array (columns,rows) for the layout of all plots
				in the GA_Plot_Window object to which this plot object belongs.
	LEVELS			The level vector for contour plot.
	NAME (Get,Set)		The name associated with this plot (used for plot selection).
	NUMBER (Get,Set)	The index number of this plot in window (starting at 0).
	OVERGRIDSTYLE (Get,Set)	Grid style for both X and Y axes.
	OVERLAYGRID (Get,Set)
	OVERLAYZERO (Get,Set)
	PSYM			The plot symbol used to display the data.
	SLICEMODE (Get,Set)
	SUBTITLE (Get,Set)
	SYMFRAC			The fraction (0-100) of symbols to be plotted.
	SYMSIZE			The plot symbol size.
	TICKSOUT (Get,Set)	If non 0, ticks appear on outside of the plot.
	TITLE (Get,Set)		The plot title.
	XCHARSIZE (Get,Set)
	XLOG (Get,Set)
	XMTICKS (Get,Set)	X minor ticks
	XRANGE (Get,Set)
	XSTYLE (Get,Set)
	XTICKFORMAT(Set)
	XTICKS (Get,Set)
	XTITLE (Get,Set)
	YCHARSIZE (Get,Set)
	YLOG (Get,Set)
	YMTICKS (Get,Set)	Y minor ticks
	YRANGE (Get,Set)
	YSTYLE (Get,Set)
	YTICKFORMAT(Set)
	YTICKS (Get,Set)
	YTITLE (Get,Set)
	WID (Get,Set)		The window index number of the window where this plot is displayed.


GA_PLOT_WINDOW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window

 PURPOSE:
	A GA_Plot_Window is a compound widget with a draw window that 
	contains one or several GA_Plot[3] objects. Plots can be added
	or deleted. The window object handles plot layout, coordinates,
	preference and properties configurations, mouse events and
	draws all the plots through their own draw methods.

 CATEGORY:
	GAplot
 SUPERCLASSES:

 SUBCLASSES:

 CREATION:
	See GA_Plot_Window::Init

 BASIC METHODS:
	GA_Plot_Window::Add_Plot
	GA_Plot_Window::Delete_Plot
	GA_Plot_Window::SetCurrentTool
	GA_Plot_Window::Set_Crosshairs
	GA_Plot_Window::Set_Status_Window


GA_PLOT_WINDOW::RESTOREPREFERENCES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::RestorePreferences

 PURPOSE:
	Restore user's preferences from file specified by
	PreferencesFile. This file is always in user's HOME directory.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]RestorePreferences


GA_PLOT_WINDOW::SAVEPREFERENCES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::SavePreferences

 PURPOSE:
	Save the current settings to user's preferences file specified by
	PreferencesFile. This file is always in user's HOME directory.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]SavePreferences


GA_PLOT_WINDOW::SETCHARSIZE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::SetCharsize

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]SetCharsize, charsize


GA_PLOT_WINDOW::SETCOLORFLAG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::SetColorFlag

 PURPOSE:
	Resetting the color table.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]SetColorFlag, COLORFLAG

 ARGUMENTS:
	COLORFLAG   Flag used by Color_Setup to determine the type of color table.
		0 - greyscale color table,
		1 - color_list() color table,
		2 - black and white only.

 KEYWORDS:
	REVERSE	    Set to have white background. The default is with black background.


GA_PLOT_WINDOW::GETPLOTLIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::GetPlotList

 PURPOSE:
	Retrieves the names of plots in this window object. A name is
	specified or a default is given when a plot object is created.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot_Window::]GetPlotList()


GA_PLOT_WINDOW::GETPLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::GetPlot

 PURPOSE:
	Retrieves a plot object specified by its index number.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot_Window::]GetPlot(INDEX)

 ARGUMENTS:
	INDEX	An index number of the plot object in this window.
		0 = 1st plot object.


GA_PLOT_WINDOW::USERSETGRID

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::UserSetGrid

 PURPOSE:
	Allows manually setting the grid layout of the plots.
	If howeve, the total number of plots is greater than
	GRID[0]*GRID[1], the grid is recalculated automatically.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]UserSetGrid, GRID

 ARGUMENTS:
	GRID	A two-element array specifying the layout of plots.
		GRID[0] = number of columns, GRID[1] = number of rows.

 KEYWORDS:
	DRAW	Set to re-draw all the plots.


GA_PLOT_WINDOW::SETMAXGRID

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::SetMaxGrid

 PURPOSE:
	Set the maximum number of columns and rows for determining
	grid layout of plots automatically.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]SetMaxGrid, MAXGRID

 ARGUMENTS:
	MAXGRID	   A two-element array.
		   MAXGRID[0] = maxcols, MAXGRID[1] = maxrows.


GA_PLOT_WINDOW::SETAUTOGRID

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::SetAutoGrid

 PURPOSE:
	Turn on or off the automatic grid layout calculation.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]SetAutoGrid, ONOFF

 ARGUMENTS:
	ONOFF	1 - turn on auto grid, 0 - turn off auto grid.

 KEYWORDS:
	DRAW	Set to re-draw all plots.


GA_PLOT_WINDOW::CHECKPLOTNUMBERS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::CheckPlotNumbers

 PURPOSE:
 	Goes through member plots and checks to ensure that they are
	sequentially numbered.  Renumbers them if they are not. Plots
	having the same number are overlayed and can cause confusing
	display results.  This routine is optional - to be used by
	the parent application if needed.
	It returns 0 if no plot has been renumbered, returns 1 otherwise.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot_Window::]CheckPlotNumbers()	


GA_PLOT_WINDOW::REPLACE_PLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Replace_Plot

 PURPOSE:
	This method replaces a current plot in the window with another plot.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Replace_Plot, OPLOT

 ARGUMENTS:
	OPLOT	A replacement GA_Plot object.

 KEYWORDS:
	NUMBER	The index number of the plot to be replaced. 
		The first plot (0) is replaced if number if not specified.


GA_PLOT_WINDOW::INSERT_PLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Insert_Plot

 PURPOSE:
 	Inserts a new plot at a specified index number. The plot numbers
	are shifted by 1 (+1) from the inserted plot.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Insert_Plot, OPLOT, NUMBER

 ARGUMENTS:
	OPLOT	A GA_Plot object to be inserted.
	NUMBER	The index number which the new plot is inserted to.

 KEYWORDS:
	NODRAW	Set to not re-draw all the plots. Useful when inserting
		more than one plot to complete insertion before re-draw.


GA_PLOT_WINDOW::REMOVE_PLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Remove_Plot

 PURPOSE:
	If the PLOT tag in EDITFLAGS structure is set, this method deletes
	the plot object specified by the index number. 
	A GA_Plot_Window::EditCallBack is generated.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Remove_Plot

 ARGUMENTS:
	NUMBER	The index number of the plot to be deleted.

 KEYWORDS:
	Any keywords acceptable by GA_Plot_Window::Delete_Plot.


GA_PLOT_WINDOW::DELETE_PLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Delete_Plot

 PURPOSE:
 	This method deletes a plot from the list of plots within the window.
 	Plots are numbered from 1 to N and are in column order in the window.

 	NO EDITCALLBACK is generated by this method! For an EDITCALLBACK
 	use GA_Plot_Window::RemovePlot.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Delete_Plot, NUMBER

 ARGUMENTS:
	NUMBER	The index number of the plot object to be deleted.

 KEYWORDS:
	NODRAW	   Set to not re-draw all plots. Useful when deleting
		   more than one plot to complete the deletion before
		   re-drawing what is left.
	NODESTROY  Set to not destroy the plot object being deleted from this window.
		   Default is to destroy the plot object.


GA_PLOT_WINDOW::ADD_PLOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Add_Plot

 PURPOSE:
 	This method adds a plot to the window. A new column of plots
 	will be created if necessary to accomodate the new plot. A plot
 	object is required. If NoDuplicate keyword is set, check if newPlot
 	belongs to the window already. If so, return.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Add_Plot, NEWPLOT

 ARGUMENTS:
	NEWPLOT	  A GA_Plot object to be added to the window.

 KEYWORDS:
	DRAW	      Set to re-draw all plots.
	NODUPLICATE   Set to make sure NEWPLOT is added to this 
		      window object only once.


GA_PLOT_WINDOW::SET_CROSSHAIRS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Set_Crosshairs

 PURPOSE:
 	This method turns cursor crosshair tracking on or off.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Set_Crosshairs, ONOFF

 ARGUMENTS
	ONOFF	1 - crosshair tracking on, 0 - crosshair tracking off.


GA_PLOT_WINDOW::GETCURRENTTOOL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::GetCurrentTool

 PURPOSE:
	Retrieves the name of the current mouse mode. Possible modes are
	['Select','Zoom','Edit','Cursor','Slice','Mark','Vector'] plus
	those defined by MOUSEMODES.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Result = Obj->[GA_Plot_Window::]GetCurrentTool()


GA_PLOT_WINDOW::SETCURRENTTOOL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::SetCurrentTool

 PURPOSE:
	This method sets the current tool(mouse mode) to be used in the window.
	'SELECT'  - Seleting a data or a plot for manipulation, copying and deletion, etc.
	'ZOOM'    - Zoom and reset a plot, switch between multiple and single-plot displays.
	'EDIT'    - Add, delete or move data points.
	'CURSOR'  - Mark reference points, switch cursor readout from absolute to relative.
	'SLICE'   - Change the slices of the 3D data being plotted.
	'MARK'    - Mark a data point with a special symbol.
	'VECTOR'  - Change vector magnitute, data point resampling rate, etc.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]SetCurrentTool, TOOL

 ARGUMENTS:
	TOOL	  A string specifies the mode to set. See above for possible values.


GA_PLOT_WINDOW::SET_STATUS_WINDOW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Set_Status_Window

 PURPOSE:
 	This method assigns a text or label widget ID to be the
 	status window. Cursor tracking reports are sent to the
 	status window.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Set_Status_Window,WID

 ARGUMENTS:
	WID     The ID of a text or a label widget to report the cursor readouts
		and other status message.


GA_PLOT_WINDOW::EDITCALLBACK

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::EditCallback

 PURPOSE:
	Perform an IDL procedure call upon certain editing action,

	    CALL_PROCEDURE,ProName,Parent,oData,oPlot,Action

	ProName is the procedure name specified by keyword EDITCALLBACK 
	when the window object is created (see GA_Plot_Window::Init).
	This procedure should expect four arguments.

	Parent	The parent widget of the PARENT argument specified in 
		GA_Plot_Window::Init.  If the GA_Plot_Window is
		created through CW_GAWindow, Parent will be the PARENT
		argument passed to CW_GAWindow.
	oData	A GA_Data object or a null object.
	oPlot	A GA_Plot object or a null object.
	Action	An action string such as 'ADD_DATA','DELETE_DATA',
		'DELETE_PLOT','REFERENCE_POINT',etc.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]EditCallback, oData, oPlot, Action

 ARGUMENTS: see above


GA_PLOT_WINDOW::DRAW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Draw

 PURPOSE:
	Draws all the plots in this window by calling the plot objects
	Draw method.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Draw


GA_PLOT_WINDOW::DUMP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Dump

 PURPOSE:
	Prints out pointers to plot objects and their associated data objects.
	For debugging purposes.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj->[GA_Plot_Window::]Dump


GA_PLOT_WINDOW::INIT

[Previous Routine] [List of Routines]
 NAME:
	GA_Plot_Window::Init

 PURPOSE:
	Initializes a GA_Plot_Window object. The window is conceived as a 
	compound widget via CW_GAWindow. When you get the "value" of the 
	compound widget, you are returned the window object. Instead of 
	"setting values" to the compound widget, you call window object 
	methods.

 CATEGORY:
	GAplot
 CALLING SEQUENCE:
	Obj = OBJ_NEW('GA_Plot_Window',PARENT)

 ARGUMENTS:
	PARENT	A parent widget ID in which the GA_Plot_Window object
	        draw widget will be build.

 KEYWORDS:
	ALLSAMEX	Set to draw all plots with the same X range. Default = 1.
	CHANGEMOUSEBITMAP Set to change cursor appearance in different modes. Default = 1.
	CURRENTTOOL	The index of currently selected mode from list
			['Select','Zoom','Edit','Cursor','Slice','Mark','Vector']
	COLOR		The color index for cursor in the window.
	DEBUG		Set to turn on debugging.
	EDITCALLBACK	A string specifies a procedure name to call when editing is performed.
	EDITFLAGS
	EMPTYMSG	A string array to display when there is no plot in the window.
	ERRORCALLBACK	A string specifies a procedure name to call when error occurs.
	EVENTCALLBACK	A string specifies a procedure name to call when WIDGET_DRAW event occurs.
	GRID		A two element array for plot layout. 
	        	GRID[0] = number of columns, GRID[1] = number of rows.
	IMAGE_COLORS
	MAXCOLS		Maximum number of columns when determining grid automatically.
	MAXROWS 	Maximum number of rows when determining grid automatically.
	MBAR		Widget ID of menubar for popup window.
	MOUSEMODES	A string array specifies additional mouse modes.
	PLOTS		A pointer to a vector of GA_Plot objects.
	POPUPOPTIONS	A 2xN string array specify entries for popup window.
			If not specified, the default options are used.
			POPUPOPTIONS[0,*] specify button names, 
			POPUPOPTIONS[1,*] specify event procedure names to call.
	PREFERENCESFILE	The file name for user preferences. File should be in user's HOME.
	STATUS		Set to include the status widget.
	TRACKING	Set to turn on cursor tracking.
	XSIZE		The X size of the draw widget display window.
	YSIZE		The Y size of the draw widget display window.


Category: Graphics

[List of Routines]


BANGPW

[Next Routine] [List of Routines]
 NAME:
       bangPW
 PURPOSE:
       Widget to set interactively some !P values. Lists colors by name, 
	if mk_color used; otherwise finds "closest" index to named colors. 
	Allows selection of several custom plotting symbols (see PLOTSYM).
 CATEGORY:
       Graphics, Widgets
 CALLING SEQUENCE:
       IDL> bangPW
 INPUTS:
 KEYWORD PARAMETERS:
     Optional Keywords:
	  UPDATECALLBACK - a routine to call after struct system variable is set
	  GROUP_LEADER - This widget is destroyed if it's GL is destroyed
 OUTPUTS:
       The system variable !P is changed               	
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> bangPW, UPDATECALLBACK='myReplotter'
 NOTES:
	If an application overrides !P.* parameters, or specifies them on
	the plot command, changing settings with this widget will not override.
	!P.SYMSIZE not controlled, because it seems to have no effect.
 MODIFICATION HISTORY:
	29-Apr-08 check for routine being compiled (vs. needing to be found)
		  added a "Refresh" button which, if a proper plotting routine
		  is provided, will replot with any changed settings.
	17-Aug-01 Allow lines with symbols [BD]
	30-Oct-00 Written by Bill Davis, PPPL


COLORBARBD

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   COLORBARbd

 PURPOSE:

       The purpose of this routine is to add a color bar to the current
       graphics window. (this is a mod by BD to handle veritcal plot ticknames better)

 AUTHOR:

   FANNING SOFTWARE CONSULTING
   David Fanning, Ph.D.
   1645 Sheely Drive
   Fort Collins, CO 80526 USA
   Phone: 970-221-0438
   E-mail: davidf@dfanning.com
   Coyote's Guide to IDL Programming: http://www.dfanning.com/

 CATEGORY:

       Graphics, Widgets.

 CALLING SEQUENCE:

       COLORBAR

 INPUTS:

       None.

 KEYWORD PARAMETERS:

       ANNOTATECOLOR: The name of the "annotation color" to use. The names are those for
                     FSC_COLOR, and using the keyword implies that FSC_COLOR is also in
                     your !PATH. If this keyword is used, the annotation color is loaded
                     *after* the color bar is displayed. The color will be represented
                     as theColor = FSC_COLOR(ANNOTATECOLOR, COLOR). This keyword is provide
                     to maintain backward compatibility, but also to solve the problem of
                     and extra line in the color bar when this kind of syntax is used in
                     conjunction with the indexed (DEVICE, DECOMPOSED=0) model is used:

                          LoadCT, 33
                          TVImage, image
                          Colorbar, Color=FSC_Color('firebrick')

                     The proper syntax for device-independent color is like this:

                          LoadCT, 33
                          TVImage, image
                          Colorbar, AnnotateColor='firebrick', Color=255

       BOTTOM:       The lowest color index of the colors to be loaded in
                     the bar.

       CHARSIZE:     The character size of the color bar annotations. Default is !P.Charsize.

       COLOR:        The color index of the bar outline and characters. Default
                     is !P.Color..

       DIVISIONS:    The number of divisions to divide the bar into. There will
                     be (divisions + 1) annotations. The default is 6.

       FONT:         Sets the font of the annotation. Hershey: -1, Hardware:0, True-Type: 1.

       FORMAT:       The format of the bar annotations. Default is '(I0)'.

       INVERTCOLORS: Setting this keyword inverts the colors in the color bar.

       MAXRANGE:     The maximum data value for the bar annotation. Default is
                     NCOLORS.

       MINRANGE:     The minimum data value for the bar annotation. Default is 0.

       MINOR:        The number of minor tick divisions. Default is 2.

       NCOLORS:      This is the number of colors in the color bar.

       NODISPLAY:    COLORBAR uses FSC_COLOR to specify some of it colors. Normally, 
                     FSC_COLOR loads "system" colors as part of its palette of colors.
                     In order to do so, it has to create an IDL widget, which in turn 
                     has to make a connection to the windowing system. If your program 
                     is being run without a window connection, then this program will 
                     fail. If you can live without the system colors (and most people 
                     don't even know they are there, to tell you the truth), then setting 
                     this keyword will keep them from being loaded, and you can run
                     COLORBAR without a display.

       POSITION:     A four-element array of normalized coordinates in the same
                     form as the POSITION keyword on a plot. Default is
                     [0.88, 0.10, 0.95, 0.90] for a vertical bar and
                     [0.10, 0.88, 0.90, 0.95] for a horizontal bar.

       RANGE:        A two-element vector of the form [min, max]. Provides an
                     alternative way of setting the MINRANGE and MAXRANGE keywords.

       REVERSE:      Setting this keyword reverses the colors in the colorbar.

       RIGHT:        This puts the labels on the right-hand side of a vertical
                     color bar. It applies only to vertical color bars.

       TICKNAMES:    A string array of names or values for the tick marks.

       TITLE:        This is title for the color bar. The default is to have
                     no title.

       TOP:          This puts the labels on top of the bar rather than under it.
                     The keyword only applies if a horizontal color bar is rendered.

       VERTICAL:     Setting this keyword give a vertical color bar. The default
                     is a horizontal color bar.

       MATCH:	      If set will match color bar to extent of plot.

 COMMON BLOCKS:

       None.

 SIDE EFFECTS:

       Color bar is drawn in the current graphics window.

 RESTRICTIONS:

       The number of colors available on the graphics display device (not the
       PostScript device) is used unless the NCOLORS keyword is used.

       Requires the FSC_COLOR program from the Coyote Library:

          http://www.dfanning.com/programs/fsc_color.pro

 EXAMPLES:

       To display a horizontal color bar above a contour plot, type:

       LOADCT, 5, NCOLORS=100
       CONTOUR, DIST(31,41), POSITION=[0.15, 0.15, 0.95, 0.75], $
          C_COLORS=INDGEN(25)*4, NLEVELS=25
       COLORBAR, NCOLORS=100, POSITION=[0.15, 0.8, 0.95, 0.90]

       To display a vertical color bar in the lower right of a contour plot, type:

	IDL> device, decompose=0
	IDL> loadct, 3
	IDL> contour, dist(100), /fill, nlevels=100, zstyle=1
	IDL> colorbar, pos=[.92,.1,.95,.4], /vert, title='Kev'

 MODIFICATION HISTORY:

       Written by: David W. Fanning, 10 JUNE 96.
       10/27/96: Added the ability to send output to PostScript. DWF
       11/4/96: Substantially rewritten to go to screen or PostScript
           file without having to know much about the PostScript device
           or even what the current graphics device is. DWF
       1/27/97: Added the RIGHT and TOP keywords. Also modified the
            way the TITLE keyword works. DWF
       7/15/97: Fixed a problem some machines have with plots that have
            no valid data range in them. DWF
       12/5/98: Fixed a problem in how the colorbar image is created that
            seemed to tickle a bug in some versions of IDL. DWF.
       1/12/99: Fixed a problem caused by RSI fixing a bug in IDL 5.2. Sigh... DWF.
       3/30/99: Modified a few of the defaults. DWF.
       3/30/99: Used NORMAL rather than DEVICE coords for positioning bar. DWF.
       3/30/99: Added the RANGE keyword. DWF.
       3/30/99: Added FONT keyword. DWF
       5/6/99: Many modifications to defaults. DWF.
       5/6/99: Removed PSCOLOR keyword. DWF.
       5/6/99: Improved error handling on position coordinates. DWF.
       5/6/99. Added MINOR keyword. DWF.
       5/6/99: Set Device, Decomposed=0 if necessary. DWF.
       2/9/99: Fixed a problem caused by setting BOTTOM keyword, but not NCOLORS. DWF.
       8/17/99. Fixed a problem with ambiguous MIN and MINOR keywords. DWF
       8/25/99. I think I *finally* got the BOTTOM/NCOLORS thing sorted out. :-( DWF.
       10/10/99. Modified the program so that current plot and map coordinates are
            saved and restored after the colorbar is drawn. DWF.
       3/18/00. Moved a block of code to prevent a problem with color decomposition. DWF.
       4/28/00. Made !P.Font default value for FONT keyword. DWF.
       9/26/00. Made the code more general for scalable pixel devices. DWF.
       1/16/01. Added INVERTCOLORS keyword. DWF.
       5/11/04. Added TICKNAME keyword. DWF.
       9/29/05. Added REVERSE keywords, which does the *exact* same thing as
           INVERTCOLORS, but I can never remember the latter keyword name. DWF.
       1/2/07. Added ANNOTATECOLOR keyword. DWF.
       4/14/07. Changed the default FORMAT to I0. DWF.
       5/1/07. Unexpected consequence of default format change is colorbar annotations
           no longer match contour plot levels. Changed to explicit formating of
           colorbar axis labels before PLOT command. DWF.
       5/25/07. Previous change has unanticipated effect on color bars using
           logarithmic scaling, which is not really supported, but I have an
           article on my web page describing how to do it: http://www.dfanning.com/graphics_tips/logcb.html.
           Thus, I've fixed the program to accommodate log scaling, while still not OFFICIALLY
           supporting it. DWF.
       10/3/07. Method used to calculate TICKNAMES produces incorrect values in certain cases when
           the min and max range values are integers. Now force range values to be floats. DWF.
       10/17/07. Accidentaly use of INTERP keyword in CONGRID results in wrong bar values for
           low NCOLORS numbers when INVERTCOLORS or REVERSE keyword is used. Removed INTERP keyword. DWF.
       11/10/07. Finished fixing program to accommodate log scaling in ALL possible permutations. DWF.
       8 Feb 2008. Added CRONJOB keyword and decided to use month names when I write the date. DWF.
       8 Feb 2008. Renamed CRONJOB to NODISPLAY to better reflect its purpose. DWF.
      21 May 2008. Changed the default CHARSIZE to !P.CHARSIZE from 1.0. DWF.
      30 Oct 2008. Fixed a problem with the FONT keyword not being recognized in certain
            configurations.
	13-Dec-2010 Default range to !Z.CRANGE (set when contour was last called) [BD]
	19-Apr-2011 handle values like 1e16. Make "nicer" intervals for tickmarks [BD]
		    fix use of maxrange and minrange
	19-Jul-2011 Added Match keyword to make vertical colorbar match in height to plot
		    window. Also, default to having number on outside of colorbar when 
		    vertical and on the right.


COLORBAR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   COLORBAR

 PURPOSE:

       The purpose of this routine is to add a color bar to the current
       graphics window.

 AUTHOR:

   FANNING SOFTWARE CONSULTING
   David Fanning, Ph.D.
   1645 Sheely Drive
   Fort Collins, CO 80526 USA
   Phone: 970-221-0438
   E-mail: davidf@dfanning.com
   Coyote's Guide to IDL Programming: http://www.dfanning.com/

 CATEGORY:

       Graphics, Widgets.

 CALLING SEQUENCE:

       COLORBAR

 INPUTS:

       None.

 KEYWORD PARAMETERS:

       ANNOTATECOLOR: The name of the "annotation color" to use. The names are those for
                     FSC_COLOR, and using the keyword implies that FSC_COLOR is also in
                     your !PATH. If this keyword is used, the annotation color is loaded
                     *after* the color bar is displayed. The color will be represented
                     as theColor = FSC_COLOR(ANNOTATECOLOR, COLOR). This keyword is provide
                     to maintain backward compatibility, but also to solve the problem of
                     and extra line in the color bar when this kind of syntax is used in
                     conjunction with the indexed (DEVICE, DECOMPOSED=0) model is used:

                          LoadCT, 33
                          TVImage, image
                          Colorbar, Color=FSC_Color('firebrick')

                     The proper syntax for device-independent color is like this:

                          LoadCT, 33
                          TVImage, image
                          Colorbar, AnnotateColor='firebrick', Color=255

       BOTTOM:       The lowest color index of the colors to be loaded in
                     the bar.

       CHARSIZE:     The character size of the color bar annotations. Default is !P.Charsize.

       COLOR:        The color index of the bar outline and characters. Default
                     is !P.Color..

       DIVISIONS:    The number of divisions to divide the bar into. There will
                     be (divisions + 1) annotations. The default is 6.

       FONT:         Sets the font of the annotation. Hershey: -1, Hardware:0, True-Type: 1.

       FORMAT:       The format of the bar annotations. Default is '(I0)'.

       INVERTCOLORS: Setting this keyword inverts the colors in the color bar.

       MAXRANGE:     The maximum data value for the bar annotation. Default is
                     NCOLORS.

       MINRANGE:     The minimum data value for the bar annotation. Default is 0.

       MINOR:        The number of minor tick divisions. Default is 2.

       NCOLORS:      This is the number of colors in the color bar.

       NODISPLAY:    COLORBAR uses FSC_COLOR to specify some of it colors. Normally, 
                     FSC_COLOR loads "system" colors as part of its palette of colors.
                     In order to do so, it has to create an IDL widget, which in turn 
                     has to make a connection to the windowing system. If your program 
                     is being run without a window connection, then this program will 
                     fail. If you can live without the system colors (and most people 
                     don't even know they are there, to tell you the truth), then setting 
                     this keyword will keep them from being loaded, and you can run
                     COLORBAR without a display.

       POSITION:     A four-element array of normalized coordinates in the same
                     form as the POSITION keyword on a plot. Default is
                     [0.88, 0.10, 0.95, 0.90] for a vertical bar and
                     [0.10, 0.88, 0.90, 0.95] for a horizontal bar.

       RANGE:        A two-element vector of the form [min, max]. Provides an
                     alternative way of setting the MINRANGE and MAXRANGE keywords.

       REVERSE:      Setting this keyword reverses the colors in the colorbar.

       RIGHT:        This puts the labels on the right-hand side of a vertical
                     color bar. It applies only to vertical color bars.

       TICKNAMES:    A string array of names or values for the tick marks.

       TITLE:        This is title for the color bar. The default is to have
                     no title.

       TOP:          This puts the labels on top of the bar rather than under it.
                     The keyword only applies if a horizontal color bar is rendered.

       VERTICAL:     Setting this keyword give a vertical color bar. The default
                     is a horizontal color bar.
       MATCH:	      If set will match color bar to extent of plot.

 COMMON BLOCKS:

       None.

 SIDE EFFECTS:

       Color bar is drawn in the current graphics window.

 RESTRICTIONS:

       The number of colors available on the graphics display device (not the
       PostScript device) is used unless the NCOLORS keyword is used.

       Requires the FSC_COLOR program from the Coyote Library:

          http://www.dfanning.com/programs/fsc_color.pro

 EXAMPLES:

       To display a horizontal color bar above a contour plot, type:

       LOADCT, 5, NCOLORS=100
       CONTOUR, DIST(31,41), POSITION=[0.15, 0.15, 0.95, 0.75], $
          C_COLORS=INDGEN(25)*4, NLEVELS=25
       COLORBAR, NCOLORS=100, POSITION=[0.15, 0.8, 0.95, 0.90]

       To display a vertical color bar in the lower right of a contour plot, type:

	IDL> device, decompose=0
	IDL> loadct, 3
	IDL> contour, dist(100), /fill, nlevels=100, zstyle=1
	IDL> colorbar, pos=[.92,.1,.95,.4], /vert, title='Kev'

 MODIFICATION HISTORY:

       Written by: David W. Fanning, 10 JUNE 96.
       10/27/96: Added the ability to send output to PostScript. DWF
       11/4/96: Substantially rewritten to go to screen or PostScript
           file without having to know much about the PostScript device
           or even what the current graphics device is. DWF
       1/27/97: Added the RIGHT and TOP keywords. Also modified the
            way the TITLE keyword works. DWF
       7/15/97: Fixed a problem some machines have with plots that have
            no valid data range in them. DWF
       12/5/98: Fixed a problem in how the colorbar image is created that
            seemed to tickle a bug in some versions of IDL. DWF.
       1/12/99: Fixed a problem caused by RSI fixing a bug in IDL 5.2. Sigh... DWF.
       3/30/99: Modified a few of the defaults. DWF.
       3/30/99: Used NORMAL rather than DEVICE coords for positioning bar. DWF.
       3/30/99: Added the RANGE keyword. DWF.
       3/30/99: Added FONT keyword. DWF
       5/6/99: Many modifications to defaults. DWF.
       5/6/99: Removed PSCOLOR keyword. DWF.
       5/6/99: Improved error handling on position coordinates. DWF.
       5/6/99. Added MINOR keyword. DWF.
       5/6/99: Set Device, Decomposed=0 if necessary. DWF.
       2/9/99: Fixed a problem caused by setting BOTTOM keyword, but not NCOLORS. DWF.
       8/17/99. Fixed a problem with ambiguous MIN and MINOR keywords. DWF
       8/25/99. I think I *finally* got the BOTTOM/NCOLORS thing sorted out. :-( DWF.
       10/10/99. Modified the program so that current plot and map coordinates are
            saved and restored after the colorbar is drawn. DWF.
       3/18/00. Moved a block of code to prevent a problem with color decomposition. DWF.
       4/28/00. Made !P.Font default value for FONT keyword. DWF.
       9/26/00. Made the code more general for scalable pixel devices. DWF.
       1/16/01. Added INVERTCOLORS keyword. DWF.
       5/11/04. Added TICKNAME keyword. DWF.
       9/29/05. Added REVERSE keywords, which does the *exact* same thing as
           INVERTCOLORS, but I can never remember the latter keyword name. DWF.
       1/2/07. Added ANNOTATECOLOR keyword. DWF.
       4/14/07. Changed the default FORMAT to I0. DWF.
       5/1/07. Unexpected consequence of default format change is colorbar annotations
           no longer match contour plot levels. Changed to explicit formating of
           colorbar axis labels before PLOT command. DWF.
       5/25/07. Previous change has unanticipated effect on color bars using
           logarithmic scaling, which is not really supported, but I have an
           article on my web page describing how to do it: http://www.dfanning.com/graphics_tips/logcb.html.
           Thus, I've fixed the program to accommodate log scaling, while still not OFFICIALLY
           supporting it. DWF.
       10/3/07. Method used to calculate TICKNAMES produces incorrect values in certain cases when
           the min and max range values are integers. Now force range values to be floats. DWF.
       10/17/07. Accidentaly use of INTERP keyword in CONGRID results in wrong bar values for
           low NCOLORS numbers when INVERTCOLORS or REVERSE keyword is used. Removed INTERP keyword. DWF.
       11/10/07. Finished fixing program to accommodate log scaling in ALL possible permutations. DWF.
       8 Feb 2008. Added CRONJOB keyword and decided to use month names when I write the date. DWF.
       8 Feb 2008. Renamed CRONJOB to NODISPLAY to better reflect its purpose. DWF.
      21 May 2008. Changed the default CHARSIZE to !P.CHARSIZE from 1.0. DWF.
      30 Oct 2008. Fixed a problem with the FONT keyword not being recognized in certain
            configurations.
	13-Dec-2010 Default range to !Z.CRANGE (set when contour was last called) [BD]
	19-Jul-2011 Added Match keyword to make vertical colorbar match in height to plot
		    window. Also, default to having number on outside of colorbar when 
		    vertical and on the right. [BD]
	23-Sep-2013 show every other tic value when numbers large [BD]


DRAWDIAMOND

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       drawdiamond
 PURPOSE:
  	draw a diamond in data coordinates
 CATEGORY:
	Graphics
 USAGE:
	IDL> drawdiamond, x, y, radius
 INPUTS:
       x - x of center 
	y - y of center
	radius - height of diamond
 KEYWORD PARAMETERS:
	color - color of diamond
	dashed - if set, linestyle is 4

 MODIFICATION HISTORY:
       22-mar-2012 Written by Bill Davis, PPPL


DRAWRECTANGLE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       drawrectangle
 PURPOSE:
  	draw a rectangle in data coordinates
 CATEGORY:
	Graphics
 USAGE:
	IDL> drawrectangle, x1, y1, x2, y2
 INPUTS:
       text - text string to write to window
 KEYWORD PARAMETERS:
	dropshadow - if set, make a drop shadow of thick=3 text
	color - color of text
	dscolor - color of drop-shadow text (defaults to black or white)
	nPixels - # of pixels to drop shadow

 MODIFICATION HISTORY:
       25-Sep-2006 Written by Bill Davis, PPPL


FSC_COLORBAR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   FSC_COLORBAR
   
      Note: The name of the routine has been changed from COLORBAR
      on 25 Sept 2010 to avoid conflicts with an IDL 8.0 routine of the
      same name. See the article "IDL 8 Name Conflicts" here:
       
           http://www.dfanning.com/ng_tips/idl8_name_conflicts.html

 PURPOSE:

       The purpose of this routine is to add a color bar to the current
       graphics window.

 AUTHOR:

   FANNING SOFTWARE CONSULTING
   David Fanning, Ph.D.
   1645 Sheely Drive
   Fort Collins, CO 80526 USA
   Phone: 970-221-0438
   E-mail: davidf@dfanning.com
   Coyote's Guide to IDL Programming: http://www.dfanning.com/

 CATEGORY:

       Graphics, Widgets.

 CALLING SEQUENCE:

       FSC_COLORBAR

 INPUTS:

       None.

 KEYWORD PARAMETERS:

       ADDCMD:       Set this keyword to add the FSC_Colorbar command to the current FSC_Window
                     command list. 
               
       ANNOTATECOLOR: The name of the "annotation color" to use. The names are those for
                     FSC_COLOR, and using the keyword implies that FSC_COLOR is also in
                     your !PATH. If this keyword is used, the annotation color is loaded
                     *after* the color bar is displayed. The color will be represented
                     as theColor = FSC_COLOR(ANNOTATECOLOR). This keyword is provide
                     to maintain backward compatibility, but also to solve the problem of
                     an extra line in the color bar when this kind of syntax is used in
                     conjunction with the indexed (DEVICE, DECOMPOSED=0) model is used:

                          LoadCT, 33
                          TVImage, image
                          FSC_Colorbar, Color=FSC_Color('firebrick')

                     The proper syntax for device-independent color is like this:

                          LoadCT, 33
                          TVImage, image
                          FSC_Colorbar, AnnotateColor='firebrick', Color=255
                          
                    Set the Modification History note for 13 November 2010 for additional
                    information about default values.

       BOTTOM:       The lowest color index of the colors to be loaded in
                     the bar.

       CHARSIZE:     The character size of the color bar annotations. Default is !P.Charsize.
       
       CLAMP:        A two-element array in data units. The color bar is clamped to these
                     two values. This is mostly of interest if you are "window-leveling"
                     an image. The clamp is set to the "window" of the color bar.
                     Normally, when you are doing this, you would like the colors outside
                     the "window" to be set to a neutral color. Use the NEUTRALINDEX keyword
                     to set the netural color index in the color bar. (See the Example section
                     for more information.

       COLOR:        The color index of the bar outline and characters. Default
                     is !P.Color. To display the color bar in a device indpendent
                     way, you should use the ANNOTATECOLOR keyword instead of this keyword.
                     If this keyword is a string color name, then ANNOTATECOLOR=color.

       DIVISIONS:    The number of divisions to divide the bar into. There will
                     be (divisions + 1) annotations. The default is 6.

       FONT:         Sets the font of the annotation. Hershey: -1, Hardware:0, True-Type: 1.

       FORMAT:       The format of the bar annotations. Default is '(I0)'.

       INVERTCOLORS: Setting this keyword inverts the colors in the color bar.

       MAXRANGE:     The maximum data value for the bar annotation. Default is
                     NCOLORS.

       MINRANGE:     The minimum data value for the bar annotation. Default is 0.

       MINOR:        The number of minor tick divisions. Default is 2.

       NCOLORS:      This is the number of colors in the color bar.
       
       NEUTRALINDEX: This is the color index to use for color bar values outside the
                     clamping range when clamping the color bar with the CLAMP keyword.
                     If this keyword is absent, the highest color table value is used
                     for low range values and the lowest color table value is used
                     for high range values, in order to provide contrast with the
                     clamped region. See the Example section for more information.

       NODISPLAY:    FSC_COLORBAR uses FSC_COLOR to specify some of it colors. Normally, 
                     FSC_COLOR loads "system" colors as part of its palette of colors.
                     In order to do so, it has to create an IDL widget, which in turn 
                     has to make a connection to the windowing system. If your program 
                     is being run without a window connection, then this program will 
                     fail. If you can live without the system colors (and most people 
                     don't even know they are there, to tell you the truth), then setting 
                     this keyword will keep them from being loaded, and you can run
                     FSC_COLORBAR without a display. As of 19 Oct 2010, set to 1  by default.

       POSITION:     A four-element array of normalized coordinates in the same
                     form as the POSITION keyword on a plot. Default is
                     [0.88, 0.10, 0.95, 0.90] for a vertical bar and
                     [0.10, 0.88, 0.90, 0.95] for a horizontal bar.

       RANGE:        A two-element vector of the form [min, max]. Provides an
                     alternative way of setting the MINRANGE and MAXRANGE keywords.

       REVERSE:      Setting this keyword reverses the colors in the colorbar.

       RIGHT:        This puts the labels on the right-hand side of a vertical
                     color bar. It applies only to vertical color bars.

       TICKNAMES:    A string array of names or values for the tick marks.

       TITLE:        This is title for the color bar. The default is to have
                     no title.

       TOP:          This puts the labels on top of the bar rather than under it.
                     The keyword only applies if a horizontal color bar is rendered.

       VERTICAL:     Setting this keyword give a vertical color bar. The default
                     is a horizontal color bar.
                     
       WINDOW:       Set this keyword if you want to add the FSC_Colorbar command to
                     the current FSC_Window application.

 COMMON BLOCKS:

       None.

 SIDE EFFECTS:

       Color bar is drawn in the current graphics window.

 RESTRICTIONS:

       The number of colors available on the graphics display device (not the
       PostScript device) is used unless the NCOLORS keyword is used.

       Requires the FSC_COLOR program from the Coyote Library:

          http://www.dfanning.com/programs/fsc_color.pro

 EXAMPLE:

       To display a horizontal color bar above a contour plot, type:

       LOADCT, 5, NCOLORS=100
       CONTOUR, DIST(31,41), POSITION=[0.15, 0.15, 0.95, 0.75], $
          C_COLORS=INDGEN(25)*4, NLEVELS=25
       FSC_COLORBAR, NCOLORS=100, POSITION=[0.15, 0.85, 0.95, 0.90]
       
       Example using the CLAMP and NEUTRALINDEX keywords.
       
       LOADCT, 33, NCOLORS=254
       TVLCT, FSC_COLOR('gray', /TRIPLE), 255
       FSC_COLORBAR, NCOLORS=254, NEUTRALINDEX=255, RANGE=[0,1500], $
           DIVISIONS=8, CLAMP=[400, 800]

 MODIFICATION HISTORY:

       Written by: David W. Fanning, 10 JUNE 96.
       10/27/96: Added the ability to send output to PostScript. DWF
       11/4/96: Substantially rewritten to go to screen or PostScript
           file without having to know much about the PostScript device
           or even what the current graphics device is. DWF
       1/27/97: Added the RIGHT and TOP keywords. Also modified the
            way the TITLE keyword works. DWF
       7/15/97: Fixed a problem some machines have with plots that have
            no valid data range in them. DWF
       12/5/98: Fixed a problem in how the colorbar image is created that
            seemed to tickle a bug in some versions of IDL. DWF.
       1/12/99: Fixed a problem caused by RSI fixing a bug in IDL 5.2. Sigh... DWF.
       3/30/99: Modified a few of the defaults. DWF.
       3/30/99: Used NORMAL rather than DEVICE coords for positioning bar. DWF.
       3/30/99: Added the RANGE keyword. DWF.
       3/30/99: Added FONT keyword. DWF
       5/6/99: Many modifications to defaults. DWF.
       5/6/99: Removed PSCOLOR keyword. DWF.
       5/6/99: Improved error handling on position coordinates. DWF.
       5/6/99. Added MINOR keyword. DWF.
       5/6/99: Set Device, Decomposed=0 if necessary. DWF.
       2/9/99: Fixed a problem caused by setting BOTTOM keyword, but not NCOLORS. DWF.
       8/17/99. Fixed a problem with ambiguous MIN and MINOR keywords. DWF
       8/25/99. I think I *finally* got the BOTTOM/NCOLORS thing sorted out. :-( DWF.
       10/10/99. Modified the program so that current plot and map coordinates are
            saved and restored after the colorbar is drawn. DWF.
       3/18/00. Moved a block of code to prevent a problem with color decomposition. DWF.
       4/28/00. Made !P.Font default value for FONT keyword. DWF.
       9/26/00. Made the code more general for scalable pixel devices. DWF.
       1/16/01. Added INVERTCOLORS keyword. DWF.
       5/11/04. Added TICKNAME keyword. DWF.
       9/29/05. Added REVERSE keywords, which does the *exact* same thing as
           INVERTCOLORS, but I can never remember the latter keyword name. DWF.
       1/2/07. Added ANNOTATECOLOR keyword. DWF.
       4/14/07. Changed the default FORMAT to I0. DWF.
       5/1/07. Unexpected consequence of default format change is colorbar annotations
           no longer match contour plot levels. Changed to explicit formating of
           colorbar axis labels before PLOT command. DWF.
       5/25/07. Previous change has unanticipated effect on color bars using
           logarithmic scaling, which is not really supported, but I have an
           article on my web page describing how to do it: http://www.dfanning.com/graphics_tips/logcb.html.
           Thus, I've fixed the program to accommodate log scaling, while still not OFFICIALLY
           supporting it. DWF.
       10/3/07. Method used to calculate TICKNAMES produces incorrect values in certain cases when
           the min and max range values are integers. Now force range values to be floats. DWF.
       10/17/07. Accidentaly use of INTERP keyword in CONGRID results in wrong bar values for
           low NCOLORS numbers when INVERTCOLORS or REVERSE keyword is used. Removed INTERP keyword. DWF.
       11/10/07. Finished fixing program to accommodate log scaling in ALL possible permutations. DWF.
       8 Feb 2008. Added CRONJOB keyword and decided to use month names when I write the date. DWF.
       8 Feb 2008. Renamed CRONJOB to NODISPLAY to better reflect its purpose. DWF.
      21 May 2008. Changed the default CHARSIZE to !P.CHARSIZE from 1.0. DWF.
      30 Oct 2008. Fixed a problem with the FONT keyword not being recognized in certain
            configurations.
      9 Nov 2009. Fixed typo in title of vertical colorbar. DWF.
      25 Sep 2010. Renamed FSC_Colorbar from Colorbar to avoid conflict with ITTVIS introduced
             colorbar.pro function in IDL 8.0. DWF.
      19 Oct 2010. Made changes so that axes titles are not picked up in _EXTRA and displayed
             on the color bar. Also changed all _EXTRA passes to _STRICT_EXTRA to report
             mis-spelled and/or inappropriate keywords. DWF.
      19 Oct 2010. Changed the default value of NODISPLAY keyword to 1, since FSC_Color
             no longer looks for system colors anyway. NODISPLAY is a depreciated keyword
             and does nothing if using the latest version of FSC_Color. DWF.
      13 Nov 2010. Samples the upper-right hand pixel on the display if it can. It this pixel is 
             "white" or the current device is PostScript, sets the ANNOTATECOLOR keyword
             to "black" if it of the COLOR keyword is not currently set to some other color. 
             If the pixel is "black" then ANNOTATECOLOR is set to "white". DWF.
      19 Nov 2010. Fixed a small problem when choosing an AnnnotateColor. DWF.
      29 Nov 2010. Added CLAMP and NEUTRALINDEX keywords, updated ability to set
             color model with SetDecomposedState command. DWF.
      1 Dec 2010. Set COLOR=1 and BITS_PER_PIXEL=8 in PostScript device. Tired of getting
             e-mails that "your damn colorbar doesn't work!". DWF.
      6 Dec 2010. I was always setting COLOR to ANNOTATECOLOR. I should only do that if
             COLOR is undefined. DWF.
      24 Jan 2011. Added WINDOW keyword. DWF.
      29 Jan 2011. Added ADDCMD keyword. DWF.


FSC_COLOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       FSC_COLOR

 PURPOSE:

       The purpose of this function is to obtain drawing colors
       by name and in a device/decomposition independent way.
       The color names and values may be read in as a file, or 192 color
       names and values are supplied with the program. These colors were
       obtained from the file rgb.txt, found on most X-Window distributions,
       and from colors in the Brewer color tables (http://colorbrewer2.org/).
       Representative colors were chosen from across the color spectrum. To
       see a list of colors available, type:

          Print, FSC_Color(/Names), Format='(6A18)'
          
        If the color names '0', '1', '2', ..., '255' are used, they will
        correspond to the colors in the current color table in effect at
        the time the FSC_Color program is called.

 AUTHOR:

       FANNING SOFTWARE CONSULTING:
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: davidf@dfanning.com
       Coyote's Guide to IDL Programming: http://www.dfanning.com

 CATEGORY:

       Graphics, Color Specification.

 CALLING SEQUENCE:

       color = FSC_Color(theColor, theColorIndex)

 NORMAL CALLING SEQUENCE FOR DEVICE-INDEPENDENT COLOR:

       If you write your graphics code *exactly* as it is written below, then
       the same code will work in all graphics devices I have tested.
       These include the PRINTER, PS, and Z devices, as well as X, WIN, and MAC.

       In practice, graphics code is seldom written like this. (For a variety of
       reasons, but laziness is high on the list.) So I have made the
       program reasonably tolerant of poor programming practices. I just
       point this out as a place you might return to before you write me
       a nice note saying my program "doesn't work". :-)

       axisColor = FSC_Color("Green", !D.Table_Size-2)
       backColor = FSC_Color("Charcoal", !D.Table_Size-3)
       dataColor = FSC_Color("Yellow", !D.Table_Size-4)
       thisDevice = !D.Name
       Set_Plot, 'toWhateverYourDeviceIsGoingToBe', /Copy
       Device, .... ; Whatever you need here to set things up properly.
       IF (!D.Flags AND 256) EQ 0 THEN $
         POLYFILL, [0,1,1,0,0], [0,0,1,1,0], /Normal, Color=backColor
       Plot, Findgen(11), Color=axisColor, Background=backColor, /NoData, $
          NoErase= ((!D.Flags AND 256) EQ 0)
       OPlot, Findgen(11), Color=dataColor
       Device, .... ; Whatever you need here to wrap things up properly.
       Set_Plot, thisDevice

 OPTIONAL INPUT PARAMETERS:

       theColor: A string with the "name" of the color. To see a list
           of the color names available set the NAMES keyword. This may
           also be a vector of color names. Colors available are these:

           Active            Almond     Antique White        Aquamarine             Beige            Bisque
             Black              Blue       Blue Violet             Brown         Burlywood        Cadet Blue
          Charcoal        Chartreuse         Chocolate             Coral   Cornflower Blue          Cornsilk
           Crimson              Cyan    Dark Goldenrod         Dark Gray        Dark Green        Dark Khaki
       Dark Orchid          Dark Red       Dark Salmon   Dark Slate Blue         Deep Pink       Dodger Blue
              Edge              Face         Firebrick      Forest Green             Frame              Gold
         Goldenrod              Gray             Green      Green Yellow         Highlight          Honeydew
          Hot Pink        Indian Red             Ivory             Khaki          Lavender        Lawn Green
       Light Coral        Light Cyan        Light Gray      Light Salmon   Light Sea Green      Light Yellow
        Lime Green             Linen           Magenta            Maroon       Medium Gray     Medium Orchid
          Moccasin              Navy             Olive        Olive Drab            Orange        Orange Red
            Orchid    Pale Goldenrod        Pale Green            Papaya              Peru              Pink
              Plum       Powder Blue            Purple               Red              Rose        Rosy Brown
        Royal Blue      Saddle Brown            Salmon       Sandy Brown         Sea Green          Seashell
          Selected            Shadow            Sienna          Sky Blue        Slate Blue        Slate Gray
              Snow      Spring Green        Steel Blue               Tan              Teal              Text
           Thistle            Tomato         Turquoise            Violet        Violet Red             Wheat
             White            Yellow

           The color OPPOSITE is used if this parameter is absent or a color name is mis-spelled. To see a list
           of the color names available in the program, type this:

              IDL> Print, FSC_Color(/Names), Format='(6A18)'

       theColorIndex: The color table index (or vector of indices the same length
           as the color name vector) where the specified color is loaded. The color table
           index parameter should always be used if you wish to obtain a color value in a
           color-decomposition-independent way in your code. See the NORMAL CALLING
           SEQUENCE for details. If theColor is a vector, and theColorIndex is a scalar,
           then the colors will be loaded starting at theColorIndex.

        When the BREWER keyword is set, you must use more arbitrary and less descriptive color
        names. To see a list of those names, use the command above with the BREWER keyword set,
        or call PICKCOLORNAME with the BREWER keyword set:

               IDL> Print, FSC_Color(/Names, /BREWER), Format='(8A10)'
               IDL> color = PickColorName(/BREWER)

         Here are the Brewer names:

       WT1       WT2       WT3       WT4       WT5       WT6       WT7       WT8
      TAN1      TAN2      TAN3      TAN4      TAN5      TAN6      TAN7      TAN8
      BLK1      BLK2      BLK3      BLK4      BLK5      BLK6      BLK7      BLK8
      GRN1      GRN2      GRN3      GRN4      GRN5      GRN6      GRN7      GRN8
      BLU1      BLU2      BLU3      BLU4      BLU5      BLU6      BLU7      BLU8
      ORG1      ORG2      ORG3      ORG4      ORG5      ORG6      ORG7      ORG8
      RED1      RED2      RED3      RED4      RED5      RED6      RED7      RED8
      PUR1      PUR2      PUR3      PUR4      PUR5      PUR6      PUR7      PUR8
      PBG1      PBG2      PBG3      PBG4      PBG5      PBG6      PBG7      PBG8
      YGB1      YGB2      YGB3      YGB4      YGB5      YGB6      YGB7      YGB8
      RYB1      RYB2      RYB3      RYB4      RYB5      RYB6      RYB7      RYB8
       TG1       TG2       TG3       TG4       TG5       TG6       TG7       TG8

       As of 3 July 2008, the Brewer names are also now available to the user without using 
       the BREWER keyword. If the BREWER keyword is used, *only* Brewer names are available.
       
       The color name "OPPOSITE" is also available. It chooses a color "opposite" to the 
       color of the pixel in the upper-right corner of the display, if a window is open.
       Otherwise, this color is "black" in PostScript and "white" everywhere else.
       
 RETURN VALUE:

       The value that is returned by FSC_Color depends upon the keywords
       used to call it, on the version of IDL you are using,and on the depth
       of the display device when the program is invoked. In general,
       the return value will be either a color index number where the specified
       color is loaded by the program, or a 24-bit color value that can be
       decomposed into the specified color on true-color systems. (Or a vector
       of such numbers.)

       If you are running IDL 5.2 or higher, the program will determine which
       return value to use, based on the color decomposition state at the time
       the program is called. If you are running a version of IDL before IDL 5.2,
       then the program will return the color index number. This behavior can
       be overruled in all versions of IDL by setting the DECOMPOSED keyword.
       If this keyword is 0, the program always returns a color index number. If
       the keyword is 1, the program always returns a 24-bit color value.

       If the TRIPLE keyword is set, the program always returns the color triple,
       no matter what the current decomposition state or the value of the DECOMPOSED
       keyword. Normally, the color triple is returned as a 1 by 3 column vector.
       This is appropriate for loading into a color index with TVLCT:

          IDL> TVLCT, FSC_Color('Yellow', /Triple), !P.Color

       But sometimes (e.g, in object graphics applications) you want the color
       returned as a row vector. In this case, you should set the ROW keyword
       as well as the TRIPLE keyword:

          viewobj= Obj_New('IDLgrView', Color=FSC_Color('charcoal', /Triple, /Row))

       If the ALLCOLORS keyword is used, then instead of a single value, modified
       as described above, then all the color values are returned in an array. In
       other words, the return value will be either an NCOLORS-element vector of color
       table index numbers, an NCOLORS-element vector of 24-bit color values, or
       an NCOLORS-by-3 array of color triples.

       If the NAMES keyword is set, the program returns a vector of
       color names known to the program.

       If the color index parameter is not used, and a 24-bit value is not being
       returned, then colorIndex is typically set to !D.Table_Size-1. However,
       this behavior is changed on 8-bit devices (e.g., the PostScript device,
       or the Z-graphics buffer) and on 24-bit devices that are *not* using
       decomposed color. On these devices, the colors are loaded at an
       offset of !D.Table_Size - ncolors - 2, and the color index parameter reflects
       the actual index of the color where it will be loaded. This makes it possible
       to use a formulation as below:

          Plot, data, Color=FSC_Color('Dodger Blue')

       on 24-bit displays *and* in PostScript output! Note that if you specify a color
       index (the safest thing to do), then it will always be honored.

 INPUT KEYWORD PARAMETERS:

       ALLCOLORS: Set this keyword to return indices, or 24-bit values, or color
              triples, for all the known colors, instead of for a single color.

       BREWER: Set this keyword if you wish to use the Brewer Colors, as defined
              in this reference:

              http://www.personal.psu.edu/cab38/ColorBrewer/ColorBrewer_intro.html
              
              As of 3 July 2008, the BREWER names are always available to the user, with or
              without this keyword. If the keyword is used, only BREWER names are available.

       DECOMPOSED: Set this keyword to 0 or 1 to force the return value to be
              a color table index or a 24-bit color value, respectively.

       CHECK_CONNECTION: If this keyword is set, the program will check to see if it can obtain
              a window connection before it tries to load system colors (which require one). If you
              think you might be using FSC_COLOR in a cron job, for example, you would want to set this
              keyword. If there is no window connection, the system colors are not available from the program.
              As of 18 October 2010, this keyword is no longer used, as system colors have been
              removed from the program.

       FILENAME: The string name of an ASCII file that can be opened to read in
              color values and color names. There should be one color per row
              in the file. Please be sure there are no blank lines in the file.
              The format of each row should be:

                  redValue  greenValue  blueValue  colorName

              Color values should be between 0 and 255. Any kind of white-space
              separation (blank characters, commas, or tabs) are allowed. The color
              name should be a string, but it should NOT be in quotes. A typical
              entry into the file would look like this:

                  255   255   0   Yellow

       NAMES: If this keyword is set, the return value of the function is
              a ncolors-element string array containing the names of the colors.
              These names would be appropriate, for example, in building
              a list widget with the names of the colors. If the NAMES
              keyword is set, the COLOR and INDEX parameters are ignored.

                 listID = Widget_List(baseID, Value=GetColor(/Names), YSize=16)


       NODISPLAY: Normally, FSC_COLOR loads "system" colors as part of its palette of colors.
              In order to do so, it has to create an IDL widget, which in turn has to make
              a connection to the windowing system. If your program is being run without a 
              window connection, then this program will fail. If you can live without the system 
              colors (and most people don't even know they are there, to tell you the truth), 
              then setting this keyword will keep them from being loaded, and you can run
              FSC_COLOR without a display. THIS KEYWORD NOW DEPRECIATED IN FAVOR OF CHECK_CONNECTION.
              As of 18 October 2010, this keyword is no longer used, as system colors have been
              removed from the program.

       ROW:   If this keyword is set, the return value of the function when the TRIPLE
              keyword is set is returned as a row vector, rather than as the default
              column vector. This is required, for example, when you are trying to
              use the return value to set the color for object graphics objects. This
              keyword is completely ignored, except when used in combination with the
              TRIPLE keyword.

       SELECTCOLOR: Set this keyword if you would like to select the color name with
              the PICKCOLORNAME program. Selecting this keyword automaticallys sets
              the INDEX positional parameter. If this keyword is used, any keywords
              appropriate for PICKCOLORNAME can also be used. If this keyword is used,
              the first positional parameter can be a color name that will appear in
              the SelectColor box.

       TRIPLE: Setting this keyword will force the return value of the function to
              *always* be a color triple, regardless of color decomposition state or
              visual depth of the machine. The value will be a three-element column
              vector unless the ROW keyword is also set.

       In addition, any keyword parameter appropriate for PICKCOLORNAME can be used.
       These include BOTTOM, COLUMNS, GROUP_LEADER, INDEX, and TITLE.

 OUTPUT KEYWORD PARAMETERS:

       CANCEL: This keyword is always set to 0, unless that SELECTCOLOR keyword is used.
              Then it will correspond to the value of the CANCEL output keyword in PICKCOLORNAME.

       COLORSTRUCTURE: This output keyword (if set to a named variable) will return a
              structure in which the fields will be the known color names (without spaces)
              and the values of the fields will be either color table index numbers or
              24-bit color values. If you have specified a vector of color names, then
              this will be a structure containing just those color names as fields.

       NCOLORS: The number of colors recognized by the program. It will be 104 by default.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       None.

 RESTRICTIONS:

   Required programs from the Coyote Library:

      http://www.dfanning.com/programs/error_message.pro
      http://www.dfanning.com/programs/pickcolorname.pro
      http://www.dfanning.com/programs/decomposedcolor.pro

 EXAMPLE:

       To get drawing colors in a device-decomposed independent way:

           axisColor = FSC_Color("Green", !D.Table_Size-2)
           backColor = FSC_Color("Charcoal", !D.Table_Size-3)
           dataColor = FSC_Color("Yellow", !D.Table_Size-4)
           Plot, Findgen(11), Color=axisColor, Background=backColor, /NoData
           OPlot, Findgen(11), Color=dataColor

       To set the viewport color in object graphics:

           theView = Obj_New('IDLgrView', Color=FSC_Color('Charcoal', /Triple))

       To change the viewport color later:

           theView->SetProperty, Color=FSC_Color('Antique White', /Triple)

       To load the drawing colors "red", "green", and "yellow" at indices 100-102, type this:

           IDL> TVLCT, FSC_Color(["red", "green", and "yellow"], /Triple), 100

 MODIFICATION HISTORY:

       Written by: David W. Fanning, 19 October 2000. Based on previous
          GetColor program.
       Fixed a problem with loading colors with TVLCT on a PRINTER device. 13 Mar 2001. DWF.
       Added the ROW keyword. 30 March 2001. DWF.
       Added the PICKCOLORNAME code to the file, since I keep forgetting to
          give it to people. 15 August 2001. DWF.
       Added ability to specify color names and indices as vectors. 5 Nov 2002. DWF.
       Fixed a problem with the TRIPLE keyword when specifying a vector of color names. 14 Feb 2003. DWF.
       Fixed a small problem with the starting index when specifying ALLCOLORS. 24 March 2003. DWF.
       Added system color names. 23 Jan 2004. DWF
       Added work-around for WHERE function "feature" when theColor is a one-element array. 22 July 2004. DWF.
       Added support for 8-bit graphics devices when color index is not specified. 25 August 2004. DWF.
       Fixed a small problem with creating color structure when ALLCOLORS keyword is set. 26 August 2004. DWF.
       Extended the color index fix for 8-bit graphics devices on 25 August 2004 to
         24-bit devices running with color decomposition OFF. I've concluded most of
         the people using IDL don't have any idea how color works, so I am trying to
         make it VERY simple, and yet still maintain the power of this program. So now,
         in general, for most simple plots, you don't have to use the colorindex parameter
         and you still have a very good chance of getting what you expect in a device-independent
         manner. Of course, it would be *nice* if you could use that 24-bit display you paid
         all that money for, but I understand your reluctance. :-)   11 October 2004. DWF.
       Have renamed the first positional parameter so that this variable doesn't change
         while the program is running. 7 December 2004. DWF.
       Fixed an error I introduced on 7 December 2004. Sigh... 7 January 2005. DWF.
       Added eight new colors. Total now of 104 colors. 11 August 2005. DWF.
       Modified GUI to display system colors and removed PickColorName code. 13 Dec 2005. DWF.
       Fixed a problem with colorIndex when SELECTCOLOR keyword was used. 13 Dec 2005. DWF.
       Fixed a problem with color name synonyms. 19 May 2006. DWF.
       The previous fix broke the ability to specify several colors at once. Fixed. 24 July 2006. DWF.
       Updated program to work with 24-bit Z-buffer in IDL 6.4. 11 June 2007. DWF
       Added the CRONJOB keyword. 07 Feb 2008. DWF.
       Changed the CRONJOB keyword to NODISPLAY to better reflect its purpose. 7 FEB 2008. DWF.
       Added the BREWER keyword to allow selection of Brewer Colors. 15 MAY 2008. DWF.
       Added the CHECK_CONNECTION keyword and depreciated the NODISPLAY keyword for cron jobs. 15 MAY 2008. DWF.
       Added the BREWER names to the program with or without the BREWER keyword set. 3 JULY 2008. DWF.
       If color names '0', '1', '2', ..., '255', are used, the colors are taken from the current
          color table in effect when the program is called. 23 March 2009. DWF.
       Added the ability to use 24-bit PostScript color, if available. 24 May 2009. DWF.
       Program relies on DecomposedColor() to determine decomposed state of PostScript device. 24 May 2009. DWF.
       Mis-spelled variable name prevented color structure from being returned by COLORSTRUCTURE keyword. 14 Oct 2009. DWF.
       The Z-buffer, after IDL 6.4, appears to be brain dead. It is *always* in DECOMPOSED=1
           mode, even when using an 8-bit graphics buffer. (Unless set manaually.) Now I set
           the decomposition mode in the program by looking at buffer depth, rather than
           the decomposition state, for the Z-buffer. 23 July 2010. DWF.
       Adding "system" colors to FSC_Color may have been the worst design decision I ever made.
            Since these require a window connection to determine, this decision has haunted
            me for years in the form of people wanting to use the software in places where
            there is no window connection. For example, in cron jobs. To accommodate legacy
            code, I need to *always* check for a connection. I am loath to do this because it
            means opening and closing a window, which is, relatively speaking, a slow process.
            I've made another attempt to solve this problem with this update and the
            corresponding update to the Coyote Library program CanConnect. CanConnect how
            creates the system variable !FSC_Display_Connection. If this system variable 
            exists, FSC_Color consults it to determine if there is a display connection. It
            it doesn't exist, it calls CanConnect. This way, a window has to be open only
            once in an IDL session to determine if a display connection can be made. 7 Oct 2010. DWF.
       I am tired of dealing with "system" colors. I've never used them, no one I know
            has ever used them, and they have given me nothing but headaches. I'm done
            with them. I'll leave the code here for awhile in case you use them, but
            I'm pretty sure I'm not putting them back in. 17 October 2010. DWF.
       Added a new color name "OPPOSITE". This is a color that is "opposite" of the pixel color
            in the upper right hand corner of the display, if a window is open and the pixel
            color can be determined. Otherwise, it is black in PostScript and white everywhere
            else. 19 Nov 2010. DWF.
       Made sure the ColorIndex that is returned is always an INTEGER. 24 Dec 2010. DWF.
       Changed the default "unknown" color from WHITE to OPPOSITE. 30 Dec 2010. DWF.
       TVLCT commands protected from NULL device. 4 Jan 2011. DWF.


MK_JPEG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MK_JPEG
 PURPOSE:
        make a bit-map color jpeg file of an IDL window for (viewable)
	 insertion into MS Word, or Powerpoint documents.
 CATEGORY:
       Graphics, Publication
 CALLING SEQUENCE:
       IDL> mk_jpeg, FILENAME=filename, WINDOW=window, /VERBOSE
 INPUTS:
       None required 
 KEYWORD PARAMETERS:
       Optional Inputs:
	  noBorder - if set, will eliminate white space at top and bottom
			and left and right
	  filename - Name of output file; Default='idljpeg.jpg'
	  overwrite - if=0, will not overwrite existing file
	  Window   - window number to dump to file
   	  VERBOSE - If set, print debugging information
 OUTPUTS:
       Just the file               			out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> LoadCT, 5
	IDL> TH_IMAGE_CONT, dist(400)	; make a color contour with color bar
	IDL> mk_jpeg, filename='myjpeg.jpg'
 NOTES:
 	do not call mk_color, or other things that limit the number of colors,
 	before running this, so you get 256 colors.

	You must have priviledges to write the file.
 MODIFICATION HISTORY:
	24-Feb-2014 added noBorder keyword
	09-Oct-2013 added overwrite keyword (the default) 
	28-Jul-2010 add status to detect stale NFS handles
	09-Aug-2009 Allow filename to be first argument
	30-Aug-2004 Added test for truecolor (24-bit color), which seems
		    to be needed for Windows
       22-Feb-00 Written by Bill Davis, PPPL; with thanks to Dave Fanning 


MK_PNG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MK_png
 PURPOSE:
        make a bit-map color png file of an IDL window for (viewable)
	 insertion into MS Word, or Powerpoint documents.
 CATEGORY:
       Graphics, Publication
 CALLING SEQUENCE:
       IDL> mk_png, FILENAME=filename, WINDOW=window, /VERBOSE
 INPUTS:
       None required 
 KEYWORD PARAMETERS:
       Optional Inputs:
	  filename - Name of output file; Default='idlpng.jpg'
	  Window   - window number to dump to file
   	  VERBOSE - If set, print debugging information
 OUTPUTS:
       Just the file               			out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> LoadCT, 5
	IDL> TH_IMAGE_CONT, dist(400)	; make a color contour with color bar
	IDL> mk_png, filename='mypng.jpg'
 NOTES:
 	do not call mk_color, or other things that limit the number of colors,
 	before running this, so you get 256 colors.

	You must have priviledges to write the file.
 MODIFICATION HISTORY:
       16-Jun-2011  Written by Bill Davis, PPPL for Charles Skinner


ONESURF

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       ONESURF

 PURPOSE:
       This function returns a 24-bit image of a surface with various
    combinations of colour, shading and grids.  The colour coding can
    tied to the surface height or to an independent array.  A grid can
    be overlaid on the surface or used to mask a coloured or shaded plot
    so as to produce a coloured and/or shaded grid.  Light shading can
    be applied to both the coloured and gridded surface, or just the
    coloured surface, leaving the grid unshaded.

        The plotting is done on the current device, which can be any
    device which supports the TVRD command: eg screen windows, pixmaps,
    or the z-buffer.

        The light shading parameters are determined by previous calls to 
    SET_SHADING.  The viewing position and 3d-2d scaling are handled by
    the usual graphics keywords - see the documentation for SURFACE and
    SHADE_SURF in the IDL user's guide.

        The image returned by ONESURF is a pixel-interleaved 24-bit 
     image of type bytarr(3, xsize, ysize), where xsize and ysize 
     are the dimensions of the current graphics window.
 

 CATEGORY:
       Graphics, Surface Plotting

 CALLING SEQUENCE:
       result = ONESURF(SURFDATA)

 INPUTS:
       SURFDATA:  a two-dimensional array of type byte containing the
                  data to be plotted.

 KEYWORD PARAMETERS:

       COLOUR:  Set this keyword to include colour coding in the plot
                The default is no colour-coding.

       COLDATA: A variable or array of type byte containing the colour 
                data to be used when plotting a colour plot.
                If COLDATA is a scalar then it is assumed to be an index to
                a colour in COLMAP which is used to give a single colour to
                whole surface.
                If COLDATA is a vector of at least three elements its first
                three elements are treated as a rgb colour triple and used
                to give a single colour to the whole surface.
                If COLDATA is two-dimensional it is treated as an array of
                colour indices of COLMAP and used to give each data point
                it's own colour.  If COLDATA has different dimensions to
                SURFDATA, CONGRID is used to stretch or squeeze a copy of
                COLDATA to fit.
                If COLOUR is set but COLDATA is undefined or does not satisfy
                any of the above conditions, a BYTSCL'ed version of SURFDATA is
                used to produce a plot coloured according to height.

       COLMAP:  The colour map to use for plotting of the colour data.
                If a number is given the corresponding inbuilt IDL colour
                map is used.  Otherwise COLMAP should be an array of three
                byte vectors [red, green, blue] such as those returned by
                the TVLCT, /get procedure.  If COLMAP is not set, the
                current colour map is used.  Note that ONESURF maintains
                the current colour map even if a different map is specified
                for the plot.

       SHADE:   Set this keyword to perform light shading.
                    SHADE = 0: no shading
                    SHADE = 1: shade everything
                    SHADE = 2: don't shade the grid
                The default is no shading
                
       GRID:    Set this keyword to apply grids to the surface
                    GRID = 0: no grid
                    GRID = 1: overlay a grid on the surface
                    GRID = 2: use the grid as a mask
                The default is no grid

       CGRID:   The colour to use for overlaid grids.  If CGRID is a number
                it is treated as an index in the colour table given by COLMAP.
                If CGRID is an three-element vector of bytes it is treated
                as the rgb values for a colour.  If it is anything else or
                undefined the grid is plotted white.

       _EXTRA:  Used to pass extra plot parameters to both SHADE_SURF and
                SURFACE.  _EXTRA provides a convenient way of passing
                common parameters such as viewing angle and plot position.
                Note that only keywords valid for both SHADE_SURF and SURFACE
                can be used.
                If EXTRA_SHADE is set, _EXTRA is ignored for the shaded plots,
                similarly with EXTRA_SURF and surface plots.
                Some keywords (eg, SHADES, COLOR, NODATA, NOERASE) will
                interfere with the plotting done by ONESURF and lead to
                unpredictable results.
                _EXTRA is itself passed to SHADE_SURF and SURFACE using
                the _EXTRA keyword, so keywords which expect a data value
                to be changed (eg [XYZ]TICK_GET) will not work.
                Useable keywords are: AX, AZ, MAX_VALUE, MIN_VALUE, SAVE,
                [XY]TYPE, CHARSIZE, CHARTHICK, CLIP, DATA, DEVICE, FONT,
                NOCLIP, NORMAL, POSITION, SUBTITLE, T3D, THICK, TICKLEN,
                TITLE, [XYZ]CHARSIZE, [XYZ]GRIDSTYLE, [XYZ]MARGIN, [XYZ]MINOR
                [XYZ]RANGE, [XYZ]STYLE, [XYZ]THICK, [XYZ]TICKFORMAT,
                [XYZ]TICKLEN, [XYZ]TICKNAME, [XYZ]TICKS, [XYZ]TICKV,
                [XYZ]TITLE, ZVALUE.

       EXTRA_SHADE:  Used to pass extra plot parameters to the SHADE_SURF 
                     procedure only.  EXTRA_SHADE is passed to SHADE_SURF
                     using the _EXTRA keyword so keywords such as IMAGE
                     which expect a variable to be altered will not work.
                     As with _EXTRA, setting the SHADES keyword can lead
                     to unpredictable results.  EXTRA_SURF should be an
                     anonymous structure.

       EXTRA_SURF:  Used to pass extra plot parameters to the SURFACE
                    procedure only.  Restrictions are as for _EXTRA and
                    EXTRA_SHADE.  If EXTRA_SHADE is set, but EXTRA_SURF
                    is not, EXTRA_SURF is made equal to _EXTRA, and vice
                    versa.
                    


 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       None.

 RESTRICTIONS:
       None.

 EXAMPLE:
       Create an image of a surface coloured according to height using
   the current colour map, with light shading and no grid:
           image = onesurf(surfdata, /colour, /shade)

       Create a shaded green grid on a shaded surface:
           image = onesurf(surfdata, /shade, /grid, cgrid=[0,255,0])

       Create a shaded view of a surface, coloured according to a second
   array using colour map 25, overlaid with a grey, unshaded grid:
           image = onesurf(surfdata, /colour, colmap=25, coldata=second_array, $
                             shade=2, /grid, cgrid=[127,127,127])

 MODIFICATION HISTORY:
       Part of Struan's Surface Tutorial: 
            http://www.sljus.lu.se/stm/IDL/Surf_Tips/
       Written by:	Struan Gray, Sljusfysik, Lunds Universitet, 970305.
       970313 SMG - added _extra, extra_surf and extra_shade keywords
                    for better control of graphics keywords.


PICKCOLORNAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       PICKCOLORNAME

 PURPOSE:

       The purpose of this program is to provide a blocking
       or modal widget interface for selecting a color "name".
       The program uses colors familiar to the FSC_COLOR program,
       and is often used to select a color name for passing to FSC_COLOR.

 AUTHOR:

       FANNING SOFTWARE CONSULTING:
       David Fanning, Ph.D.
       1645 Sheely Drive
       Fort Collins, CO 80526 USA
       Phone: 970-221-0438
       E-mail: davidf@dfanning.com
       Coyote's Guide to IDL Programming: http://www.dfanning.com

 CATEGORY:

       Graphics, Color Specification.

 CALLING SEQUENCE:

       colorName = PickColorName(startColorName)

 OPTIONAL INPUT PARAMETERS:

       startColorName: A string with the "name" of the color. Colors available are these:

            Almond     Antique White        Aquamarine             Beige            Bisque             Black
              Blue       Blue Violet             Brown         Burlywood        Cadet Blue          Charcoal
        Chartreuse         Chocolate             Coral   Cornflower Blue          Cornsilk           Crimson
              Cyan    Dark Goldenrod         Dark Gray        Dark Green        Dark Khaki       Dark Orchid
          Dark Red       Dark Salmon   Dark Slate Blue         Deep Pink       Dodger Blue         Firebrick
      Forest Green              Gold         Goldenrod              Gray             Green      Green Yellow
          Honeydew          Hot Pink        Indian Red             Ivory             Khaki          Lavender
        Lawn Green       Light Coral        Light Cyan        Light Gray      Light Salmon   Light Sea Green
      Light Yellow        Lime Green             Linen           Magenta            Maroon       Medium Gray
     Medium Orchid          Moccasin              Navy             Olive        Olive Drab            Orange
        Orange Red            Orchid    Pale Goldenrod        Pale Green            Papaya              Peru
              Pink              Plum       Powder Blue            Purple               Red              Rose
        Rosy Brown        Royal Blue      Saddle Brown            Salmon       Sandy Brown         Sea Green
          Seashell            Sienna          Sky Blue        Slate Blue        Slate Gray              Snow
      Spring Green        Steel Blue               Tan              Teal           Thistle            Tomato
         Turquoise            Violet        Violet Red             Wheat             White            Yellow


       The color WHITE is used if this parameter is absent.

   If the BREWER keyword is set, you can use the Brewer Color names:

       WT1       WT2       WT3       WT4       WT5       WT6       WT7       WT8
      TAN1      TAN2      TAN3      TAN4      TAN5      TAN6      TAN7      TAN8
      BLK1      BLK2      BLK3      BLK4      BLK5      BLK6      BLK7      BLK8
      GRN1      GRN2      GRN3      GRN4      GRN5      GRN6      GRN7      GRN8
      BLU1      BLU2      BLU3      BLU4      BLU5      BLU6      BLU7      BLU8
      ORG1      ORG2      ORG3      ORG4      ORG5      ORG6      ORG7      ORG8
      RED1      RED2      RED3      RED4      RED5      RED6      RED7      RED8
      PUR1      PUR2      PUR3      PUR4      PUR5      PUR6      PUR7      PUR8
      PBG1      PBG2      PBG3      PBG4      PBG5      PBG6      PBG7      PBG8
      YGB1      YGB2      YGB3      YGB4      YGB5      YGB6      YGB7      YGB8
      RYB1      RYB2      RYB3      RYB4      RYB5      RYB6      RYB7      RYB8
       TG1       TG2       TG3       TG4       TG5       TG6       TG7       TG8

 INPUT KEYWORD PARAMETERS:

       BOTTOM: The colors used in the program must be loaded somewhere
           in the color table. This keyword indicates where the colors
           start loading. By default BOTTOM is set equal to !D.Table_Size-NCOLORS-1.

       BREWER: Set this keyword if you wish to use the Brewer Colors, as defined
              in this reference:

              http://www.personal.psu.edu/cab38/ColorBrewer/ColorBrewer_intro.html

       COLUMNS: Set this keyword to the number of columns the colors should
           be arranged in.

       FILENAME: The string name of an ASCII file that can be opened to read in
           color values and color names. There should be one color per row
           in the file. Please be sure there are no blank lines in the file.
           The format of each row should be:

              redValue  greenValue  blueValue  colorName

           Color values should be between 0 and 255. Any kind of white-space
           separation (blank characters, commas, or tabs) are allowed. The color
           name should be a string, but it should NOT be in quotes. A typical
           entry into the file would look like this:

               255   255   0   Yellow

       GROUP_LEADER: This identifies a group leader if the program is called
           from within a widget program. Note that this keyword MUST be provided
           if you want to guarantee modal widget functionality. (If you don't know
           what this means, believe me, you WANT to use this keyword, always.)

       INDEX: This keyword identifies a color table index where the selected color
           is to be loaded when the program exits. The default behavior is to restore
           the input color table and NOT load a color.

       TITLE: This keyword accepts a string value for the window title. The default
           is "Select a Color".

 OUTPUT KEYWORD PARAMETERS:

       CANCEL: On exit, this keyword value is set to 0 if the user selected
           the ACCEPT button. IF the user selected the CANCEL button, or
           closed the window in any other way, this keyword value is set to 1.

 COMMON BLOCKS:

       None.

 SIDE EFFECTS:

       Colors are loaded in the current color table. The input color table
       is restored when the program exits. This will only be noticable on
       8-bit displays. The startColorName is returned if the user cancels
       or destroys the widget before a selection is made. Users should
       check the CANCEL flag before using the returned color.

 EXAMPLE:

       To call the program from the IDL comamnd line:

         IDL> color = PickColorName("red") & Print, color

       To call the program from within a widget program:

         color = PickColorName("red", Group_Leader=event.top) & Print, color

 MODIFICATION HISTORY:

       Written by: David W. Fanning, 31 August 2000.
       Modified program to read colors from a file and to use more
         colors on 24-bit platforms. 16 October 2000. DWF.
       Added the COLUMNS keyword. 16 October 2000. DWF.
       Fixed a small problem with mapping a modal widget. 2 Jan 2001. DWF
       Now drawing small box around each color. 13 March 2003. DWF.
       Added eight new colors. Total now of 104 colors. 11 August 2005. DWF.
       Modified GUI to display system colors. 13 Dec 2005. DWF.
       Added BREWER keyword to allow Brewer Colors. 15 May 2008. DWF.


PSWINDOW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
    PSWINDOW

 PURPOSE:

    This function is used to calculate the size of a PostScript
    window that has the same aspect ratio (ratio of height to
    width) as the current display graphics window. It creates
    the largest possible PostScript output window with the
    desired aspect ratio. This assures that graphics output
    looks similar, if not identical, to PostScript output.

 AUTHOR:

   FANNING SOFTWARE CONSULTING
   David Fanning, Ph.D.
   1645 Sheely Drive
   Fort Collins, CO 80526 USA
   Phone: 970-221-0438
   E-mail: davidf@dfanning.com
   Coyote's Guide to IDL Programming: http://www.dfanning.com/

 CATEGORY:

    Graphics.

 CALLING SEQUENCE:

    pageInfo = PSWINDOW()

 INPUTS:

    None.

 KEYWORD PARAMETERS:

    CM: Normally the structure value that is returned from this
    function reports its values in inches. Setting this keyword
    causes the return values to be in units of centimeters.

    FUDGE: A quick way to set symetrical XFUDGE and YFUDGE factors.
    If this keyword is set to a value, XFUDGE and YFUDGE keywords are
    set to the same value.

    LANDSCAPE: Normally this function assumes a PostScript window
    in Portrait mode. Setting this keyword assumes you want
    the graphic in Landscape mode.

    MARGIN:  The margin around the edges of the plot. The value must be
    a floating point value between 0.0 and 0.5. It is expressed in
    normalized coordinate units. The default margin is 0.15.

    PAGESIZE: Set this keyword to a string indicating the type
    of PostScript page size you want. Current values are "LETTER",
    "LEGAL", and "A4". Default is "LETTER".

    PRINTER: Set this keyword if the output will be used to
    configure the PRINTER device, rather than the PS device.
    (In the PRINTER device, offsets are always calculated from
    the lower-left corner of the page and do not rotate in
    Landscape mode, as they do with the PS device.) Note that
    the PRINTER device is only able to accept these keywords
    in IDL 5.1 and higher.

    XFUDGE: Printers calculate the offset point from the printable
    edge of the paper (sometimes), rather from the corner of the paper.
    For example, on my Lexmark printer, both X and Y offsets are
    calculated from a point 0.25 inches in from the edge. This keyword
    allows you to set a "fudge" factor that will be subtracted from
    the XOFFSET that is returned to the user. This allows you to create
    output that is centered on the page. The fudge factor should be in
    the same units as the returned size and offset values.

    YFUDGE: Printers calculate the offset point from the printable
    edge of the paper (sometimes), rather from the corner of the paper.
    For example, on my Lexmark printer, both X and Y offsets are
    calculated from a point 0.25 inches in from the edge. This keyword
    allows you to set a "fudge" factor that will be subtracted from
    the YOFFSET that is returned to the user. This allows you to create
    output that is centered on the page. The fudge factor should be in
    the same units as the returned size and offset values.

 OUTPUTS:

    pageInfo: The output value is a named structure defined like
    this:

      pageInfo = {PSWINDOW_STRUCT, XSIZE:0.0, YSIZE:0.0, $
         XOFSET:0.0, YOFFSET:0.0, INCHES:0, PORTRAIT:0, LANDSCAPE:0}

    The units of the four size fields are inches unless the CM
    keyword is set.

    The output can be used to immediately configure the PostScript
    or Printer device, like this:

       Set_Plot, 'PS' ; or 'PRINTER'
       Device, _Extra=pageInfo

 RESTRICTIONS:

    The aspect ratio of the current graphics window is calculated
    like this:

       aspectRatio = FLOAT(!D.Y_VSIZE) / !D.X_VSIZE

 EXAMPLE:

    To create a PostScript output window with the same aspect
    ratio as the curently active display window, type:

     pageInfo = PSWINDOW()
     SET_PLOT, 'PS'
     DEVICE, _Extra=pageInfo

     To configure the PRINTER device:

     pageInfo = PSWINDOW(/Printer, Fudge=0.25)
     SET_PLOT, 'PRINTER'
     DEVICE, _Extra=pageInfo

 MODIFICATION HISTORY:

    Written by: David Fanning, November 1996.
       Fixed a bug in which the YOFFSET was calculated incorrectly
          in Landscape mode. 12 Feb 97.
       Took out a line of code that wasn't being used. 14 Mar 97.
       Added correct units keyword to return structure. 29 JUN 98. DWF
       Fixed a bug in how landscape offsets were calculated. 19 JUL 99. DWF.
       Fixed a bug in the way margins were used to conform to my
          original conception of the program. 19 JUL 99. DWF.
       Added Landscape and Portrait fields to the return structure. 19 JUL 99. DWF.
       Added PageSize keyword, changed MARGIN keyword, and completely
          rewrote most of the intenal code. 9 FEB 2000. DWF.
       Fixed a bug in how I calculated the aspect ratio. 1 MAR 2000. DWF.
       Added PRINTER keyword to return proper offset values for the
          PRINTER device, where the offset location is not rotated. 1 MAR 2000. DWF.
       Added PRINTER fudge factors to take into account that printer offsets are
          calculated from the printable area of the paper, rather than the corner
          of the paper. 8 AUG 2000. DWF.
  07-Mar-02 made work for correctly for landscape/portrait


RIGHT_ASPECT

[Previous Routine] [Next Routine] [List of Routines]
  NAME: 
	Right_Aspect

  PURPOSE: 
	Allow contour (or x-y) plots to have the aspect ratio of the data

  CATEGORY: 
	Graphics

  USE:
	IDL> RIGHT_ASPECT, xarray, yarray, IN_POSITION=in_position, $
                  MARGIN=margin, POSITION=position

  KEYWORD PARAMETERS:

     MARGIN: (INPUT)  The margin around the edges of the plot. The value 
    	must be a floating point value between 0.0 and 0.5. It is expressed 
    	in normalized coordinate units. The default margin is 0.15.
    	If margin is a 2-element array, the first value is the left and 
    	bottom margin, and the second is the right and top margin. Otherwise,
    	the right and top margin is set to 1/2 the value of margin.

     IN_POSITION: (INPUT) A 4-element floating array of normalized coordinates.
    	The order of the elements is [x0, y0, x1, y1], similar to the
    	!P.POSITION system variable or the POSITION keyword on any IDL
    	graphic command. Fit resulting contour plot within these limits.

     POSITION: (OUTPUT) A 4-element floating array of normalized coordinates.
    	The order of the elements is [x0, y0, x1, y1], similar to the
    	!P.POSITION system variable or the POSITION keyword on any IDL
    	graphic command. If not present, will set system variable !p.position.

     XRANGE_IN & YRANGE_IN: (INPUTS) - hese override ranges in data

     GetWithZ - if set, plots to Z buffer, and reads back X & Y ticks to
		 determine plot range.

  EXAMPLE: 
	IDL> xarray=FINDGEN(41) & yarray=FINDGEN(21)
	IDL> z = DIST(41,21)
	IDL> in_pos = [.1,.4,.9,.9]		; draw in top part of screen
	IDL> Right_Aspect, xarray, yarray, IN_POS=in_pos, POSITION=out_pos
       IDL> CONTOUR, z, xarray, yarray, XSTYLE=1,YSTYLE=1,  $
		      XMARGIN=[0,0], YMARGIN=[0,0], POSITION=out_pos

  LIMITATIONS: 
	if the POSITION keyword is not used, then the 
	!P.POSITION variable will be set after calling this routine. 
	So, after plotting, do this:  IDL> !P.POSITION = [0,0,0,0]

  MODIFICATIONS:
	03-Feb-2010 added GetWithZ keyword.
	07-Dec-2006 Added xrange_in & yrange_in keywords. These override ranges
		  in data
	28-May-03 Added keyword In_Position. Should now work when partial
		  screen specified.
	04-Apr-01 Do like David Fanning routine, ASPECT, so will work with 
		  A4 paper
	14-Mar-01 Take into account !p.multi settings when computing !p.position
		  Also remove adjustment for x & y pixel number differences.
		  Add POSITION keyword (not fully tested)


RIGHTYAXISLIMITS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       rightYaxisLimits
 PURPOSE:
       Widget to set some Y Axis values for the right-hand axis
	in mdsw
 CATEGORY:
       Graphics, Widgets
 CALLING SEQUENCE:
       IDL> rightYaxisLimits
 INPUTS:
       none required  
 KEYWORD PARAMETERS:
    Inputs (Optional):
	nPlots - # of plots to allow for (def=8)
	GROUP_LEADER - This widget is destroyed if it's GL is destroyed
 OUTPUTS:
 COMMON BLOCKS:
       rightAxis
 EXAMPLE:
	IDL> rightYaxisLimits
 NOTES:
	Upgrade could use a user-defined system variable rather than common
 MODIFICATION HISTORY:
	13-Feb-01 Added multiple axes settings
	07-Feb-01 Written by Bill Davis, PPPL


SETPMULTI

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	setpmulti

 PURPOSE:
  	partition the screen into different graphs

  if 7 or less plot boxes, then 1 column of plots
  if more than 7 plot boxes, then 2 columns of plots

 CATEGORY:
       Graphics, Color Specification.

 CALLING SEQUENCE:
	setpmulti, nboxes
	setpmulti, nboxes, /SameXTitles
	setpmulti, nboxes, /SameXTitles, /sameXlabels, /SamePTitles
 INPUTS:
       nboxes: number of plot boxes per page
 KEYWORD PARAMETERS:
	CharSize   : Value desired for !P.CHARSIZE, else guesses
       SameXTitles: If set and non-zero, just place xtitle at bottom
		     (This reserves less vertical space between plots)
       SamePTitles: If set and non-zero, just place title at top
		     (This reserves less vertical space between plots)
       SameXlabels: If set and non-zero, just label x-axis at bottom
		     (This reserves less vertical space between plots)
	NRows	   : Maximum number of rows (default is 7) 
 COMMON BLOCKS:
       SetPMulti_Local

 SIDE EFFECTS:
       Leaves !P.MULTI set unless you call UnSetPMulti.
	Changes character sizes, etc.
 MODIFICATION HISTORY:
	01-May-01 fix for # of rows and columns
	24-Jan-01 Don't force !x.margin[1] to 3. Only reduce this for multi-
		  columns if !x.margin[1] = 3.
	11-Jan-01 Undid setting of !y.ticks, because can't force axis then
	21-Nov-00 Fine tuned !y.multi values; if no columns, make x.margin[1]=3
	18-Sep-00 Corrected SamePtitle keyword use
	24-Jun-99 changed charsize when more than one plot (to 1.4 if rows or cols > 2)
	03-Jun-99 added CHARSIZE keyword [BD]
	Jan-99 - Written by Bill Davis


SETUP_TEK

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       setup_tek

 PURPOSE:
   	Set system variables for tektronix device.
  	Use to direct plots to the Tek window in Versaterm, or to XTC.
 CATEGORY:
	Graphics, Cross-platform plotting

 CALLING SEQUENCE:  
   	setup_tek

 INPUTS:

 KEYWORD PARAMETERS:
    Optional Inputs:
	CharMagnification - magnify !p.charsize (or, if !p.charsize=0, use as charsize)
 OUTPUTS:
	none

 CALLING EXAMPLE:
   	 setup_tek
   	 plot,indgen(11)			; any number of plot commands
   	 unsetup_tek				; send to printer and back to X

   	 setup_tek, /xtc			; use Tektronix simulator on X
   	 plot,indgen(11)			; any number of plot commands
   	 unsetup_tek				; send to printer and back to X

 RELATED ROUTINES:
   	unsetup_tek

 LIMITATIONS:
	Y-axis ticklabels may overlay the axis. If so, you may use:
	   IDL> plot, x, y, YTICKFORMAT='betterticklabels', ...	
 SIDE EFFECTS:
	System variables are changed until unsetup_tek is called.

 NOTE:
   see http://w3.pppl.gov/~pshare/help/xtc.htm
 MODICATION HISTORY:
   12-Sep-2008 change "/bin/ps -auxw" to "/bin/ps auxw"
   28-Jun-2006 allow for different complier loading in .cshrc
   13-Feb-2006 add XTC calls
   26-Oct-2000 Written by Bill Davis


SETUP_XPC

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       setup_xpc

 PURPOSE:
  	Use to direct postscript plots to the X-windows Plot Controller (XPC).
 CATEGORY:
	Graphics, Postscript

 CALLING SEQUENCE:  
   	setup_xpc

 INPUTS:

 KEYWORD PARAMETERS (all optional):
    SETUP_PS Keywords:
	PORTRAIT - If set, print is in portrait mode
	FONT     - font for printing, e.g., TIMES, HELVETICA, AVANTGARDE,
		   BKMAN, BOLD, PALATINO, ZAPFCHANCERY, NARROW (Default is Times)
	AspectRatio - if set, Ascpect ratio of image is maintained
	CharMagnification - magnify !p.charsize (or, if !p.charsize=0, use as charsize)
       xsize 
	ysize
    XPC keywords:
 	scratchDir - defaults to /loca/$USER/tmpdir (or value of $TMPDIR)
		     programs running on different computers will have differnt 
		     areas. This must be the same used by the plotting-control 
		     software, setup_xpc.pro.
	NODELETE - if set, files in sractchDir (from previous invocation) are 
		   not deleted when application is started.
       TITLE:  A scalar string to be used for the window title.  
	NFILES - # of files to show at one time in window (def=10)
	filter - search filter for plots to show in window (def=XPC_*.ps)
	psPlotFile - file with plotting application keeps plotting 
			(def=scratchDir+'/GV2plot.ps')
	psApp - file plotting application (def="gv")
	appSwitch - switch for file plotting application (def="--watch")
	updateTime - time in seconds between checks to see if list needs refreshed (def=0.5)
	ext - file extensions to look for (def='ps')
 OUTPUTS:
	establishes XPC window

 CALLING EXAMPLE:
   	 setup_xpc				; xpc and gv windows should appear
   	 PLOT, indgen(11)		     	; any number of plot commands
	 XYOUT, .2, .3, 'This is a Label'
   	 unsetup_xpc				; close ps file

 PROCEDURE:
	(see xpc.pro)

 RELATED ROUTINES:
	xpc
   	unsetup_xpc

 LIMITATIONS:
	Y-axis ticklabels may overlay the axis. If so, you may use:
	   IDL> plot, x, y, YTICKFORMAT='betterticklabels', ...	
	This system assumes that /local disks are unique to each system.
 SIDE EFFECTS:
	Post script files (default of 10) are written to ~/XPC_scratch

 NOTE:
   This, in conjunction with unsetup_xpc, is supposed to be a replacement for XTC.
   see http://w3.pppl.gov/~pshare/help/xtc.htm
 MODICATION HISTORY:
   09-Jul-2011 don't use /local, so can be used from different computers
   18-Nov-2009 Written by Bill Davis


TV_24

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       TV_24

 PURPOSE:
       This procedure displays a 24-bit image on the current
       graphics device, constructing a custom colour table if
       the device supports less than 257 colours.

 CATEGORY:
       Graphics.

 CALLING SEQUENCE:
       TV_24(image)

 INPUTS:
       IMAGE: the pixel-interleaved, 24-bit image to be displayed.
              IMAGE should be of type BYTARR(3,M,N).

 KEYWORD PARAMETERS:
       None. 

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       On 8-bit displays the current colour table is overwritten,
       on 24-bit displays it is preserved.

 RESTRICTIONS:
       None.

 EXAMPLE:
       Display a 24-bit image on an 8-bit display:
            TV_24(image)
       

 MODIFICATION HISTORY:
       Part of Struan's Surface Tutorial: 
            http://www.sljus.lu.se/stm/IDL/Surf_Tips/
       Written by:	Struan Gray, Sljusfysik, Lunds Universitet, 970305.


TVRD_24

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       TVRD_24

 PURPOSE:
       This function reads a 24-bit image from a 24-bit or 8-bit
       display device, returning a pixel-interleaved byte array 
       of type BYTARR(3, xsize, ysize), where xsize and ysize are
       the dimensions of the current graphics device.

 CATEGORY:
       Graphics.

 CALLING SEQUENCE:
       image = TVRD_24()

 INPUTS:
       None

 KEYWORD PARAMETERS:
       None. 

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       None.

 RESTRICTIONS:
       None.

 EXAMPLE:
       image = tvrd_24()
       

 MODIFICATION HISTORY:
       Part of Struan's Surface Tutorial: 
            http://www.sljus.lu.se/stm/IDL/Surf_Tips/
       Written by:	Struan Gray, Sljusfysik, Lunds Universitet, 970305.


TWOSURF

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       TWOSURF

 PURPOSE:
       This function returns a 24-bit image of two interlocking surfaces 
    with various combinations of colour, shading and grids.  

       For each surface the colour coding can tied to the surface height 
    or to an independent array.  A grid can be overlaid on the surface or 
    used to mask a coloured and/or shaded plot so as to produce a coloured 
    and/or shaded grid.  Light shading can be applied to both the coloured 
    and gridded surface, or just the coloured surface, leaving the grid 
    unshaded.

        The light shading parameters are determined by previous calls to 
    SET_SHADING.  The viewing position and 3d-2d scaling are handled by
    the usual graphics keywords - see the documentation for SURFACE and
    SHADE_SURF in the IDL user's guide.

        The image returned by TWOSURF is a pixel-interleaved 24-bit image 
    of type bytarr(3, xsize, ysize).  If on entry the current graphics 
    device is a screen window or the z-buffer, xsize and ysize are the 
    dimensions of the current or default window on that device.  If the 
    current device is anything else (eg a plotter or a postscript file) 
    the default size of the z-buffer (640x480) is used.  On exit the 
    current graphics device and colour map are unchanged.
 

 CATEGORY:
       Graphics, Surface Plotting

 CALLING SEQUENCE:
       result = TWOSURF(SURFONE, SURFTWO)

 INPUTS:
       SURFONE:  A two-dimensional array containing the data for the
                 first of the surfaces to be plotted.

       SURFTWO:  A two-dimensional array containing the data for the
                 second of the surfaces to be plotted.

 KEYWORD PARAMETERS:

       COLOUR1:  Set this keyword to include colour coding in the plot
                 of SURFONE The default is no colour-coding.

       COLOUR2:  As for COLOUR1 but for SURFTWO.  The default is to be
                 the same as COLOUR1.

       COLDATA1: A variable or array of type byte containing the colour 
                 data to be used when plotting a colour plot.
                 If COLDATA1 is a scalar then it is assumed to be an index to
                 a colour in COLMAP which is used to give a single colour to
                 the whole surface.
                 If COLDATA1 is a vector of at least three elements its first
                 three elements are treated as a rgb colour triple and used
                 to give a single colour to the whole surface.
                 If COLDATA1 is two-dimensional it is treated as an array of
                 colour indices of COLMAP and is used to give each data point
                 it's own colour.  If COLDATA1 has different dimensions to
                 SURFONE, CONGRID is used to stretch or squeeze a copy of
                 COLDATA1 to fit.
                 If COLOUR1 is set but COLDATA1 is undefined or does not
                 satisfy any of the above conditions, a BYTSCL'ed version of
                 SURFONE is used to produce a plot coloured according to height.

       COLDATA2: As for COLDATA1 but for SURFTWO.

       SHADE1:   Set this keyword to perform light shading for SURFONE.
                    SHADE = 0: no shading
                    SHADE = 1: shade everything
                    SHADE = 2: don't shade the grid
                 The default is no shading.

       SHADE2:   As for SHADE1 but for SURFTWO.  The default is to be
                 the same as SHADE1.
                
       GRID1:    Set this keyword to apply grids to SURFONE.
                    GRID = 0: no grid
                    GRID = 1: overlay a grid on the surface
                    GRID = 2: use the grid as a mask
                 The default is no grid
                
       GRID2:    As for GRID1 but for SURFTWO.  The default is to be
                 the same as GRID1.

       CGRID1:   The colour to use for overlaid grids on SURFONE.  If CGRID
                 is a number it is treated as an index in the colour table
                 given by COLMAP.  If CGRID is an three-element vector of
                 bytes it is treated as the rgb values for a colour.  If it
                 is anything else or undefined the grid is plotted white.

       CGRID2:   As for CGRID1 but for SURFTWO.  The default is to be
                 the same as CGRID1.

       TRANSP1:  The transparency factor for SURFONE, which determines how
                 much the hidden parts of SURFTWO show through SURFONE's
                 surfaces.  TRANSP1 is converted to type FLOAT before use,
                 where 0.0 corresponds to an opaque surface and 1.0 mixes
                 equal parts of SURFONE and SURFTWO.
                 Note that if GRID1=2, the holes in the grid are already
                 completely transparent and TRANSP1 affects only the grid
                 lines.
                 The default is 0.0.

       TRANSP2:  As for TRANSP1 but for SURFTWO.  The default is to be
                 the same as TRANSP1.

       COLMAP:   The colour map to use for plotting of the colour data.
                 If a number is given the corresponding inbuilt IDL colour
                 map is used.  Otherwise COLMAP should be an array of three
                 byte vectors [red, green, blue] such as those returned by
                 the TVLCT, /get procedure.  If COLMAP is not set, the
                 current colour map is used.  Note that TWOSURF maintains
                 the current colour map even if a second colour map is
                 specified for the plot.
                 Because the z-buffer is only an 8bit device plotting
                 SURFONE and SURFTWO with different colours has to be done
                 by user manipulation of COLMAP and the arrays passed as
                 COLDATA1 and COLDATA2.
                 If either one of the surfaces has light shading applied
                 the background is set to [0,0,0] (black), otherwise the
                 background colour of COLMAP is used.

       _EXTRA:   Used to pass extra plot parameters to both SHADE_SURF and
                 SURFACE.  _EXTRA provides a convenient way of passing
                 common parameters such as viewing angle and plot position.
                 Note that only keywords valid for both SHADE_SURF and
                 SURFACE can be used.
                 If EXTRA_SHADE is set, _EXTRA is ignored for the shaded
                 plots, similarly with EXTRA_SURF and surface plots.
                 Some keywords (eg, SHADES, COLOR, NODATA, NOERASE) will
                 interfere with the plotting done by ONESURF and lead to
                 unpredictable results.
                 _EXTRA is itself passed to SHADE_SURF and SURFACE using
                 the _EXTRA keyword, so keywords which expect a data value
                 to be changed (eg [XYZ]TICK_GET) will not work.
                 Useable keywords are: AX, AZ, MAX_VALUE, MIN_VALUE, SAVE,
                 [XY]TYPE, CHARSIZE, CHARTHICK, CLIP, DATA, DEVICE, FONT,
                 NOCLIP, NORMAL, POSITION, SUBTITLE, T3D, THICK, TICKLEN,
                 TITLE, [XYZ]CHARSIZE, [XYZ]GRIDSTYLE, [XYZ]MARGIN,
                 [XYZ]MINOR, [XYZ]RANGE, [XYZ]STYLE, [XYZ]THICK,
                 [XYZ]TICKFORMAT, [XYZ]TICKLEN, [XYZ]TICKNAME, [XYZ]TICKS,
                 [XYZ]TICKV, [XYZ]TITLE, ZVALUE.

       EXTRA_SHADE: Used to pass extra plot parameters to the SHADE_SURF 
                    procedure only.  EXTRA_SHADE is passed to SHADE_SURF
                    using the _EXTRA keyword so keywords such as IMAGE
                    which expect a variable to be altered will not work.
                    As with _EXTRA, setting the SHADES keyword can lead
                    to unpredictable results.  EXTRA_SURF should be an
                    anonymous structure.

       EXTRA_SURF: Used to pass extra plot parameters to the SURFACE
                   procedure only.  Restrictions are as for _EXTRA and
                   EXTRA_SHADE.  If EXTRA_SHADE is set, but EXTRA_SURF
                   is not, EXTRA_SURF is made equal to _EXTRA, and vice
                   versa.


 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       None.

 RESTRICTIONS:
       None.

 EXAMPLE:
       SURFONE plotted as a shaded, coloured, partially transparent
       surface with the colours corresponding to height and a black
       grid, interlocking with SURFTWO, plotted as a shaded, coloured,
       partially transparent surface also coloured according to height
       but with different colours, and with an unshaded white grid:
       
       image = twosurf(surfone, surftwo,                $
                 colour1 = 1,                           $
                 coldata1 = 127b + bytscl(surfone)/2b,  $
                 shade1 = 2,                            $
                 grid1 = 1,                             $
                 cgrid1 = [0,0,0],                      $
                 transp1 = 0.3,                         $
                 colour2 = 1,                           $
                 coldata2 = 127b - bytscl(surftwo)/2b,  $
                 shade2 = 2,                            $
                 grid2 = 1,                             $
                 cgrid2 = [250,250,250],                $
                 transp2 = 0.6,                         $
                 colmap=25)

        For further examples see the SURFDEMO procedure


 MODIFICATION HISTORY:
       Part of Struan's Surface Tutorial: 
            http://www.sljus.lu.se/stm/IDL/Surf_Tips/
       Written by:	Struan Gray, Sljusfysik, Lunds Universitet, 970305.
       970313 SMG - added _extra, extra_surf and extra_shade keywords
                    for better control of graphics keywords.


WRITE_IN_BOX

[Previous Routine] [Next Routine] [List of Routines]
 NAME: 
	WRITE_IN_BOX 
 
 PURPOSE: 
	Writes a text message within a box in a graphics window. 

 CATEGORY: 
	Graphics
 
 Explanation : This procedure writes a short text message within a box-shaped 
               area in a graphics window.  The message may be split at word 
               boundaries into several lines, and the character size and 
               orientation may be adjusted for the text to fit within the box. 
 
 CALLING SEQUENCE:
	IDL> WRITE_IN_BOX, X1, X2, Y1, Y2, TEXT 
 
 Inputs      : X1, X2  = X coordinates of the box limits. 
               Y1, Y2  = Y coordinates of the box limits. 
               TEXT    = ASCII text string containing the message. 
 
 Opt. Inputs : None. 
 
 Outputs     : None. 
 
 Opt. Outputs: None. 
 
 Keywords    : DATA        = If set, then the coordinates are in data units. 
                             This is the default. 
               DEVICE      = If set, then the coordinates are in device units. 
               NORMAL      = If set, then the coordinates are in normalized 
                             units. 
               MAXCHARSIZE = The maximum character size to use in displaying 
                             the message.  If not passed, then determined from 
                             !P.CHARSIZE. 
               COLOR       = Color to use to display the text.  The default is 
                             !COLOR. 
               ALIGNMENT   = Controls the alignment of the text in the box.  A 
                             value of 0 means to left justify the text, 0.5 
                             means center it (default), and 1 stands for right 
                             justification. 
 
 Calls       : None. 
 
 Common      : None. 
 
 Restrictions: X2 must be greater than X1, and Y2 must be greater than Y1. 
 
 Side effects: The appearance of the displayed message may not be optimal if 
               any words are separated by multiple blanks, or by tab 
               characters. 
 
 Category    : Planning, Science. 
 
 Prev. Hist. : None. 
 
 Written     : William Thompson, GSFC, 7 July 1993. 
 
 Modified    : Version 1, William Thompson, GSFC, 7 July 1993. 
               Version 2, William Thompson, GSFC, 24 September 1993. 
                       Added ALIGNMENT keyword based on code provided by Jim 
                       Pendleton, GRO/OSSE NU. 
               Version 3, William Thompson, GSFC, 21 September 1994 
                       Added STRTRIM call. 
 
 Version     : Version 3, 21 September 1994 


XAXISW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       xAxisW
 PURPOSE:
       Widget to set some X Axis values via the system variable !X
 CATEGORY:
       Graphics, Widgets
 CALLING SEQUENCE:
       IDL> xAxisW
 INPUTS:
       input = whatever.  
 KEYWORD PARAMETERS:
       Optional Keywords:
	  UPDATECALLBACK - a routine to call after axis system variable is set
	  GROUP_LEADER - This widget is destroyed if it's GL is destroyed
 OUTPUTS:
       The system variable !X is changed               	out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> xAxisW,  UPDATECALLBACK='myAxisUpdating'
 NOTES:
 MODIFICATION HISTORY:
	29-Apr-08 check for routine being compiled (vs. needing to be found)
		  added a "Refresh" button which, if a proper plotting routine
		  is provided, will replot with any changed settings.
	08-Dec-04 Removed callback test because of compiling on PC
	22-Jan-01 Added Default and Auto Scale buttons [BD]
	20-Sep-00 Added TickLen & GridStyle fields [BD]
       30-Mar-99 Written by Bill Davis, PPPL


YAXISW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       yAxisW
 PURPOSE:
       Widget to set some Y Axis values via the system variable !Y
 CATEGORY:
       Graphics, Widgets
 CALLING SEQUENCE:
       IDL> yAxisW
 INPUTS:
       input = whatever.  
 KEYWORD PARAMETERS:
       Optional Keywords:
	  UPDATECALLBACK - a routine to call after axis system variable is set
	  GROUP_LEADER - This widget is destroyed if it's GL is destroyed
 OUTPUTS:
       The system variable !Y is changed               	out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> yAxisW, UPDATECALLBACK='myAxisUpdating'
 NOTES:
	If an application overrides !Y.* parameters, or specifies them on
	the plot command, changing settings with this widget will have no
	affect.
 MODIFICATION HISTORY:
	29-Apr-08 check for routine being compiled (vs. needing to be found)
		  added a "Refresh" button which, if a proper plotting routine
		  is provided, will replot with any changed settings.
	08-Dec-04 Removed callback test because of compiling on PC
	22-Jan-01 Added Default and Auto Scale buttons [BD]
	28-Sep-00 Correct the display of initial values [BD]
	20-Sep-00 Added TickLen & GridStyle fields [BD]
       30-Mar-99 Written by Bill Davis, PPPL


ZAXISW

[Previous Routine] [List of Routines]
 NAME:
       zAxisW
 PURPOSE:
       Widget to set some Z Axis values via the system variable !Y
 CATEGORY:
       Graphics, Widgets
 CALLING SEQUENCE:
       IDL> zAxisW
 INPUTS:
       input = whatever.  
 KEYWORD PARAMETERS:
       Optional Keywords:
	  UPDATECALLBACK - a routine to call after axis system variable is set
	  GROUP_LEADER - This widget is destroyed if it's GL is destroyed
 OUTPUTS:
       The system variable !Y is changed               	out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> zAxisW, UPDATECALLBACK='mzAxisUpdating'
 NOTES:
	If an application overrides !Z.* parameters, or specifies them on
	the plot command, changing settings with this widget will have no
	affect.
 MODIFICATION HISTORY:
	17-Oct-00 Written by Bill Davis, PPPL


Category: GUI

[List of Routines]


BITMAPBUTTONS

[Next Routine] [List of Routines]
 NAME:
       bitmapbuttons
 PURPOSE:
       Illustrate use of bitmapbuttons in IDL
 CATEGORY:
       GUI, buttons
 CALLING SEQUENCE:
       IDL> bitmapbuttons
    Then click on buttons and watch them change.
 COMMON BLOCKS:
       none
 NOTES:
	Requires IDL 5.2 or later.
 LIMITATIONS:
	This may not be the easiest way to manage button states
 MODIFICATION HISTORY:
	27-Jan-00 [BD]


COLOR_RESOURCE_EXAMPLE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       color_resource_example
 PURPOSE:
       Example of color buttons on a widget.
 CATEGORY:
       GUI, Color, Example
 CALLING SEQUENCE:
       IDL> color_resource_example
 INPUTS:
       none.  
 KEYWORD PARAMETERS:
       none.  
 OUTPUTS:
       none.  
 EXAMPLE:
	IDL> color_resource_example
 NOTES:
	For IDL color widgets, you need corresponding lines in your 
	~/.Xresources file (on the computer that is managing your X windows!), 
	e.g., :
          
          Idl*colorbuttons*blue*background:blue
          Idl*colorbuttons*red*background: red
          Idl*colorbuttons*lightblue*background: lightblue
          Idl*colorbuttons*green*background: green
          Idl*colorbuttons*purple*background: purple
          Idl*colorbuttons*yellow*background: yellow
          Idl*colorbuttons*white*background: white
          Idl*colorbuttons*gold*background: gold
          Idl*colorbuttons*black*background: black
          Idl*colorbuttons*magenta*background: magenta
          Idl*colorbuttons*orange*background: orange

 LIMITATIONS:
	This works consistantly on PPPL Solaris 2.6 computers. 
	Bug On Linux, the colors initially work, 
	but disappear on subsequent execution!

 MODIFICATION HISTORY:
       18-Apr-03 Written by Bill Davis, PPPL


COLOR_STATUS_EXAMPLE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       color_status_example
 PURPOSE:
       Example of color status fields on a widget.
 CATEGORY:
       GUI, Example, Color, Monitoring Application
 EXPLANATION:
	Makes two rows, each with two buttons to send a color to an
	adjacent status field. The status field is just a window in which
	the appropriate colors are drawn.  MK_COLOR, or a similar routine,
	should be used for consistant color display.
 CALLING SEQUENCE:
       IDL> color_status_example
 INPUTS:
       none.  
 KEYWORD PARAMETERS:
       none.  
 OUTPUTS:
       none.  
 COMMON BLOCKS:
       info
 ROUTINES USED:
	MK_COLOR
 EXAMPLE:
	IDL> color_status_example
 NOTES:
       The status fields are initially the background color.
	A real program might want to save !D.WINDOW before the TV commands
	and restore it immediately afterwards.
 MODIFICATION HISTORY:
       11-May-00 Written by Bill Davis, PPPL


DIALOG_INPUT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
     DIALOG_INPUT

 PURPOSE:
     A modal (blocking) dialog widget to input a line of text.
     The dialog must be dismissed, by entering text and pressing the
     Return key, or by clicking on the 'Ok' or 'Cancel' button before
     execution of the calling program can continue.

 TYPE:
     FUNCTION

 CATEGORY:
     GUI, Input, WIDGETS

 CALLING SEQUENCE:
     result = DIALOG_INPUT (PROMPT)

 INPUTS:
     NONE

 KEYWORD PARAMETERS:

     PROMPT: Optional STRING or STRARR displayed on the widget.
         If the keyword NFIELDS is set, then PROMPT must be a
         STRARR of length NFIELDS.  If NFIELDS is not set, and PROMPT is
         a STRARR, each element of the array will appear on a separate line.

         If not supplied, default = 'Enter Text'

     TITLE: Window title [default = 'dialog_input']

     INITIAL: Initial value to show in the input area.  If PROMPT is 
              supplied, this must be a array of length FIELDS.

     XSIZE, YSIZE: The width and height of the dialog

     WIDTH: Set the width of the input field IN CHARACTERS.  

     NFIELDS: Show multiple input fields.  If PROMPT and/or INITIAL are
              supplied, they must be STRARR of length FIELDS.  
 
     CHECKBOX - prompt for optional check box
     BOXINIT - initial value of check box (Default=0)
     BOXOUT - if=1, then box was checked
     TOPLABEL - label above inputs

     FLOATING, INTEGER, LONG, DOUBLE - type of input
     DIALOG_PARENT: Set this keyword to the widget ID of a widget over
         which the message dialog should be positioned. When displayed,
         the DIALOG_INPUT dialog will be positioned over the specified
         widget. Dialogs are often related to a non-dialog widget tree.
         The ID of the widget in that tree to which the dialog is most
         closely related should be specified.

     RETURN_EVENTS:	
	Set this keyword to make cluster return an event when a
	 is pressed in a text field.  The default is
	not to return events.  

     OK: STRING label for the 'Ok' button (default = '  OK  ' )
     CANCEL: STRING label for the 'Cancel' button (default = 'Cancel')

 OUTPUTS:
     result: STRING or STRARR of input text, or '' if dialog is cancelled

 EXAMPLE:
     IDL> a=DIALOG_INPUT('enter val', CHECK='turn on', BOXOUT=box )

     IDL> a=DIALOG_INPUT(['x1:','y1:', 'x2:','y2:'], NFIELDS=4, TITLE='Box Overlay', $
			  INITIAL=[1,1,5,6],  $
			  checkBox='Show Box', boxOut=showBox, boxInit=1,  $
			  TOPLABEL='Enter lower left and upper right coords')

 SIDE EFFECTS:
     Creates a modal widget

 MODIFICATION HISTORY:
     24-Feb-2011 added Top Label & boxInit [BD]
     03-Feb-2011 added Check Box [BD]
     22-Jul-2009 added Alt button [BD]
     15-Jul-2009 added didCancel keyword
     01-Jun-06 default to return events [BD]
     12-Sep-04 improvement for prompt on just one entry 
		Allow for no cancel button [BD]
     02-Jul-01 Fixed bug for floating point values [BD]
     13-Sep-00 Added RETURN_EVENTS keyword [BD]
     03-Feb-00 Added FLOATING, INTEGER and LONG keywords [BD]

     v1.03: RSM, Aug 1998, Added WIDTH keyword to set the width of the 
            input field IN CHARACTERS.  Fixed layout bug when using NFIELDS.

     v1.02: RSM, May 1998, Non-backward compatible changes to allow multiple
            input fields.

     v1.01: RSM, Mar 1998, fixed error when used with a modal toplevel base.

     v1.0:  Written, Robert.Mallozzi@msfc.nasa.gov, July 1997.


EDITTABLE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       EDITTABLE
 PURPOSE:
       Edit a structure with a table where the second item in the structure 
	is on/off. You can set all items (but the first) on, off, or to a specific value.
	If there are more rows than will fit on your screen, it will make new columns.
 CATEGORY:
       GUI, Editor, Structures
 CALLING SEQUENCE:
       IDL> newStruct= editTable( struct )
 INPUTS:
       struct = structure where all tags have same number of elements, and the second
		 one is for on/off
 KEYWORD PARAMETERS:
	nrows - defaults to scFrac  of screen
	noFields - if set, do not show fields, other than on/off
	labels - labels of columns, else use tagnames
	scFrac= fraction (roughly) of y length to use
	title - window title
	col1Title - title of first column, else use tagname
	fieldSz - size of all numeric fields (defaults to 12)
	verbose - if set, print some info
	debug - if set, stop in the middle
 OUTPUTS:
       newStruct = edited structure
 EXAMPLE:

    items = replicate( '\OPERATIONS::F_FLEVVL', 40 )
    nitems = n_elements( items )
    for i=0,nitems-1 do items[i]=items[i]+string(i,format='(i2.2)')

    onoffs = replicate( 1, nitems )
    errvals = replicate( 1.e6, nitems )
    more = errvals
    third =replicate( 1, nitems )
    forth=third

    struct = { items : items, onoffs : onoffs, errvals : errvals, more:more, $
 		third:third, forth:forth}

    s= edittable( struct, title='My Dets')

 MODIFICATION HISTORY:
	WRITTEN 19-Jan-2005 by Bill Davis for Jon Menard 


GET_TEXT_INPUT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       get_text_input

 PURPOSE:
       Prompt the user for input with a question and
       return the text string typed by user.
       For X-windows the input is through a text widget, in the middle of 
       the screen, and the text widget waits until carriage return is entered.
       Otherwise input is in the terminal window, with a beep to alert user.

 CATEGORY:
       GUI, Input
 CALLING:
       text = get_text_input( question )

 INPUTS:
       question = string(s), prompt for input, default is null string.
               If an array is passed, each element is shown on its own line.

 KEYWORDS:
       DEFAULT_INPUT = optional string, setting the default response.

 OUTPUTS:
       Function returns the text string entered by user,
       with leading and trailing blanks removed.

 HISTORY:
       Written, Frank Varosi NASA/GSFC 1993.
       F.V.1997, question can be a string array, shown as multiple lines.


MK_PDMENU

[Previous Routine] [List of Routines]
 NAME:
       mk_pdmenu

 PURPOSE:
       make a structure for a pull down menu for CW_PDMENU routine

 CATEGORY:
	GUI, Programming

 CALLING SEQUENCE:
        menu = mk_pdmenu( list )

 INPUTS:
       list - string array      in

 KEYWORD PARAMETERS:
    inputs
	maxPerSubMenu = max # of menu items per sub-menu. If not specified,
			will try to limit max number to fit on screen.
	MenuTitle = menu title (Default=Select)
    outputs:
	menuItems -  items in the menu

 OUTPUTS:
	menu - structure which can be input to CW_PDMenu

 EXAMPLE:
	pro test_pdmenu
	base = WIDGET_BASE()
	colID=WIDGET_BASE(base,/col)

	Printer_List = list_printer_unix( )
	Printer_List = Printer_List( sort( Printer_List ))

	printer_pdmenu = MK_PDMENU( Printer_List, maxPerSubMenu=20 )
	menu = CW_PDMENU(colID, printer_pdmenu, /RETURN_FULL_NAME, /MBAR)

	butID = WIDGET_BUTTON(colID, VALUE='Quit', UVALUE='Quit')
	WIDGET_CONTROL, /REALIZE, base
	repeat begin
	  ev = WIDGET_EVENT(base)
	  PRINT, ev.value
	end until ev.value eq 'Quit'
	WIDGET_CONTROL, /DESTROY, base
	stop
	end

 COMMON BLOCKS:

 NOTES:

 MODIFICATION HISTORY:
	11-Feb-2014 bombing on list variable
	11-Apr-03 make default maxPerSubMenu fit on screen, if not given
	27-Jan-03 Automatically make submenus when list of items is large
	26-Mar-99 by Bill Davis


Category: Image Processing

[List of Routines]


BIN2D

[Next Routine] [List of Routines]
 NAME:
       Bin2D
 PURPOSE:
       Create a density image (2D histogram) from arrays of (x,y) points,
       or create an image of a function from arrays of ( x, y, f(x,y) ) data.
       In first case each pixel counts # of (x,y) points falling into
       a 2D bin (box), thus forming an image of counters. In optional case,
       each pixel is the average of all f(x,y) data falling into the box.
       Boxes are determined by dividing the (x,y) range into a uniform grid.
 CATEGORY:
	Image Processing
 CALLING EXAMPLES:
       imh = Bin2D( x, y, NPIX=64, XRAN=[0,20], YRAN=[-5,5] )
       imz = Bin2D( x, y, FXY=z, NPIX=[200,100] )
 INPUTS:
       X = array (any dimension) of x values.
       Y = array of y values, should correspond to x array.
               optionally, x can be of the form [[x],[y]]
               containing both x and y coordinates as rows of matrix,
               and then argument y should not be specified.
 KEYWORDS:
       XRAN and YRAN : specify the x,y range to be mapped into the image.
                       Common Bin2D, xminc,xmaxc, yminc,ymaxc
                       can also specify the x,y range if keywords are not used,
                       otherwise the defaults = min-max ranges of x and y.
       NPIXELS = 1 or 2 element integer array specifying size of result,
                       (single value means square image), default = [64,64].
      /NOCLIP means do not bother checking if (x,y) are within range (faster).
       TYPE_VAR = type code specifying the IDL variable type of result,
               (1=byte, 2=short, 3=Long, 4=float,... default=2, short integer).
 KEYWORDS (optional):
       IMAGE_DENSITY = an existing image of counters (2D histogram)
                       to which the result is added (overrides NPIX=).
       FXY = array giving z = f(x,y) for the purpose of binning into an image
               however, bins with no (x,y) data points are left = zero.
               (NOTE: must specify XRAN and YRAN, or set /NOCLIP).
   if /BOTH is set and FXY=z is given, then the binned image of z=f(x,y) is
               returned by function, and an image of (x,y) density is
               returned via the keyword IMAGE_DENSITY.
 OUTPUTS:
       Result of function is an image of the density of (x,y) points, or an
       image of scalar field function if z values are given at (x,y) points.
 PROCEDURE:
       Binning is performed by finding number of (x,y) duplicates
       at each pixel,  using the IDL sort and where functions.
 HISTORY:
       written Frank Varosi, U.of MD., 1988.
               F.V. 1990, modif. for IDL-V2.


BPASS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
		bpass
 PURPOSE:
		Implements a real-space bandpass filter which suppress 
		pixel noise and slow-scale image variations while 
		retaining information of a characteristic size.

 CATEGORY:
		Image Processing
 CALLING SEQUENCE:
		res = dgfilter( image, lnoise, lobject )
 INPUTS:
		image:	The two-dimensional array to be filtered.
		lnoise: Characteristic lengthscale of noise in pixels.
			Additive noise averaged over this length should
			vanish. MAy assume any positive floating value.
		lobject: A length in pixels somewhat larger than a typical
			object. Must be an odd valued integer.
 OUTPUTS:
		res:	filtered image.
 PROCEDURE:
		simple 'wavelet' convolution yields spatial bandpass filtering.
 NOTES:
 MODIFICATION HISTORY:
   19-May-2009 Limit filter width so convol doesn't exceed array dimensions [BD]
		Written by David G. Grier, The University of Chicago, 2/93.
		Greatly revised version DGG 5/95.
		Added /field keyword JCC 12/95.
		Revised & added 'stack','voxel' capability JCC 5/97.

	This code 'bpass.pro' is copyright 1997, John C. Crocker and 
	David G. Grier.  It should be considered 'freeware'- and may be
	distributed freely in its original form when properly attributed.


CINELOAD

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       cineload
 PURPOSE:
       Read a frame from a .cin file from a Phantom 7 camera.
	File is opened only the first time (or when filename is new), and
	pointers and things are remembered from one call to the next.
 CATEGORY:
       Image Processing
 CALLING SEQUENCE:
       IDL> image = cineload( filename, frame )
 INPUTS:
   	filename - a .cin file
   	frame - absolute frame number in file desired. 0 is always the first
 OUTPUTS
	image - a [n,y] or [3,n,y] image
    optional:
	fps - frames per second
	exposure - exposore time
 KEYWORD PARAMETERS (optional):
    input:
	init - first call for this filename
	verbose - print out lots of info
	debug - will stop within routine if error detected.
    output:
	bitcount - 
	outMsg - 
	status - if odd, then OK
 EXAMPLE:
	IDL> filename = '/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139475.cin'
	IDL> cine_time, filename, times
	IDL> img = cineload(filename, 0)	; get the first frame

 NOTES:
 MODIFICATION HISTORY:
   27-Feb-2013 error message, and assume FirstFrame=0, if frame outside
		range in file. This is necessary for some apps when the
		first frame in the file is not 0.
   03-Jan-2013 fixed exposure output
   22-Jun-2010 don't return image as UINT if only 8 bits
   02-Apr-2010 flip Miro files if gt 137000, according to Lane
   01-Jul-2009 merged "memory feature" of cine_time.pro with this
   12-Nov-2008 Hide firstFrame ne 0 within this routine, so calling program 
		can ask for first frame.
   10-Nov-2008 don't force frame=0 when /INIT [BD]
   02-Jul-2008 added capability for MIRO color cameras [BD]
   19-Apr-2007 added keyword INIT in case frames don't start at 1 [BD]

   IDL> img = CINELOAD(GETENV("NSTXUSR")+'/miro/MIRO_130363.cin', 100, /debug)
   IDL> img = CINELOAD(GETENV("NSTXUSR")+'/phantom4/NSTX_130363.cin', 100, /debug)

 WRITTEN by Ricky Maqueda, Bill Davis & Werner Boeglin


CINERATE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       cinerate
 PURPOSE:
       Return framing rate from a .cin file from a Phantom 7 camera.
 CATEGORY:
       Image Processing
 CALLING SEQUENCE:
       IDL> rate= cinerate( filename )
 RETURNED:
	rate - frames per second
 INPUTS:
   	filename - a .cin file
 KEYWORD PARAMETERS:
   OUTPUT:
	serialNum - serial number of camera
	warning - if set to 0, will not pop dialog up for messages
 EXAMPLE:
	IDL> cine_time,'/p/camdata/dust/nstx121048.cin', time

 NOTES:
 MODIFICATION HISTORY:
   Written by Bill Davis 17-Jul


CINE_SNUM

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       cine_snum
 PURPOSE:
       Return camera serial number from a .cin file from a Phantom camera.
 CATEGORY:
       Image Processing
 CALLING SEQUENCE:
       IDL> serialNumber = cine_snum( filename )
 INPUTS:
 KEYWORD PARAMETERS:
   INPUT:
   	filename - a .cin file
   OUTPUT:
	serialNumber - serial number of camera
 EXAMPLE:
	IDL> print, cine_snum('/p/nstxcam/Miro2-7988/2010/nstx_2_137839.cin')

 MODIFICATION HISTORY:
   Written May-2010 by Bill Davis
           from program written by Ricky Maqueda.


CINE_TIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       cine_time
 PURPOSE:
       Read time from a .cin file from a Phantom 7 camera.
 CATEGORY:
       Image Processing
 CALLING SEQUENCE:
       IDL> cine_time, filename, times[, frames, xsize=xsize, ysize=ysize]
 INPUTS:
 KEYWORD PARAMETERS:
   INPUT:
   	filename - a .cin file
	positive - if set, will not return negative image numbers
   OUTPUT:
	times - array of times in seconds of frames
   	frames - array of frame numbers
	firstImage - first image number
	imageSize - image size in bytes
	xsize - horizontal size of an image
	ysize - vertical size of an image
	serialNum - serial number of camera
	warning - if set to 0, will not pop dialog up for messages
 EXAMPLE:
	IDL> cine_time,'/p/camdata/dust/nstx121048.cin', time

 NOTES:
 MODIFICATION HISTORY:
   04-Mar-2014 keyword POSITIVE to correct for negative frame numbers
   16-Jan-2014 fixed exposure output
   19-Aug-2012 fixed dt being 2usec, 3usec, 2usec, etc. for Phantoms with 400,000 rate
   16-Aug-2010 added warning keyword, so doesn't pop dialog box on wall if error
   22-Jun-2010 don't make image UINT if only 8 bits
   05-May-2010 added keyword serialNum
   02-Apr-2010 flip Miro files if gt 137000, according to Lane
   01-Jul-2009 merged "memory feature" of cineload.pro with this
   17-Jul-2008 return FirstImage (first frame)
   17-Jun-2008 check for existence of file 
   27-Apr-2007 commented out time-correction code which was giving -NaN for
		$NSTXUSR/phantom4/flipped_123648.cin (exposure time was changed)
   Written by Bill Davis, for Lane Roquemore, 31-May-2006
           from program written by Ricky Maqueda.


CONVOLVE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       CONVOLVE
 PURPOSE:
       Convolution of an image with a Point Spread Function (PSF)
 CATEGORY:
	Image Processing, Math
 EXPLANATION:
       The default is to compute the convolution using a product of 
       Fourier transforms (for speed).

 CALLING SEQUENCE:

	psf = psf_Gaussian( NPIXEL=21, FWHM=5, /NORMALIZE )
       imconv = convolve( image1, psf, FT_PSF = psf_FT )
  or:
       correl = convolve( image1, image2, /CORREL )
  or:
       correl = convolve( image, /AUTO )

 INPUTS:
       image = 2-D array (matrix) to be convolved with psf
       psf = the Point Spread Function, (size < or = to size of image).

 OPTIONAL INPUT KEYWORDS:

       FT_PSF = passes out/in the Fourier transform of the PSF,
               (so that it can be re-used the next time function is called).
       FT_IMAGE = passes out/in the Fourier transform of image.

       /CORRELATE uses the conjugate of the Fourier transform of PSF,
               to compute the cross-correlation of image and PSF,
               (equivalent to IDL function convol() with NO rotation of PSF)

       /AUTO_CORR computes the auto-correlation function of image using FFT.

       /NO_FT overrides the use of FFT, using IDL function convol() instead.
               (then PSF is rotated by 180 degrees to give same result)
 METHOD:
       When using FFT, PSF is centered & expanded to size of image.
 HISTORY:
       written, Frank Varosi, NASA/GSFC 1992.
       Converted to IDL V5.0   W. Landsman   September 1997


FASTCAM_FRAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	fastcam_frame
		   
 PURPOSE:
       a generic routine to get a frame of data from Fast Cameras.
       You can get camera data from MDSplus at MIT, read
       localNetCDF, HDF,  or CIH files  (which follow expected
       conventions), as well as the Cine  files.
		   
 CATEGORY:
       Image Processing
		   
 CALLING SEQUENCE:
       IDL> image = fastcam_frame( filename, frame )
		   
 INPUTS:
   	filename - a .cin file
   	frame - absolute frame number in file desired. 0 is always the first
		   
 OUTPUTS
	image - a [n,y] or [3,n,y] image
    optional:
	fps - frames per second
	exposure - exposore time
		   
 KEYWORD PARAMETERS (optional):
    input:
	timeWanted - 
	frameWanted - 
	force - for remote data from MIT, connect to MDSplus server, 
		open Spectroscopy tree, etc.
	outMsg - error message, if problem
	status - if 0, then a problem
	verbose - print out lots of info
	debug - will stop within routine if error detected.
    Only for .cin files:
	init - 
	bitcount - 
	pps - 
	exposure - 

 EXAMPLES:
	IDL> data = fastcam_frame( '/u/bdavis/Blobs/solt_012_3.5b.hdf', frame=2 )

	IDL> dataM = fastcam_frame( 'shot_1120224022.cin', frame=2 )
	IDL> dataX = fastcam_frame( 'shot_1120224022.cine', frame=2 )

	IDL>     ; e.g., shot=138846  &  timeWanted=0.2
	IDL>     ; this is an easy way to get GPI filenames for NSTX
	IDL>  filename = findCamFiles( shot, cam=5 )
	     
	IDL>     ; if you want to access frames by time, get the allTimes array 
	IDL>     ;   (seconds) so you can look up the frame number
	IDL>  FASTCAM_TIMES, filename, allTimes, frames, status=status
   
	IDL>     ; (frames[0] is usually 0, but not always!)
	IDL>  frameNumber = nearesti( allTimes, timeWanted ) + frames[0]
	IDL>  image = FASTCAM_FRAME( filename, frameNumber, $		; inputs
	IDL>    			outMsg=outMsg, status=status )  ; returned

 NOTES:
	can be used in conjunction with cine_time.pro

 MODIFICATION HISTORY:
    31-Oct-2013 - support for NetCDF files (ext nc) for test blob files
    17-Jul-2013 - try to use read_generic for single frame files
    10-Sep-2012 - if no directory info, and shot is > 9, then get from tree
    	  	   at MIT
    26-Mar-2012 - added support for SOLT model output written by Jim Myra
    WRITTEN 15-Apr-2009 by Bill Davis


FASTCAM_TIMES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	fastcam_times
		   
 PURPOSE:
       a generic routine to get timing array for Fast Cameras.
       You can get camera data from MDSplus at MIT, read
       localNetCDF, HDF, or CIH files  (which follow expected
       conventions), as well as the Cine files.

 CATEGORY:
       Image Processing
		   
 CALLING SEQUENCE:
       IDL> fastcam_times, filename, times
		   
 INPUTS:
   	filename - a .cin file
		   
 OUTPUTS
	times - times of frames in seconds after T0
    optional:
	fps - frames per second
	exposure - exposore time
		   
 KEYWORD PARAMETERS (optional):
    inputs:
	noOpen - if=1, will force a file open
	cam - for MIT cameras (1 is midplane camera)
    outputs:
	serialNum 
	frame_rate
		   
  EXAMPLE:
	IDL> fastcam_times, '/u/bdavis/Blobs/solt_012_3.5b.hdf', times 

       IDL> fastcam_times, 'shot_1120224022.cin', times, frames

 MODIFICATION HISTORY:
    31-Oct-2013 - support for NetCDF files (ext nc) for test blob files
    10-Sep-2012 - if no directory info, and shot is > 9, then get from tree
  	  	   at MIT
    26-Mar-2012 - added support for SOLT model output written by Jim Myra
    05-May-2010 - added keyword serialNum
    WRITTEN 15-Apr-2009 by Bill Davis


FCPLAYER

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       fcplayer
 PURPOSE:
       Also displays files from the Phantom or color Miro cameras (.cin 
	files) and optionally save frames as JPEG, PNG or TIFF files. 
	Allows recording of click locations on .cin files from a 
	Phantom 4 or 7 camera (for tracking dust, e.g.). Also trackes "blobs"
	from images of edge turbulence.
 CATEGORY:
       Image Processing, Animation, Fast Cameras
 CALLING SEQUENCE:
       IDL> fcplayer, filename
 INPUTS:
       filename - a .cin file 
		(or will pop dialog box)
	  Environmental/System variable FC_DATA_DIR will be used, if set, to look for
	  files containing the string in 'filename'
 KEYWORD PARAMETERS:
	AveT1 - start time in seconds to form average frame for normalizing
	AveT2 - end time in seconds to form average frame for normalizing
	AveF1 - start frame to form average frame for normalizing
	AveF2 - end frame to form average frame for normalizing
	bgFrame - the first frame of the background (default=0)
	box - if set, will try to handle two boxes that show up on one of Ricky's cameras
	ByteScale - if =0, will not byte scale image before displaying.
	camera - a number from 1-7, which will go into wildcard search for filename
		like 'nstx_5_'
	colorTable - default to IDL color table 3 (hot metal)
	drawXSize - the horizontal size in pixels of the image window
	gamma - gamma correction. (Default=1, which is no correction). 0.5 probably better 
		for Miro
	horizontal_flip - if set, flip images horizontally (desired for NSTX and CMOD shots)
	INTERP - if =1, pixels will be smoothed, rather than replicated
	loop - if set, will continue to loop over all times, or those in widget boxes.
	maxPlayMinutes - defaults to 60
	minXsize - minimum X size of window displaying image
	nBG - number of background frames. If=0 (the default) no background subtraction is done
	noCaption - do not put text on or above image
	pause - time to pause between frames when playing
	radius - 1/2 of square in pixels drawn around click point, setting the area to be 
		used for the maxval calculation.
       RotCCW - rotate image Counter-ClockWise (desired for NSTX shots)
	RotCW - rotate image ClockWise
	RotDegrees - rotate an arbitray # of degrees Clockwise
	saturation - As in HSV color representation, for color camera. Default is 0.3.
	startTime - start time in milliseconds
	shot - a number which will go into wildcard search for filename
		like '*123456.*'
	vertical_flip - if set, flip images vertically
	FrameOffset - if set, subtract this (like a baseline) from all pixels
	FrameAveMin - if set, make close-to-zero pixels this number, 
		      so when dividing into data, as in normalizing, result is near zero
			(if <= 0, then just one average frame will be used) 
	AveFrameSmooth - smoothing for the averaged frame(s)
	FrameAveDeltaMS - make frames used for normalizing an average of this many millisec
	verbose - if set, lots of information output listed
       debug - if set, will output even more and may stop at some spots
       GROUP_LEADER - Group_Leader ID
   Blob-related keywords:
       blobs - if set, will track blobs (and will set normalize=1, if not set)
	normalize - if set, will divide frames by the average frame
       saveBlobs - if set, will save blob info to a file (may be easier to run saveblobs.pro)
       BlobArrows - if set, will draw arrow from where blob was in the last frame 
			(if database available for shot and time range)
       history - if set, will draw plus signs of previous locations of blob
			(if database available for shot and time range)
       surface - show shaded surface plot of blobs in another window
       aveT1 - if tracking blobs, use this as start time in sec. for averaging frame (DEF=0)
       aveT2 - if tracking blobs, use this as ending time in sec. for averaging frame 
		(DEF=end of file)   
 OUTPUTS:
       none.
 COMMON BLOCKS:
       region_com
 ROUTINES USED:
	MK_COLOR, usingXwindows
 EXAMPLE:
	IDL> fcplayer	; you will be prompted for a .cin file

    or IDL> fcplayer,'nstx121048.cin',start=200
    or IDL> fcplayer,'MIRO_130376.cin',start=232
       IDL> fcplayer,file='~bdavis/France/Data/ball_against_wall_cam2.cine', $
			nsmooth=5, /gauss, nbg=1, /invert, /debug

    fcplayer, colorTable=3, /horiz, minXsize=256, normalize=0, $
          /RotCCW, /edge,   $
          file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138844.cin'

    fcplayer, '/u/bdavis/03-03-2014essais5.cine',  $
		minX=500, blobs=1, norm=0, showNum=0, nsmooth=3, GaussSmooth=0, $
		gamma=0.3, min2show=5                                                 ,/debug

    fcplayer, '/u/bdavis/03-03-2014essais5.cine', aveF1=10, aveF2=110,  $
		minX=500, blobs=0, norm=1, showNum=0, nsmooth=3, GaussSmooth=0
		gamma=0.5, min=40                                              ,/debug


  for GPI 2015 paper:
    fcplayer,file='nstx_5_140395.cin', /horiz, /RotCC, /show5,  $
             	colorTable=3, minxsize=500, aveT1=.5505, aveT2=.5515, $
		showNum=0, plusSign=0, FrameAveDeltaMS=0	;;;, /rainbow	;;;, minVal=0.405, maxVal=2.159

    fcplayer,file='nstx_5_141746.cin', aveT1=.208, aveT2=.209, minxsize=400

  for GPI study:
    fcplayer,file='nstx_5_137582.cin', $
	      aveT1=0.329, aveT2=0.333, /horiz, /RotCC,  $
	      colorTable=3, minXsize=400, FrameAveDeltaMS=0                                ,/debug

    fcplayer, '/u/bdavis/cvs/idl_cvs/circoneup_1.nc', horiz=0, minx=400

   examples for Blob tracking:
    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139056.cin', $
	      aveT1=0.420, aveT2=0.430, /horiz, /RotCC,  $
	      colorTable=3, /blobs, minXsize=300  , FrameAveDeltaMS=0                                ,/debug

    fcplayer, file='/u/bdavis/Blobs/solt_012_3.5b.hdf', /horiz, /rotcw, ctb=3, minXsize=300,  $
    	       minNorm=0.001, aveT1=0.0, aveT2=1.e-5, FrameAveDeltaMS=0, /blobs  , /debug

    fcplayer, aveT1=0.0, aveT2=0.02, colorTable=3, /blobs, /horiz, minXsize=400, $
         file='/home/bdavis/shot_1091216028.cin'		; at MIT

    fcplayer, aveT1=0.0, aveT2=0.02, colorTable=3, /blobs, /horiz, minXsize=400, $
         file='/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216028.cin'

	(Myra:)
    fcplayer, aveT1=0.055, aveT2=0.0580, colorTable=3, /blobs, /horiz, minXsize=256, $
         file='/p/gpi/szweben/Phantom_Data/2010_data/1100120/shot_1100120025.cin'
    fcplayer, aveT1=0.06, aveT2=0.08, colorTable=3, /blobs, /horiz, minXsize=256, $
         file='/p/gpi/szweben/Phantom_Data/2010_data/1100824/shot_1100824017.cin'

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139432.cin', $
	      aveT1=0.268, aveT2=0.288, /horiz, /RotCC,  $
	      colorTable=3, /blobs, minXsize=300                                  ,/debug

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139442.cin', $
	      aveT1=0.310, aveT2=0.312, /horiz, /RotCC, colorTable=3, minXsize=300                            ,/debug

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_139444.cin', $
	      aveT1=0.265, aveT2=0.275, /horiz, /RotCC,  $
	      colorTable=3, /blobs, minXsize=300  , FrameAveDeltaMS=0                                ,/debug

    fcplayer, $
       file='/p/gpi/szweben/Phantom_Data/2009_Phantom_data/1091216/shot_1091216030.cin', $
	colorTable=3, minXsize=256, /blobs, /horiz, aveT1=0., aveT2=0.02,    /debug

    fcplayer,colortable=3, minXsize=256, /blobs, /horiz, avet1=1.25, avet2=1.27, $
	file='/p/gpi/szweben/Phantom_Data/2010_data/1100803/shot_1100803008.cin'

    fcplayer, aveT1=0.0, aveT2=0.02, colorTable=3, /blobs, /horiz, minXsize=512, $
         file='/p/gpi/szweben/Phantom_Data/2011_data/1110114/shot_1110114026.cin'

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141751.cin', $
	      aveT1=0.2, aveT2=0.22, /horiz,  /RotCC,  $
	      colorTable=3, minXsize=256, /blobs,/debug

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_141752.cin', $
	      aveT1=0.21, aveT2=0.23, /horiz, /RotCC,  $
	      colorTable=3, minXsize=256, /blobs

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138234.cin', $
	      aveT1=0.530, aveT2=0.550, /horiz, /RotCC, colorTable=3,   $
		minXsize=300, /blobs                           ,/debug

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138234.cin', $
	      aveT1=0.530, aveT2=0.540, /horiz, /RotCC,  $
	      colorTable=3,  minXsize=300, /blobs , FrameAveDeltaMS=0             ,/debug

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138128.cin', $
	      aveT1=0.280, aveT2=0.290, /horiz, /RotCC,  $
	      colorTable=3,  minXsize=300, /blobs , FrameAveDeltaMS=0                  ,/debug

    fcplayer,file='/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138114.cin', $
	      aveT1=0.225, aveT2=0.235, /horiz, /RotCC,  $
	      colorTable=3,  minXsize=300, /blobs , FrameAveDeltaMS=0                  ,/debug

    fcplayer,'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_138120.cin' , $	     
    	     avet1=0.219,avet2=0.229, colorTable=3, minXsize=256, /blobs, /horiz, $  
    	     /rotccw, starttim=.2						     

	NB shot, with 1MW during some FC timesL
    fcplayer,'/p/nstxcam-archive/Phantom710-9205/2010/nstx_5_142220.cin' , $	     
    	     avet1=0.280,avet2=0.300, colorTable=3, minXsize=256, /blobs, /horiz, $  
    	     /rotccw, starttim=.29			     

	for looking at elliptical changes at 0.922:
    fcplayer, colorTable=3, /blobs, /horiz, minXsize=400, $
    	  file='/p/gpi/szweben/Phantom_Data/2011_data/1110114/shot_1110114032.cin'

       to look at X-pt camera from CMOD:
    fcplayer, aveT1=0.08, aveT2=0.09, colorTable=3, /blobs, /horiz, /RotCW, minXsize=400,  $
	   file='/p/gpi/szweben/Phantom2_Data/2012_shots/1120815/shot_1120815021.cine', $
          FrameAveMin=25, FrameAveDeltaMS=1, max2show=2

       to look at X-pt camera from CMOD via MDSplus (times are shot times):
    fcplayer, aveT1=1.044, aveT2=1.048, colorTable=3, /blobs, /horiz, /RotCW,  $
	   minXsize=400,  file='shot_1120224022.cine', $
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2 

	to look at mid-plane camera from CMOD via MDSplus
    fcplayer, aveT1=1.044, aveT2=1.045, colorTable=3, /blobs, /horiz,  $
	   minXsize=400,  file='shot_1120224022.cin', $	  ; no "e" on end for midplane
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2 



    shot = '1120815018'  &  t1=1.270  &  t2=1.274
       ; black part will be across top with /horiz and /RotCW
    fcplayer, aveT1=t1, aveT2=t2, colorTable=3, /blobs, /horiz, /RotCW,  $
	       minXsize=400,  file='shot_'+shot+'.cine', $	; .cine is X-pt cam
              FrameAveDeltaMS=0, FrameAveMin=25, max2show=2

       to look at corresponding mid-plane camera from CMOD:
    fcplayer, aveT1=t1, aveT2=t2, colorTable=3, /blobs, /horiz,   $
	       minXsize=400,  file='shot_'+shot+'.cin', $	; .cin is midplane cam
              FrameAveDeltaMS=0, FrameAveMin=25, max2show=2	; blacking good here?



    fcplayer, aveT1=1.086, aveT2=1.088, colorTable=3, /blobs, /horiz,  $
	   minXsize=400,  file='shot_1120224029.cin', $
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2 , minrise = 0.06

    fcplayer, aveT1=1.440, aveT2=1.443, colorTable=3, /blobs, /horiz,  $
	   minXsize=400,  file='shot_1120712028.cin', $
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2 , minrise = 0.06

    fcplayer, aveT1=1.440, aveT2=1.443, colorTable=3, /blobs, /horiz, /rotcw, $
	   minXsize=400,  file='shot_1120712028.cine', $
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2 , minrise = 0.06

    fcplayer, aveT1=1.086, aveT2=1.088, colorTable=3, /blobs, /horiz,  $
	   minXsize=400,  file='shot_1120224029.cine',   $		    ; RotDeg=51, $
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2, minrise = 0.06

    fcplayer, aveT1=1.089, aveT2=1.091, colorTable=3, /blobs, /horiz, /rotcw,  $
	   minXsize=400,  file='shot_11202240.cine', $
          FrameAveMin=25, FrameAveDeltaMS=0, max2show=2 

 NOTES:
 MODIFICATION HISTORY:
	11-Jun-2015 Stewart wants TOPNORM, xFromSEP,tiltHM, ellipHM and EHMht printed 
		    beside blobs
	12-Mar-2014 added ability to specify Fit for separatrix
	03-Mar-2014 when GPI fast camera asked for, use BD preferences.
  	31-Oct-2013 - support for NetCDF files (ext nc) for test blob files
	08-Oct-2013 added manifold-showing option. New limiter position
	17-Jul-2013 made to work (again) with a single frame
	05-Mar-2013 added shot and camera keywords.
	29-Nov-2012 Replaced Save-as-GIF with PNG
	06-Oct-2012 allow surface plot axes to be in cm
	05-Oct-2012 added showNumbers keyword so text on images can be surpressed.
	13-Sep-2012 If CMOD files not in local directory, or the one specified, get from 
			MDSplus at MIT.
	05-Sep-2012 different smoothing parameter for Frame Averaging.  
		    Allow average frames to be for 1ms, or whatever. 
		    New keyword FrameOffset to be subtracted from each frame. 
		    Reinstated the printing of "rise" next to blobs.
	04-Sep-2012 read file for Average Intensity plot, if not in tree.
	27-Mar-2012 support for HDF files from simulations by Jim Myra.
	07-Mar-2012 In findblobs, check Chi Squared first, before tossing all 
			interior contours (fixed a bug where occaisional blobs missing).
       01-Mar-2012 decided not to smooth average frame. Changed median smoothing to regular
	23-Feb-2012 allow for not smoothing the average frame. Smooth average frame the
		    same as the setting for the data
	14-Dec-2011 added option to show separatrix (keyword edge); probably only makes
		    sense for GPI camera (#5) data
	07-Dec-2011 subtract background right after data read, so shouldn't rotate,
  		    flip, etc., background data
	26-Sep-2011 Anticipating loading of blob database will be done with loadblob.pro,
		    made the blobCriteria more reasonable. MinHt 1.1, MinArea 15, 
		    MinChiSq 5, minRise 0.05
	06-Sep-2011 reworked findblobs, so can plot surface within same window
	20-May-2011 fixed printer selection and aspect ration of prints
	07-Apr-2011 added NoCaption keyword for NOVA work.
	21-Jan-2011 use database of parent/child relations of blobs to draw arrows
		    Using point of maximum withing (smoothed) blob as center to track.
	04-Jan-2011 blob tracking and output file for Stewart Zweben
	22-Jul-2010 added Preview and Revert buttons to Image Enhancement widget.
	23-Jun-2010 desensitze widgets in slave window that would create new widget IDs
	14-Jun-2010 added rotate-image options
	10-Jun-2010 added Master Player feature to allow synced play of two different cameras
	08-Jun-2010 use amedian, so edges of images get filtered
	28-May-2010 fixed play range, and made jpeg saves a screen dump (so would
			use image enhancements.
	27-May-2010 can specify nBG and BGframe on command line.
	18-May-2010 fixed one pixel too many being displayed on zoom (so click points off a little)
	06-May-2010 Improved default dir for writing Click files, and don't destroy clicked
		    data if cancel out of writing.
	19-Apr-2010 combined background dialogs into one widget
	27-Jan-2010 remove /KEEP_ASPECT from TVIMAGE and draw at z=0 so Z Position is correct
	21-Jan-2010 set Val printed back to value of clicked point (for later reasonableness checking)
	11-Jan-2010 Added slider for saturation in "Image Enhancement" widget, and made default=0.3
	05-Jan-2010 Added display of X & Y positions
	21-Dec-2009 Added "Specify region to display" option
	10-Dec-2009 Added option to plot average intensity vs. time of RGB components
	01-Sep=2009 added /horizontal_flip and /vertical_flip and menu items.
	06-Jul-2009 Added menu option to search for movie files.
	24-Jun-2009 Added Write MPEG, and min/max values to show.
	15-Apr-2009 Added support for *.raww files, from new Photron camera
	10-Nov-2008 cleaned up incompatibility with tvimage. Added menu options for # of
		    background frames to subtract, start frame for background subtraction,
		    turn off/on byte scaling of image.
	04-Aug-2008 added Frame Time slider widget
	31-Jul-2008 Added imageproc option to Special menu & gamma setting to Edit menu.
		    Also added median smoothing option.
	16-Jul-2008 Can ungzip .gz files automatically
	14-Jul-2008 Added support for color images. Added GAMMA keyword.
	10-Jun-2008 Added XSectionW option. Changed default to no background subtraction
	15-May-2008 Added maxPlayMinutes, so movie won't run for ever (Default to 1 hour)
	12-May-2008 made advance and backup buttons more clear. Added noLoad keyword so
		    color palette loading can be surpressed.
	15-Feb-2008 Add options to save as JPEG, GIF & TIFF
	15-Mar-2007 add animation feature
	26-Oct-2006 added Advance-number-of-frames box
	19-Oct-2006 added BG subtraction and "box disquising"
       01-Jun-2006 Written by Bill Davis, PPPL


FEATURE

[Previous Routine] [Next Routine] [List of Routines]

 see http://www.physics.emory.edu/~weeks/idl
   for more information

 NAME:
		Feature	
 PURPOSE:
		Finds and measures roughly circular 'features' within 
		an image.
 CATEGORY:
		Image Processing
 CALLING SEQUENCE:
		f = feature( image, diameter [, separation, masscut = masscut,
			min = min, iterate = iterate, /field, /quiet ] )
 INPUTS:
		image:	(nx,ny) array which presumably contains some
			features worth finding
		diameter: a parameter which should be a little greater than
			the diameter of the largest features in the image.
			Diameter MUST BE ODD valued.
		separation: an optional parameter which specifies the 
			minimum allowable separation between feature 
			centers. The default value is diameter+1.
		masscut:Setting this parameter saves runtime by reducing the
			runtime wasted on low mass 'noise' features.
		min: 	Set this optional parameter to the minimum allowed
			value for the peak brightness of a feature. Useful
			for limiting the number of spurious features in
			noisy images.
		field: 	Set this keyword if image is actually just one field
			of an interlaced (e.g. video) image. All the masks
			will then be constructed with a 2:1 aspect ratio.
		quiet:	Supress printing of informational messages.
		iterate: if the refined centroid position is too far from
			the initial estimate, iteratively recalc. the centroid
			using the last cetroid to position the mask.  This 
			can be useful for really noisy data, or data with
			flat (e.g. saturated) peaks.  Use with caution- it
			may 'climb' hills and give you multiple hits.
 OUTPUTS:
		f(0,*):	this contains the x centroid positions, in pixels.
		f(1,*): this contains the y centroid positions, in pixels. 
		f(2,*): this contains the integrated brightness of the 
			features.
		f(3,*): this contains the square of the radius of gyration
			of the features.
		f(4,*): this contains the eccentricity, which should be 
			zero for circularly symmetric features and order
			one for very elongated images.
 SIDE EFFECTS:
		Displays the number of features found on the screen.
 RESTRICTIONS:
		To work properly, the image must consist of bright, 
		circularly symmetric regions on a roughly zero-valued 
		background. To find dark features, the image should be 
		inverted and the background subtracted. If the image
		contains a large amount of high spatial frequency noise,
		performance will be improved by first filtering the image.
		BPASS will remove high spatial frequency noise, and 
		subtract the image background and thus provides a good 
		complement to using this program. Individual features 
		should NOT overlap.
 PROCEDURE:
		First, identify the positions of all the local maxima in
		the image ( defined in a circular neighborhood with diameter
		equal to 'diameter' ). Around each of these maxima, place a 
		circular mask, of diameter 'diameter', and calculate the x & y
		centroids, the total of all the pixel values, and the radius
		of gyration and the 'eccentricity' of the pixel values within
		that mask. If the initial local maximum is found to be more
		than 0.5 pixels from the centroid and iterate is set, the mask 
		is moved and the data are re-calculated. This is useful for 
		noisy data. If the restrictions above are adhered to, and the 
		features are more than about 5 pixels across, the resulting x 
		and y values will have errors of order 0.1 pixels for 
		reasonably noise free images.

 *********	       READ THE FOLLOWING IMPORTANT CAVEAT!        **********
		'feature' is capable of finding image features with sub-pixel
		accuracy, but only if used correctly- that is, if the 
		background is subtracted off properly and the centroid mask 
		is larger than the feature, so that clipping does not occur.
		It is an EXCELLENT idea when working with new data to plot
		a histogram of the x-positions mod 1, that is, of the
		fractional part of x in pixels.  If the resulting histogram
		is flat, then you're ok, if its strongly peaked, then you're
		doing something wrong- but probably still getting 'nearest
		pixel' accuracy.

		For a more quantitative treatment of sub-pixel position 
		resolution see: 
		J.C. Crocker and D.G. Grier, J. Colloid Interface Sci.
		*179*, 298 (1996).

 MODIFICATION HISTORY:
		This code is inspired by feature_stats2 written by
			David G. Grier, U of Chicago, 			 1992.
		Written by John C. Crocker, U of Chicago, optimizing 
			runtime and measurement error, 			10/93.
		Added field keyword, 		 			 4/94. 
		Added eccentricity parameter, 	 			 5/95.
		Added quiet keyword					12/95.
		Added iteration, fixed up the radius/diameter fiasco and
		did some debugging which improves non-centroid data.	 4/96.
		
	This code 'feature.pro' is copyright 1997, John C. Crocker and 
	David G. Grier.  It should be considered 'freeware'- and may be
	distributed freely in its original form when properly attributed.


FILTER_IMAGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       FILTER_IMAGE

 PURPOSE:
       Identical to MEDIAN or SMOOTH but handle edges and allow iterations.
 CATEGORY:
       Image Processing
 EXPLANATION:
       Computes the average and/or median of pixels in moving box,
       replacing center pixel with the computed average and/or median,
               (using the IDL smooth or median functions).
       The main reason for using this function is the option to
       also process the pixels at edges and corners of image, and,
       to apply iterative smoothing simulating convolution with Gaussian,
       and/or to convolve image with a Gaussian kernel.

 CALLING SEQUENCE:
       Result = filter_image( image, SMOOTH=box_width, /MEDIAN, /ALL )

 INPUT:
       image = 2-D array (matrix)

 OPTIONAL INPUT KEYWORDS:
       SMOOTH = scalar (odd) integer specifying the width of a square box 
               for moving average, in # pixels.
       /SMOOTH  means use box width = 3 pixels for smoothing.

       MEDIAN = scalar (odd) integer specifying the width of square moving 
               box for median filter, in # pixels.
       /MEDIAN  means use box width = 3 pixels for median filter.
   
       /ALL_PIXELS causes the edges of image to be filtered as well,
               accomplished by reflecting pixels adjacent to edges outward.

       /ITERATE means apply smooth(image,3) iteratively for a count of
               (box_width-1)/2 times (=radius), when box_width >= 5.
               This is equivalent to convolution with a Gaussian PSF
               of FWHM = 2 * sqrt( radius ) as radius gets large.
               Note that /ALL_PIXELS is automatically applied,
               giving better results in the iteration limit.
               (also, MEDIAN keyword is ignored when /ITER is specified).

       FWHM_GAUSSIAN = Full-width half-max of Gaussian to convolve with image. 
                       FWHM can be a single number (circular beam),
                       or 2 numbers giving axes of elliptical beam.

       /NO_FT_CONVOL causes the convolution to be computed directly,
               with IDL function convol.
               The default is to use FFT when factors of size are all LE 13.
               (note that external function convolve handles both cases)

 RESULT:
       Function returns the smoothed, median filtered, or convolved image.
       If both SMOOTH and MEDIAN are specified, median filter is applied first.

 EXAMPLES:
       To apply 3x3 moving median filter and
       then 3x3 moving average, both applied to all pixels:

               Result = filter_image( image, /SMOOTH, /MEDIAN, /ALL )

       To iteratively apply 3x3 moving average filter for 4 = (9-1)/2 times,
       thus approximating convolution with Gaussian of FWHM = 2*sqrt(4) = 4 :

               Result = filter_image( image, SMOOTH=9, /ITER )

       To convolve all pixels with Gaussian of FWHM = 3.7 x 5.2 pixels:

               Result = filter_image( image, FWHM=[3.7,5.2], /ALL )

 EXTERNAL CALLS:
       function psf_gaussian
       function convolve
       pro factor
       function prime          ;all these called only if FWHM is specified.

 PROCEDURE:
       If /ALL_PIXELS or /ITERATE keywords are set then
       create a larger image by reflecting the edges outward,
       then call the IDL median and/or smooth function on the larger image,
       and just return the central part (the orginal size image).
 HISTORY:
       Written, 1991, Frank Varosi, NASA/GSFC.
       FV, 1992, added /ITERATE option.
       FV, 1993, added FWHM_GAUSSIAN= option.
       Converted to IDL V5.0   W. Landsman   September 1997


GAMMA_RAISE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	GAMMA_RAISE

 PURPOSE:
	Apply gamma correction to an array, presumably an image.

 CATEGORY:
	Image Processing.

 CALLING SEQUENCE:
	newImage = GAMMA_RAISE(image, Gamma)

 INPUTS:
	Gamma:	The value of gamma correction.  A value of 1.0 indicates a
		linear ramp, i.e., no gamma correction.  Higher values of 
		gamma give more contrast.  Values less than 1.0 yield lower 
		contrast.

 KEYWORD PARAMETERS:

 OUTPUTS:
	A gamma-corrected image.

 RESTRICTIONS:
	None.

 PROCEDURE:
	The gamma correction is implemented as x^gamma.

 MODIFICATION HISTORY:
	Written 14-Jul-2008 by Bill Davis


GETIMAGE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       GETIMAGE

 PURPOSE:
       The purpose of this function is to allow the user to open either
       regular or XDR binary image files of two or three dimensions.

 CATEGORY:
       Image Processing, Widgets, File I/O

 CALLING SEQUENCE:
       image = GETIMAGE(filename)

 INPUTS:
       filename: The name of the file to open for reading.

 KEYWORD PARAMETERS:

       CANCEL: An output variable that can be set to a named variable.
       The value of the return variable will be 1 if the user clicked
       the "Cancel" button or if there was a problem reading the file.

       DIRECTORY: The name of the directory the file is located in. By
       default the program looks in the "training" directory under the
       main IDL directory, if one exists. Otherwise, it defaults to the
       current directory.

       FRAMES: The 3rd dimension of a 3D data set. Defaults to 0.

       HEADER: The size of any header information in the file in BYTES.
       Default is 0.

       PARENT: The group leader for this widget program. The PARENT is
       required if GETIMAGE is called from another widget program.

       XDR: Set this keyword if the binary file is of XDR type.

       XOFFSET: This is the X offset of the program on the display. The
       program will be placed approximately in the middle of the display
       by default.

       XSIZE: The size of the 1st dimension of the data.

       YOFFSET: This is the Y offset of the program on the display. The
       program will be placed approximately in the middle of the display
       by default.

       YSIZE: The size of the 2nd dimension of the data.

 COMMON BLOCKS:
       None.

 SIDE EFFECTS:
       A "CANCEL" operation is indicated by a 0 return value.
       Any error in reading the file results in a 0 return value.

 RESTRICTIONS:
       None.

 EXAMPLE:
       To load the image "galaxy.dat" in the $IDL/examples/data
       directory, type:

       image = GETIMAGE('galaxy.dat', DIRECTORY=!DIR + '/examples/data', $
          XSIZE=256, YSIZE=256, Cancel=cancelled, Parent=event.top)
       IF NOT cancelled THEN TV, image

 MODIFICATION HISTORY:
       Written by: David Fanning, 3 February 96.
       Fixed bug that prevented reading INTEGER data. 19 Dec 96.
       Modifed program for IDL 5 MODAL operation. 19 Oct 97.
       Added CANCEL keyword. 27 Oct 97. DWF.
       Fixed CANCLE keyword spelling. Sigh... 29 JUN 98. DWF.


IMAGEPROC

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
       imageproc

  PURPOSE:
       Demonstrate a few of IDL's image processing features:
       Fourier filtering, pixel scaling, pixel distribution
       (histogram), edge enhancement, dilate & erode,
       convolution, and zooming.

  CATEGORY:
       Image Processing, 2-D Plotting

  CALLING SEQUENCE: 
	IDL> imageproc
 INPUTS:
       input = a 2-D image (optional, otherwise will pop dialog for tiff file

 KEYWORD PARAMETERS:
	NColors - # of colors to use
	Bottom - value to add to bytescaled image
	magnification - magnification factor desired for image
	INTERP - if magnification set, INTERP=1 will cause interpolation
	XSIZE - xsize of displayed image
	YSIZE - ysize of displayed image
  REFERENCE: IDL Reference Guide, IDL User's Guide

  NAMED STRUCTURES:
       none.

  COMMON BLOCS:
       none.

  MODIFICATION HISTORY:
	July, 2004 a few more additions [BD]
	23-Jan-00 Modified from RSI d_imageproc by Bill Davis.
	d_imageproc Written by:  DC, RSI,  1995


SHOCKVSTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       shockvstime
 PURPOSE:
       Stack plots of a line from the center of .cin file image at various 
	times See http://nstx.pppl.gov/nstx/Software/Help/shockwaves.html for 
	sample images. After plotting, you will be prompted for times for which
	calculate the  speed of the leading edge of the shockwave.
 CATEGORY:
       Image Processing, CINE files.
 CALLING SEQUENCE:
       IDL> shockvstime, filename
 INPUTS:
       filename - a .cin file 
 KEYWORD PARAMETERS:
    INPUTS:
	filename - .cin filename
	title - will default to 'Shock Wave at various times'
	times - times entered in msec (are seconds in file)
	jline - vertical index in image to use for line plot. Defaults to 25
	addIn - vertical space between plots
	inc - increment between files to plot (defaults to 1, which plots all)
	gradient - if set, uses a gradient color palette
	flatFrac - see leadingedge.pro
	deltaPercent -  see leadingedge.pro
	edge - if set, draw symbol at leading edge of shockwave (defined by
		point of increase after a long flat portion.
	cmPerPixel - centimeters per  pixel (Default=0.2423)
	debug - if set, will stop
    RETURNED:
	allData - returns all the data within the time specified
 OUTPUTS:
       none.
 EXAMPLE:
       To get a postscript file:
           IDL> setup_ps, filename='shockvstime.ps', /color
           IDL> shockvstime
           IDL> unsetup_ps

       surftime=findgen(145)/145*(0.00119100-0.000773)*1000 +1.191
       surfx =findgen(128)
       surf = interpPeak(allData)
       for j=1,2 do surf = interpPeak(surf)
       save,surfx,surfTime,surf, file='Surf_50ma.sav'

       shockvstime, /edge, inc=3
 MODIFICATION HISTORY:
       18-Jun-2009 Written by Bill Davis, PPPL, for Lane Roquemore


XSECTIONW

[Previous Routine] [List of Routines]
 NAME:
	xsectionw
 PURPOSE:
	Widget to display an image and x-y plots of cross-sections.
	Color palettes may be loaded, adjusted and saved. 
	Images can be saved as 'jpg','tif','tif','bmp','jpeg,'png', 'ppm', 
	'pgm', or 'gif'
 CATEGORY:
	Image Processing, 2-D Plotting, Files, Graphics
 CALLING SEQUENCE:
	IDL> xsectionw[[, image], x, y]
 INPUTS:
	image - a 2D array. If missing, and Keyword Filename not
	        specified, a dialog box will appear allowing browsing
		for a TIFF image.
	x & y are optional inputs for x & y axes. Must be same dimension as image.
 KEYWORD PARAMETERS:
    (optional) 
	filename - file to read (can be type 'jpg','tif','tif','bmp', 
		   'jpeg,'png','ppm', 'pgm', or 'gif')
	xvals - optional values for X axis
	yvals - optional values for Y axis
	title - title to display at top of plot (Defaults to filename, if relevant)
	xsize - horizontal size of window (default is 0.75 of screen, but > 800)
	ysize - vertical size of window
	xoffset - initial horizontal offset of the widget (DEFAULT=0)
	yoffset - initial vertical offset of the widget (DEFAULT=30)
	INTERP - if magnification set, INTERP=1 will cause interpolation,
		rather than pixel replication.
	max_colors - # used by display (Default is 256)
	NOLOAD - if set, do not load color table
	colorTable - color table to use. Default is 03 (Hot Metal)
	NoCont - if set, no contours are drawn (default)
	file - color table file (for personal color tables)
	(other keywords to th_image_cont.pro may be included)
	GROUP_LEADER - Group_Leader ID
 OUTPUTS:
       none.
 COMMON BLOCKS:
       none
 ROUTINES USED:
	MK_COLOR, usingXwindows, NWORDS, FLIP
 EXAMPLE:
	IDL> xsectionw, dist(200,200)

	IDL> xsectionw, '/u/bdavis/FTP/nstx000113723_90.tif'

   For serious testing of zooming, etc.:
	IDL> x=findgen(120)/120
	IDL> y=findgen(50)*!PI
	IDL> d=sin(x*6+1)#cos(y/20+2)
	IDL> d[20:30,*]=-2
	IDL> d[*,35:40]=.5
	IDL> d=d*1000
	IDL> d=d-min(d)
	IDL> th_image_cont,d,x,y
	IDL> xsectionw,d,x,y

 NOTES:
	If you specify max_colors to be something other than 256, and
	want to change color tables, you need to do something like:
		IDL> dum=MK_COLOR( table=3 )
	Using XLOADCT, etc. won't work well, since it loads 256 colors.
 MODIFICATION HISTORY:
	27-Nov-2013 handle input image file name
	05-Nov-2013 list location of click line in x-y plot titles
	23-Sep-2013 increase left margin when y-axis has exponents. Added
		    /drag to xcolors call, so colors updated when drag slider
	22-Oct-2010 Fixed a couple of bugs opening new images
	05-Jan-2010 Default to just red component for true color images, but COMPONENT
		    keyword added to override this.
	18-Aug-2009 fixed bug in zooming
	24-Jun-2009 added xrange, yrange, and zrange keywords
	30-Sep-2008 just use channel 0 of 24-bit images
	14-Jul-2008 Handle 24-bit color images (poorly, but doesn't bomb)
	25-Apr-07 Added more modify color table options, and option to save color table.
		  Support more kinds of image files. Can set background color from menu.
		  Can save image or window to files. Added Median Smoothing opt
	25-May-06 added noload keyword
	02-May-06 fixed x-y plot axis limits when zoomed in
	12-Apr-06 added x & y keywords, and made to work with resizing and drawing box
	03-Feb-03 Option to force lines to black or white
	11-Dec-01 Written by Bill Davis, PPPL


Category: Interpolation

[List of Routines]


INTERP2DFIT

[Next Routine] [List of Routines]
 NAME:
 	interp2dfit 
 PURPOSE:
       fit irregularly-spaced x, y, & z points by fitting a 2-D surface 
	using SFIT,  and, using the returned coefficients, compute new
	values at other irregularly-spaced locations.
 CATEGORY:
       Interpolation
 CALLING SEQUENCE:
       IDL> zWant = interp2dfit( x, y, z, Xwant, Ywant, surfaceOut=surfaceOut )
 INPUTS:
       x, y, z - randomly-spaced points
	Xwant, Ywant - X & Y points at which to compute new points
 KEYWORD PARAMETERS:
    Inputs:
	degree - degree of polynomial passed to SFIT (default=6)
	plot - if set, will plot data and surfaces so you can see
		if fit is reasonable
	gtzero - if set, will force all values to be greater than 0
	NXout - # of X points to use for fitted surface, and in returned array
	NYout - # of Y points to use for fitted surface, and in returned array
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	Zwant - (returned value) interpolated values at Xwant & Ywant
	KX - coeficients of polynomial fit, returned from SFIT.
       surfaceOut - 2-D grid to which irregular points were interpolated
  EXAMPLE:

	   ; get randomly-spaced x, y, & z values:
     IDL> restore,'/u/bdavis/cvs/idl_cvs/interp2dfiteg.sav'
     IDL> minx = MIN( x, MAX=maxx )
     IDL> miny = MIN( y, MAX=maxy )
     IDL> XWant = randomu(seed,200)*(maxX-minX) + minX  ; more points make smoother plots
     IDL> YWant = randomu(seed,200)*(maxY-minY) + minY
     IDL> Zwant = interp2dfit( x, y, z, Xwant, Ywant, /gtZero, /plot )

 NOTES:
       Polynomial fits can be way off beyond the edges of the data.
	(Probably should pass in as a parameter the 100 currently used
	 to make the interpolated surface)
 MODIFICATION HISTORY:
	22-Aug-2012 fix bug when plotting, but not returning regsurf
	15-May-2010 Use Xwant and Ywant for output array
 	WRITTEN 17-Jan-2010 by Bill Davis for Manny Manickam


INTERP2D

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	interp2d

 PURPOSE:
	Perform bilinear 2d interpolation using the IDL intrinsic 
	interpolate procedure

 CATEGORY:
       Interpolation

 CALLING SEQUENCE:
       result = interp2d(A,x0,y0,x1,y1)
       result = interp2d(A,x0,y0,x1,y1,/grid)
       result = interp2d(A,x0,y0,x1,y1,/regular,/cubic)
       result = interp2d(A,x0,y0,x1,y1,missing=missing)

 INPUTS:
       A   = 2d array to interpolate
       x0  = Values that correspond to A(0,0), A(1,0), ...
       y0  = Values that correspond to A(0,0), A(0,1), ...
       x1  = New X values at which A should be interpolated
       y1  = New Y values at which A should be interpolated

 OPTIONAL INPUTS:
       nxny = [nx,ny] Vector of length 2 which specifies the size of
             the regular linearized grid produced with trigrid.  The
             default is nxny = [51,51].  If the size of A is much larger
             than 51 by 51, greater accuracy may be obtained by having
             nxny = [n_elements(A(*,0),n_elements(A(0,*))]

 OPTIONAL INPUT KEYWORDS:
       grid= If set, return an n_elements(X1) by n_elements(y1) grid
       missing = Value to points which have X1 gt max(X0) or X1 lt min(X0)
       	    and the same for Y1.
       quintic = If set, use smooth interpolation in call to trigrid
       regular = If set, do not call trigrid -- x0 and y0 must be linear.
       cubic	= If set, use cubic convolution
       extrapolate = If set, then extrapolate beyond boundary points
       bin = set to bin data prior to interpolation.
             (e.g. bin=2 interpolate every second pixel)

 Returned:
       result = a vector N_elements(X1) long 
          or, if /grid is set
       result = an array that is N_elements(X1) by N_elements(Y1)

 PROCEDURE:
   	First call the IDL intrinsic routines TRIANGULATE & TRIGRID to make
	sure that X0 and Y0 are linear (if /regular is not set).
   	Then call the IDL intrinsic INTERPOLATE to do bilinear interpolation.

 RESTRICTIONS:
   	X0 and Y0 must be linear functions.
   	A must be a 2-d array

 HISTORY:
    9-mar-94, J. R. Lemen LPARL, Written.
   20-Jan-95, JRL, Added the REGULAR & CUBIC keywords
   6-Sept-97, Zarro, GSFC, allowed for 2-d (X-Y) coordinate inputs
  22-Apri-99, Zarro, SM&A/GSFC - added /triangulate and made /regular
              the default (much faster).


INTERPWF

[Previous Routine] [Next Routine] [List of Routines]
  NAME: 
	interpwf

  PURPOSE: 
	Interpolate MDS signal, or array, to 1 KHz.

  CATEGORY:
       Interpolation

  CALLING SEQUENCE:
	IDL> data1KHz = interpwf( inData, time=intime, OUTTIME=outTime)
	  or
	IDL> data1KHz = interpwf( sigName )
  INPUTS:
	inData - data array or MDSplus signal name
  KEYWORDS:
	intime - timebase of input. If not present will get dim_of(inData)
	dt - delta time desired of output. Default to 1.0e-3 (1 KHz)
	TSTART - start time desired. If not present, =0.0
	TSTOP - last output time desired. If not present = max(inTime)
     Returned
	outTime - timebase of desired output array.
  EXAMPLES:
    (works with just arrays, if time present:)
	IDL> data1KHz = interpwf(findgen(3000), time=findgen(3000)/(3000)*1.2, $
		                 OUTTIME=outTime)
	IDL> mdsopen, 'engineering', 130000 
	IDL> wf=interpwf( '\ip1', OUTTIME=outTime, $
				tStart=-0.5, tStop=1.5 )
	IDL> data=mdsvalue('\ip1')
	IDL> time=mdsvalue('dim_of(\ip1)')
	IDL> plot, time, data
	IDL> oplot, outTime, wf, color=colorsearch('red')
  LIMITATION:
	If a signal name is passed in, assume the tree is already open
  MODIFICATION HISTORY:
       13-Feb-2009 do everything in IDL
	27-Jun-2008 Convert to Linux
	06-Apr-06 made default endtime lesser of input and output time
       05-Jul-00 Written by Bill Davis, PPPL


LINTERP

[Previous Routine] [List of Routines]
 NAME:   
       LINTERP  
 PURPOSE: 
       Linearly interpolate tabulated 1-d data from one grid to a new one.
 CATEGORY:
	Interpolation
 EXPLANATION:
       The results of LINTERP are numerically equivalent to the RSI
       INTERPOL() function, but note the followign:
         (1) LINTERP is a procedure rather than a function
         (2) INTERPOL() extrapolates beyond the end points whereas LINTERP
             truncates to the endpoints (or use the MISSING keyword)
         (3) LINTERP (unlike INTERPOL) uses the intrinsic INTERPOLATE function
                 and thus may have a speed advantage

       Use QUADTERP for quadratic interpolation.

 CALLING SEQUENCE:
       LINTERP, Xtab, Ytab, Xint, Yint, [MISSING =, /NoInterp ]   

 INPUT PARAMETERS: 
       Xtab -  Vector containing the current independent variable grid.
               Must be monotonic increasing or decreasing
       Ytab -  Vector containing the current dependent variable values at 
               the XTAB grid points.
       Xint -  Scalar or vector containing the new independent variable grid 
               points for which interpolated value(s) of the dependent 
               variable are sought.

 OUTPUT PARAMETERS:
       Yint  -  Scalar or vector with the interpolated value(s) of the 
               dependent variable at the XINT grid points.
               YINT is double precision if XTAB or YTAB are double,
               otherwise YINT is REAL*4

 OPTIONAL INPUT KEYWORD:
       MISSING - Scalar specifying YINT value(s) to be assigned, when Xint
               value(s) are outside of the range of Xtab.     Default is to
               truncate the out of range YINT value(s) to the nearest value 
               of YTAB.   See the help for the INTERPOLATE function.
       /NoINTERP - If supplied then LINTERP returns the YTAB value(s) 
               associated with the closest XTAB value(s)rather than 
               interpolating.

 EXAMPLE:
       To linearly interpolate from a spectrum wavelength-flux pair
       WAVE, FLUX to another wavelength grid defined as:
       WGRID = [1540., 1541., 1542., 1543., 1544, 1545.]
   
       IDL>  LINTERP, WAVE, FLUX, WGRID, FGRID  

       FGRID will be a 6 element vector containing the values of FLUX 
       linearly interpolated onto the WGRID wavelength scale

 PROCEDURE: 
       Uses TABINV to calculate the effective index of the values
       in Xint in the table Xtab.  The resulting index is used
       with the intrinsic INTERPOLATE function to find the corresponding 
       Yint value in Ytab.  Unless the MISSING keyword is supplied, out
       of range Yint values are truncated to the nearest value of Ytab.

 PROCEDURES CALLED:
       TABINV, ZPARCHECK
 MODIFICATION HISTORY:
       Adapted from the IUE RDAF,  W. Landsman      October, 1988
       Modified to use the new INTERPOLATE function        June, 1992
       Modified to always return REAL*4             October, 1992
       Added MISSING keyword                        August, 1993
       Converted to IDL V5.0   W. Landsman   September 1997
       Added NoInterp keyword  W. Landsman      July 1999


Category: Math

[List of Routines]


DT_NICENUMBER

[Next Routine] [List of Routines]
  NAME:
 	dt_nicenumber

  PURPOSE:
 	Makes nice delta time numbers, by rounding to 3 significant digits
	Can be used if you want to know if you have a constant timebase.

 CATEGORY:
       Math, Graphics

 CALLING SEQUENCE:
        niceDts = dt_nicenumber( dts )

 INPUTS:
	dts - an array of numbers

 KEYWORD PARAMETERS:
    Optional Inputs:
	nSignificantDigits - number of significant digits to round to
				(defaults to 3)
    Optional Outputs:
       nDecimals - number of significant decimal places in returned value
  EXAMPLE:
	IDL> dt=[2.0003,2.15,.2003,.20009,22.0004,.250002,.5001,100000.1]
	IDL> print, dt_nicenumber(dt) 
	   2.00000    2.15000   0.200000   0.200000    22.0000   0.250000
	   0.500000    100000.

	IDL> print,  dt_nicenumber( -1.876e6 ) 
 NOTES:
	see nicenumber.pro to round to numbers like 1, 2, 2.5, 5, etc.,
	which might be time intervals for older digitizer rates.
  HISTORY:
	13-May-2011 fixed bug
	20-Apr-2011 handle arrays
	05-Nov-2008 corrected for numbers like -1.876e6
	26-Sep-2005 fixed nToShift for nums less than zero (like 0.0016)
	26-Jul-04 work OK for 0
  	03-Nov-00 Rewrote [BD]


FACTOR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       FACTOR
 PURPOSE:
       Find prime factors of a given number.
 CATEGORY:
	Math
 CALLING SEQUENCE:
     FACTOR, x, p, n
 INPUTS:
      x = Number to factor, scalar positive integer
 OUTPUT PARAMETERS:
      p = Array of prime numbers.    
      n = Count of each element of p. 
 INPUT KEYWORD PARAMETER: 
      /HELP - Display help documentation
 PROCEDURES USED:
      PRIME()
      Also see numfactors, print_fact in the JHUAPL Library
 MODIFICATION HISTORY:
       R. Sterner.  4 Oct, 1988.
       RES 25 Oct, 1990 --- converted to IDL V2.
       Johns Hopkins University Applied Physics Laboratory.

 Copyright (C) 1988, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.
       Converted to IDL V5.0   W. Landsman   September 1997


GAUSSIAN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       GAUSSIAN
 PURPOSE:
       Compute the 1-d Gaussian function and optionally the derivative
 CATEGORY:
       Math
 EXPLANATION:
       Compute the 1-D Gaussian function and optionally the derivative 
       at an array of points.

 CALLING SEQUENCE:
       y = gaussian( xi, parms,[ pderiv ])

 INPUTS:
       xi = array, independent variable of Gaussian function.

       parms = parameters of Gaussian, 2 or 3 element array:
               parms(0) = maximum value (factor) of Gaussian,
               parms(1) = mean value (center) of Gaussian,
               parms(2) = standard deviation (sigma) of Gaussian.
               (if parms has only 2 elements then sigma taken from common).

 OPTIONAL OUTPUT:
       pderiv = optional output of partial derivatives,
               computed only if parameter is present in call.

               pderiv(*,i) = partial derivative at all xi absisca values
               with respect to parms(i), i=0,1,2.

       Function returns array of Gaussian evaluated at xi.

 EXAMPLE:
       Evaulate a Gaussian centered at x=0, with sigma=1, and a peak value
       of 10 at the points 0.5 and 1.5.   Also compute the derivative

       IDL> f = gaussian( [0.5,1.5], [10,0,1], DERIV )
       ==> f= [8.825,3.25].   DERIV will be a 2 x 3 array containing the
       numerical derivative at the two points with respect to the 3 parameters.
 
 COMMON BLOCKS:
       common gaussian, sigma
 HISTORY:
       Written, Frank Varosi NASA/GSFC 1992.
       Converted to IDL V5.0   W. Landsman   September 1997


NDECIMALS

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
 	ndecimals

  PURPOSE:
 	returns the number of non-zero digits after decimal point.
	ignores insigificant bits (in principle)

 CATEGORY:
       Math, Graphics

 CALLING SEQUENCE:
        n = ndecimals( num )

 INPUTS:
	num - a number

 KEYWORD PARAMETERS:
    Optional Inputs:
	nSignificantDigits - max number of decimals to consider
				(defaults to 3 decimals)
  EXAMPLE:
	IDL> print, ndecimals(1.40001) 
           1
       IDL> print, ndecimals(1.123001,nsig=2) 
           2
       IDL> print, ndecimals(1.123001 ) 
           3

       IDL> print, ndecimals('36.123456') 
           6

  HISTORY:
	21-Sep-2012 fixed bug for 1.434001 & '36.123456'
	03-Mar-2011 Written [BD]


NICENUMBER

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       NICENUMBER
 PURPOSE:
       Find a "nice" number close to the given number. Actually, this
	is for older digitizers, so "rounds" to numbers like 
	1, 2, 2.5, 5, etc.
 CATEGORY:
	Math
 CALLING SEQUENCE:
       n = nicenumber(x)
 INPUTS:
       x = given number.              in
 KEYWORD PARAMETERS:
       Keywords:
         /FLOOR finds next nice number le to X.
         /CEIL finds the next nice number ge to X.
         MINOR=m  Returned suggested minor tick spacing.
 OUTPUTS:
       n = nice number close to x.    out
         1, 2, 2.5, or 5 scaled to size of x.
 COMMON BLOCKS:
 NOTES:
       Notes:
         Default operation is useful for finding tick spacings:
         dx = nicenumber((xmx-xmn)/nticks).
         /FLOOR and /CEIL are useful for scaling data plots:
         xmn = nicenumber(min(x),/floor)
         xmx = nicenumber(max(x),/ceil)
         plot, x, y, xrange=[xmn,xmx], . . .
         /floor and /ceil may not give values related to the
         step size, dx.  The following method will:
         ceil(t/dx)*dx is a multiple of dx on the high side of t.
         floor(t/dx)*dx  is a multiple of dx on the low side of t.

        Use DT_NICENUMBER.PRO to "round" to a specific number of digits.

 MODIFICATION HISTORY:
	20-Apr-2011 fix for array starting with zero, like;
			[ 0.0,  5.0e+15,  1.0e+16 ]
	17-Feb-00 handle 190KHz ! (Bill Davis)
       R. Sterner, 6 Feb, 1990
       R. Sterner, 27 Jan, 1993 --- dropped reference to array.
       R. Sterner, 12 Feb, 1993 --- returned 1 element array as a scalar.

 Copyright (C) 1990, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


PRIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	PRIME
 PURPOSE:
	Return an array with the specified number of prime numbers.
 CATEGORY:
	Math
 EXPLANATATION:
	This procedure is similar to PRIMES in the standard IDL distribution,
	but stores results in a common block, and so is much faster 

 CALLING SEQUENCE:
       p = prime(n)
 INPUTS:
       n = desired number of primes, scalar positive integer
 OUTPUTS:
       p = resulting array of primes, vector of positive integers
 COMMON BLOCKS:
       prime_com
 NOTES:
       Note: Primes that have been found in previous calls are
         remembered and are not regenerated.
 MODIFICATION HISTORY:
       R. Sterner  17 Oct, 1985.
       R. Sterner,  5 Feb, 1993 --- fixed a bug that missed a few primes.
       Converted to IDL V5          March 1999

 Copyright (C) 1985, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


PSF_GAUSSIAN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       PSF_GAUSSIAN

 PURPOSE:
       Create a 1-d, 2-d, or 3-d Gaussian with specified FWHM, center 
 CATEGORY:
	Math
 EXPLANATION:
       Return a point spread function having Gaussian profiles,
       as either a 1D vector, a 2D image, or 3D volumetric-data.

 CALLING SEQUENCE:
       psf = psf_Gaussian( NPIXEL=, FWHM= , [/NORMALIZE, /ST_DEV,  )
 or:
       psf = psf_Gaussian( parameters, NPIXEL =  )

 REQUIRED INPUT KEYWORD:
       NPIXEL = number pixels for each dimension, specify as an array,
               or just one number to make all sizes equal.

 OPTIONAL KEYWORDS:

       NDIMEN = dimension of result: 1 (vector), 2 (image), or 3 (volume),
               default = 2 (an image result).

       FWHM = the desired Full-Width Half-Max (pixels) in each dimension,
               specify as an array, or single number to make all the same.

       CENTROID = pixels numbers of PSF maximum ( 0.5 is center of a pixel ),
               default is exact center of requested vector/image/volume.

       STDEV = optional way to specify width by standard deviation param.

       XY_CORREL = scalar between 0 and 1 specifying correlation coefficient
               Use this keyword, for example, to specify an elliptical 
               gaussian oriented at an angle to the X,Y axis

       /NORMALIZE causes resulting PSF to be normalized so Total( psf ) = 1.

 INPUTS (optional):

       parameters = an NDIMEN by 3 array giving for each dimension:
                       [ maxval, center, stdev ],  overrides other keywords.

 EXAMPLE:
       Create a 31 x 31 array containing a normalized centered gaussian 
       with an X FWHM = 4.3 and a Y FWHM = 3.6

       IDL> array = PSF_GAUSSIAN( Npixel=31, FWHM=[4.3,3.6], /NORMAL

 EXTERNAL CALLS:
       function Gaussian

 HISTORY:
       Written, Frank Varosi NASA/GSFC 1991.
       Converted to IDL V5.0   W. Landsman   September 1997


RUNTOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       runTot
 PURPOSE:
       compute a running total of an array by calling an external routine
	(this is inefficient in normal IDL)
 CATEGORY:
       Math
 CALLING SEQUENCE:
       IDL> outarray = runTot(inarray)
 INPUTS:
       inarray = a numeric array.  
 KEYWORD PARAMETERS:
       Keywords:
	  HLP - When set, help information is printed.
 OUTPUTS:
       outarray = returned array of running total                 			out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> print, runtot(findgen(10))

 	IDL> MDSOPEN, 'operations', 100601
	IDL> ip = MDSVALUE( '\operations::ip_ipf1b_1' )
	IDL> V = runTot( ip )
 NOTES:
       When the routine is called with no parameters, or with the
	keyword hlp set, help information is printed.
 MODIFICATION HISTORY:
       04-Oct-99 Written by Bill Davis, PPPL


SDEV

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       SDEV
 PURPOSE:
       Returns standard deviation of an array.
 CATEGORY:
	Math
 CALLING SEQUENCE:
       s = sdev(a)
 INPUTS:
       a = input array.               in
 KEYWORD PARAMETERS:
 OUTPUTS:
       s = standard deviation of a.   out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	01-Aug-00 Commented-out checks for a major speed up. [BD]
       Written by K. Kostoff, 1/16/85
       Johns Hopkins University Applied Physics Laboratory.
       Modified by B. Gotwols, R. Sterner --- 1 Oct, 1986.

 Copyright (C) 1986, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


SIGN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       SIGN
 VERSION:
       3.0
 PURPOSE:
       Gives the sign of X, i.e. 1 for positive, -1 for negative, 0 for 0.
 CATEGORY:
       Math
 CALLING SEQUENCE:
       Result = SIGN(X)
 INPUTS:
    X
       Numerical, otherwise arbitrary.
 OPTIONAL INPUT PARAMETERS:
       None.
 KEYWORD PARAMETERS:
       None.
 OUTPUTS:
       Returns the value of SIGN(X), see above, as an long integer.
 OPTIONAL OUTPUT PARAMETERS:
       None.
 COMMON BLOCKS:
       None.
 SIDE EFFECTS:
       None.
 RESTRICTIONS:
       For complex X the result is SIGN(REAL(X)), the imaginary part is ignored
 PROCEDURE:
       Straightforward.  Using CAST from MIDL.
 MODIFICATION HISTORY:
       Created 15-JUL-1991 by Mati Meron.
       Modified 25-DEC-1991 by Mati Meron.
       Modified 5-DEC-1993 by Mati Meron.  Output type changed to LONG.


SIGX

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       sigx

 PURPOSE:
       Compute horizontal extent of blob along center axis, from 
	edge to edge, given theta, and the two radii.
	Equation from Jim Myra

 CATEGORY:
       Math

 CALLING SEQUENCE:
       IDL> sigx = sigx( theta, radius1, radius2 )

 INPUTS:
	theta - radians clockwise, from zero to the horizontal left
	radius1 - 
	radius2 - 

 RETURNED:
	distance from center, horizontally, to edge of ellipse
	will be in the same units as the input radii

 TESTING:
	IDL> print, sigx( .5, 6, 6)
	      12.00000
	IDL> print, sigx( 1.5, 6, 6)
	      12.00000
	IDL> print, sigx( 0, 10, 5) 
	      20.0000
	IDL> print, sigx( !pi/2, 10, 5)
	      10..00000
	IDL> print, sigx( !pi/4, 10, 5)
	      12.6491

 MODIFICATION HISTORY:
	23-Jun-2015 return distance from edge to edge, rather than center to edge
       16-Jun-2015 Written by Bill Davis, PPPL, for Stewart Zweben


SIGY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       sigy

 PURPOSE:
       Compute vertical extent of blob from edge to edge along center axis
	given theta, and the two radii. The units of the result will be
	the same as the units of radius1 & radius2.
	Equation from Jim Myra

 CATEGORY:
       Math

 CALLING SEQUENCE:
       IDL> sigy = sigy( theta, radius1, radius2 )

 INPUTS:
	theta - radians clockwise, from zero to the horizontal left
	radius1 - 
	radius2 - 

 RETURNED:
	distance from center, vertically, to edge of ellipse
	will be in the same units as the input radii

 TESTING:
	Can be tested with testfcfitellipse.pro

	IDL> print, sigy( .5, 6, 6 )
	      12.0000
	IDL> print, sigy( 2.35, 15, 10 )
	      23.5902
	IDL> print, sigy( 0, 15, 10 )
	      20.0000

 MODIFICATION HISTORY:
	23-Jun-2015 return distance from edge to edge, rather than center to edge
       16-Jun-2015 Written by Bill Davis, PPPL, for Stewart Zweben


TWOSCOMPLEMENT

[Previous Routine] [List of Routines]
  NAME:
	TWOSCOMPLEMENT

  PURPOSE:
 	Taking the Two's Complement of an integer

 CATEGORY:
	Math, Hardware, CAMAC

 CALLING SEQUENCE:
       twoscomp = TwosComplement( int )

 INPUT:
       int - raw encoder value (8, 16 or 32 bit integer)

 OUTPUT:
       twoscomp - Two's complement of input.

 KEYWORDS:
    Optional Input:
	NBITS - # of bits; throw away this bit if there is a carry after 
		adding 1 to the complement. Default is determined by data type.
	IfNeg - Only return the Two's Complement if value negative
 ALGORITHM:

	Taking the Two's Complement of a k-Digit Bitstring:

   1.Complement the bitstring; i.e., change all 0s to 1s and all 1s to 0s; retain all leading 0s in your result. 
   2.Add 1 to this binary number  (if there is a carry of 1 into the (k+1)st position, throw it away so that the
     result is still k-digits). 
   3.The result from (2) is the two's complement of the bitstring 

 COMMENT:
	Works in many cases, but sign bit may get extended in some applications
  MODIFICATION HISTORY:
 	5-Jun-00 WMD Added Nbits & IfNeg Keywords


Category: MDSplus

[List of Routines]


ADDLABELNODES

[Next Routine] [List of Routines]
 NAME:
       addLabelNodes
 PURPOSE:
       Add LABEL sub-nodes to MDSplus signal nodes reading info from a file
 CATEGORY:
       MDSplus, TCL 
 CALLING SEQUENCE:
       addLabelNodes, shot1, shot2, filename=filename
 INPUTS:
	shot1 = starting shot number to process (defaults to last shot)
	shot2 = last shot number to process (optional)
 KEYWORDS:
	filename - name of file with info - REQUIRED, 
		   see, e.g., BDAVIS$:[CVS.MISC.WF]tauslabel.dat
	   the file must contain 4 columns, separated by white space.  
	   the first column is the tagname (without \), the last column is 
	   the Label text enclosed in double quotes. The middle columns
	   can be any single word or character (file format from another
	   application).
	tree - name of tree -- defaults to 'WF'
 COMMON BLOCKS:
       NONE
 NOTES:
       YOU NEED PRIVILEGES to write to the MDSplus tree.
 LIMITATIONS:
 MODIFICATION HISTORY:
	25-Jan-01 Written by Bill Davis.


ADDMDSTAGS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       addmdstags
 PURPOSE:
       Add tags to MDSplus nodes
 PROCEDURE:
 CATEGORY:
       MDSplus, Summary 
 CALLING SEQUENCE:
       addmdstags, shot=shot, nodes=nodes, tags=tags
 INPUTS:
 KEYWORDS:
	shot - shot number to process
	nodes - MDSplus node names to which tag will added (all in same tree)
	tags - to add
	VERBOSE  - if set, more info is printed
	test  - doesn't write to MDSplus
 EXAMPLE:
       nodes = ['\PASSIVESPEC::TOP.IR.IMG0.RAWDATA.IR_408:TIMES', $
		 '\PASSIVESPEC::TOP.IR.IMG1.RAWDATA.IR_408:TIMES', $
		 '\PASSIVESPEC::TOP.IR.IMG2.RAWDATA.IR_408:TIMES' ]
	tags = ['img0_408_times', 'img1_408_times', 'img2_408_times' ]
	addmdstags, shot=128000, nodes=nodes, tags=tags, /verb, /test
   for i=shot1,shot1+499 do addmdstags, shot=i, nodes=nodes, tags=tags, /verb
 NOTES:
       YOU NEED PRIVILEGES to write to the MDSplus tree.
 LIMITATIONS:
	Divide by zeroes, etc. will cause a message like:
	    % Program caused arithmetic error: Floating illegal operand
 MODIFICATION HISTORY:
	27-Mar-2008 Written by Bill Davis.


ADDSIGNODES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       addsignodes
 PURPOSE:
       Add signal nodes and tags to a MDSplus tree for many shots
 PROCEDURE:
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       addsignodes, shot1, shot2, tags=[tag1,tag2,tag3,...]
 INPUTS:
	shot1 = starting shot number to process
	shot2 = last shot number to process
 KEYWORDS:
	tags - tags to add (if defined in the model tree, you
	       will not need to specify the corresponding nodes).
	nodes = if tags are not defined in the model tree, these are necessary
	tree - MDSplus tree
	usage - for MDSTCL node creation. Default='signal'
	VERBOSE  - if set, more info is printed
	test  - doesn't write to MDSplus
 NOTES:
       YOU NEED PRIVILEGES to write to the MDSplus tree.
 LOGIC:
	finds node names for tags. Then, if node names are not different
	than the "tag" names, does not add tags.
 LIMITATIONS:
	all signals must be in the same tree
 MODIFICATION HISTORY:
	11-Apr-07 changed for Linux (add output= to mdstcl)
	13-Jun-02 Written by Bill Davis.


ADDTREETOTAG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       addTreeToTag
 PURPOSE:
       return tags with trees merged in
 CATEGORY:
       MDSplus, SCOPE
 CALLING SEQUENCE:
	names = addTreeToTag( tags, trees )
 INPUTS:
   tags - array of tags, e.g., '\ip1' (if tree already there, will not change)
   trees - array of trees (same dimension as tags)
 RETURNED:
	names - tag names with tree in them, e.g., '\engineering::ip1'
 KEYWORDS:
 COMMON BLOCKS:
       none
 EXAMPLE:
 	IDL> print, addTreeToTag( ['\ip1+\ip2'], ['engineering'] )
	\engineering::ip1+\engineering::ip2
 	IDL> print, addTreeToTag( ['\engineering::ip1.blah+\ip2'], ['engineering'] )      
	\engineering::ip1.blah+\engineering::ip2

 LIMITATIONS:
 MODIFICATION HISTORY:
	30-Apr-01 Written by Bill Davis


BREAKMDSNAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       BreakMDSname

 PURPOSE:
       break an MDS pathname near the middle, if too long

 CATEGORY:
	MDSplus, Strings

 CALLING SEQUENCE:
        newLines = BreakMDSname( line )

 INPUTS:
       line - string containing an MDSplus tag or node name      in

 KEYWORD PARAMETERS:
	MAXLENGTH  - max line length (default 72)  OPTIONAL

 OUTPUTS:
	newlines - string array of MDSplus name broken near middle

 EXAMPLE:
    IDL> line = '\ENGINEERING::OPERATIONS.PC_OH_BR_1_CUR_1'
    IDL> newLines = BreakMDSname( line, MAXLENGTH=25 )

 COMMON BLOCKS:
 NOTES:

 MODIFICATION HISTORY:
	01-Apr-99 Written earlier by Bill Davis


BREAK_PATH

[Previous Routine] [Next Routine] [List of Routines]
 NAME: 
    BREAK_PATH

 PURPOSE: 
     Breaks up a path string into its component directories.

 CATEGORY:
       MDSplus, Strings
 CALLING SEQUENCE: 
     Result = BREAK_PATH( PATHS [ /NoCurrent])

 INPUTS: 
     PATHS   = A string containing one or more directory paths.  The
               individual paths are separated by commas, although in UNIX, 
               colons can also be used.  In other words, PATHS has the same 
               format as !PATH, except that commas can be used as a separator 
               regardless of operating system.

               A leading $ can be used in any path to signal that what follows 
               is an environmental variable, but the $ is not necessary.  (In 
               VMS the $ can either be part of the path, or can signal logical
               names for compatibility with Unix.)  Environmental variables
               can themselves contain multiple paths.

 OUTPUT: 
      The result of the function is a string array of directories.
      Unless the NOCURRENT keyword is set, the first element of the array is 
      always the null string, representing the current directory.  All the 
      other directories will end in the correct separator character for the 
      current operating system.

 OPTIONAL INPUT KEYWORD:
      /NOCURRENT = If set, then the current directory (represented by
               the null string) will not automatically be prepended to the
               output.

 PROCEDURE CALLS:
      Functions:  DATATYPE(), breakstring()

 REVISION HISTORY:
       Version 1, William Thompson, GSFC, 6 May 1993.
               Added IDL for Windows compatibility.
       Version 2, William Thompson, GSFC, 16 May 1995
               Added keyword NOCURRENT
       Version 3, William Thompson, GSFC, 29 August 1995
               Modified to use OS_FAMILY
       Version 4, Zarro, GSFC, 4 August 1997
               Added trim to input
       Converted to IDL V5.0   W. Landsman 25-Nov-1997


CHECKMDSTREE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        checkMDStree
 PURPOSE:
      Check MDS trees, say after a transfer. Produce a file with a 
	list of nodes and checksum of contents of each numerical node or first 
	element of non-numeric nodes.
 CATEGORY:
       MDSplus, Searching
 CALLING SEQUENCE:
       IDL> checkMDStree, tree=tree, shot=shot, outFile=outFile
 INPUTS:
	tree - MDSplus tree. 
	shot - MDSplus shot to search. 
 KEYWORD PARAMETERS:
    Input (Optional):
	server - MDSplus server. Default is the default server for the tree.
	outFile - defaults to tree_nnnnnn_server_list.txt
	remove - if set, removes the tree::top when listing the node name
    Returned (Optional):
	status - status from mdsopen call
 OUTPUTS:
    (Optional):
	outFile - 
	outDir - output dir (DEF='')
 EXAMPLE:
	IDL> checkMDStree, tree='particles', shot=130000, server='lark:8501', /verb

	IDL> checkMDStree, tree='usxr', shot=142000, server='skylark:8501', /verb
 NOTES:
 MODIFICATION HISTORY:
	24-Feb-2011 include any port info into default output filename
	01-Oct-2008 add checksum for Alphanumerics, too.
	29-Aug-2008 Written by Bill Davis, PPPL


CHECKSIG

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
	checkSig

  PURPOSE:
	checks for existence of a signal in MDSplus for current shot and
	optionally declares an event. It can also execute an IDL string when
	it sees  the event. It will then start watching for the next shot.

  CATEGORY:
	MDSplus, Events

  CALLING SEQUENCE:
       IDL> checksig, tree=tree, sig=sig, event=event

  INPUTS:
  KEYWORD PARAMETERS:
    Inputs:
	tree - MDSplus tree (DEFAULT=engineering)
	sig - MDSplus signal to look for in current shot
	event - MDSplus event to declare (DEFAULT=$USER_test)
	logfile - where to write log messages
	pause - seconds to pause between checks (default=10 sec)
	test - if set, will not set event, only print messages
	realVerbose - if set will tell you too much stuff
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
  OUTPUTS:
	none, just printing

  EXAMPLE:
	IDL> checksig, tree='engineering', sig='\fdia', event='bdtest'

	IDL> checksig, tree='engineering', sig='\fdia', /test,/verb, pause=10

	IDL> checksig, sig='\cameras::ph7_1_count',  $
		exec='cinethumbnails, "*nstx_2_*'+strtrim(lastshot(),2)+'*.cin"'
	IDL> checksig, sig='\efit02::r',  $
	     exec='cinethumbnails,findLastFile("/p/nstxcam/Miro2-7988/2010/*.cin")'

  15-Apr-2010 alternately can call an IDL routine [BD]
  13-Apr-2010 increased default pauses [BD]
  WRITTEN by Bill Davis, 01-Apr-2010


CP2JSCOPEFILE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       cp2jScopeFile
 PURPOSE:
       Copy an MDSplus Scope input file to one that will work with jScope
 CATEGORY:
       MDSplus, SCOPE
 CALLING SEQUENCE:
	cp2jScopeFile, fileName, outfile=outfile
 INPUTS:
	filename - name of scope input filename (else will get a dialog box)
 RETURNED:
 KEYWORDS:
 COMMON BLOCKS:
       none
 METHOD:
	insert lines in variable addLines after line 2 of input file
 EXAMPLE:
	   (list files changed within the last 1000 days)
	find . -name "*.scope" -mtime -1000 -print > dirls.txt
	find . -name "*.dat" -mtime -1000 -print >> dirls.txt
	idl
	IDL> files = read_list('dirls.txt')
	IDL> for i=0,n_elements( files )-1 do $
	IDL>    cp2jScopeFile, files[i], outDir='/p/nstxusr/util/jscp'
	IDL> 
 NOTES:
 LIMITATIONS:
 MODIFICATION HISTORY:
	06-Apr-2010 debugged.
	03-Nov-2009 Written by Bill Davis


EVENTSPAWN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	eventspawn
 PURPOSE:
       When a designated MDSplus event is detected, spawn an IDL procedure, 
	first killing any versions that are running.
 CATEGORY:
       MDSplus, Program Control
 CALLING SEQUENCE:
	IDL> eventspawn, event=event, procedure=procedure, server=server, $
                        immediate=immediate, display=display
 INPUTS:
       none required, but procedure is probably necessary
 KEYWORD PARAMETERS:
    Keywords:
	event - MDSplus event to wait for (default to NSTX_ACQ_DONE
	procedure - file to pass to idl batch command (default is batchmyidl.pro)
	ASCII - if set, will assume data block contains ascii representation of numbers
	server - MDSplus event server (default is europa.pppl.gov:8501)
	immediate - if set, execute procedure even before waiting for event
	display - X display to send IDL graphics to.
 OUTPUTS:
       none
 EXAMPLE:
	IDL> eventspawn, pro='/u/bdavis/RFcam/batchrfmovie', $
			event='RFcamera_loaded', display='nstxwindowspc:0', /immed
 LIMITATIONS:
	currently, no arguments can be passed to IDL command.
	only works on Unix/Linux.
 NOTES:
	see /u/bdavis/RFcam/batchtedmovie.pro as example of routine to call.
	shot numbers must be accessed in the calling programs via LASTSHOT()
	or an environmental variable.
 MODIFICATION HISTORY:
	09-Mar-2007 Added ASCII keyword which is needed on sflip PC
	15-Aug-2005 written by Bill Davis


FILEONEVENT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	fileOnEvent
 PURPOSE:
       When a designated MDSplus event is detected, write a file containing a shot 
	number, first deleting existing file.
 CATEGORY:
       MDSplus, Program Control
 CALLING SEQUENCE:
	IDL> fileOnEvent, event=event, file=file, server=server,
 INPUTS:
       none required
 KEYWORD PARAMETERS:
    Keywords:
	event - MDSplus event to wait for (default to NSTX_ACQ_DONE
	server - MDSplus event server (default is europa.pppl.gov:8501)
	file - default to 'E:/pulse.ini'
 OUTPUTS:
       none
 EXAMPLE:
	IDL> fileOnEvent,  event='bdtest', file='bdfile.txt'

 LIMITATIONS:
 NOTES:
 MODIFICATION HISTORY:
	23-Aug-2010 written by Bill Davis for Doug Darrow


FINDMDSNODES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        FindMDSNodes
 PURPOSE:
      Search for MDSplus nodes or tags with a name containing a string
 CATEGORY:
       MDSplus, Search, Utiltiy
 CALLING SEQUENCE:
       IDL> paths = FindMDSNodes( nodeString, status=status )
 INPUTS:
       nodeString - string to search nodenames for
 KEYWORD PARAMETERS:
	nonNodeString - exclude nodes in returned array if this string found in name
	tags - if set, just look for nodes with tags, and search tagnames
	Scalars - if=0, then only return nodes with more than one data element
       JustText - if set, just look for Text nodes (no effect if /TAGS set)
	usage - if /TAGS not set, what GETNCI expects 
		(if used, overrides /JustText; DEFAULT: ANY)
	max2find - max # of nodes returned (DEFAULT=10000)
	status - success if true (odd number)
	debug - print some debugging info

  the tree may be opened before this routine is called, or you can specify:
	treeName - MDSplus tree. Default='NSTX' (unless embedded in nodeString)
	shot - MDSplus shot to search. Default=-1 (the model tree).
   returned:
	states - string array containing 'OFF' or 'ON'.
	isSignal - logical array where 1s indicate corresponding node is a signal
	COMPRESS_ON_PUT - logical array
	PARENT_STATE -    logical array
	NUMERIC -         logical array
	NO_WRITE_MODEL -  logical array
	NO_WRITE_SHOT -   logical array
 OUTPUTS:
	paths - paths satifying search criteria
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> paths = FindMDSNodes( 'ip', status=status, tree='wf', shot=120200 )
	IDL> tags = FindMDSNodes('*', /tags, tree='lrdfit04', shot=117747)
   	    ; exclude some nodes:
	IDL> paths = FindMDSNodes( 'ip',non='formula', tree='wf', shot=120200 ) 
	IDL> paths = FindMDSNodes( 'ip',non=['formula','description'], tree='wf', shot=120200 ) 
    	IDL> p = FindMDSNodes( 'svd', tree='engineering', shot=142039)

 NOTES:
	if tree already open before FindMDSNodes is called, tree & shot need not be set.
	if no records are found in current tree, returns ['']
 LIMITATIONS:
	If connect to VMS, will not get tags from trees on Linux.
 MODIFICATION HISTORY:
	08-Mar-2013 with tree NSTX, must be too many returned when getting all, so use 
		    nodestring in filter.
	04-Oct-2012 try with more stars for searches like from engineering tree with
		    'svd'
	06-May-2010 never check more than 2000 nodes for being a signal (too slow)
	21-Apr-2010 added keyword max2find 
	20-Apr-2010 added keyword isSignal & checkSignals
	08-May-2009 If /tag set and no tree, use getenv('MACHINE'), and if empty, use
		    'nstx'.
       16-Mar-2009 add Sclars keyword
	02-Feb-2009 have to spawn MDSTCL and read it's commands from a file
		    for big results, like searching for '*' in operations.
	19-Jan-2009 don't return names that are blank or have spaces in them
	02-Dec-2008 added STATES keyword to return 'OFF' or 'ON'
	09-Jan-08 fintags.fun not on Linux, so don't use. 
		  nonNodeString can be an array of strings
	22-Nov-06 use MDSTCL for tags on Linux trees. Use mdsopen, instead of
		  openMDSshot, and only if tree not entered
	11-Nov-05 Added keywords for use with new treesearch web page.
	31-Jan-01 Written by Bill Davis, PPPL


FINDMDSTIME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       findMDStime
 PURPOSE:
        find a time within an MDSplus shot, correspoding to
	 the time of Max Ip, time of Max W-tot, etc. 
	signals come from the EFIT tree when possible.
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> time = findMDStime( /maxIp )
 INPUTS:
       shotListString - a string indicating shots, 
		e.g., 107694 108305 108330-108350
		 or   108100+20		
			(this returns shots 108100, 108101,...,108120)
       nshots - # of shots to search over (def=10)
 KEYWORD PARAMETERS:
	maxIp - if set, return time of Max Ip (less 3 msec)
	MaxNeutrons - if set, return time of Maximum Neutron production
	MaxBetaN - if set, return time of Beta Normal 
	MaxPTot - if set, return time of maximum heating power
	MaxWMHD - if set, return time of maximum Plasma Stored Energy
	MaxTAUMHD - if set, return time of maximum Energy confinement time
	MaxDENS - if set, return time of maximum Line Density
	shot - if set, will return value for this shot, else for opened shot
 OUTPUTS:
       time in seconds         			
 EXAMPLE:
	IDL> time = findMDStime( /maxIp )
 NOTES:
	if more than one time is found for the max, a median time will be
	returned.
 MODIFICATION HISTORY:
       14-Jun-02 Written by Bill Davis, PPPL


FINDVALIDSHOTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       findvalidshots
 PURPOSE:
	Search MDS Plus Trees for valid shot numbers with data in a 
	particular node
 
 CATEGORY:
       MDSplus, Utility
 CALLING SEQUENCE:
       IDL> findvalidshots ; This is interactive widget version
 or    IDL> findvalidshots, signal,beginshotnumber,endshotnumber
 
 INPUTS:
       none 
 KEYWORD PARAMETERS:
       none
 OUTPUTS:
       on screen: valid shot numbers in entered range               			
 COMMON BLOCKS:
       none
 EXAMPLE:  IDL>findvalidshots, '\passivespec::vs2.rawdata:spectra',104500,104515

 NOTES:
       
 MODIFICATION HISTORY:
	01-Oct-2008 Removed mdsconnect [BD]
       4-JAN-2001 Written by Dana Mastrovito, PPPL


FIRSTSIGNAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       firstSigName
 PURPOSE:
       Return the first signal name in a TDI expression.
	Needed when you want the xaxis from a combination of signals.
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
	sig1 = firstSigName( TDIexpr )
 INPUTS:
   	TDIexpr - TDI expression. Can be just a signal name, or '(\ip1+\ip2)/2'
 RETURNED:
	sig1 - first signal name in TDI expr, e.g., '\ip1'
 KEYWORDS:
    Optional Outputs:
	FOUNDTDI - 1 returned if TDI in node
	DIMENSION - if root node is 2-D, but expression limits to 1.
	SECOND - the second signame name in the expression, if any (else '')
    Optional Inputs:
	DATA = if set, return everything from DATA to ']', if present, or
	       to ')'
 COMMON BLOCKS:
       none
 EXAMPLE:
 	IDL> print, firstSigName( '\engineering::ip1+\engineering::ip2' )
	   \engineering::ip1
 LIMITATIONS:
	probably won't return proper dimension when DATA() is within a TDI function, 
	like BCSMOOTH( data( \camera:image, 1) )
 MODIFICATION HISTORY:
	31-Aug-2007 added keyword SECOND
	19-Jun-2007 ONLY return dimension number from syntax like ",1" if 
		    MAXVAL, MINVAL or DATA (others can be included here).
	06-Apr-2007 Added data and dimension keywords 
  		    to handle style of maxval(\efit01::pisrz,1) and 
		    data(\efit01::pisrz)[10,*] )
	01-May-01 Written by Bill Davis


FITSRUN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       FITSRUN
 PURPOSE:
       Quickly tell which EFITs and LRDFITs exist for an MDSplus shot
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> fits=fitsrun(shot)
 INPUTS:
       shot - NSTX shot number 
 KEYWORD PARAMETERS:
       maxefits= MAX efits to check 
       maxlrdfits - max lrdfits to check
       quiet - if set to 0, will tell you about each open
       realquiet - if set to 0, will tell you about failed opens
	needSig - a node that you need in the tree to use that tree
		DEFAULT='\CODE_VERSION'
 OUTPUTS:
       fits - string array like  ['EFIT01', 'EFIT03', 'LRDFIT04']
 EXAMPLE:
	IDL> print,fitsrun(117707, maxefits=5, maxlrdfits=5)
	EFIT01 EFIT02 EFIT03 EFIT04 EFIT05 LRDFIT04

	IDL> for i=122440,123244 do print, i,' ',fitsrun(i,loadfit='EFIT03')

	IDL> fits = fitsrun( 130000, run_by=user, /noLoad )

	IDL> fits = fitsrun( 129125, run_by=run_by, comments=comments, $
	                     code_version=code_version, date_run=date_run )
 NOTES:
       When the routine is called with no parameters, 
	help information is printed.

	To load fits into the code_rundb database used by EFIT and other codes, 
	see fit_run_loader.pro

 MODIFICATION HISTORY:
	15-Jan-2015 add checks for efitrt, efitrt_dev, efitrt_ga, efitrt_test
	11-Dec-2012 don't let comments be integer (0)
	17-Aug-2010 added needSig keyword
  	22-Jun-2010 added comments, code_version, and date_run keywords [BD]
	02-Feb-2010 Added noLoad & run_by keywords
	25-May-2007 Just look in EFIT tree for all possible subtrees
	12-Apr-2007 Option to load fits into code_rundb database (for efitviewer)
       07-Mar-2006 Written by Bill Davis, PPPL


FOUNDSUBTREE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       foundsubtree
 PURPOSE:
       determine if sub trees like efit05, lrdfit06, etc. exist
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> found = foundSubTree( shot=shot, tree=tree, index=index)
 INPUTS:
       none but keywords 
 KEYWORD PARAMETERS:
	shot - MDSplus shot/pulse number
	tree - main fit tree, e.g., 'EFIT' or 'LRDFIT'
	index - "subtree" version number, 5 would get you 'EFIT05' or 'LRDFIT05'
	SERVER - MDS server (default is skylark.pppl.gov:8501 for NSTX)
    RETURNED:
	status - MDS status from open if failed, else from mdsvalue
 OUTPUTS:
       found - 1 if found, 0 if not found.
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> print, foundsubtree(shot=117449, tree='efit', index=2 )

 MODIFICATION HISTORY:
       26-Jun-2006 Written by Bill Davis, PPPL


FULLMDSPATH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       fullMDSpath
 PURPOSE:
       Return an MDSplus path for a tag
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       fullpath = fullMDSpath( tag, shot=shot )
 INPUTS:
       MDSplus tagname
 KEYWORD PARAMETERS:
	shot - if present, will open NSTX tree for this shot
 OUTPUTS:
	fullpaths - returns full pathnames of tags found
 EXAMPLE:
	IDL> mdsopen, 'edge', 129850
	IDL> print, fullMDSpath('\BE_H908_01')
       \EDGE::TOP.BEAP.RAWDATA:BE_H908_01

 NOTES:
       Only returns signals with data in them.
 LIMITATIONS:
	An MDSplus shot file must be open first.
 MODIFICATION HISTORY:
	17-Jun-2008 use tree in tagname, if present. Add tip, if not found.
	14-Mar-00 more efficient & added keywords [BD]
	20-Jan-00 Written by Bill Davis


GETMDSLABEL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:  
	getMDSlabel
 PURPOSE: 
	return a label for an MDSplus signal. If there is a :LABEL sub-node,
	use that string, else if there is a :COMMENT sub-node, use that, else
	return the MDSplus signal name.
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
	IDL> (the tree has to be opened)
       IDL> label=getMDSlabel( signal, textNode=textNode, FOUNDTDI=foundTDI, $
                      status=status, /quiet, /fullPath )
 INPUTS:
       signal - mdsplus signal or tag name (shot must be opened)
 OUTPUT:
       label - contents of :LABEL substring, if found. Otherwise the
		signal name is returned (just the last two elements, unless
		/fullPath set)
 KEYWORD PARAMETERS:
    Optional Inputs:
	quiet - just passed to mdsvalue
	fullPath - if set, return fullpath if no :LABEL subnode found
    Optional Outputs:
	textNode - 1 returned if a text node
	FOUNDTDI - 1 returned if TDI in node 
	status - if odd, successfull
 NOTES:
       The relevant MDSplus tree must be open for this routine to work.
 MODIFICATION HISTORY:
	01-Jun-01 Also look for :COMMENTS sub-node. 
	11-Mar-01 if no :LABEL node, look for :COMMENT node
       15-Feb-01 Written by Bill Davis, PPPL


GET_NEBAR

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
       get_nebar

  PURPOSE:
  	Get Ne Bar (line-averaged plasma density at the midplane) from
   	Multi-point Thomson Scattering data and EFIT gap data.

  CATEGORY:
       MDSplus, Density
 
  CALLING SEQUENCE:
	nebar = get_nebar( shot, time=time )
  INPUTS:
	shot1 = starting shot number to process
  KEYWORDS:
    (Optional)
	efit - #. Defaults to 2
	time - time base of output (sec). Probably on the MPTS timebase

  EXAMPLE:
	IDL> nebar = get_nebar( 138846, time=time )

  NOTES:
	This has not been verified by the MPTS Cognizant Physicist

  HISTORY:
	08-May-2014 fixed bug in goodTimes determination
	WRITTEN 23-Jul-2013, by Bill Davis for Stewart Zweben


GETSCOPENAMES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       getScopeNames
 PURPOSE:
       return signal names and plot settings from an MDSplus Scope input file
 CATEGORY:
       MDSplus, SCOPE
 CALLING SEQUENCE:
	names = getScopeNames( fileName, titles=titles )
	names = getScopeNames()	; will get a dialog box
 INPUTS:
   Optional:
	filename - name of scope input filename (else will get a dialog box)
 RETURNED:
	names - Array of signal names, including TDI, (Y values)
	        if nothing found, will return a '-1'
 KEYWORDS:
   (All Optional) Returned:
	Titles - string array of the plot titles from the scope file, else y-name
	xMins - array of each plot's x-minimum from the scope file (else global, or 0)
	xMaxes - array of each plot's x-maximum from the scope file (else global, or 0)
	yMins - array of each plot's y-minimum from the scope file (else global, or 0)
	yMaxes - array of each plot's y-maximum from the scope file (else global, or 0)
	nCols - # of columns for plot
	nRows - (array) # of rows in each column for plot
   Optional inputs:
	stripTitles - if set, remove double quotes and everything after //
	noEqualSigns - if set, remove equal signs (=)
	addTrees - if set, add trees into signals
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
 NOTES:
 LIMITATIONS:
	For jScope files, won't handle 2 signals on a single frame
 EXAMPLES:
	IDL> file = 'wfplus.scope'
	IDL> SigNames = GetScopeNames( file, titles=titles, yMins=yMins, yMaxes=yMaxes, $
	IDL>                         	xMins=xMins, xMaxes=xMaxes, xNames=xNames, $
	IDL> 				nRows=nRows, nCols=nCols, /addTrees )

	IDL> file = '/p/nstxusr/util/jscp/wfplus.jscp'
	IDL> file = '/p/nstxusr/util/jscp/EAST_Mag_probes.jscp'
	IDL> names = getScopeNames( file, TITLES=titles, yMins=yMins, yMaxes=yMaxes )

 MODIFICATION HISTORY:
	21-Jan-2015 fixed logic on newExt
	14-Feb-2014 ignore sets of 3 vertical bars after Y-signal names
	12-Feb-2014 added jScope keyword, so don't have to rely on .jscp 
			ext
	22-Apr-2010 made to work with jScope input files (ext .jscp) (and with files
		    with blank lines in header lines)
	23-Jun-2008 added nRows and nCols keywords.
	22-Mar-2006 revised xName logic when some there and some not.
	27-Jan-06 add xNames keyword for specied X values.
	19-Oct-01 if file not found, try other versions of name
	13-Sep-01 Added addTrees keyword
	17-Mar-01 default directory on Unix to /p/nstxusr/util/scopes/
	02-Mar-01 added x & y mins and maxes
	11-Jan-01 Written by Bill Davis


GETTREES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       gettrees

 PURPOSE:
       Return subtree or subnode names from an MDSplus tree

 CATEGORY:
       MDSplus

 CALLING SEQUENCE:
       IDL> opt = gettrees(shot)

 INPUTS:
       shot = NSTX shot number (Default=-1)
	
 KEYWORD PARAMETERS:
    Inputs:
	topTree - tree to start (Default='NSTX')
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	status - if odd, then success

 OUTPUTS:
       trees = MDSplus trees

 EXAMPLES:
	IDL> trees = gettrees( )

	IDL> subtrees = gettrees(top='passivespec')

 NOTES:

 MODIFICATION HISTORY:
       20-Oct-2013 Written by Bill Davis, PPPL


GOOD_IP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       good_ip

 PURPOSE:
       Determine if plasma current (Ip) was good for a shot and, optionally
	declare an event.

 CATEGORY:
	MDSplus, Shot Number, Plasma Current

 CALLING SEQUENCE:
        nextShot = good_ip( shot )

 INPUTS:
       shot - shot number

 KEYWORD PARAMETERS:
    Inputs:
	goodValue - value required for tag for next good shot (default=30000 Amps)
	event     - if non-blank, will be declared if plasma current > goodValue
	Server 	  - MDS server (default is NSTX)
	TagToUse  - Tag to use for IP check (default to \OPERATIONS::CAL_IROGEVVUL1)
	IPforGood - alternate to goodValue (for compatibility with old routine)
	Verbose   - if set, print debugging information
    Returned:
	IpTime - time of good plasma current in seconds.
 OUTPUTS:
	1 or 0
 EXAMPLE:
	IDL> ipOK = good_ip( shot, goodValue = 100. )
 COMMON BLOCKS:
 NOTES:
 	if TagToUse not specified, will try to use in the following order:
	  1) \ENGINEERING::IP1UNC
	  2) \ENGINEERING::PPCC_IP1
	  3) \WF::IP
	if SigUnits from MDSplus begins with 'K' will mult. by 1000. If it 
	begins with an 'M' will mult. by 1000000.
 RESTRICTIONS:
 MODIFICATION HISTORY:
 	Written by Bill Davis March, 2006


LASTMDSSHOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       LastMDSshot
 PURPOSE:
       get the last (current) MDS shot
 CATEGORY:
	MDSplus
 CALLING SEQUENCE:
       currentShot = LastMDSshot()
 INPUTS:
       none
 KEYWORD PARAMETERS:
	SERVER - MDS server (default is NSTX)
	MACHINE - machine (default is NSTX)
 OUTPUTS:
	currentShot - current shot number
 EXAMPLE:
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	30-Jan-2015  return status
 	25-Feb-99 BD added way to get current shot from either VMS or UNIX
		default to NSTX
 	11-Dec-98 BD added MDSplus access for shotnumber, if on VMS at PPPL
 	01-Dec-98 BD use fas_dir and Mk_Filename for filename lookup
 	5/14/98 changing USER directory to BE1 etc [PR]


LEAFNAME

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       LeafName
 PURPOSE:
       Return leaf name from MDSplus pathname(s)
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> leaf = leafname(mdspath)
 INPUTS:
       mdspath - MDSplus path string.  
 OUTPUTS:
       leaf - MDSplus leaf node string (last signal in multi-signal TDI)
 KEYWORDS:
	Delim - delimiter (default is ':')
	Tree  - returns tree of input (last signal in multi-signal TDI),
		or environmental variable 'MACHINE' if Signal Math TDI used
		on signals from more than one tree
	AllTrees - all trees in input path
	Prefix - returns everything before the leafname
	nParts - # of parts to return, counting from the end (default=1, 
			max of 2)
	BRACKETSTR - (1st) square bracket clause, as in an array subscript
 COMMON BLOCKS:
       NONE
 EXAMPLE:
       IDL> print,leafname('\JMENARD_DAY1::TOP.FLUX_LOOP.FLUX:FFLPF1BL')
		FFLPF1BL
       IDL> print,leafname('\wf::ip')
		ip
	IDL> print,leafname('TOP.FLUXLOOP.FLUX.CALIBRATION',delim='.')
		CALIBRATION
 NOTE: 
	for multi-signal TDI, will return the leaf name of last signal, as well as the
	last tree.
 MODIFICATION HISTORY:
	23-Nov-2010 fixed bug introduced 15-Oct with defaulting to '::' delimiter
	15-Oct-2010 fixed bug using 2-char delimiter
	30-Sep-2010 set delimiter to '::' and don't return '-1' in allTrees
	26-Oct-07 Ignore square bracket clauses (but return in keyword BRACKETSTR)
	16-Aug-07 return last tree for multi-line TDI
	06-Aug-07 fix bug where no backslash in name
	11-Jul-07 return all tree names in ALLTREES keyword. 
		  If sigadd, sigmult, etc., used with more than one tree, 
		  return 'NSTX' in TREE keyword
	
	11-Jan-01 Remove comma and anything after, and ')' if TDI
	28-Nov-00 Don't return tree name with '\'
       23-Jul-99 Written by Bill Davis, PPPL


LISTSHOTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       ListShots
 PURPOSE:
	List shot numbers with signal over/under a certain amount
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> listshots, shot, nshots,  signal=signal, warningLevel=warningLevel
 INPUTS:
       shot - if an interger: beginning shot # to search for 
		if an array of integers, use as a shot list (ignore nshots)
       nshots - # of shots to search over (def=10)
 KEYWORD PARAMETERS:
    Optional Inputs:
	comparator - 'GT' (default) or 'LT' for cutoff and warning
	cutoff - value under which value will be ignored
	outFile - outFile for output
	nSmooth - # for median smoothing before using signal (default=0)
	noScreen - if set, do not echo output to screen
	server - MDSplus server, default='EUROPA.PPPL.GOV:8501'
	signal - mdsplus signal name
	skip - shots to skip while looping through list
	warningLevel - warn if greater than than this value
    Optional Returned:
	count - number of shots satisfying criteria
 OUTPUTS:
       just to screen and/or file           			
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> listshots, 102915, 10,  signal='\WF::IP', warn=1.0
 NOTES:
       tree should be in signal name
 MODIFICATION HISTORY:
	17-Apr-2008 Made > 0 not return zero values
	04-May-2006 changed openMDSshot to mdsopen
	03-Mar-04 a little bullet proofing
	23-May-01 Written by Bill Davis, PPPL


LOAD_NEBAR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       load_nebar

 PURPOSE:
       Load Ne-bar Waveform into MDSplus.

 CATEGORY:
       MDSplus, Density 

 CALLING SEQUENCE:
       load_nebar, shot1, shot2

 INPUTS:
	shot1 = starting shot number to process
	shot2 = (Optional) last shot number to process

 KEYWORDS:
    (Optional)
	test  - doesn't write to MDSplus
	wfTree - name of MDSplus tree to write to (defalut='WF')

 NOTES:
       YOU NEED PRIVILEGES to write to the MDSplus tree.

 LIMITATIONS:
	Divide by zeroes, etc. will cause a message like:
	    % Program caused arithmetic error: Floating illegal operand

 MODIFICATION HISTORY:
	WRITTEN 23-Jul-2013, by Bill Davis for Stewart Zweben


MDIR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdir
 PURPOSE:
       Directory listing of MDSplus data files with wild cards
 CATEGORY:
       MDSplus, files
 CALLING SEQUENCE:
       IDL> list = mdir(shot, tree=tree)
 INPUTS:
       shot - shot number (defaults to 0). Can be a character string
		with wildcards.
       tree - an MDSplus e.g. 'operations' (defaults to 'wf')
 KEYWORD PARAMETERS:
   inputs:
	tree - an MDSplus e.g. 'operations' (defaults to 'wf')
 	dataroot - file system root for MDSplus data (default = '/nstxdata')
	extension - extension of file wanted, default = 'datafile'
	server - MDSplus server for data, if not set will use 
	denied - if set, will not return permission-denied messages
	nDigits - when trying to extract a shot number from a filename, assume
		  this number of digits.
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
   outputs:
	allShots - tries to extract shot number from all files.
	date - dates of files found
	ctimes - creation times of files found
	files - actual file names found
 OUTPUTS:
       list - list of data files found
 EXAMPLE:
	IDL> print, mdir( '13000*', tree='wf' )

	IDL> list = mdir( '555555*', tree='engineering', date=date)

	IDL> result = mdir( '9??????', tree='mptscalib', date=date, allshots=shots, $
			    nDigits=7, files=files, /verbose, /debug )
	     (the above took 18 minutes!)
 NOTES:
	if on a system with a /nstxdata directory, will spawn "find" 
	otherwise, you will have to enter your password to ssh into the server.
	You may also have to respond "yes" to a question about connecting.
	You must have the same username on the server as the machine you are on.

	You may, instead, use tree_exists.pro, which is slower.

	If you get tired of entering your password when looking for data on a 
	remote host, see http://w3.pppl.gov/~bdavis/swdoc/SSH_login_without_pw.txt
 MODIFICATION HISTORY:
	03-Mar-2010 parse server name from environmental variable for remote access
	19-Nov-2009 Tidied up, added keywords, let shotstring work with wildcards.
	27-Mar-2009 Added ctime output for Creation time, e.g. "Mar 19 14:37" or
			"May 19 2005"
	18-Mar-2009 Added date keyword [Bd]
	15-Nov-2008 Written by Bill Davis, PPPL


MDSDATAVSSHOT

[Previous Routine] [Next Routine] [List of Routines]
   NAME:
	MDSdataVsShot

  PURPOSE:
	Print single values of MDSplus signals vs. shot number.
	The value can be the max or min, or at a specific time, including
	time of Max Ip, Max Neutrons, etc. The shot list may be reduced
	by certain qualifiers, such as to shots where the max of an 
	arbitrary signal is > a given value.
	Output can be in a format suitable for importing into
	Kaleidograph, Excel, etc.

  CATEGORY:
       MDSplus, Output

  CALLING SEQUENCE:
	MDSdataVsShot, shot, nshots, signal
  INPUTS:
	MDStree - e.g. 'operations'. Default is 'NSTX'
	shot - MDSplus shot number, i.e, ID.
	signal - a single MDSplus signal name, or array of names.
		(ignored if Keyword "Scope" is present.)
  OUTPUTS:
	none returned
  KEYWORDS:
    (all Optional)
	format - output format. Defaults to '(100(g15.6, a1))' 
		 (a tab or space is written between the columns)
	tabs - if set, columns will be separated by tabs instead of spaces
	headings - if set, the signal labels are at the top of each column
		   in row 1.
 	scope - if present, gets the signal names and column titles from 
		this scope file.
		(if present, the signal input is ignored). THIS SHOULD BE
	        THE FULL PATHNAME OF THE FILE, or it will default to general
		areas.
	status - 1=OK, 0 means shot, signal, or scope file weren't found.
	units - if set, will append units to headings
	WhatToList - 'MaxValues', 'MinValues', 
		(time of the following:) 'MaxNeutrons', 'MaxIP', 'MaxBetaN',
		'MaxDENS', 'MaxWMHD'
  EXAMPLES:
  LIMITATION:
  HISTORY:
	11-Feb-05 bug fix for when 1 dimension of 2-d array smaller than nsmooth
	04-Jun-04 Bug fix when lots of bad shots
	04-Nov-02 default to skipping a shot if any requested signal missing
	Written 17-Jul-02 by Bill Davis at the request of Steve Paul


MDSDAT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	MDSDAT

 PURPOSE:

	"replacement" for gadat.pro. Get MDSplus signal data without
	having to open a tree (much faster, if a tree is specified)

 CATEGORY:
	MDSplus

 CALLING SEQUENCE:

	mdsdat, X, Y, signame, SHOT [,err=ERR] [,debug=DEBUG]		$
                                   [,xmin=XMIN] [,xmax=XMAX]		$
                                   [,npts=NPTS] 
 KEYWORDS: (all are optional)

    INPUT/OUTPUT keywords:

      NPTS:  (INPUT) Number of samples to return.  Defaults to 64K.
             Cannot exceed 64K (if it does, it is set to 64K).

             (OUTPUT) Number of samples actually returned.

    INPUT KEYWORDS:

      DEBUG:  If set (ie. called as gadat,/debug), debug printouts on 
              the progress of gadat are reported


      XMIN:  specifies the "start" time for the time window within
             which to return the data.  Specify the time in
             milliseconds.  If not set, defaults to -10000 ms.

      XMAX:  specifies the "end" time for the time window within
             which to return the data.  Specify the time in
             milliseconds.  If not set, defaults to 100000 ms.
      XUNITS - if non-zero, return units of x-axis		out
      YUNITS - if non-zero, return units of y-axis		out
      ALWAYSOPEN - always open the tree (for when other opens or MDSconnects are done)

    OUTPUT KEYWORDS:

      ERR:  PTDATA/MDSplus error code.  0 = success, anything
            else = failure

      PLABEL:  plot label for pointname

 OUTPUTS: 

    X:  The time base of the requested pointname in seconds

    Y:  Data from the requested signal name.  See keywords NPTS and
        A_NPTS for details on the number of samples returned.

 EXAMPLE:
	IDL> mdsdat, iptime, ip, 'wf::IP', 120200
	IDL> mdsdat, efittime, ipmeas, 'efit01::IPMEAS', 120200
	IDL> 
 COMMON BLOCKS: 
	MDSDAT_LOCAL

 SIDE EFFECTS: 

 RESTRICTIONS:

 MODIFICATION HISTORY:
	07-May-2008 added /AlwaysOpen keyword for when other opens or MDSconnects are done
		    outside of mdsdat.  This will make it slower.
	04-Feb-2008 Written by Bill Davis


MDSDECLAREEVENT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSDeclareEvent

 PURPOSE:
       set an MDS event with shot number associated with the event

 CATEGORY:
       MDSplus, Events

 CALLING SEQUENCE:
       IDL> MDSDeclareEvent, eventName [, shot_num]

 INPUTS:
	eventName - string of MDS event name, e.g., 'NE_DENSITY_CALC'
       shot_num - NSTX shot number (OPTIONAL -- will default to current shot)

 KEYWORD PARAMETERS:
    Optional:
	VERBOSE - If set, print debugging information
	NOCONNECT - if set, will not try to connect to an MDSplus server

 OUTPUTS:
       none -- just sets the event
 COMMON BLOCKS:
       NONE
 EXAMPLE:
 NOTES:
	Works from Unix or VMS
 MODIFICATION HISTORY:
	11-Feb-04 use SETEVENT in MDSVALUE on Unix. Add connect option on unix.
   	20-Dec-99 Written [bd]


MDSEDITBRANCH

[Previous Routine] [Next Routine] [List of Routines]
  NAME:
       MDSeditBranch
  PURPOSE:
       Read a branch of MDSplus values, allow editing of scalar values 
	in a widget and write back out.
  CATEGORY:
       MDSplus
  CALLING SEQUENCE:
       MDSeditBranch, shot=shot, tree=tree, branch=branch
  INPUTS:
      
      
  KEYWORD PARAMETERS:
    Inputs:
	shot - shot number to edit
	tree - MDSplus treename to edit (DEF='cameras')
	branch - branch of tree to edit values in (DEF=".FC_1.SETTINGS")
	cautions - array, where, if=1, will warn user about changing (not implemented)
	order - if =0 will order inputs by Integers, reals & then strings
	comments - tips, to go after fields (not implemented)
	ignore - array, where, if=1, will not present that element for editing
	ncols - # of columns in display
	title - title of widget
	maxPerCol -   
	maxFieldSize - if not present, takes reasonable defaults
	nInFirstCol - 
	debug - if set, prints debug info and stops in a few places
	verbose - if set, prints information messages 

  OUTPUTS:
       NONE unless user chooses to write new values to a tree
	(user must have priviledges to write to tree)

  EXAMPLE 
	
     setenv cameras_path /u/bdavis/TCLcode
     idl
     IDL> MDSeditBranch, 142000, tree='cameras', branch='.FC_1.SETTINGS', $
			  ignore='BACKIMAGE'

  NOTES:
	For text nodes, you can enter \n for a new line

  MODIFICATION HISTORY:
       27-Mar-2010 Written by Bill Davis, PPPL


MDSEVENTWAIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdseventwait
 PURPOSE:
       Widget to Wait for an MDSplus event, 
	or the user clicks the CANCEL button.
 CATEGORY:
       MDSplus; Event Widgets
 CALLING SEQUENCE:
       IDL> shot = mdseventwait( someEvent, cancel=cancel )
 INPUTS:
       someEvent - (string) an MDSplus event (defualts to 'nstx_acq_done')
 KEYWORD PARAMETERS:
    Optional:
	cancel - if user hits cancel button, cancel = 1 (& shot=-1), else 0
	group_leader - higher level widget to place this on top of 
 OUTPUTS:
       shot - shot # (data) set like: IDL> setmdsshotevent,'dum',999999
 COMMON BLOCKS:
       NONE
 EXAMPLE:
 RELATED ROUTINE:
 NOTES:
	Only works on X.
 MODIFICATION HISTORY:
	29-Aug-00 Written by Bill Davis for David Swain


MDSGETSIG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSGETSIG
 PURPOSE:
       Get a signal, units and axes values easily from MDSplus
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       d = MDSGETSIG( signal, SIGUNITS=fUnits, XAXIS=time, XUNITS=timeUnits)
 INPUTS:
      signal - MDSplus Signal name
 KEYWORD PARAMETERS:
       Keywords:
	    SIGUNITS - if non-zero, return units of signal		out
	    XAXIS    - if non-zero, return array of x-axis		out
	    XUNITS   - if non-zero, return units of x-axis		out
	    YAXIS    - if non-zero, return array of y-axis		out
	    YUNITS   - if non-zero, return units of y-axis		out
	    ZAXIS    - if non-zero, return array of Z-axis		out
	    ZUNITS   - if non-zero, return units of Z-axis		out
	    status   - if non-zero, return status (1=OK)		out
 OUTPUTS:
       d - 1- or 2-D data                 				out
 COMMON BLOCKS:
       NONE
 EXAMPLE 
	MDSCONNECT, 'yourhost.pppl.gov:8501'
	MDSOPEN, 'testtree', 10
	sig = 'onedim'
	data = MDSGETSIG( signal,SIGUNITS=fUnits, XAXIS=time,XUNITS=timeUnits )'
	PLOT, time, data, XTITLE = timeUnits, YTITLE = fUnits,  $
		TITLE = signal + ' - shot ' + STRTRIM( STRING(shot), 2 )
 NOTES:
	If something like x units were NOT stored for the signal, and they are
	asked for, IDL will complain about an access violation, but continue.
	When signals are TDI combinations of others, use the
	units and xaxis from the first signal (could be erroneous)
 MODIFICATION HISTORY:
	10-Aug-2009 Check for data being a number (not '*') when taking min & max
	23-Jun-2008 when finding Xunits of a signal like dim_of(\...), use it
	13-May-08 handle \rf::refl_avgdens[*,33]
	26-Oct-07 handle 2-D square bracket clauses, as in an array subscript
	31-Aug-07 made xAxis work when SigMath TDI used
	06-Apr-07 made work for 'maxval(\activespec::chers_best:vt,1)'
	03-Jun-05 Added Z data
	01-May-01 When signals are TDI combinations of others, use the
		  units and xaxis from the first signal (could be erroneous)
	11-Nov-99 test for input signal name not defined
	10-Aug-99 Use Arg_Present so don't have to set keywords before call
	26-Jan-99 Trim trailing blanks from unit strings [BD]
	13-Jan-99 Written by Bill Davis, PPPL


MDSLARGESTNODE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdsLargestNode

 PURPOSE:
       find largest node in a tree

 CATEGORY:
       MDSplus

 CALLING SEQUENCE:
       IDL> size = mdsLargestNode( tree, searchStr, shot=shot,  $
					biggestSig=biggestSig )

 INPUTS:
       tree - MDSplus tree. Defaults to 'PCS'
    optional:
	searchStr - what to use to search for nodes. Defaults to '*'

 KEYWORD PARAMETERS:
    Inputs:
       shot = NSTX shot number (defaults to latest shot)
	usage - Defaults to 'SIGNAL'. Can be "ANY", "TEXT" or "NUMERIC"
       verbose - if set, will print many informational messages
       debug - if set, debug output will be printed
    Outputs:
       status - if odd, then success
	biggestSig - name of biggest signal found

 OUTPUTS:
       size - size of contents of node in bytes

 EXAMPLES:
	IDL> size =mdsLargestNode( 'WF', shot=136000, biggestSig=biggestSig )

	IDL> size=mdsLargestNode( 'operations', 'PCS', shot=136000,  $
				biggestSig=biggestSig )
	IDL> help
	BIGGESTSIG      STRING    = '\OPERATIONS::TOP.PCS.MAGCONTROL.CURRENT:IPLAS_PF1B_1'
	SIZE            LONG      =           90
 MODIFICATION HISTORY:
       22-Aug-2013 Written by Bill Davis for Keith Erickson


MDSLIST

[Previous Routine] [Next Routine] [List of Routines]
   NAME:
	mdslist

  PURPOSE:
	Print ASCII file containing data for MDSplus signal(s). 
	The "dimension" of one of the signals (typically time) is in the 
	first column, followed by data values at that time. 
	Output may be in the format suitable for importing into
	Kaleidograph, Excel, etc.

  CATEGORY:
       MDSplus, Output

  CALLING SEQUENCE:
	mdslist, MDStree, shot, signames
	mdslist, MDStree, shot, signames,  $
               t1=t1, t2=t2, npts=npts, format=format, tabs=tabs, $
               headings=headings, SigForX=SigForX, scope=scope
  INPUTS:
	MDStree - e.g. 'operations'. Default is 'NSTX'
	shot - MDSplus shot number, i.e, ID.
	signames - a single MDSplus signal name, or array of names.
		(ignored if Keyword "Scope" is present.)
  OUTPUTS:
	none returned
  KEYWORDS:
    (all Optional)
	t1 - Starting x-value desired (typically time, in seconds). 
	     Defaults to beginning of data for 1st signal.
	t2 - Ending x-value desired. Defaults to end of data
	npts - number of points desired. Defaults to all points.
	nth - just list every nth point
	format - output format. Defaults to '(100(g15.6, a1))' 
		 (a tab or space is written between the columns)
	tabs - if set, columns will be separated by tabs instead of spaces
	headings - if set, the signal labels are at the top of each column
		   in row 1.
	SigForX - The signal from which to extract the output x-values.
		  Especially relevant when signals of different timebase are 
		  requested (defaults to that of the first signal).
 	scope - if present, gets the signal names and column titles from 
		this scope file.
		(if present, the signames input is ignored). THIS SHOULD BE
	        THE FULL PATHNAME OF THE FILE, or it will default to general
		areas.
	outFile - name of output file. Default is 'mdslist.txt'
	status - 1=OK, 0 means shot, signames, or scope file weren't found.
	units - if set, will append units to headings
  EXAMPLES:

	   To write the first 100 points of time and 
	    ip pairs to file mdsoutput_106138.dat:
	IDL> mdslist,'wf',106138,'\ip',npts=100

	   To write 3 columns,  of time, Ip, and Itf, from 0.1-0.2 sec to 
	    file mdsoutput_106138.dat:
	IDL> mdslist,'wf',106138,['\ip','\itf'],t1=.1,t2=.2
      
	   To make a tab-delimited file of signals from an MDSplus Scope, 
	    with column headings, on efit times:
	IDL> mdslist,'',106138,scope='/u/Old/bdavis/bv.scope', $
			SigForX='EFIT', /headings, /tabs   

	   To write time and stored energy data at 1 KHz 
	    (like all signals in WF tree):
	IDL> mdslist,'',106138,'\EFIT01::WMHD/1000', SigForX='\WF::IP'  
  LIMITATION:
	Would be faster, if it just opened trees that were needed.
  HISTORY:
	01-May-2012 start time different than data wasn't working
	06-Apr-2011 added nth keyword for Hiro Takahashi
	05-Jan-2010 handle missing signal. Print good error messages and warning on
		    web page and in file.
	11-Jul-2008 add /XML output option
	24-Mar-08 puts tabs between columns if tabs='on' (as well as if tabs=1)
	07-Jan-08 Close file before e-mailing, because not all of file begin sent
	26-Sep-07 Add message on how to get file from Linux Cluster nodes
	09-Aug-07 bug fix with Yunits not defined
	29-Mar-07 changed openMDSshot to mdsopen, so SFLIP and such would work
	13-Sep-06 Don't worry if time and data arrays different length
	15-Feb-05 Handle when time not first dimension in 2-d array
	20-Sep-01 converted from mdsmkfile
	05-Sep-01 Added multi-column and interpolation options.
	Written 13-jul-00 by Bill Davis at the request of Charlie Neumeyer


MDSLOADSCALAR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSloadScalar
 PURPOSE:
       Load MDSplus scalar with one simple call (after opening shot)
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       MDSloadScalar, sig, data, SIGUNITS = sigUnits, XAXIS = xAxis,   $ 
    		XUNITS = xUnits, YAXIS = yAxis, YUNITS = yUnits
 INPUTS:
      sig  - MDSplus Signal name
      data - 1- or 2-D data array to load
 KEYWORD PARAMETERS:
       Keywords:
	    stat=val     - if non-zero, return status (1=OK)		out
 OUTPUTS:
       NONE
 COMMON BLOCKS:
       NONE
 EXAMPLE 
	stat=openMDSshot('engineering', 100700)
	sig = '\Some_sig'
	MDSloadScalar, sig, 3.14159

 MODIFICATION HISTORY:
       02-Nov-99 Written by Bill Davis, PPPL


MDSLOADSIG

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSLOADSIG
 PURPOSE:
	Load MDSplus signals with one simple call (after opening shot)
	Optionally add node and/or tag to a shot tree.
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       MDSLOADSIG, sig, data, SIGUNITS=sigUnits, XAXIS=xAxis,   $
                   XUNITS=xUnits, YAXIS=yAxis, YUNITS=yUnits
 INPUTS:
      sigName  - MDSplus Signal name
      data - 1- or 2-D data array to load (can be 3-D, but must have all
             keywords)
 KEYWORD PARAMETERS:
    Keywords:
       SIGUNITS=val - units of signal       in
       XAXIS=val    - array of x-axis       in
       XUNITS=val   - units of x-axis       in
       YAXIS=val    - array of y-axis       in
       YUNITS=val   - units of y-axis       in
       ZAXIS=val    - array of z-axis       in
       ZUNITS=val   - units of z-axis       in
       FullX  - if set, store full x-axis, even if dx constant (1-D only)
       SkipCheck    - if set, do not check time base for constancy (assume)
       AddNode      - if set, will try and add the node to the tree
       TagToAdd     - Tag to add
       shot   - needed if adding node or tag
       tree   - needed if adding node or tag
       JustAdd      - if set, just add node and/or tag, but don't load data
       stat=val     - bad if even, OK if odd           out
       quiet  - passed to MDSplus routines (default=1)
 OUTPUTS:
       NONE
 COMMON BLOCKS:
       NONE
 EXAMPLE
   mdsopen,'wf', 99999, stat=stat
   sigName = '\ip'
   x = findgen(10)
   y = sin( x/n_elements( x ) * 3 * 2 * !PI )
   MDSLOADSIG, sigName, y, SIGUNITS='Y Units',  XAXIS=x, XUNITS='X Units'
   or, to just add a signal and tag:
   MDSLOADSIG, sigName, TagToAdd=tag, SHOT=shot, TREE=tree, /JUSTADD

 MODIFICATION HISTORY:
       17-Jul-2014 add check for 1 or less data points
	23-Jul-2013 added noclose and forceAdd keywords
	05-Mar-2009 check output keyword on dir in mdstcl (needed for Linux)
	09-Jul-2008 use dt_nicenumber, instead of nicenumber, for 
		    digitizing rates of 4, etc.
	03-Jul-2008 Added dt keyword for Stefan Gerhardt, with ~4e-6 dt.
	24-Apr-06 change mds$tcl to mdstcl for Unix.
	22-Jun-04 allow 3-d, but must have all parameters
	27-Jan-03 Just store x0, dx, y0, and dy for 2-D signals, if xaxis input
	23-May-01 Make, as a default, signals with constant timebase
       	store with t0 & delta t, rather than storing whole time array.
	16-Nov-00 Added the AddNode & TagToAdd keywords
	28-Aug-00 Don't Use Arg_Present
	07-Jan-99 Written by Bill Davis, PPPL


MDSMKFILE

[Previous Routine] [Next Routine] [List of Routines]
   NAME:
	mdsmkfile

  PURPOSE:
	Write an ascii file containing time and data for MDSplus signal(s). 
	Time is in the first column, followed by data values at that time. 
	Output may be in the format suitable for importing into
	Kaleidograph, Excel, etc.

  CATEGORY:
       MDSplus, Output, File I/O

  CALLING SEQUENCE:
	mdsmkfile, MDStree, shot, signals
	mdsmkfile, MDStree, shot, signals, filename=filename, $
               t1=t1, t2=t2, npts=npts, format=format, tabs=tabs, $
               headings=headings, timeSig=timeSig, scope=scope
  INPUTS:
	MDStree - e.g. 'operations'. Default is 'NSTX'
	shot - MDSplus shot number, i.e, ID.
	signals - a single MDSplus signal name, or array of names.
		(ignored if Keyword "Scope" is present.)
  OUTPUTS:
	none returned
	file named mdsoutput_nnnnnn.dat is written, where
	   nnnnnn is the shot number, or, if a scope is used, the
	   scope name is in the place of mdsoutput. If Keyword "Filename"
	   is present, that name is used.
  KEYWORDS:
    (all Optional)
	filename - output filename (default is mdsoutput_nnnnnn.dat, where
		   nnnnnn is the shot number, or, if a scope is used, the
		   scope name -- without extension -- is in the place of 
		   mdsoutput).
	DeltaTime - time step for output - Default is that of the first 
		    signal specified. If = 0, then do not list time.
	t1 - Starting time desired, in seconds. 
	     Defaults to beginning of data for 1st signal.
	t2 - Ending time desired. Defaults to end of data
	npts - number of points desired. Defaults to all points.
	format - output format. Defaults to '(100(g15.6, a1))' 
		 (a tab or space is written between the columns)
	tabs - if set, columns will be separated by tabs instead of spaces
	headings - if set, the signal labels are at the top of each column
		   in row 1.
	timeSig - The signal from which to extract the output timebase.
		  Especially relevant when signals of different timebase are 
		  requested (defaults to that of the first signal).
		  If DeltaTime is specified, this keyword is overridden.
 	scope - if present, gets the signal names and column titles from 
		this scope file.
		(if present, the Signals input is ignored). THIS SHOULD BE
	        THE FULL PATHNAME OF THE FILE, or it will default to general
		areas.
	status - 1=OK, 0 means shot, signals, or scope file weren't found.
  EXAMPLES:

	   To write the first 100 points of time and 
	    ip pairs to file mdsoutput_106138.dat:
	IDL> mdsmkfile,'wf',106138,'\ip',npts=100

	   To write 3 columns,  of time, Ip, and Itf, from 0.1-0.2 sec to 
	    file mdsoutput_106138.dat:
	IDL> mdsmkfile,'wf',106138,['\ip','\itf'],t1=.1,t2=.2
      
	   To make a tab-delimited file of signals from an MDSplus Scope, 
	    with column headings, on efit times:
	IDL> mdsmkfile,'',106138,scope='/u/bdavis/bv.scope', $
			timeSig='EFIT', /headings, /tabs   

	   To write time and stored energy data at 1 KHz 
	    (like all signals in WF tree):
	IDL> mdsmkfile,'',106138,'\EFIT01::WMHD/1000', timeSig='\WF::IP'  
  LIMITATION:
  HISTORY:
	12-Oct-01 Added deltaTime keyword [BD]
	05-Sep-01 Added multi-column and interpolation options.
	Written 13-jul-00 by Bill Davis at the request of Charlie Neumeyer


MDSNODECHANGES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSnodeChanges
 PURPOSE:
       Print times when the last change was made to an MDSplus node.
 CATEGORY:
       MDSplus, Tree Status, dates
 CALLING SEQUENCE:
       MDSnodeChanges, node, shot1=shot1, shot2=shot2, skip=skip, tree=tree
 INPUTS:
       node = MDSplus node name, e.g. \OPERATIONS::TOP.RAWDATA:LM_H908_01
 KEYWORDS:
	shot1 = starting shot number to process
	shot2 = last shot number to process (else shot1+400)
	skip = skip factor
	tree = MDSplus tree (defaults to nstx -- 
		will be faster if specific tree specified)
	BEFORE - show only nodes written before this date (defaults to '1-jan-1971'), 
		so can see what never got written.
	AFTER - show only nodes written after this date (defaults to '1-jan-1971'),
		so can see only nodes that HAVE been written.
	OUTFILE - a file name to contain a script related all shots for which
		  a valid node was found in MDSplus
	PREFIX - string to prefix the shot # in the script. 
		DEFAULT is '/bin/rm -R -f '
	MAX - if set, will print max of signal
	VERBOSE - if set, will tell you what shots could not be opened.
 EXAMPLE:
	IDL> tree='microwave'
	IDL> node='\top.electron_den:line_density'
	IDL> MDSnodeChanges, node, shot1=101300, shot2=101330, tree=tree

	IDL> MDSnodeChanges, '\cameras2::FastSoftXray:frames',shot1=124459, $
				shot2=125000, /after

    to produce a script to delete shot directories that have been put in MDSplus:
	IDL> MDSnodeChanges, node, shot1=shot1, shot2=shot2, /after, outfile='shots.txt'

 COMMON BLOCKS:
 NOTES:
	see MDStreeChanges for who last changed a tree.
	Note that "OWNER" returns 0 from getnci call.
	This runs quickly.
 LIMITATIONS:
 MODIFICATION HISTORY:
	20-Aug-2009 added Max keyword
	30-Apr-2008 added outfile and prefix keywords, so directories can be
		    deleted after verifying they are in MDSplus
	09-Jul-2007 added AFTER keyword, so you can see what nodes have been written
	30-Apr-2007 add BEFORE keyword, so you can see what nodes never got written
	26-Apr-2007 "Who" stopped working (returning numberical value)
	09-May-2006 Allow for numerical or '*' for who.
       20-Dec-99 Written for Rajesh Maingi.


MDSSCALARS

[Previous Routine] [Next Routine] [List of Routines]
   NAME:
	mdsscalars

  PURPOSE:
	Print ASCII file containing values of MDSplus scalars(s) for a list of shots. 

  CATEGORY:
       MDSplus, Output

  CALLING SEQUENCE:
	mdsscalars, MDStree, shot, signames
  INPUTS:
	MDStree - e.g. 'operations'. Default is 'NSTX'
	shot - MDSplus shot number, i.e, ID. Can be an array, or range of shots.
	signames - a single MDSplus signal name, or array of names.
  OUTPUTS:
	none returned
  KEYWORDS:
    (all Optional)
	format - output format. Defaults to '(100(g15.6, a1))' 
		 (a tab or space is written between the columns)
	tabs - if set, columns will be separated by tabs instead of spaces
	headings - if set, the signal labels are at the top of each column
		   in row 1.
	status - 1=OK, 0 means shot, signames, or scope file weren't found.
  EXAMPLES:

	IDL> mdsscalars,'',118956,'\ENGINEERING::TOP.EPICS.GAS.PARAMETERS:INJ1_READY'
  LIMITATION:
	Would be faster, if it just opened trees that were needed.
  HISTORY:
	28-May-2015 BD fixed bug where scalar string starts with a number. IDL wants to
			make an octal out of "27-Apr-2015". So using single quotes.
	Written 20-Aug-2006 by Bill Davis


MDSSETEVENT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	MDSSETEVENT
 PURPOSE:
	Generates an MDSplus event
 CATEGORY:
	MDSplus, Events
 CALLING SEQUENCE:
	MDSSETEVENT,event[,/QUIET][,STATUS=STATUS][,DATA=data][,/INFO]
 INPUT PARAMETERS:
	event = Name of MDSplus event to generate.
 Keywords:
	QUIET = prevents IDL error if TCL command fails
	STATUS = return status, low bit set = success
	DATA = bytarr(12) to send with event
	INFO - if this keyword is set the VMS error will be displayed but
              control will be returned to the caller instead of doing a
              longjump back to the IDL prompt.
 OUTPUTS:
       istat = return status, low bit set = success
 COMMON BLOCKS:
	None.
 SIDE EFFECTS:
	None.
 RESTRICTIONS:
	None.
 PROCEDURE:
	Straightforward.  Makes a call to MDSplus shared image library
	procedure MDS$OPEN and checks for errors.
 MODIFICATION HISTORY:
	renamed from mds$setevent & made to work on UNIX, too	[BD]
	 VERSION 1.0, CREATED BY T.W. Fredian, April 22,1991


MDSSIGINTERP

[Previous Routine] [Next Routine] [List of Routines]
   NAME:
	mdsSigInterp

  PURPOSE:
	call TDI to interpolate signals, but handle expressions
	in which multiple signals are included.
	(assumes all same timebase within a given TDI expression)

  CATEGORY:
       MDSplus, Timing

  CALLING SEQUENCE:
	IDL> interpData = mdsSigInterp(inSig, outXsig_in, status=status)

  INPUTS:
	inSig - character string of signal to interpolate
	outXsig_in - signal to get timebase for output of inSig 

  OUTPUTS:
	returns array on desired timebase

  KEYWORDS:
    (all Optional)
	inXsig_in - signal to find timebase for. Default is dim_of(inSig)
	minTime - if set, just returns time range common to both signals
	outTimes - time base of returned signal
	status - 1=OK, 0 means problem

  EXAMPLE:
	stat=openMDSshot('nstx', 109070)
	interpData = mdsSigInterp( '\wf::ip', '\engineering::ip1', outTimes=outTimes, /mintime )
	plot,outtimes,interpdata

  HISTORY:
	10-Apr-03 outTimes and minTime keywords added
  	05-Nov-01 Written by Bill Davis


MDSTREECHANGES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDStreeChanges
 PURPOSE:
       Print times when the last change was made to an MDSplus tree,
	and who did it.
 CATEGORY:
       MDSplus, Tree Status, dates
 CALLING SEQUENCE:
       MDStreeChanges, tree, shot1=shot1, shot2=shot2, skip=skip
 INPUTS:
       tree = MDSplus tree name, e.g. 'Microwave' or 'NSTX'
 KEYWORDS:
	shot1 = starting shot number to process
	shot2 = last shot number to process
	skip = skip factor (default to no skip
	since = only list changes for a shot if since this date
		e.g. - '20-sep-2001'
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> mdstreechanges, 'microwave', shot1=101300, shot2=101301
	 
	Latest changes from shot 101300 to 101301 for the microwave tree
	 
	  Shot       Who       Date        Node
	  ----       ---       ----        ----
	 101300    [BDAVIS]  4-APR-2000  .ELECTRON_DEN:LINE_DENS_DF
	 101301    [BDAVIS]  4-APR-2000  .ELECTRON_DEN:LINE_DENS_DF

 MODIFICATION HISTORY:
	01-Feb-02 added text for repeated lines
	28-Jan-02 added SINCE keyword [BD]
	20-Dec-99 Written by Bill Davis for Rajesh Maingi.


MDSUNITS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MDSunits
 PURPOSE:
       return units of an MDS tag, or the time, or time units
 CATEGORY:
	MDSplus
 CALLING SEQUENCE:
        units = MDSunits( tag )
 INPUTS:
       tag - MDSplus tag or node name      in
 KEYWORD PARAMETERS 
	Input:
	  TIME  - If set, Time returned (unless UNITS also set)
	  UNITS - If set, Units of tag returned (unless TIME also set)
	Returned:
	  STATUS- Status of call (can be used in IDL logical expressions)
 OUTPUTS:
	units - units
 EXAMPLES:
    MDSOPEN, 'tftr', 89725
    tag = '.waveforms:mb_ip_sl'
    f = MDSVALUE( tag )

    time = MDSUNITS( tag, /TIME )
    flabel = MDSUNITS( tag, /UNITS )
    timelabel = MDSUNITS( tag, /TIME, /UNITS )
    plot, time, f/1000., xtitle = timelabel, ytitle = 'milli'+flabel
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
    29-Mar-99 Return status from MDSVALUE [BD]
    21-Dec-98 Written by Bill Davis


MDSW

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdsw
 PURPOSE:
       Interactively plot MDS signals with Crosshairs and many options
 CATEGORY:
       MDSplus, Plotting, Widget Example, Printing Plots, Crosshairs
 CALLING SEQUENCE:
	mdsw
	mdsw, xsize=800, ysize=600
 KEWORDS:
	XSIZE - initial horizontal size of graphics window 
	YSIZE - initial vertical size of graphics window 
	shot - MDSplus shot number, i.e, ID
	tree - tree to open. Defaults to NSTX
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> mdsw,tree='engineering',shot=130000,charsize=2, Az=140, $
		  signal='\engineering::ppsum'
 NOTES:
       Your display may have to be set to 256 colors to see the crosshairs.
 LIMITATIONS:
	Some of the MDSplus signals in the list may not have any data.
	You need IDL version 5, or greater to run this application.
 MODIFICATION HISTORY:
	16-Mar-2009 Option to not display scalars in Signal list
	19-Jan-2008 Added option to change Az & Ax on surface plots
	16-Jan-2009 added zAxisW calls for RGA data
	17-Oct-05 Add Save to Tek option.
	08-Mar-02 Fixed screen dump cabability for 24-bit color, and some minor things.
	05-Oct-01 Improved restoring settings. Allowed for "Next Shot" to be missing.
	18-May-01 Use Vcomp for "visual compression" if more points than resolution
	07-May-01 Added Reload color table. Better behavior when copying plots that
		  don't fill the screen.
	08-Mar-01 Bug fixed on Reference Shots with signals of different length.
	02-Feb-01 Use Label sub-node as title, if available. Access to
		  nodes, even if not tags. Display text nodes.
		  Display Signal List initially.  Plot 2-D data.
	30-Nov-00 Allow "Save Settings" to include Signal List & !X, !Y, !P.
		  (old settings files won't work).
		  Axis selection with middle mouse button just redraws last plot.
	20-Nov-00 Rearranged menus (added Appearance Menu); better plot spacing.
	13-Nov-00 Added "Assume same x-label" & "Assume same x-axis" options
	30-Oct-00 Added widget for !P settings, so can specify symbols, etc.
	26-Oct-00 Fixed "Copy Plot to Tek" to return to X color table afterwards.
	18-Oct-00 Added "Edit Selected Signal" option in Signal Menu. 
		  TDI expressions included in name will be displayed. Added button
		  to show treenames in list.
	10-Oct-00 Added "Label Every Other tick options" & better tick labels
		  Made postscript output a little better for grid of plots
	03-Oct-00 Add "Always Include 0 on Y-axis" (not default) and 
		  "Draw dashes at y=0" (now default) options.
	28-Sep-00 Allow yaxisw to control Y-axis range,
		  in some situations, at least.
	20-Sep-00 Just label "No Data" if data not found. Put < & > on Signal Menu
	07-Oct-99 Redraw whole screen when mouse used. Alphabetize signal list.
		  Default to "Only zoom X" 
	19-Aug-99 Allow overlays of data with different dimensions
	23-Jun-99 Added Reference shot. Added "Plot all on one page" option.
	12-Apr-99 Added Tek output option [BD]
	29-Mar-99 Added X & Y Style editing. [BD]
	15-Mar-99 Add "Get Next Good Shot" buttons [BD]
	08-Mar-99 Add overlays and legends. [BD]
	26-Feb-99 Multiplot option and x-only zooming [BD]
	11-Feb-99 Added a pick list for MDS signals
	26-Jan-99 Modified for using MDS at PPPL by Bill Davis

       GA Crosshair routines originally written by John Ferron. 


MK_SCOPE_GIF

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	mk_scope_gif

 PURPOSE:
	make gif files from scope-like output, using a scope file as input

 CATEGORY:
	MDSplus, Plot files

 KEYWORD INPUTS:
       shots - a string indicating shots, 
                e.g., 107694 108305 108330-108350
                 or   108100+20         
                        (this returns shots 108100, 108101,...,108120)
	scopeFile - if not specified will prompt
	rightSpace - fractioanal space to right of last plot (0-1)
	leftSpace - fractioanal space to left of first plot (0-1)
	colSpace - fractioanal space between plot columns (0-1)
	vertSpace - fractioanal space between plot rows (0-1)
	t1 - start time of plots (sec)
	t2 - end time of plots (sec)
	nRows - # of rows of plots
	nCols - # of columns of plots
	pixmap - if set, will not display plots on screen (much faster)

 EXAMPLE:
    (on Unix:)
	mk_scope_gif,shots='109071-109075',scope='wf.scope', /pixmap

     or
	mk_scope_gif,shots='109071+5' ; (will be prompted for file)

     or 
     mk_scope_gif, shots='109070+2',scope='/u/kaye/Scope/sk.scope',   $
                 leftspace=.07, rightspace=0.005, $
                 tweenspace=0.008, vertSpace = 0.03,  $
                 nrows=8, ncols=4, charsize=1.3
 HISTORY:
	Written by Bill Davis for Stan Kaye, Dec. 2004


NEXTGOODSHOT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       nextGoodShot

 PURPOSE:
       find the next shot that has more than a certain Ip.

 CATEGORY:
	MDSplus, Shot Number

 CALLING SEQUENCE:
        nextShot = nextGoodShot( StartShot )

 INPUTS:
       StartShot - shot number to start from      in

 KEYWORD PARAMETERS:
    Inputs:
	goodValue - value required for tag for next good shot (default=30000 Amps)
	Backwards - look backwards for good shots
	MaxShots  - Maximum number of shots to search over 
		   (default=1000 or end). IF MAXSHOTS=1 JUST PROCESS SHOT1
	Server 	  - MDS server (default is NSTX)
	TagToUse  - Tag to use for IP check (default to \OPERATIONS::CAL_IROGEVVUL1)
	Verbose   - if set, print debugging information
 OUTPUTS:
	nextShot - next Shot number, based on criterion
                  IF no good shot meeting criterion is found, -1 is returned
 EXAMPLE:
	IDL> ishot = NextGoodshot( laopenStathot, goodValue = 100. )
 COMMON BLOCKS:
 NOTES:
 	this routine just works for NSTX and DIII-D (uses gadat at GA).
 RESTRICTIONS:
	LASTSHOT() may sometimes return a small number during test periods
 MODIFICATION HISTORY:
	02-Nov-2009 better debug statements
	10-Mar-06 Default to \WF::IP. Check for different tree for backup tag.
	15-Aug-05 add LastIpTime keyword [BD].
	28-Sep-01 Return status. Assume values read are in Amps.
		  Use \ENGINEERING::IP2 as a backup value
	28-Nov-00 Changed Ip to look for \ENGINEERING::PPCC_IP1
	20-Sep-99 Add MaxShots keyword
	18-Sep-99 Keep going after 1 missing shot, but stop after 5
	16-Sep-99 Added TagToUse keyword & medsmooth to remove spikes [BD]
 	Written by Bill Davis March, 1999


NONVARPOS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       nonVarPos
 PURPOSE:
 	find position of characters which are not valid for MDSplus names
 CATEGORY:
       MDSplus, Character Search, Strings
 CALLING SEQUENCE:
	posArray = nonVarPos( inStr )

 RETURNED:
       posArray = array of positions of characters which are not
		   valid characters for an MDSplus tag name
		-1 if none found
 KEYWORDS:
   (OPTIONAL)
	GOOD - if set, will retrun positions of good characters
	noNum - if set, don't count numbers as good characters
 MODIFICATION HISTORY:
	01-May-01 - Added keywords
	2001 Written by Bill Davis


NSEARCH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       nsearch
 PURPOSE:
      Search MDS Plus Trees for a node
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> result=nsearch(searchnode[, fullpath=path])
 INPUTS:
       searchnode and optional variable to return an array of full paths 
	 containing node name 
 KEYWORD PARAMETERS:
       fullpath - full path of node found
 OUTPUTS:
       status of function (-1 if not found, 0 if found)            			
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> result=nsearch('xray', fullpath=path)
 NOTES:
       tree must be open before nsearch can be called.
	will return 0 if node is found and -1 if it is not found in the current 
	tree.
 MODIFICATION HISTORY:
	12-Feb-00 strip tree info, if in node name [BD]
        7-Feb-00 Written by Dana Mastrovito, PPPL


PLOTSCOPE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       plotscope
 PURPOSE:
       make scope-like plots, optionally with overlays from multiple shots.
 CATEGORY:
       MDSplus, SCOPE
 CALLING SEQUENCE:
	IDL> plotscope, shots=shots, scope=scope
 INPUTS:
	shots - scalar or array of shot numbers, e.g. [104500,104501]
	scope - name of scope input filename (else will get a dialog box)
 RETURNED:
	None
 KEYWORDS:
   (All Optional) Inputs:
	t1 - starting time desired. Defaults to scope value
	t2 - ending time desired. Defaults to scope value
	refshot - a reference shot to be overplotted.
       SameXlabels - If set and non-zero, just label x-axis at bottom
		     (This reserves less vertical space between plots)
	NRows - Maximum number of rows.
	NCols - Number of columns (default is to compute from rows & # sigs)
       nSmooth - # for median smoothing before using signal (default=0)
	pCharSize - Value desired for !P.CHARSIZE, else guesses
	Titles - string array of the plot titles from the scope file, else y-name
	xMins - array of each plot's x-minimum from the scope file (else global, or 0)
	xMaxes - array of each plot's x-maximum from the scope file (else global, or 0)
	yMins - array of each plot's y-minimum from the scope file (else global, or 0)
	yMaxes - array of each plot's y-maximum from the scope file (else global, or 0)
	tweenspace - vertical space between plots in normalized coordinates
	colSpace - horizontal space between plots in normalized coordinates
	rightSpace  - space on right in normalized coordinates
	leftSpace - space on left in normalized coordinates
 EXAMPLE:
   (Send plots to a Tektronix window, say, from on a Mac from VersaTerm):
	IDL> setup_tek
	IDL> plotscope, shots=104500, refshot=104501, scope='WF'
	IDL> unsetup_tek
    (Make a scope-like plot without space between plots 
      -- the tick labels are outside their grids, unlike in Scope)
	IDL> plotscope,shot=105830,scope='wf',tweenspace=0,colspace=0
 COMMON BLOCKS:
       none
 NOTES:
 LIMITATIONS:
 MODIFICATION HISTORY:
	24-Aug-01 Written by Bill Davis


PRINTSCOPE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	printscope

 PURPOSE:
	print scope-like output, using a scope file as input

 CATEGORY:
	MDSplus, Printing Plots

 KEYWORD INPUTS:
       shots - a string indicating shots, 
                e.g., 107694 108305 108330-108350
                 or   108100+20         
                        (this returns shots 108100, 108101,...,108120)
	scopeFile - if not specified will prompt
	printer - if not specified will prompt on Unix
	rightSpace - fractioanal space to right of last plot (0-1)
	leftSpace - fractioanal space to left of first plot (0-1)
	colSpace - fractioanal space between plot columns (0-1)
	vertSpace - fractioanal space between plot rows (0-1)
	t1 - start time of plots (sec)
	t2 - end time of plots (sec)
	nRows - # of rows of plots
	nCols - # of columns of plots
	noprint - if set, will not send plot to printer

 EXAMPLE:
    (on Unix:)
	printscope,shots='109071-109075',scope='wf.scope',printer='nstx-xn4525'

     or
	printscope,shots='109071+5' ; (will be prompted for file & printer)

     or 
     printscope, shots='109070+2',scope='/u/kaye/Scope/sk.scope',   $
                 leftspace=.07, rightspace=0.005, $
                 tweenspace=0.008, vertSpace = 0.03,  $
                 nrows=8, ncols=4,  $
                 printer='nstx-xn4525', charsize=1.3
 HISTORY:
	Written by Bill Davis for Stan Kaye, jan, 2003


SEARCHMDSNODES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        SearchMDSNodes
 PURPOSE:
      Search MDSplus nodes for string contents
 CATEGORY:
       MDSplus, Searching
 CALLING SEQUENCE:
       IDL> paths= SearchMDSNodes( str[, sensitivity, text=text][,path=path])
 INPUTS:
       str - string to search on
	sensitivity - (Optional) if ='Sensitive', then make search case sensitive
 KEYWORD PARAMETERS:
    Input (Optional):
       JustText - if set, just look for Text nodes (no effect if /TAGS set)
	nonNodeStr - exclude nodes in returned array if this string found in name
	tags - if set, just look for nodes with tags
       sizesearch - when searching text, length of string to check (def=1024)
	whatToSearch - = 'NAMES', 'TEXT', or 'TDI'
	treeName - MDSplus tree. Default='NSTX'
	shot - MDSplus shot to search. Default=-1 (the model tree).
	server - MDSplus server. Default is the default NSTX data server.
    Returned (Optional):
       text (contains the full text found), path(returns the full path to the text)
	isSignal - logical array where 1s indicate corresponding node is a signal
	status - status from mdsvalue call
 OUTPUTS:
	result - status of function: 0 = success, -1 = failed to find
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> paths=SearchMDSNodes('xray', text=text ) 
 NOTES:
	tree must already be open before SearchMDSNodes can be called
	if no records are found in current tree returns -1 else returns 0
 MODIFICATION HISTORY:
	12-Feb-2015 made it so don't have to enter shot keyword
  	06-May-2010 added max2search keyword
	20-Apr-2010 added keyword isSignal 
	11-Nov-05 Added tree keyword
	01-Dec-00 Added capability for wildcards in search string
	10-Nov-00 Added sensitivity [BD]
       7-Feb-00 Written by Dana Mastrovito, PPPL


SEARCHTEXTNODES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        SearchTextNodes
 PURPOSE:
      Search MDS Plus Trees for Textual Data
 CATEGORY:
       MDSplus, Searching
 CALLING SEQUENCE:
       IDL> result= SearchTextNodes( keyword[, sensitivity, text=text][,path=path])
 INPUTS:
       keyword - string to search on
	sensitivity - (Optional) if ='Sensitive', then make search case sensitive
 KEYWORD PARAMETERS:
       text (contains the full text found), path(returns the full path to the text)

 OUTPUTS:
	result - status of function: 0 = success, -1 = failed to find
   
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> result=SearchTextNodes('xray', text=text,path=path)
 NOTES:
	tree must already be open before tsearch can be called
	if no records are found in current tree returns -1 else returns 0

 MODIFICATION HISTORY:
	01-Dec-00 Added capability for wildcards in search string
	10-Nov-00 Added sensitivity [BD]
       7-Feb-00 Written by Dana Mastrovito, PPPL


SETMDSSHOTEVENT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
        setmdsshotevent

 PURPOSE:
       set an MDS event with shot number associated with the event

 CATEGORY:
       MDSplus, Events

 CALLING SEQUENCE:
       IDL> setmdsshotevent, eventName [, shot_num]

 INPUTS:
	eventName - string of MDS event name, e.g., 'NE_DENSITY_CALC'
       shot_num - NSTX shot number (OPTIONAL -- will default to current shot)

 KEYWORD PARAMETERS:
    Optional:
	VERBOSE - If set, print debugging information
	NOCONNECT - if set, will not try to connect to an MDSplus server
	SERVER - if not set, will connect to default server in OpenMDSshot
       STATUS = return status, low bit set = success

 OUTPUTS:
       none -- just sets the event
 COMMON BLOCKS:
       NONE
 EXAMPLE:
 NOTES:
       to test:
	   on one node:
	   IDL> wfmdsshotevent, 'mytest', shotnum

	   on another:
	   % setevent mytest 123456

	   or:
	   IDL> setmdsshotevent, 'mytest', 123456

	   on first node:
	   IDL> print, shotnum

	BTW, 
	   % setevent mytest 123456
	will give 875770417, because data is not unpacked.

 MODIFICATION HISTORY:
 	17-Dec-2008 don't try to fill valBlk if shot_num not a number [bd]
 	11-Nov-2008 Default to no mdsconnect [BD]
	02-Nov-2008 Added status keword.
	11-Feb-04 use SETEVENT in MDSVALUE on Unix. Add connect option on unix.
   	20-Dec-99 Written [bd]


SHOTDURATION

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       ShotDuration
 PURPOSE:
       Return the Shot Duration in seconds
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       IDL> seconds = ShotDuration(ishot, IpNeeded=IpNeeded, IpSignal=IpSignal,   $
                       RoundUp=RoundUp)
 INPUTS:
       ishot - shot number. If not supplied, will use current shot
 KEYWORD PARAMETERS:
       Keywords:
	  IpNeeded - plamsa current in kiloAmps to be considered real (default=50)
	  IpSignal - mdsplus signal to use to determine plasma current
		default = \wf::ip
		NOTE if signal is not in kiloAmps, divide or multiply by correct factor
	  InSignal - input Ip signal, so doesn't have to be read
	  maxValue - returns max plasma current in KA.
	  nSmooth - the amount to smooth Ip signal before checking the value
		    Default = 11 points.
	  RoundUp  - if set, add 0.1 seconds and round up to nearest 0.1 seconds
	  quiet - if not set, quiet
	  realquiet - if set, no "MDSOPEN success" message
	  Verbose  - if set, print debugging information
	  Server   - MDS server (default is for NSTX)
	  HLP - When set, help information is printed.
 OUTPUTS:
         seconds               			out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> opt = ShotDuration( IpNeeded=5, IpSignal='\engineering::ip2' )

   to load a scalar with the shot duration time, 

	IDL> for i=shot1,shot2 do d=ShotDuration( i, outSig='\nstx::shotduration' )
 NOTES:
 MODIFICATION HISTORY:
	07-Oct-2009 fixed bug recently introduced when reading default signal.
	05-Mar-2008 Allow Ip to be passed in
	18-Feb-2008 Account for WF tree, but no \IP
	06-Feb-2008 replaced openMDSshot with mdsopen [BD]
	25-Apr-2006 added MaxValue (for Ip) keyword
	29-Aug-2005 nSmooth keyword added 
	28-Jul-2004 added realquiet keyword
      	08-Apr-2004 Written by Bill Davis, PPPL


SIGALERT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       sigalert

 PURPOSE:
       Send email alerts when MDSplus signals are not acquired, or have
	undesirable values.This routine can be run in your IDL session, 
	or it can be put into the "Auto-reload Facility" of NSTX-U.

 CATEGORY:
       MDSplus, events, Utility

 CALLING SEQUENCE:
       IDL> sigalert, signals, emails

 INPUTS:
       signals - list of MDSplus signals to monitor
	emails - corresponding list of emails to notify of alarm condition
		 multiple recipients can be separated by a blank,comma or 
		 semicolon. If emails are from PPPL, they do not have to have
		 the @pppl.gov.

 KEYWORD PARAMETERS:
    Inputs:
	checkEvents - Events at which to check (defaults to SOP of next shot)
	nSmooth - width of neighborhood to be used for the median filter
		  when checking for invalid values.
	maxAllowed - alarm value(s) (alarm if filtered signal exceeds this)
	minRequired - min required (alarm if filtered signal never reaches 
		      this value)
	    if neither maxAllowed or minRequired are specified for a signal,
	    an alarm is raised only if there is no data for the shot
	idlroutines - function to call to evaluate signal (optional)
	epicsAlarm - EPICS alarm to set (optional)
	setEvents - MDSplus event to set upon alarm condition (optional)
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed

 EXAMPLE:

	IDL> sigalert, '\wf::mirnov_rms', 'bdavis', maxAllow=5

	IDL> signals    = ['\wf::ip', '\wf::pnb', '\wf::mirnov_rms' ]
	IDL> emails      = ['bdavis', 'bdavis', 'bdavis' ]
	IDL> checkEvents = ['bdtest', 'bdtest1', 'bdtest' ]
	IDL> sigalert, signals, emails, checkEvents=checkEvents, /debug

		; should flag "too high":
	IDL> sigalert, '\wf::ip', 'bdavis', checkEvents='bdtest',  $
			maxAllowed=800, testshot=142000, /debug

		; should flag "too high":
	IDL> sigalert, '\wf::ip', 'bdavis', checkEvents='bdtest',  $
			maxAllowed=800, testshot=142000, nsmooth=11, /debug

		; should flag "too low":
	IDL> sigalert, '\wf::ip', 'bdavis', checkEvents='bdtest',  $
			minReq=1000, testshot=142000, /debug

		; should flag nothing:
	IDL> sigalert, '\wf::ip', 'bdavis', checkEvents='bdtest',  $
			maxAllowed=2000, minReq=2, testshot=142000, /debug

	IDL> sigalert, fileDir='/p/nstxops/bin/mds/SigAlert/Files',  $
			/debug

    and then somewhere on Linux:  setevent bdtest

 NOTES:
	If the alarm value is too large a negative value, the signal 
	could be specified as (-1*\signame) 

 MODIFICATION HISTORY:
	03-Feb-2015 added files read recorded in log file
       30-Sep-2013 Written by Bill Davis, PPPL, for Stefan Gerhardt


TAG_EXIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	TAG_EXIST
 PURPOSE:
	To test whether a tag name exists in a structure.
 CATEGORY:
	MDSplus, structure
 CALLING SEQUENCE:
       status = tag_exist(str, tag)
 INPUTS: 
	str  -  structure variable to search
       tag  -  tag name to search for
 OUTPUTS: 
	Function returns 1 if tag name exists or 0 if it does not.
 KEYWORDS:
	INDEX = index of matching tag
 METHOD:
	Routine obtains a list of tagnames and tests whether the
       requested one exists or not. The search is recursive so 
       if any tag names in the structure are themselves structures
       the search drops down to that level.
 Common      : None
 Restrictions: None
 Side effects: None
 Written     : C D Pike, RAL, 18-May-94
 Modified    : 03-May-2007 datatype wasn't working, so just use SIZE [BD]
	      : Version 1.1, D Zarro, ARC/GSFC, 27-Jan-95
               Passed out index of matching tag
 Version     : Version 1.1, 27-Jan-95


TAGRANKOF

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       tagRankOf
 PURPOSE:
       Return a list of MDSplus signals with a certain rank
	(that contain data)
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       tags = tagRankOf( rankDesired )
 INPUTS:
       rankDesired = 0 for scalars, 1 for vectors, etc.  
 KEYWORD PARAMETERS:
    Optional Keywords:
	filter - wild card specifer. E.g. '*ip*' will get all of 
		 specifed rank with ip in the the tag name.
	fullpaths - returns full pathnames of tags found
	print  - if set, tags and full pathnames found will be printed
	debug - print some debugging info
  the tree may be opened before this routine is called, or you can specify:
	treeName - MDSplus tree. Default='NSTX' (unless embedded in nodeString)
	shot - MDSplus shot to search. Default=-1 (the model tree).
	server - MDSplus server. Default comes from the environmental variable _path
 OUTPUTS:
       tags = tagnames of specifed rank fitting any filter specified
		if none are found fitting criteria, 'none' is returned.
 EXAMPLE:
	IDL>  print, tagRankOf( 1, filter='i*', shot=120200, tree='wf' )
\WF::ICHI \WF::IOH \WF::IP \WF::IPF1AL \WF::IPF1AU \WF::IPF1B \WF::IPF2L \WF::IPF2U
\WF::IPF3L \WF::IPF3U \WF::IPF4 \WF::IPF5 \WF::ITF

	IDL> mdsopen,'microwave', 120200
	IDL> scalarNames = tagRankOf(0)
	IDL> someSigs = tagRankOf( 1, filter='n*', /print )
 COMMON BLOCKS:
       none
 NOTES:
       Only returns signals with data in them.
 LIMITATIONS:
	An MDSplus shot file must be open first.
 MODIFICATION HISTORY:
	10-Jan-08 Added extra keywords for findMDSnodes [BD]
	14-Mar-00 more efficient & added keywords [BD]
	20-Jan-00 Written by Bill Davis


TAGSEARCH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       tagsearch
 PURPOSE:
	Search MDS Plus Trees for a tag
 CATEGORY:
	MDSplus, Utility
 CALLING SEQUENCE:
       IDL> status=tagsearch(searchtag[,tag=tag, path=path])
 INPUTS:
	searchnode and optional variable to return an array of full paths containing
	 tag name and an array containing the tag names
 KEYWORD PARAMETERS:
  the tree may be opened before this routine is called, or you can specify:
    Inputs (optional):
	treeName - MDSplus tree. Default='NSTX' (unless embedded in nodeString)
	shot - MDSplus shot to search. Default=-1 (the model tree).
	server - MDSplus server. Default comes from the environmental variable _path
    Returned:
       path
	tag
 OUTPUTS:
       status of function              			
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> status=tagSearch('xp_', tag=tag, path=fullpath, tree='nstx')
 NOTES:
       will return 0 if tag is found and -1 if it is not found in the tree specified
 MODIFICATION HISTORY:
	08-May-2009 default to nstx tree if none indicated [BD]
	10-Jan-08 use findMDSnodes, since findtags.fun not in Linux distribution [BD]
	01-Dec-00 Added capability for wildcards in search string
       28-Feb-00 Written by Dana Mastrovito, PPPL


TDIS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       tdis
 PURPOSE:
      Search MDS Plus Trees for TDI DATA
 CATEGORY:
       MDSplus, Utility
 CALLING SEQUENCE:
       IDL> result = tdis( keyword[,sensitvity][, tdi=tdi][,path=path] )
 INPUTS:
       searchstring and optional variables to control case sensitivity and return an array of text strings found
	and an array of paths to those strings
 KEYWORD PARAMETERS:
   (output)
       tdi  - the full tdi found 
	path - the full path to the text

 OUTPUTS:
	result=status of function
   
 COMMON BLOCKS:
       none
 EXAMPLE:
	IDL> result=tdi('build','sensitive',tdi=tdi,path=path)
 NOTES:
       this version is specifically for idl4 (?)
	tree must already be open before tsearch can be called
	if no records are found in current tree returns -1 else returns 0

 MODIFICATION HISTORY:
	30-Jan-00 Speed up. Fixed node names.
	01-Dec-00 Added capability for wildcards in search string
       07-Feb-00 Written by Dana Mastrovito, PPPL


TREE_EXISTS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:  
       tree_exists
 PURPOSE: 
       Return a true if an MDSplus tree exists for a given shot number

 CATEGORY:
       MDSplus, Trees
 CALLING SEQUENCE:
       found = tree_exists( shot, tree )
 INPUTS:
    (tree and shot arguments can be reversed, if shot is an number)
	shot - MDSplus shot number, i.e, ID. Can be string acceptable to 
		mk_shotlist.pro
	tree - tree to open. Defaults to 'wf'
 KEWORDS:
    (returned)
	list - list of shots found
 EXAMPLE:  
       IDL> IF tree_exists(101526,'operations') THEN ...

       IDL> founds = tree_exists( '112300-112302 112305+2', 'wf', list=shots )
 NOTE:
       Returns true only if shot exists; the shot may be empty.
	If you have an account on skylark.pppl.gov, you use mdir.pro,
	which is faster.

 19-Nov-2008 make work if input arguments are reversed
 WRITTEN 15-Nov-2008 by Bill Davis (old version replaced)


TRIMTAGNAMES

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       trimtagnames
 PURPOSE:
       Trim tree info from an MDSplus tag name
 CATEGORY:
	MDSplus, Tagnames
 CALLING SEQUENCE:
         trimmedList = trimtagnames( sigList )
 INPUTS:
       sigList - a string array of MDSplus tag names 			 in
 KEYWORD PARAMETERS:
   (Optional)
	all - if set, trim everything but string following the last :
       treeOnly - if set only remove the tree (& top:). 
		   Leave the backslash, TDI, etc.
 OUTPUTS:
	trimmedList - a string array of MDSplus tag names 
 EXAMPLE:
	trimmedList = trimtagnames( sigList )
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	18-Oct-00 Added keyword treeOnly:
		  Don't assume tree name at beginning of string
		  (allows for trimming tree names from TDI expressions)
 	Written by Bill Davis March, 1999


USESIGMATH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	useSigMath

 PURPOSE:
	parse an MDSplus TDI string, substituting Brian Nelson's Signal Math TDI
	routines for +,-,* and /, so timebases get adjusted, if necessary.

 CATEGORY:
	MDSplus

 CALLING SEQUENCE:
       IDL> newTDI = useSigMath( tdi )

 INPUTS:
       tdi = a TDI string in which any signals are preceded by '\'

 OUTPUTS:
	newTDI - math operations -, +, * & / are replaced by Brian Nelson's SigMath
		 functions sigsub, sigadd, sigmul and sigdiv.
 EXAMPLE:
	print, useSigMath('(\engineering::ip1+\engineering::ip2)/2')
	   SIGADD(\engineering::ip1,\engineering::ip2)/2

	print, useSigMath('\wf::ip-\wf::ipf4/\wf::ipf5')
	   SIGDIV(SIGSUB(\wf::ip,\wf::ipf4),\wf::ipf5)	   NOTE ORDER OF OPERATIONS IS LEFT TO RIGHT

	print, useSigMath('1000*\wf::ip-\engineering::ip1')
	   SIGSUB(1000*\wf::ip,\engineering::ip1)

	print, useSigMath('(\engineering::ip1/1000 - \wf::ip)')
	   SIGSUB(\engineering::ip1/1000,\wf::ip)

	print, useSigMath('1000*\wf::ip-\engineering::ip1')
	   SIGSUB(1000*\wf::ip,\engineering::ip1)

	print, useSigMath('\wf::ip-bcsmooth(\engineering::ip1/1000)')
	   SIGSUB(\wf::ip,bcsmooth(\engineering::ip1/1000))

	print, useSigMath('1000*\wf::ip-(\engineering::ip1+\engineering::ip2)/2')
	   SIGSUB(1000*\wf::ip,SIGADD(\engineering::ip1,\engineering::ip2)/2)

	print, useSigMath('abs(bcsmooth(\engineering::ip1/1000)-\wf::ip)')
	   (abs(SIGSUB(bcsmooth(\engineering::ip1/1000),\wf::ip)))

	print, useSigMath('\wf::ip-\wf::ip[0]')

 LIMITATIONS:
	Without brackets expressions will be evaluated from left to right.
	The SigMath routines do not correct for different units, like Amps and KiloAmps.
	Signals are only recognized when they begin with a backslash.

 MODIFICATION HISTORY:
	04-Aug-2008 made to work (i.e., not use Sigmath) with '\wf::ip-\wf::ip[0]'
  	WRITTEN 10-Aug-2007 by Bill Davis


WFMDSSHOTEVENT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	wfMDSshotEvent
 PURPOSE:
	Wait for an MDSplus event, with shot number coming in
 CATEGORY:
	MDSplus, Events
 CALLING SEQUENCE:
	wfMDSshotEvent, event, shotnum, [,/QUIET][,STATUS=istat]
 INPUT PARAMETERS:
	event = name of an MDSplus event to wait for.
 RETURNED PARAMETERS:
	shotnum - whatever data was passed when the event was set.
	          for MDSplus events, except for nstx_acq_started
 Keywords (Optional):
	ASCII - if set, will assume data block contains ascii representation of numbers
	NOCONNECT - if set, will not try to connect to an MDSplus server
	SERVER - if not set, will connect to default server in OpenMDSshot
       QUIET = prevents IDL error if MDSplus command fails
       STATUS = return status, low bit set = success
 COMMON BLOCKS:
	None.
 SIDE EFFECTS:
	None.
 RESTRICTIONS:
 PROCEDURE:
	Makes a call to MDSplus shared image library
       procedure MDS$WTEVENT and checks for errors.
 NOTES:
       to test:
	   on one node:
	   IDL> wfmdsshotevent, 'mytest', shotnum

	   on another:
	   % setevent mytest 123456

	   or:
	   IDL> setmdsshotevent, 'mytest', 123456

	   on first node:
	   IDL> print, shotnum

	BTW, 
	   % setevent mytest 123456
	will give 875770417, because data is not unpacked.

; MODIFICATION HISTORY:
 	11-Nov-2008 Default to no mdsconnect [BD]
	02-Nov-2008 Return -1 if error from mdsvalue. Have an option not to 
		    connect.
	09-Mar-2007 Added ASCII keyword which is needed on sflip PC
	08-Jul-2005 Added support for Windows
	31-May-05 include server keyword
	06-Apr-05 use MdsValue( 'WFEVENT($)'... instead. [BD]
	24-May-01 If on Unix, connect to VMS if not already [BD]
	06-Nov-00 Made same version work on VMS & Unix [BD]
	copied from mds$wfevent.pro, so could have the same name on vms & unix
	VERSION 1.0, CREATED BY T.W. Fredian, April 22,1991

 debug version 7/14/05 PR syntax error in if/endif structure


WITHRANKOF

[Previous Routine] [List of Routines]
 NAME:
       WithRankOf
 PURPOSE:
       Return a list of MDSplus signals with a certain rank
	(that contain data)
 CATEGORY:
       MDSplus
 CALLING SEQUENCE:
       sigs=withrankof( rank )
 INPUTS:
	rank - integer rank of signal desired
 KEYWORD PARAMETERS:
	filter - wildcard specification to find signal names with desired rank
	signalnames - if present, use these, and ignore filter
 OUTPUTS:
	sigs - MDSplus signal names with 
 EXAMPLE:
	IDL> stat=mdsopen('passivespec',101964)
	IDL> scalarNames = withrankof(0)
 COMMON BLOCKS:
       none
 NOTES:
       Only returns signals with data in them.
 LIMITATIONS:
	An MDSplus shot file must be open first.
 MODIFICATION HISTORY:
	31-Jan-07 add keyword to pass in signalnames
	20-Jan-00 Written by Bill Davis


Category: Misc

[List of Routines]


ADDGPICOMMENT.PRO

[Next Routine] [List of Routines]
 NAME:
       addGPIcomment.pro

 PURPOSE:
       add comments to a file for GPI web pages

 CATEGORY:
       GPI, Web, NSTX

 CALLING SEQUENCE:
       IDL> addGPIcomment, headline=headline, Description=Description, username=username,  $
                           shot=shot, PagePassword='something',

 INPUT KEYWORDS:
   Required:
	username - Linux username of person making entry
	PagePassword - this is required
	shot - NSTX shot # for which comment applies
	headline - a one-line Summary of status
   Optional:
	Description - more detailed comment, can be up to 20 lines
	outFile - web page, DEFAULT='/w/nstx.pppl.gov/htdocs/nstx/Software/nstxstatus.html'
	maxLength - max length of status field
	logfile - name of log file. 
		  DEFAULT='/local/nstxops/web/log/addGPIcomment.log'
	debug - if set prints debugging info
	verbose - if set prints lots of info
	status - if odd, successful
   
 OUTPUTS:
       appends to a text file, comments.txt, to a web-accessible directory.

 METHOD:
	Gets data for fields (like Description) to be updated from addGPIcomment.html
	(via idlMDSPlotServer2550.pl) and appends to the output file.

 COMMON BLOCKS:
       NONE

 EXAMPLE:
       IDL> addGPIcomment, shot=999999, headline='This is a test',  $
		            username='bdavis', PagePassword='Masa', /debug
       IDL> addGPIcomment, shot=999999, headline='This is a big test',  $
		            username='bdavis', PagePassword='Masa', $
	       description=strconcat(replicate('blah', 200), delim=' '), /debug
 MODIFICATION HISTORY:
	15-Oct-2013  Written by Bill Davis, PPPL, for Stewart Zweben


BAD_PTDATA_ERROR

[Previous Routine] [Next Routine] [List of Routines]
 
 NAME:
       BAD_PTDATA_ERROR
 PURPOSE:
       Return a logical true IF  the PTDATA error is serious
 CATEGORY:
       GA, error processing
 CALLING SEQUENCE:
       logical = Bad_PTDATA_Error(ptdata_ierr)
 INPUTS:
       ptdata_ierr - error return from PTDATA calls
 KEYWORD PARAMETERS:
 OUTPUTS:
 RETURNED:	logical indication of a serious error 
		(per IDL definition, e.g., 0 IF  false)
 COMMON BLOCKS:
 MODIFICATION HISTORY:
               1-Apr-97 WMD Written


BLOBVYFIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	blobvyfit 

 PURPOSE:
	plot Poloidal velocity (Vy) of blobs from Fast Camera data
	vs. distance from the separatrix. Bin and smooth things so
	a curve can be fit through data, with the ultimate goal
	of categorizing the vertical shear.

 CATEGORY:
	GPI

 CALLING SEQUENCE:
	blobvyfit, shot,  BinSize=binsize, barFraction=barFrac,  $
	         title=title, Overlay=Overlay, $
                 WindowTitle=WindowTitle, GROUP_LEADER=group_leader, $
		 XSIZE=xsize_in, YSIZE=ysize_in, xtitle=xtitle, ytitle=ytitle, $
		 _extra=_extra
 INPUTS:
	shot - NSTX shot number

 OUTPUTS:
	plot in graphics widget

 KEYWORDS:
    barFraction - fraction of interval over which bar is drawn (0-1) 
		   (default=0.5)
    BinSize -  The size of each bin of the histogram,  scalar (not necessarily
             integral).  If not present (or zero), the bin size is set to 1.
    Overlay - if set, overlay a curve 
    ShotList - list of shots to cycle through

 EXAMPLE:
	IDL> blobvyfit, 138234

	   ; to be able to make JPEGS for all shots, with fixed limits:
	IDL> blobvyfit, 138234, plotLimitsFile='PlotLims.txt'

 MODIFICATION HISTORY:
	17-Feb-2014 Written by Bill Davis 


BPWFEDIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	BPWFEDIT

 PURPOSE:
	Read, Edit, & Plot Breakpoint Waveform files used in ppcc system on TFTR
 CATEGORY:
       TFTR, Waveforms, GUI Editing

 REVISION HISTORY:
	21-Aug-98 Written by Bill Davis


CAMAC_HERE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       CAMAC_here
 PURPOSE:
       Return 1 if CAMAC on this computer
	(if environmental variable "camac_server" is non-blank)
 CATEGORY:
       CAMAC
 CALLING SEQUENCE:
       IDL> OK = CAMAC_here()
 INPUTS:
       none required  
 KEYWORD PARAMETERS:
	var - Environmental variable to check to determine if CAMAC available.
		(defaults to 'camac_server')
	HLP - When set, help information is printed.
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
 OUTPUTS:
       OK = 1 if environmental variable "camac_server" is non-blank
 EXAMPLE:
 NOTES:
       When the routine is called with the
	keyword hlp set, help information is printed.
 MODIFICATION HISTORY:
       08-Jan-2009 Written by Bill Davis, PPPL


CH_EXAMPLE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       CH_Example
 PURPOSE:
       a simple example using the GA Crosshair routines
 CATEGORY:
       GUI Graphics, Example
 CALLING SEQUENCE:
       CH_Example
 COMMON BLOCKS:
       ch_example
 NOTES:
       Your display may have to be set to 256 colors to see the crosshairs.
 MODIFICATION HISTORY:
       Written by Bill Davis, 8/29/97

       GA Crosshair routines originally written by John Ferron. 
       Now maintained by T. Terpstra


CH_REGISTER

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
  	ch_register
 PURPOSE:
	register window for crosshair routines

 CATEGORY:
	GUI Graphics, Cursor Cross-hairs

 EXAMPLE:
	See ch_example.pro

 MODIFIED:
	29-Nov-07 Don't handle if window names not found in ch_set [BD]
	30-Oct-00 Override !P.PSYM & !P.LINESTYLE for cros-hairs  [BD]
	04-Dec-99 Make mask bit 6, so it's red when used with MK_COLOR  [BD]
	29-Mar-99 Added newX, newY & newP keywords to CH_SET for changing
		  plotting parameters  [BD]
	26-Jan-99 Taken from GA   [BD]
		  Combining all ch_ files here, since this must be called 1st.


COPY_STRUCT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       COPY_STRUCT

 PURPOSE:
       Copy all fields with matching tag names from one structure to another

 CATEGORY:
	Programming
 
 EXPLANATION
       Fields with matching tag names are copied from one structure array to 
       another structure array of different type.
       This allows copying of tag values when equating the structures of
       different types is not allowed, or when not all tags are to be copied.
       Can also recursively copy from/to structures nested within structures.
       Note that the number of elements in the output structure array
       is automatically adjusted to equal the length of input structure array.
       If this not desired then use pro copy_struct_inx which allows
       specifying via subscripts which elements are copied where in the arrays.

 CALLING SEQUENCE:

       copy_struct, struct_From, struct_To, NT_copied
       copy_struct, struct_From, struct_To, EXCEPT=["image","misc"]
       copy_struct, struct_From, struct_To, /RECUR_TANDEM

 INPUTS:
       struct_From = structure array to copy from.
       struct_To = structure array to copy values to.

 KEYWORDS:

       EXCEPT_TAGS = string array of tag names to ignore (to NOT copy).
               Used at all levels of recursion.

       SELECT_TAGS = tag names to copy (takes priority over EXCEPT).
               This keyword is not passed to recursive calls in order
               to avoid the confusion of not copying tags in sub-structures.

       /RECUR_FROM = search for sub-structures in struct_From, and then
               call copy_struct recursively for those nested structures.

       /RECUR_TO = search for sub-structures of struct_To, and then
               call copy_struct recursively for those nested structures.

       /RECUR_TANDEM = call copy_struct recursively for the sub-structures
               with matching Tag names in struct_From and struct_To
               (for use when Tag names match but sub-structure types differ).

 OUTPUTS:
       struct_To = structure array to which new tag values are copied.
       NT_copied = incremented by total # of tags copied (optional)

 INTERNAL:
       Recur_Level = # of times copy_struct calls itself.
               This argument is for internal recursive execution only.
               The user call is 1, subsequent recursive calls increment it,
               and the counter is decremented before returning.
               The counter is used just to find out if argument checking
               should be performed, and to set NT_copied = 0 first call.
 EXTERNAL CALLS:
       pro match       (when keyword SELECT_TAGS is specified)
 PROCEDURE:
       Match Tag names and then use corresponding Tag numbers.
 HISTORY:
       written 1989 Frank Varosi STX @ NASA/GSFC
       mod Jul.90 by F.V. added option to copy sub-structures RECURSIVELY.
       mod Aug.90 by F.V. adjust # elements in TO (output) to equal
                       # elements in FROM (input) & count # of fields copied.
       mod Jan.91 by F.V. added Recur_Level as internal argument so that
                       argument checking done just once, to avoid confusion.
                       Checked against Except_Tags in RECUR_FROM option.
       mod Oct.91 by F.V. added option SELECT_TAGS= selected field names.
       mod Aug.95 by W. Landsman to fix match of a single selected tag.
       mod Mar.97 by F.V. do not pass the SELECT_TAGS keyword in recursion.


CW_ANIMATE_DUPS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	CW_ANIMATE_DUPS

 PURPOSE:
	This widget displays an animated sequence of images using
	X-windows Pixmaps. This is a compound widget, based on the
	XINTERANIMATE procedure, with the following advantages:
		- It can be included in other applications.
		- Multiple copies can be run simultaneously.

	The speed and direction of the display can be adjusted using
	the widget interface.

 CATEGORY:
	Image display, compound widgets.

 CALLING SEQUENCE:
	To initially create:
		widget = CW_ANIMATE_DUPS(PARENT, SIZEX, SIZEY, NFRAMES)

	To reinitialize when another animation is loaded:
		CW_ANIMATE_DUPS_INIT, ANIMATEBASE, SIZEX, SIZEY, NFRAMES

	To load a single image:
		CW_ANIMATE_DUPS_LOAD, WIDGET, IMAGE = IMAGE, FRAME = FRAME_INDEX

	To load a single image that is already displayed in an existing window:

		CW_ANIMATE_DUPS_LOAD, WIDGET, FRAME = FRAME_INDEX, $
			WINDOW = [WINDOW_NUMBER [, X0, Y0, SX, SY]]

	(This technique is much faster than reading back from the window.)

	To display the animation after all the images have been loaded:

		CW_ANIMATE_DUPS, WIDGET [, RATE]

	To get a copy of the vector of Pixmaps being used by the widget.
	If this routine is called, the widget does not destroy the pixmaps
	when it is destroyed. The user can then provide them to a later
	call to CW_ANIMATE_DUPS to re-use them while skipping the Pixmap creation
	and rendering step:

		CW_ANIMATE_DUPS_GETP, widget, PIXMAPS

 INPUTS:
   CW_ANIMATE_DUPS:
		PARENT:	 The ID of the parent widget.
		SIZEX:	 The width of the displayed image.
		SIZEY:	 The height of the displayed image.
		NFRAMES: The number of frames in the animation sequence.

   CW_ANIMATE_DUPS_INIT:
		ANIMATEBASE: The ID of the base animation widget.
		SIZEX:	 The width of the displayed image.
		SIZEY:	 The height of the displayed image.
		NFRAMES: The number of frames in the animation sequence.

  	CW_ANIMATE_DUPS_LOAD:
		WIDGET:	 The ID of the widget (as created with CW_ANIMATE_DUPS)
			 into which the image should be loaded.

   CW_ANIMATE_DUPS_RUN:
		WIDGET:	 The ID of the widget (as created with CW_ANIMATE_DUPS)
			 into which the image should be loaded.
		RATE:	 A value between 0 and 100 that represents the
			 speed of the animation as a percentage of the
			 maximum display rate. The fastest animation has
			 a value of 100 and the slowest  has a value of 0.
			 The default animation rate is 100.
       STOP:    If this keyword is set, the animation is stopped.
       NFRAMES: Specifies the number of frames to animate, must
                        <= the number specified in CW_ANIMATE_DUPS().

 KEYWORD PARAMETERS:
   	CW_ANIMATE_DUPS:
		PIXMAPS: This keyword provides the new widget with a vector
			 of pre-existing pixmap (off screen window) IDs.
			 This vector is usually obtained from a call to
			 CW_ANIMATE_DUPS_GETP applied to a previous animation
			 widget.
		UVALUE:  A user supplied value to be stored in the widget's
			 user value field.
               UNAME:   A user supplied string name to be stored in the
                        widget's user name field.
               NO_KILL: If NOT set, an "End Animation" button is added to the
			 animation base.  If set the button is not added.
		OPEN_FUNC: A user supplied string that specifies a callback
			 function name. When a value is specified for this
			 keyword, an "Open..." pushbutton is added to the
			 window.  When the "Open..." pushbutton is clicked
			 the OPEN_FUNC function is called to load new
			 animation data.
		INFO_FILE: A filename containing text to be displayed by
                        XDISPLAYFILE when user selects the help button.

   	CW_ANIMATE_DUPS_INIT:
		PIXMAPS: This keyword provides the new widget with a vector
			 of pre-existing pixmap (off screen window) IDs.
			 This vector is usually obtained from a call to
			 CW_ANIMATE_DUPS_GETP applied to a previous animation
			 widget.

   	CW_ANIMATE_DUPS_LOAD:
		CYCLE:   If set, cycle. Normally, frames are displayed
			 going either forward or backwards. If CYCLE is
			 set, reverse direction after the last frame in
			 either direction is displayed.
		FRAME: 	 The frame number to be loaded. This is a value
			 between 0 and NFRAMES. If not supplied, frame 0
		  	 is loaded.
		IMAGE:   The image to be loaded.
		ORDER:   Set this keyword to display images from the top
			 down instead of the default bottom up. This keyword
			 is only used when loading images with the IMAGE
			 keyword.
		TRACK:   If set, the frame slider tracks the current frame.
			 Default is not to track.
		WINDOW:  When this keyword is specified, an image is copied
			 from an existing window to the animation pixmap.
			 When using X windows, this technique is much faster
			 than reading from the display and then loading with
			 the IMAGE keyword.

			 The value of this parameter is either an IDL window
			 number (in which case the entire window is copied),
			 or a vector containing the window index and the
			 rectangular bounds of the area to be copied. For
			 example:
			 WINDOW = [Window_Number, X0, Y0, Sx, Sy]

      		XOFFSET: The horizontal offset, in pixels from the left of
			 the frame, of the image in the destination window.

      		YOFFSET: The vertical offset, in pixels from the bottom of
			 the frame, of the image in the destination window.

 OUTPUTS:
	No explicit outputs.

 SIDE EFFECTS:
	If the widget is realized before calls to CW_ANIMATE_DUPS_LOAD, the frames
	are displayed as they are loaded. This provides the user with an
	indication of how things are progressing.

	When the widget is destroyed, it destroys the pixmaps used in the
	animation, unless they were previously obtained via CW_ANIMATE_DUPS_GETP
       and the KILL_ANYWAY keyword was not set.

	The only event returned by this widget indicates that the user
	has pressed the DONE button. The parent application should use
	this as a signal to kill the animation widget via WIDGET_CONTROL.

 RESTRICTIONS:
	If more than one animation widget is running at a time, they
	will fight for resources and run slower.

 PROCEDURE:
	When initialized, this procedure creates pixmaps containing the
	frames of the animation sequence. Once the images are loaded,
	they are displayed by copying the images from the pixmap or buffer
	to the visible draw widget.

 EXAMPLE:
	Assume the following event handler procedure exists:
		PRO EHANDLER, EV
		  WIDGET_CONTROL, /DESTROY, EV.TOP
		end

	Enter the following commands to open the file ABNORM.DAT (a series
	of images of a human heart) and load the images it contains into
	an array H:

		OPENR, 1, FILEPATH('abnorm.dat', SUBDIR = 'images')
		H = BYTARR(64, 64, 16)
		READU, 1, H
		CLOSE, 1
		H = REBIN(H, 128, 128, 16)

	Create an instance of the animation widget at load the frames:

		base = widget_base()
		animate = CW_ANIMATE_DUPS(base, 128, 128, 16)
		WIDGET_CONTROL, /REALIZE, base
		for i=0,15 do CW_ANIMATE_DUPS_LOAD, animate, FRAME=i, IMAGE=H[*,*,I]

	Start the animation:

		CW_ANIMATE_DUPS_RUN, animate
		XMANAGER, "CW_ANIMATE_DUPS Demo", base, EVENT_HANDLER = "EHANDLER"

	Pressing the DONE button kills the application.

 MODIFICATION HISTORY:
	AB, June 1992		Heavily based on the XINTERANIMATE procedure.
	SR, September 1992	Fixed a problem when a paused animation's
				frame selection was moved and the resulting
				frame change ended up in another animation.
	SR, November  1992	Fixed a problem when a single paused animation
				would fail when the frame selection slider
				event tried to set do a bad drawing window.
	DMS/AB, March, 1993	Got rid of state caching. Got rid of
				XMANAGER background tasks in favor of new
				"WIDGET_CONTROL,timer=" feature.
	ACY, October 1993	Set RETAIN=2 for draw widget to prevent
				clipping by an overlapping window when
				loading frames.
   DMS, Dec, 1993   Added STOP and NFRAMES keywords to CW_ANIMATE_DUPS_RUN.
                    Added KILL_ANYWAY keyword to CW_ANIMATE_DUPS_GETP.
   WSO, Jan, 1995   Added OPEN_FUNC keyword and updated UI.
   ACY, Jan, 1997   Added INFO_FILE keyword to allow user-supplied
                    files for help text
   JLP, Jan, 2000   Allow TrueColor images as input to CW_ANIMATE_DUPS_LOAD.
   WMD, Jul, 2010   Add NDUPS field when writing MPEGS so playback can be slower.
   WMD, Aug, 2010   Added button for writing QuickTime movies; "jmovie" script
		     needs to be known when spawned. At PPPL jmovie is aliased to
		     /p/nstxusr//util/scripts/javamoviemaker.csh which uses
		     /u/efeibush/w3_html/makemovie/jpegtomovie.jar


FIND_COMMON()

[Previous Routine] [Next Routine] [List of Routines]
 Project     : SOHO - CDS     
                   
 Name        : FIND_COMMON()
               
 Purpose     : Find which elements are common to the input vectors.
               
 Explanation : Returns the indices of the elements in second vector which
               are also present in the first vector.
               
 Use         : IDL> c = find_common(first, second)
    
 Inputs      : first  -  vector to be searched
               second -  search vector
               
 Opt. Inputs : None
               
 Outputs     : Function returns indices of elements in second vector which
               are common to first and second vectors
               
 Opt. Outputs: None
               
 Keywords    : None

 Calls       : FIND_DUP()

 Common      : None
               
 Restrictions: None
               
 Side effects: None
               
 Category    : Util
               
 Prev. Hist. : None

 Written     : C D Pike, RAL, 9-Nov-94
               
 Modified    : Make loop variable LONG.  CDP, 1-Oct-97

 Version     : Version 2, 1-Oct-97


FINDPEAKS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       findpeaks
 PURPOSE:
       Find peaks in a data array. To be a peak a local maximum must have
	a 25% higher range than the first and last quarter of the peak range.
 CATEGORY:
       Data Analysis
 CALLING SEQUENCE:
	IDL> peaks = findpeaks( data )
 INPUTS:
	data - array 
 OUTPUTS:
	peaks - (up to "maxPeaks") values of peaks found. Returns 0 if no
		peaks found.
 KEYWORDS:
   Optional Input:
	maxPeaks - max # of peaks to search for (DEF=2)
	AboveFrac - Fraction of peak height that peak must be above the 
		peak "tails" to be counted (default=0.25)
	NeighborhoodFrac - fraction of whole X range to be a neighborhood.
          	Range is initially divided up in these neighborhoods
		for determination of initial maxima.
	HowCloseToMax - if set, will not be considered a peak, if not within
		this fraction of maximum of whole data set.
	OnlyBig - if set will not count peaks 1/3 the size of the biggest peak
	Plot - if set, will plot data with vertical lines indicating which
		peaks qualified.
	Ordered - if set, returns peaks in order of highest first
   Optionally Returned via Keyword:
	indicesOfPeaks - array indices of peaks returned (=-1 if no peaks found)
	FWHM - full width at half max estimate, in indices
	nAbove - # points above 2*median
 EXAMPLE:
	IDL> data = mk_2peaks()
	IDL> peaks = findpeaks( data, /plot )

	IDL> peaks = findpeaks( data, indicesOfPeaks=indicesOfPeaks )
 COMMON BLOCKS:
       none
 NOTES:
	Maxima too close to the beginning and end of array are not counted.
       You may wish to do filtering or smoothing before passing data.
 LIMITATIONS:
	What constitutes a "peak" is subjective, so this won't fit all needs
 MODIFICATION HISTORY:
	03-Dec-2014 added output keyword nAbove
	07-Oct-2013 fixed bug when more than 16K points in a range being
		    examined for peaks (as in fast camera averages)
			added SATURATED keyword, to count peaks flattopping
	05-Aug-2008 Added HowCloseToMax keyword & many mods for finding Lithium peaks
	08-May-2003 Written by Bill Davis, PPPL


FLUXCOORDS

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       fluxcoords
 PURPOSE:
       Return flux coordinates for input R values at a given Z
 CATEGORY:
       Physics, Plotting
 CALLING SEQUENCE:
       IDL> newXs = fluxcoords( shot=shot, time=time, Radius=Radius, z=z )
 INPUTS:
       (only keywords) 
 KEYWORD PARAMETERS:
   Inputs
     Required:
	shot - NSTX shot number
	time - time after T0, in seconds
	Radius - floating point array of major radii, in meters
     Optional:
	Z - Z value (above mid-plane) in meters (default = 0), scalar or dimensioned 
	    same as Radius.
	fit - E.g., 'EFIT01', EFIT02', 'LRDFIT04', etc. (defaults to 'EFIT01')
	psi_n - if set, will return on psi_n surfaces
	verbose - if set, will print many informational messages
   Outputs
	newXs - transformed input points to rho or psi_n, depending on keyword inputs
	status - if odd, then was successful
 OUTPUTS:
       opt = returned value                                    out
 COMMON BLOCKS:
       NONE
 EXAMPLE:
       IDL> Radius=findgen(10)/10.*.30+1.50
       IDL> newXs = fluxcoords( shot=121100, time=0.205, Radius=Radius, fit='EFIT01') 
       IDL> newXs = fluxcoords( shot=120440, time=0.206, Radius=Radius, z=0.5, fit='lrdfit09') 
 NOTES:
       Slow 1st time called for each new time. Especially slow for LRDFIT trees because 
	need to an MDSCONNECT to VMS, for some reason, for this to work.
       
 MODIFICATION HISTORY:
	01-Oct-2008 Removed mdsconnect [BD]
       22-Feb-2007 Written by Bill Davis, PPPL, using LOTS of code from Jon Menard


GETCMODEFIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       getCmodEfit
 PURPOSE:
       Get efit data from CMOD for separatrix and limiter locations
 CATEGORY:
       CMOD
 CALLING SEQUENCE:
       IDL> 
 INPUTS:
       shot = CMOD shot number 
	
 KEYWORD PARAMETERS:
    Inputs:
	tree - MDSplus tree
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	status - if odd, then success
 OUTPUTS:
       
 COMMON BLOCKS:
       NONE
 EXAMPLE:
	IDL> getcmodefit, 1100824017, rbbbs=rbbbs, zbbbs=zbbbs, $
			nbbbs=nbbbs, efitTimes=efitTimes          ,/debug  
 NOTES:
 MODIFICATION HISTORY:
	29-Nov-2012 use connect_cmd
       21-Dec-2011 Written by Bill Davis, PPPL


GET_WEBPLOTSUM

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
 	get_webplotsum

 PURPOSE:
	Creates summary plots vs time with plasma current, D-alpha,
	injected power and stored energy (W-mhd).

 CATEGORY:
       Web
 CALLING SEQUENCE:
	IDL> image = get_webplotsum( ishot )
 INPUTS:
       shot = NSTX shot number 
	
 KEYWORD PARAMETERS:
    Inputs:
	(many)
 EXAMPLE:
   	image = get_webplotsum( ishot, tois=ftime[0:nActualTimes-1]/1000., $
   			     sig=signals, status=status )
   	if status then begin
   	   jfile = 'SHOTSUMMARY_'+strtrim( ishot, 2 )+'.jpeg'
   	   mk_jpeg, filename=dir+subDir+jfile, image=image
   	   PRINTF,LUN,''
   	endif

   	image = get_webplotsum( 127264, tois=[50,100,150,200,300]/1000.)
   	tv, image, true=1

 MODIFICATION HISTORY:
  	04-Mar-2008 call webplotsum to add W-mhd (stored energy) to plot
  	WRITTEN by Bill Davis, PPPL


IDLV4_TO_V5

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	IDLV4_TO_V5
 PURPOSE:
	Modify an IDL V4.0 (or earlier) procedure such that variables are 
	indexed using square brackets, as allowed (and suggested) 
	within IDL V5.0 and later

 CALLING SEQUENCE:
	IDLV4_TO_V5, infiles, outdir 

 INPUTS:
	infiles - scalar string specifying IDL procedure name(s), wild card 
		values allowed
	outdir - scalar string giving directory to contain output file.

 EXAMPLES:
	Convert the procedure curvefit.pro in the current directory to a
	IDL V5 version in the (Unix) idlv5 directory

	IDL> idlv4_to_v5,'curvefit.pro','idlv5/'

	Convert all the procedures in the current directory to IDL V5 versions
	in the /share/idlv5 directory

	IDL> idlv4_to_v5, '*.pro', '/share/idlv5/'

 METHOD:
	ISFUNCTION() is used to determine all the routine names in the file,
	and then ROUTINE_INFO() is used to determine the names of all variables
	in the procedure.    Each (non-commented) line is scanned for
	parentheses, and converted to square brackets if the token to the left
	of the left parenthesis matches a variable name.
 
 NOTES:
	(1) Only runs under IDL V5.0 (since it calls ROUTINE_INFO())
	(2) May possibly get confused by parenthesis within strings.
	(3) May get confused by IDL statements that extend over multiple lines
	    idlv4_to_v5 will supply a warning when it becomes confused by
	    unmatched parenthesis.
	(4) Do not include this procedure 'idlv4_to_v5' in the directory that 
	    you are trying to convert (since it will compile the procedure 
	    while executing it, and do a retall.)
	(5) Conversions cannot be performed unless specified procedure(s) 
	    already compile properly
	(6) Will not work on IDL main programs
	(7) May get confused by gaps between array name and parenthesis

 PROCEDURES CALLED:
	FDECOMP, MATCH, REMOVE, ISFUNCTION()
 REVISION HISTORY:
	Written  W. Landsman   Hughes STX     June 1997 
	Variable names can have numerals      August 1997
	Never change an intrinsic IDL function to square brackets, even if it
	is also a variable name.


MATCH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MATCH
 PURPOSE:
       Routine to match values in two vectors.

 CALLING SEQUENCE:
       match, a, b, suba, subb, [ COUNT =, /SORT ]

 INPUTS:
       a,b - two vectors to match elements, numeric or string datatype

 OUTPUTS:
       suba - subscripts of elements in vector a with a match
               in vector b
       subb - subscripts of the positions of the elements in
               vector b with matchs in vector a.

       suba and subb are ordered such that a[suba] equals b[subb]

 OPTIONAL INPUT KEYWORD:
       /SORT - By default, MATCH uses two different algorithm: (1) the 
               /REVERSE_INDICES keyword to HISTOGRAM is used for integer data,
               while a sorting algorithm is used for non-integer data.   The
               histogram algorithm is usually faster, except when the input
               vectors are sparse and contain very large numbers, possibly
               causing memory problems.   Use the /SORT keyword to always use
               the sort algorithm.
               
 OPTIONAL KEYWORD OUTPUT:
       COUNT - set to the number of matches, integer scalar

 SIDE EFFECTS:
       The obsolete system variable !ERR is set to the number of matches;
       however, the use !ERR is deprecated in favor of the COUNT keyword 

 RESTRICTIONS:
       The vectors a and b should not have duplicate values within them.
       You can use rem_dup function to remove duplicate values
       in a vector

 EXAMPLE:
       If a = [3,5,7,9,11]   & b = [5,6,7,8,9,10]
       then 
               IDL> match, a, b, suba, subb, COUNT = count

       will give suba = [1,2,3], subb = [0,2,4],  COUNT = 3
       and       suba[a] = subb[b] = [5,7,9]

 
 METHOD:
       For non-integer data types, the two input vectors are combined and
       sorted and the consecutive equal elements are identified.   For integer
       data types, the /REVERSE_INDICES keyword to HISTOGRAM of each array
       is used to identify where the two arrays have elements in common.   
 HISTORY:
       D. Lindler  Mar. 1986.
       Fixed "indgen" call for very large arrays   W. Landsman  Sep 1991
       Added COUNT keyword    W. Landsman   Sep. 1992
       Fixed case where single element array supplied   W. Landsman Aug 95
       Converted to IDL V5.0   W. Landsman   September 1997
       Use a HISTOGRAM algorithm for integer vector inputs for improved 
             performance                W. Landsman         March 2000
       Work again for strings           W. Landsman         April 2000


IJ2RZ

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       ij2rz
 PURPOSE:
       Convert from fast GPI camera pixels at CMOD or NSTX to R & Z
 CATEGORY:
       Fast 2-D Cameras
 CALLING SEQUENCE:
       IDL> ij2rz, shot=shot, cam=cam, nx=nx, ny=ny,  $
		     Rvals=Rvals, Zvals=Zvals
 INPUTS:
	
 KEYWORD PARAMETERS:
    Inputs:
       shot - CMOD or NSTX shot number (default to 1120224029)
	cam - default to 1 for NSTX (only one), but 2 (X-pt) for CMOD
	nx - # of pixels in X (defaults to that of camera)
	ny - # of pixels in Y (defaults to that of camera)
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
    Outputs:
	Rvals - 2-D array of R (major Radius) values in meters of pixel location 
		(at Gas Puff)
	Zvals - 2-D array of Z values (m) of pixel location (at Gas Puff)
 OUTPUTS:
 EXAMPLE:
	IDL> ij2rz, shot=1120224029, cam=1,  $  ; input
		    Rvals=Rvals, Zvals=Zvals	; returned
 NOTES:
	Unrotated images from NSTX are read as [80,64]. Since these need to
	to be rotated so up is up, default to ny=80.


 MODIFICATION HISTORY:
	25-Sep-2012 don't transpose R-Z values, so 80 pixels is in vertical direction
       27-Aug-2012 Written by Bill Davis, PPPL, for Stewart Zweben


ISFUNCTION()

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	ISFUNCTION()
 PURPOSE:
	Determine whether the IDL program(s) in a file are procedures or 
	functions.    Needed because the intrinisc RESOLVE_ROUTINE and 
	ROUTINE_INFO() procedures require the user to know beforehand whether 
	to supply the /IS_FUNCTION or /FUNCTION keywords.

 CALLING SEQUENCE:
	status = ISFUNCTION( filename, [ outnames, numlines]
 INPUT:
	filename = scalar string giving complete specification if file name
		(include .pro extension)

 OUTPUT:
	status - integer vector with number of elements equal to the number 
	of routines in the file.    Each status value consists of 0 or 1
	 1 - routine is an IDL function
	 0 - routine is an IDL procedure
	 If no valid IDL functions or procedures are found in the file, then
		ISFUNCTION() returns a scalar value of -1 

 OPTIONAL OUTPUTS:
	outnames - vector string, giving name of each IDL procedure or function
		in the file
	numlines - integer vector, giving the number of lines in each IDL
		procedure or function in the file
 PROCEDURE CALLS:
	FDECOMP
 REVISION HISTORY:
	Written, W. Landsman                  June, 1995


ISNUMBER

[Previous Routine] [Next Routine] [List of Routines]

 NAME:
       ISNUMBER
 PURPOSE:
       Determine if a text string is a valid number.
 CATEGORY:
 CALLING SEQUENCE:
       i = isnumber(txt, [x])
 INPUTS:
       txt = text string to test.                      in
 KEYWORD PARAMETERS:
 OUTPUTS:
       x = optionaly returned numeric value if valid.  out
       i = test flag:                                  out
           0: not a number.
           1: txt is a long integer.
           2: txt is a float.
           -1: first word of txt is a long integer.
           -2: first word of txt is a float.
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
	28-Feb-2011 don't call a character when has a minus sign [BD]
	15-Feb-2008 don't consider date string, like 02/15/2008, a number [BD]
	29-Oct-2007 return 0 if input not defined [BD]
	01-Dec-2006 handle structures (treat as not a number) [Bill Davis]
       Richard Garrett, 14 June, 1992 --- fixed bug in returned float value.
       R. Sterner, 12 Mar, 1990 --- upgraded.
       R. Sterner.  15 Oct, 1986.
       Johns Hopkins Applied Physics Lab.

 Copyright (C) 1986, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


LINT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       LINT
 PURPOSE:
       Find the intersection of two lines in the XY plane.
 CATEGORY:
 CALLING SEQUENCE:
       lint, a, b, c, d, i1, i2
 INPUTS:
       a, b = Points on line 1.          in
       c, d = Points on line 2.          in
 KEYWORD PARAMETERS:
       Keywords:
         FLAG=f  Returned flag:
           0 means no intersections (lines parallel).
           1 means one intersection.
           2 means all points intersect (lines coincide).
         /COND print condition number for linear system.
 OUTPUTS:
       i1, i2 = Returned intersection.   out
         Both i1 and i2 should be the same.
 COMMON BLOCKS:
 NOTES:
       Notes: Each point has the form [x,y].
 MODIFICATION HISTORY:
       R. Sterner, 1998 Feb 4

 Copyright (C) 1998, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


LISTFROMPERL

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
      listFromPerl
 PURPOSE:
       Called from a Perl Script to list MDSplus data from a Web Page
 CATEGORY:
       WebTools, MDSplus
 MODIFICATION HISTORY:
       14-Jul-04 added parseShotInput for handling inputs


MAKEN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MAKEN
 PURPOSE:
       Make an array of N values, linear between two given limits.
 CATEGORY:
 CALLING SEQUENCE:
       x = makex( first, last, num)
 INPUTS:
       first, last = array start and end values.          in
       num = number of values from first to last.         in
 KEYWORD PARAMETERS:
 OUTPUTS:
       x = array of values.                               out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
       Ray Sterner,  26 Sep, 1984.
       Johns Hopkins University Applied Physics Laboratory.

 Copyright (C) 1984, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


MAKENXY

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       MAKENXY
 PURPOSE:
       Make 2-d x and y coordinate arrays of specified dimensions.
 CATEGORY:
 CALLING SEQUENCE:
       makenxy, x1, x2, nx, y1, y2, ny, xarray, yarray
 INPUTS:
       x1 = min x coordinate in output rectangular array.  in
       x2 = max x coordinate in output rectangular array.  in
       nx = Number of steps in x.                          in
       y1 = min y coordinate in output rectangular array.  in
       y2 = max y coordinate in output rectangular array.  in
       ny = Number of steps in y.                          in
 KEYWORD PARAMETERS:
 OUTPUTS:
       xarray, yarray = resulting rectangular arrays.      out
 COMMON BLOCKS:
 NOTES:
 MODIFICATION HISTORY:
       R. Sterner, 1996 Jul 11

 Copyright (C) 1996, Johns Hopkins University/Applied Physics Laboratory
 This software may be used, copied, or redistributed as long as it is not
 sold and this copyright notice is reproduced on each copy made.  This
 routine is provided as is without any express or implied warranties
 whatsoever.  Other limitations apply as described in the file disclaimer.txt.


MDSW_NOCH

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mdsw_noch
 PURPOSE:
       Plot one MDS signal simply (without Crosshairs)
 CATEGORY:
       Example
 CALLING SEQUENCE:
       mdsw_noch
 COMMON BLOCKS:
       mdsw_noch
 NOTES:
       Your display may have to be set to 256 colors to see the crosshairs.
 LIMITATIONS:
	The printers and help file used here only work from UNIX.
	Only one version of this program may be run from a given IDL session.
 MODIFICATION HISTORY:
	11-Feb-99 Using UNSETUP_X rather than SETUP_X
	28-Jan-99 Took out cross-hair routines
	26-Jan-99 Modified for using MDS at PPPL by Bill Davis
       8/29/97 CH_example written by Bill Davis, 


MK_HTML_HELP

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	MK_HTML_HELP

 PURPOSE:
	Given a list of IDL procedure files (.PRO), VMS text library 
       files (.TLB), or directories that contain such files, this procedure 
       generates a file in the HTML format that contains the documentation 
       for those routines that contain a DOC_LIBRARY style documentation 
       template.  The output file is compatible with World Wide Web browsers.

 CATEGORY:
	Help, documentation.

 CALLING SEQUENCE:
	MK_HTML_HELP, Sources, Outfile

 INPUTS:
     Sources:  A string or string array containing the name(s) of the
		.pro or .tlb files (or the names of directories containing 
               such files) for which help is desired.  If a source file is 
               a VMS text library, it must include the .TLB file extension.  
               If a source file is an IDL procedure, it must include the .PRO
               file extension.  All other source files are assumed to be
               directories.
     Outfile:	The name of the output file which will be generated.

 KEYWORDS:
     BY_CATEGORY: if set, will group output by their first Category
     INCLUDE:	set to 'CATEGORY' or 'PURPOSE' to include at top of the file
     TITLE:	If present, a string which supplies the name that
		should appear as the Document Title for the help.
     VERBOSE:	Normally, MK_HTML_HELP does its work silently.
		Setting this keyword to a non-zero value causes the procedure
		to issue informational messages that indicate what it
		is currently doing. !QUIET must be 0 for these messages
               to appear.
     STRICT:   If this keyword is set to a non-zero value, MK_HTML_HELP will 
               adhere strictly to the HTML format by scanning the 
               the document headers for characters that are reserved in 
               HTML (<,>,&,").  These are then converted to the appropriate 
               HTML syntax in the output file. By default, this keyword
               is set to zero (to allow for faster processing).
     EXTENSION: if want to do the for files other than .pro files
     STARTHEAD: characters at the beginning of a line which indicate the 
		header start (default = ';+')
     STOPHEAD:  characters at the beginning of a line which indicate the 
		header end (default = ';-')

     caveat:	string that will be displayed above the links, like a copyright
		notice.
 EXAMPLE:
     if on Unix:
	% cd directory-where-web-pages-will-be
	   (e.g., /w/nstx.pppl.gov/htdocs/nstx/Software/Programming)

	% rm pro_sources.txt
	% /bin/ls -1 the-directory-with-IDL-code/*.pro > pro_sources.txt
	   (e.g., ./src/cvs/idl_cvs)
	% idl
	IDL> sources = READ_LIST('pro_sources.txt')
	IDL> MK_HTML_HELP, sources, 'idl_routines.html', include='purpose',/by_category
	IDL> exit
     This just gives a relative path, but the web link will find it.
     When /BY_CATEGORY is specified, an additional page, e.g., 
     idl_routines_alphabet.html, will be produced as well.

 COMMON BLOCKS:
	None.

 SIDE EFFECTS:
	A help file with the name given by the Outfile argument is
	created.

 RESTRICTIONS:
	The following rules must be followed in formatting the .pro
	files that are to be searched.
		(a) The first line of the documentation block contains
		    only the characters ";+", starting in column 1.
               (b) There must be a line which contains the string "NAME:",
                   which is immediately followed (same or next line) by the
                   name of the procedure or function being described in
                   that documentation block.  If this NAME field is not
                   present, the name of the source file will be used.
		(c) Likewise, for organizing by category, after the purpose,
		    The "CATEGORY:" line should follow. If fitting, use one of
		    existing categories as the first category (the only one 
		    sorted on). If less than two routines are in a category,
		    they are listed in the Misc category.
		(d) The last line of the documentation block contains
		    the characters ";-", starting in column 1.
		(e) Every other line in the documentation block contains
		    a ";" in column 1.

       Note that a single .pro file can contain multiple procedures and/or
       functions, each with their own documentation blocks. If it is desired
       to have "invisible" routines in a file, i.e. routines which are only
       for internal use and should not appear in the help file, simply leave
       out the ";+" and ";-" lines in the documentation block for those
       routines.

 MODIFICATION HISTORY:
	26-Sep-2013 option to not put link to actual code
	04-May-01 Add /BY_CATEGORY switch [BD]
	31-Oct-00 Add link to actual code [BD]
	07-Jun-99 Added Extension keyword [BD]
	01-Apr-99 Allow CATEGORY or PURPOSE to be included in the top of 
		  of the HTML file [Bill Davis]
       July 17, 1995, DD, RSI. Added code to alphabetize the subjects;
               At the end of each description block in the HTML file,
               added a reference to the source .pro file.
       July 13, 1995, Mark Rivers, University of Chicago. Added support for
               multiple source directories and multiple documentation
               headers per .pro file.
       July 5, 1995, DD, RSI. Original version.


MK_SHOTLIST

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
	mk_shotlist
 PURPOSE:
	Parse an input string for shots into an array of shots
 CATEGORY:
	Input, MDSplus
 CALLING SEQUENCE:
	IDL> shotlist = mk_shotlist(input)
 INPUTS:
	input =e.g., 107694 108305 108330-108350
		(108100+20 will search 108100-108120)
	      if a shot number is given as 0, use latest MDSplus shot
 KEYWORD PARAMETERS:
	dupsOK - if=0, will remove duplicate shot numbers
 OUTPUTS:
	opt = returned value                 			out
 COMMON BLOCKS:
	NONE
 EXAMPLES:
	IDL> print,mk_shotlist('112300+3')
	      112300      112301      112302      112303
	IDL> print,mk_shotlist('112300-4')
	      112300      112299      112298      112297      112296
	IDL> print,mk_shotlist('0+3')
	      113862      113863      113864      113865
	IDL> print,mk_shotlist('0-3')
	      113862      113861      113860      113859
	IDL> print,mk_shotlist('112300-112302 112305+2')
	      112300      112301      112302      112305      112306      112307
	IDL> print,mk_shotlist('107694 108305 108330-108332')
	      107694      108305      108330      108331      108332
	IDL> print,mk_shotlist('4(138846) 4(138847)')
	IDL> print,mk_shotlist('138846-2  4(138847)')
 NOTES:
	When there are duplicate shots, the list is ordered, and the duplicates 
	removed.
 MODIFICATION HISTORY:
	22-Jul-2013 allow inputs with multipliers, like 4(138846)
		*** made the default dupsOK=1
	23-Nov-2009 fixed bug with test for negative shot number
	08-Aug-07 added dupsOK keyword
	21-Aug-06 Allow for blanks around "-" and "+"
	14-Jul-04 Written by Bill Davis, PPPL


MK_WTINPUTFILE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
       mk_wtinputfile

 PURPOSE:
       Create an input file for Web Plotting Tools, like
	http://nstx.pppl.gov/nstx/Software/WebTools/mdsplotfileinput.php
	from an MDSplus Scope or jScope input file.

 CATEGORY:
       WebTools, MDSplus, SCOPE

 CALLING SEQUENCE:
	mk_wtinputfile, scopeFile, wtFile, status=status

 INPUTS:
   	scopeFile - name of a scope file
	wtFile -  name of web tool input file (defaults to *.txt)

 KEYWORDS:
	verbose - if set, will print many informational messages
	debug - if set, debug output will be printed
	jScope - if set, the input file is assumed to be a jScope input file

 RETURNED:
	status - if odd #, then was successful.

 OUTPUT:
	file wtFile is created. 

 NOTES:
	can handle multi-signal expressions, but tree will only be added
	to the first signal, so, if all signals must be in the first tree

 LIMITATIONS:
	Does not work with jScope files (yet)

 EXAMPLES:
	IDL> scopeFile = '/p/nstxusr/util/scopes/wfplus.scope'
	IDL> wtFile = 'wfplus.txt'
	IDL> mk_wtinputfile, scopeFile, wtFile

	IDL> scopeFile = '/u/bdavis/bdtest.jscp'
	IDL> mk_wtinputfile, scopeFile	; will output to bdtest.txt

	IDL> mk_wtinputfile, "/u/psichta/scopes/pcs.jscp", "pcs.txt"

 MODIFICATION HISTORY:
	12-Feb-2014 added jScope keyword, so don't have to rely on .jscp ext
	10-Feb-2014 Written by Bill Davis


MPCURVEFIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPCURVEFIT

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Perform Levenberg-Marquardt least-squares fit (replaces CURVEFIT)

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   YFIT = MPCURVEFIT(X, Y, WEIGHTS, P, [SIGMA,] FUNCTION_NAME=FUNC, 
                     ITER=iter, ITMAX=itmax, 
                     CHISQ=chisq, NFREE=nfree, DOF=dof, 
                     NFEV=nfev, COVAR=covar, [/NOCOVAR, ] [/NODERIVATIVE, ]
                     FUNCTARGS=functargs, PARINFO=parinfo,
                     FTOL=ftol, XTOL=xtol, GTOL=gtol, TOL=tol,
                     ITERPROC=iterproc, ITERARGS=iterargs,
                     NPRINT=nprint, QUIET=quiet, 
                     ERRMSG=errmsg, STATUS=status)

 DESCRIPTION:

  MPCURVEFIT fits a user-supplied model -- in the form of an IDL
  function -- to a set of user-supplied data.  MPCURVEFIT calls
  MPFIT, the MINPACK-1 least-squares minimizer, to do the main
  work.

  Given the data and their uncertainties, MPCURVEFIT finds the best
  set of model parameters which match the data (in a least-squares
  sense) and returns them in the parameter P.  

  MPCURVEFIT returns the best fit function.
  
  The user must supply the following items:
   - An array of independent variable values ("X").
   - An array of "measured" *dependent* variable values ("Y").
   - An array of weighting values ("WEIGHTS").
   - The name of an IDL function which computes Y given X ("FUNC").
   - Starting guesses for all of the parameters ("P").

  There are very few restrictions placed on X, Y or FUNCT.  Simply
  put, FUNCT must map the "X" values into "Y" values given the
  model parameters.  The "X" values may represent any independent
  variable (not just Cartesian X), and indeed may be multidimensional
  themselves.  For example, in the application of image fitting, X
  may be a 2xN array of image positions.

  MPCURVEFIT carefully avoids passing large arrays where possible to
  improve performance.

  See below for an example of usage.
   
 USER FUNCTION

  The user must define a function which returns the model value.  For
  applications which use finite-difference derivatives -- the default
  -- the user function should be declared in the following way:

    ; MYFUNCT - example user function
    ;   X - input independent variable (vector same size as data)
    ;   P - input parameter values (N-element array)
    ;   YMOD - upon return, user function values
    ;   DP - upon return, the user function must return
    ;          an ARRAY(M,N) of derivatives in this parameter
    ;
    PRO MYFUNCT, x, p, ymod, dp
     ymod = F(x, p)         ;; Model function
     
     if n_params() GE 4  then begin
       ; Create derivative and compute derivative array
       dp = make_array(n_elements(x), n_elements(p), value=x[0]*0)

       ; Compute derivative if requested by caller
       for i = 0, n_elements(p)-1 do dp(*,i) = FGRAD(x, p, i)
     endif
    END

  where FGRAD(x, p, i) is a model function which computes the
  derivative of the model F(x,p) with respect to parameter P(i) at X.
  The returned array YMOD must have the same dimensions and type as
  the "measured" Y values.  The returned array DP[i,j] is the
  derivative of the ith function value with respect to the jth
  parameter.

  User functions may also indicate a fatal error condition
  using the ERROR_CODE common block variable, as described
  below under the MPFIT_ERROR common block definition.
 
  If NODERIVATIVE=1, then MPCURVEFIT will never request explicit
  derivatives from the user function, and instead will user numerical
  estimates (i.e. by calling the user function multiple times).

 CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD

  The behavior of MPFIT can be modified with respect to each
  parameter to be fitted.  A parameter value can be fixed; simple
  boundary constraints can be imposed; limitations on the parameter
  changes can be imposed; properties of the automatic derivative can
  be modified; and parameters can be tied to one another.

  These properties are governed by the PARINFO structure, which is
  passed as a keyword parameter to MPFIT.

  PARINFO should be an array of structures, one for each parameter.
  Each parameter is associated with one element of the array, in
  numerical order.  The structure can have the following entries
  (none are required):
  
     .VALUE - the starting parameter value (but see the START_PARAMS
              parameter for more information).
  
     .FIXED - a boolean value, whether the parameter is to be held
              fixed or not.  Fixed parameters are not varied by
              MPFIT, but are passed on to MYFUNCT for evaluation.
  
     .LIMITED - a two-element boolean array.  If the first/second
                element is set, then the parameter is bounded on the
                lower/upper side.  A parameter can be bounded on both
                sides.  Both LIMITED and LIMITS must be given
                together.
  
     .LIMITS - a two-element float or double array.  Gives the
               parameter limits on the lower and upper sides,
               respectively.  Zero, one or two of these values can be
               set, depending on the values of LIMITED.  Both LIMITED
               and LIMITS must be given together.
  
     .PARNAME - a string, giving the name of the parameter.  The
                fitting code of MPFIT does not use this tag in any
                way.  However, the default ITERPROC will print the
                parameter name if available.
  
     .STEP - the step size to be used in calculating the numerical
             derivatives.  If set to zero, then the step size is
             computed automatically.  Ignored when AUTODERIVATIVE=0.
             This value is superceded by the RELSTEP value.

     .RELSTEP - the *relative* step size to be used in calculating
                the numerical derivatives.  This number is the
                fractional size of the step, compared to the
                parameter value.  This value supercedes the STEP
                setting.  If the parameter is zero, then a default
                step size is chosen.

     .MPSIDE - the sidedness of the finite difference when computing
               numerical derivatives.  This field can take four
               values:

                  0 - one-sided derivative computed automatically
                  1 - one-sided derivative (f(x+h) - f(x)  )/h
                 -1 - one-sided derivative (f(x)   - f(x-h))/h
                  2 - two-sided derivative (f(x+h) - f(x-h))/(2*h)

              Where H is the STEP parameter described above.  The
              "automatic" one-sided derivative method will chose a
              direction for the finite difference which does not
              violate any constraints.  The other methods do not
              perform this check.  The two-sided method is in
              principle more precise, but requires twice as many
              function evaluations.  Default: 0.

     .MPMAXSTEP - the maximum change to be made in the parameter
                  value.  During the fitting process, the parameter
                  will never be changed by more than this value in
                  one iteration.

                  A value of 0 indicates no maximum.  Default: 0.
  
     .TIED - a string expression which "ties" the parameter to other
             free or fixed parameters.  Any expression involving
             constants and the parameter array P are permitted.
             Example: if parameter 2 is always to be twice parameter
             1 then use the following: parinfo(2).tied = '2 * P(1)'.
             Since they are totally constrained, tied parameters are
             considered to be fixed; no errors are computed for them.
             [ NOTE: the PARNAME can't be used in expressions. ]

     .MPPRINT - if set to 1, then the default ITERPROC will print the
                parameter value.  If set to 0, the parameter value
                will not be printed.  This tag can be used to
                selectively print only a few parameter values out of
                many.  Default: 1 (all parameters printed)

  
  Future modifications to the PARINFO structure, if any, will involve
  adding structure tags beginning with the two letters "MP".
  Therefore programmers are urged to avoid using tags starting with
  the same letters; otherwise they are free to include their own
  fields within the PARINFO structure, and they will be ignored.
  
  PARINFO Example:
  parinfo = replicate({value:0.D, fixed:0, limited:[0,0], $
                       limits:[0.D,0]}, 5)
  parinfo(0).fixed = 1
  parinfo(4).limited(0) = 1
  parinfo(4).limits(0)  = 50.D
  parinfo(*).value = [5.7D, 2.2, 500., 1.5, 2000.]
  
  A total of 5 parameters, with starting values of 5.7,
  2.2, 500, 1.5, and 2000 are given.  The first parameter
  is fixed at a value of 5.7, and the last parameter is
  constrained to be above 50.

 INPUTS:
   X - Array of independent variable values.

   Y - Array of "measured" dependent variable values.  Y should have
       the same data type as X.  The function FUNCT should map
       X->Y.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  If WEIGHTS is specified then the ERR
             parameter is ignored.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Y-FUNCT(X,P))^2 * ABS(WEIGHTS) )

             Here are common values of WEIGHTS:

                1D/ERR^2 - Normal weighting (ERR is the measurement error)
                1D/Y     - Poisson weighting (counting statistics)
                1D       - Unweighted

   P - An array of starting values for each of the parameters of the
       model.  The number of parameters should be fewer than the
       number of measurements.  Also, the parameters should have the
       same data type as the measurements (double is preferred).

       Upon successful completion the new parameter values are
       returned in P.

       If both START_PARAMS and PARINFO are passed, then the starting
       *value* is taken from START_PARAMS, but the *constraints* are
       taken from PARINFO.
 
   SIGMA - The formal 1-sigma errors in each parameter, computed from
           the covariance matrix.  If a parameter is held fixed, or
           if it touches a boundary, then the error is reported as
           zero.

           If the fit is unweighted (i.e. no errors were given, or
           the weights were uniformly set to unity), then SIGMA will
           probably not represent the true parameter uncertainties.

           *If* you can assume that the true reduced chi-squared
           value is unity -- meaning that the fit is implicitly
           assumed to be of good quality -- then the estimated
           parameter uncertainties can be computed by scaling SIGMA
           by the measured chi-squared value.

              DOF     = N_ELEMENTS(X) - N_ELEMENTS(P) ; deg of freedom
              CSIGMA  = SIGMA * SQRT(CHISQ / DOF)     ; scaled uncertainties

 RETURNS:

   Returns the array containing the best-fitting function.

 KEYWORD PARAMETERS:

   CHISQ - the value of the summed, squared, weighted residuals for
           the returned parameter values, i.e. the chi-square value.

   COVAR - the covariance matrix for the set of parameters returned
           by MPFIT.  The matrix is NxN where N is the number of
           parameters.  The square root of the diagonal elements
           gives the formal 1-sigma statistical errors on the
           parameters IF errors were treated "properly" in MYFUNC.
           Parameter errors are also returned in PERROR.

           To compute the correlation matrix, PCOR, use this:
           IDL> PCOR = COV * 0
           IDL> FOR i = 0, n-1 DO FOR j = 0, n-1 DO $
                PCOR(i,j) = COV(i,j)/sqrt(COV(i,i)*COV(j,j))

           If NOCOVAR is set or MPFIT terminated abnormally, then
           COVAR is set to a scalar with value !VALUES.D_NAN.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).

   ERRMSG - a string error or warning message is returned.

   FTOL - a nonnegative input variable. Termination occurs when both
          the actual and predicted relative reductions in the sum of
          squares are at most FTOL (and STATUS is accordingly set to
          1 or 3).  Therefore, FTOL measures the relative error
          desired in the sum of squares.  Default: 1D-10

   FUNCTION_NAME - a scalar string containing the name of an IDL
                   procedure to compute the user model values, as
                   described above in the "USER MODEL" section.

   FUNCTARGS - A structure which contains the parameters to be passed
               to the user-supplied function specified by FUNCT via
               the _EXTRA mechanism.  This is the way you can pass
               additional data to your user-supplied function without
               using common blocks.

               By default, no extra parameters are passed to the
               user-supplied function.

   GTOL - a nonnegative input variable. Termination occurs when the
          cosine of the angle between fvec and any column of the
          jacobian is at most GTOL in absolute value (and STATUS is
          accordingly set to 4). Therefore, GTOL measures the
          orthogonality desired between the function vector and the
          columns of the jacobian.  Default: 1D-10

   ITER - the number of iterations completed.

   ITERARGS - The keyword arguments to be passed to ITERPROC via the
              _EXTRA mechanism.  This should be a structure, and is
              similar in operation to FUNCTARGS.
              Default: no arguments are passed.

   ITERPROC - The name of a procedure to be called upon each NPRINT
              iteration of the MPFIT routine.  It should be declared
              in the following way:

              PRO ITERPROC, FUNCT, p, iter, fnorm, FUNCTARGS=fcnargs, $
                PARINFO=parinfo, QUIET=quiet, ...
                ; perform custom iteration update
              END
         
              ITERPROC must either accept all three keyword
              parameters (FUNCTARGS, PARINFO and QUIET), or at least
              accept them via the _EXTRA keyword.
          
              FUNCT is the user-supplied function to be minimized,
              P is the current set of model parameters, ITER is the
              iteration number, and FUNCTARGS are the arguments to be
              passed to FUNCT.  FNORM should be the
              chi-squared value.  QUIET is set when no textual output
              should be printed.  See below for documentation of
              PARINFO.

              In implementation, ITERPROC can perform updates to the
              terminal or graphical user interface, to provide
              feedback while the fit proceeds.  If the fit is to be
              stopped for any reason, then ITERPROC should set the
              common block variable ERROR_CODE to negative value (see
              MPFIT_ERROR common block below).  In principle,
              ITERPROC should probably not modify the parameter
              values, because it may interfere with the algorithm's
              stability.  In practice it is allowed.

              Default: an internal routine is used to print the
                       parameter values.

   ITMAX - The maximum number of iterations to perform.  If the
             number is exceeded, then the STATUS value is set to 5
             and MPFIT returns.
             Default: 200 iterations

   NFEV - the number of FUNCT function evaluations performed.

   NFREE - the number of free parameters in the fit.  This includes
           parameters which are not FIXED and not TIED, but it does
           include parameters which are pegged at LIMITS.

   NOCOVAR - set this keyword to prevent the calculation of the
             covariance matrix before returning (see COVAR)

   NODERIVATIVE - if set, then the user function will not be queried
                  for analytical derivatives, and instead the
                  derivatives will be computed by finite differences
                  (and according to the PARINFO derivative settings;
                  see above for a description).

   NPRINT - The frequency with which ITERPROC is called.  A value of
            1 indicates that ITERPROC is called with every iteration,
            while 2 indicates every other iteration, etc.  Note that
            several Levenberg-Marquardt attempts can be made in a
            single iteration.
            Default value: 1

   PARINFO - Provides a mechanism for more sophisticated constraints
             to be placed on parameter values.  When PARINFO is not
             passed, then it is assumed that all parameters are free
             and unconstrained.  Values in PARINFO are never 
             modified during a call to MPFIT.

             See description above for the structure of PARINFO.

             Default value:  all parameters are free and unconstrained.

   QUIET - set this keyword when no textual output should be printed
           by MPFIT

   STATUS - an integer status code is returned.  All values other
            than zero can represent success.  It can have one of the
            following values:

	   0  improper input parameters.
         
	   1  both actual and predicted relative reductions
	      in the sum of squares are at most FTOL.
         
	   2  relative error between two consecutive iterates
	      is at most XTOL
         
	   3  conditions for STATUS = 1 and STATUS = 2 both hold.
         
	   4  the cosine of the angle between fvec and any
	      column of the jacobian is at most GTOL in
	      absolute value.
         
	   5  the maximum number of iterations has been reached
         
	   6  FTOL is too small. no further reduction in
	      the sum of squares is possible.
         
	   7  XTOL is too small. no further improvement in
	      the approximate solution x is possible.
         
	   8  GTOL is too small. fvec is orthogonal to the
	      columns of the jacobian to machine precision.

   TOL - synonym for FTOL.  Use FTOL instead.

   XTOL - a nonnegative input variable. Termination occurs when the
          relative error between two consecutive iterates is at most
          XTOL (and STATUS is accordingly set to 2 or 3).  Therefore,
          XTOL measures the relative error desired in the approximate
          solution.  Default: 1D-10

   YERROR - upon return, the root-mean-square variance of the
            residuals.


 EXAMPLE:

   ; First, generate some synthetic data
   npts = 200
   x  = dindgen(npts) * 0.1 - 10.                  ; Independent variable 
   yi = gauss1(x, [2.2D, 1.4, 3000.])              ; "Ideal" Y variable
   y  = yi + randomn(seed, npts) * sqrt(1000. + yi); Measured, w/ noise
   sy = sqrt(1000.D + y)                           ; Poisson errors

   ; Now fit a Gaussian to see how well we can recover
   p0 = [1.D, 1., 1000.]                           ; Initial guess
   yfit = mpcurvefit(x, y, 1/sy^2, p0, $           ; Fit a function
                     FUNCTION_NAME='GAUSS1P',/autoderivative)
   print, p

   Generates a synthetic data set with a Gaussian peak, and Poisson
   statistical uncertainty.  Then the same function is fitted to the
   data to see how close we can get.  GAUSS1 and GAUSS1P are
   available from the same web page.


 COMMON BLOCKS:

   COMMON MPFIT_ERROR, ERROR_CODE

     User routines may stop the fitting process at any time by
     setting an error condition.  This condition may be set in either
     the user's model computation routine (MYFUNCT), or in the
     iteration procedure (ITERPROC).

     To stop the fitting, the above common block must be declared,
     and ERROR_CODE must be set to a negative number.  After the user
     procedure or function returns, MPFIT checks the value of this
     common block variable and exits immediately if the error
     condition has been set.  By default the value of ERROR_CODE is
     zero, indicating a successful function/procedure call.

 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:
   Translated from MPFITFUN, 25 Sep 1999, CM
   Alphabetized documented keywords, 02 Oct 1999, CM
   Added QUERY keyword and query checking of MPFIT, 29 Oct 1999, CM
   Check to be sure that X and Y are present, 02 Nov 1999, CM
   Documented SIGMA for unweighted fits, 03 Nov 1999, CM
   Changed to ERROR_CODE for error condition, 28 Jan 2000, CM
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Propagated improvements from MPFIT, 17 Dec 2000, CM
   Corrected behavior of NODERIVATIVE, 13 May 2002, CM
   Documented RELSTEP field of PARINFO (!!), CM, 25 Oct 2002
   Make more consistent with comparable IDL routines, 30 Jun 2003, CM
   Minor documentation adjustment, 03 Feb 2004, CM
   Fix error in documentation, 26 Aug 2005, CM
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   Move STRICTARR compile option inside each function/procedure, 9 Oct 2006
   Fix bug in handling of explicit derivatives with errors/weights
     (the weights were not being applied), CM, 2012-07-22
   Add more documentation on calling interface for user function and
     parameter derivatives, CM, 2012-07-22

  $Id: mpcurvefit.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFIT2DFUN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFIT2DFUN

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Perform Levenberg-Marquardt least-squares fit to a 2-D IDL function

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   parms = MPFIT2DFUN(MYFUNCT, X, Y, Z, ERR, start_parms, ...)

 DESCRIPTION:

  MPFIT2DFUN fits a user-supplied model -- in the form of an IDL
  function -- to a set of user-supplied data.  MPFIT2DFUN calls
  MPFIT, the MINPACK-1 least-squares minimizer, to do the main
  work.  MPFIT2DFUN is a specialized version for two-dimensional 
  data.

  Given the data and their uncertainties, MPFIT2DFUN finds the best set
  of model parameters which match the data (in a least-squares
  sense) and returns them in an array.
  
  The user must supply the following items:
   - Two arrays of independent variable values ("X", "Y").
   - An array of "measured" *dependent* variable values ("Z").
   - An array of "measured" 1-sigma uncertainty values ("ERR").
   - The name of an IDL function which computes Z given (X,Y) ("MYFUNCT").
   - Starting guesses for all of the parameters ("START_PARAMS").

  There are very few restrictions placed on X, Y, Z, or MYFUNCT.
  Simply put, MYFUNCT must map the (X,Y) values into Z values given
  the model parameters.  The (X,Y) values are usually the independent
  X and Y coordinate positions in the two dimensional plane, but need
  not be.

  MPFIT2DFUN carefully avoids passing large arrays where possible to
  improve performance.

  See below for an example of usage.
   
 USER FUNCTION

  The user must define a function which returns the model value.  For
  applications which use finite-difference derivatives -- the default
  -- the user function should be declared in the following way:

    FUNCTION MYFUNCT, X, Y, P
     ; The independent variables are X and Y
     ; Parameter values are passed in "P"
     ZMOD = ... computed model values at (X,Y) ...
     return, ZMOD
    END

  The returned array YMOD must have the same dimensions and type as
  the "measured" Z values.

  User functions may also indicate a fatal error condition
  using the ERROR_CODE common block variable, as described
  below under the MPFIT_ERROR common block definition.

  See the discussion under "ANALYTIC DERIVATIVES" and AUTODERIVATIVE
  in MPFIT.PRO if you wish to compute the derivatives for yourself.
  AUTODERIVATIVE is accepted and passed directly to MPFIT.  The user
  function must accept one additional parameter, DP, which contains
  the derivative of the user function with respect to each parameter
  at each data point, as described in MPFIT.PRO.

 CREATING APPROPRIATELY DIMENSIONED INDEPENDENT VARIABLES

  The user must supply appropriate independent variables to
  MPFIT2DFUN.  For image fitting applications, this variable should
  be two-dimensional *arrays* describing the X and Y positions of
  every *pixel*.  [ Thus any two dimensional sampling is permitted,
  including irregular sampling. ]
  
  If the sampling is regular, then the x coordinates are the same for
  each row, and the y coordinates are the same for each column.  Call
  the x-row and y-column coordinates XR and YC respectively.  You can
  then compute X and Y as follows:
  
      X = XR # (YC*0 + 1)             eqn. 1
      Y = (XR*0 + 1) # YC             eqn. 2
  
  For example, if XR and YC have the following values:
  
    XR = [  1, 2, 3, 4, 5,]  ;; X positions of one row of pixels
    YC = [ 15,16,17 ]        ;; Y positions of one column of
                                pixels
  
  Then using equations 1 and 2 above will give these values to X and
  Y:
  
     X :  1  2  3  4  5       ;; X positions of all pixels
          1  2  3  4  5
          1  2  3  4  5
  
     Y : 15 15 15 15 15       ;; Y positions of all pixels
         16 16 16 16 16
         17 17 17 17 17
  
  Using the above technique is suggested, but *not* required.  You
  can do anything you wish with the X and Y values.  This technique
  only makes it easier to compute your model function values.

 CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD

  The behavior of MPFIT can be modified with respect to each
  parameter to be fitted.  A parameter value can be fixed; simple
  boundary constraints can be imposed; limitations on the parameter
  changes can be imposed; properties of the automatic derivative can
  be modified; and parameters can be tied to one another.

  These properties are governed by the PARINFO structure, which is
  passed as a keyword parameter to MPFIT.

  PARINFO should be an array of structures, one for each parameter.
  Each parameter is associated with one element of the array, in
  numerical order.  The structure can have the following entries
  (none are required):
  
     .VALUE - the starting parameter value (but see the START_PARAMS
              parameter for more information).
  
     .FIXED - a boolean value, whether the parameter is to be held
              fixed or not.  Fixed parameters are not varied by
              MPFIT, but are passed on to MYFUNCT for evaluation.
  
     .LIMITED - a two-element boolean array.  If the first/second
                element is set, then the parameter is bounded on the
                lower/upper side.  A parameter can be bounded on both
                sides.  Both LIMITED and LIMITS must be given
                together.
  
     .LIMITS - a two-element float or double array.  Gives the
               parameter limits on the lower and upper sides,
               respectively.  Zero, one or two of these values can be
               set, depending on the values of LIMITED.  Both LIMITED
               and LIMITS must be given together.
  
     .PARNAME - a string, giving the name of the parameter.  The
                fitting code of MPFIT does not use this tag in any
                way.  However, the default ITERPROC will print the
                parameter name if available.
  
     .STEP - the step size to be used in calculating the numerical
             derivatives.  If set to zero, then the step size is
             computed automatically.  Ignored when AUTODERIVATIVE=0.
             This value is superceded by the RELSTEP value.

     .RELSTEP - the *relative* step size to be used in calculating
                the numerical derivatives.  This number is the
                fractional size of the step, compared to the
                parameter value.  This value supercedes the STEP
                setting.  If the parameter is zero, then a default
                step size is chosen.

     .MPSIDE - the sidedness of the finite difference when computing
               numerical derivatives.  This field can take four
               values:

                  0 - one-sided derivative computed automatically
                  1 - one-sided derivative (f(x+h) - f(x)  )/h
                 -1 - one-sided derivative (f(x)   - f(x-h))/h
                  2 - two-sided derivative (f(x+h) - f(x-h))/(2*h)

              Where H is the STEP parameter described above.  The
              "automatic" one-sided derivative method will chose a
              direction for the finite difference which does not
              violate any constraints.  The other methods do not
              perform this check.  The two-sided method is in
              principle more precise, but requires twice as many
              function evaluations.  Default: 0.

     .MPMINSTEP - the minimum change to be made in the parameter
                  value.  During the fitting process, the parameter
                  will be changed by multiples of this value.  The
                  actual step is computed as:

                     DELTA1 = MPMINSTEP*ROUND(DELTA0/MPMINSTEP)

                  where DELTA0 and DELTA1 are the estimated parameter
                  changes before and after this constraint is
                  applied.  Note that this constraint should be used
                  with care since it may cause non-converging,
                  oscillating solutions.

                  A value of 0 indicates no minimum.  Default: 0.

     .MPMAXSTEP - the maximum change to be made in the parameter
                  value.  During the fitting process, the parameter
                  will never be changed by more than this value.

                  A value of 0 indicates no maximum.  Default: 0.
  
     .TIED - a string expression which "ties" the parameter to other
             free or fixed parameters.  Any expression involving
             constants and the parameter array P are permitted.
             Example: if parameter 2 is always to be twice parameter
             1 then use the following: parinfo[2].tied = '2 * P[1]'.
             Since they are totally constrained, tied parameters are
             considered to be fixed; no errors are computed for them.
             [ NOTE: the PARNAME can't be used in expressions. ]
  
  Future modifications to the PARINFO structure, if any, will involve
  adding structure tags beginning with the two letters "MP".
  Therefore programmers are urged to avoid using tags starting with
  the same letters; otherwise they are free to include their own
  fields within the PARINFO structure, and they will be ignored.
  
  PARINFO Example:
  parinfo = replicate({value:0.D, fixed:0, limited:[0,0], $
                       limits:[0.D,0]}, 5)
  parinfo[0].fixed = 1
  parinfo[4].limited(0) = 1
  parinfo[4].limits(0)  = 50.D
  parinfo[*].value = [5.7D, 2.2, 500., 1.5, 2000.]
  
  A total of 5 parameters, with starting values of 5.7,
  2.2, 500, 1.5, and 2000 are given.  The first parameter
  is fixed at a value of 5.7, and the last parameter is
  constrained to be above 50.


 COMPATIBILITY

  This function is designed to work with IDL 5.0 or greater.
  
  Because TIED parameters rely on the EXECUTE() function, they cannot
  be used with the free version of the IDL Virtual Machine.


 INPUTS:
   MYFUNCT - a string variable containing the name of an IDL
             function.  This function computes the "model" Z values
             given the X,Y values and model parameters, as described above.

   X - Array of "X" independent variable values, as described above.
       These values are passed directly to the fitting function
       unmodified.

   Y - Array of "Y" independent variable values, as described
       above. X and Y should have the same data type.

   Z - Array of "measured" dependent variable values.  Z should have
       the same data type as X and Y.  The function MYFUNCT should
       map (X,Y)->Z.

   ERR - Array of "measured" 1-sigma uncertainties.  ERR should have
         the same data type as Z.  ERR is ignored if the WEIGHTS
         keyword is specified.

   START_PARAMS - An array of starting values for each of the
                  parameters of the model.  The number of parameters
                  should be fewer than the number of measurements.
                  Also, the parameters should have the same data type
                  as the measurements (double is preferred).

                  This parameter is optional if the PARINFO keyword
                  is used (see MPFIT).  The PARINFO keyword provides
                  a mechanism to fix or constrain individual
                  parameters.  If both START_PARAMS and PARINFO are
                  passed, then the starting *value* is taken from
                  START_PARAMS, but the *constraints* are taken from
                  PARINFO.
 
 RETURNS:

   Returns the array of best-fit parameters.

 KEYWORD PARAMETERS:

   BESTNORM - the value of the summed, squared, weighted residuals
              for the returned parameter values, i.e. the chi-square value.

   COVAR - the covariance matrix for the set of parameters returned
           by MPFIT.  The matrix is NxN where N is the number of
           parameters.  The square root of the diagonal elements
           gives the formal 1-sigma statistical errors on the
           parameters IF errors were treated "properly" in MYFUNC.
           Parameter errors are also returned in PERROR.

           To compute the correlation matrix, PCOR, use this example:
                  PCOR = COV * 0
                  FOR i = 0, n-1 DO FOR j = 0, n-1 DO $
                    PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j])
           or equivalently, in vector notation,
                  PCOR = COV / (PERROR # PERROR)

           If NOCOVAR is set or MPFIT terminated abnormally, then
           COVAR is set to a scalar with value !VALUES.D_NAN.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).

   ERRMSG - a string error or warning message is returned.

   FTOL - a nonnegative input variable. Termination occurs when both
          the actual and predicted relative reductions in the sum of
          squares are at most FTOL (and STATUS is accordingly set to
          1 or 3).  Therefore, FTOL measures the relative error
          desired in the sum of squares.  Default: 1D-10

   FUNCTARGS - A structure which contains the parameters to be passed
               to the user-supplied function specified by MYFUNCT via
               the _EXTRA mechanism.  This is the way you can pass
               additional data to your user-supplied function without
               using common blocks.

               By default, no extra parameters are passed to the
               user-supplied function.

   GTOL - a nonnegative input variable. Termination occurs when the
          cosine of the angle between fvec and any column of the
          jacobian is at most GTOL in absolute value (and STATUS is
          accordingly set to 4). Therefore, GTOL measures the
          orthogonality desired between the function vector and the
          columns of the jacobian.  Default: 1D-10

   ITERARGS - The keyword arguments to be passed to ITERPROC via the
              _EXTRA mechanism.  This should be a structure, and is
              similar in operation to FUNCTARGS.
              Default: no arguments are passed.

   ITERPROC - The name of a procedure to be called upon each NPRINT
              iteration of the MPFIT routine.  It should be declared
              in the following way:

              PRO ITERPROC, MYFUNCT, p, iter, fnorm, FUNCTARGS=fcnargs, $
                PARINFO=parinfo, QUIET=quiet, ...
                ; perform custom iteration update
              END
         
              ITERPROC must either accept all three keyword
              parameters (FUNCTARGS, PARINFO and QUIET), or at least
              accept them via the _EXTRA keyword.
          
              MYFUNCT is the user-supplied function to be minimized,
              P is the current set of model parameters, ITER is the
              iteration number, and FUNCTARGS are the arguments to be
              passed to MYFUNCT.  FNORM should be the
              chi-squared value.  QUIET is set when no textual output
              should be printed.  See below for documentation of
              PARINFO.

              In implementation, ITERPROC can perform updates to the
              terminal or graphical user interface, to provide
              feedback while the fit proceeds.  If the fit is to be
              stopped for any reason, then ITERPROC should set the
              common block variable ERROR_CODE to negative value (see
              MPFIT_ERROR common block below).  In principle,
              ITERPROC should probably not modify the parameter
              values, because it may interfere with the algorithm's
              stability.  In practice it is allowed.

              Default: an internal routine is used to print the
                       parameter values.

   MAXITER - The maximum number of iterations to perform.  If the
             number is exceeded, then the STATUS value is set to 5
             and MPFIT returns.
             Default: 200 iterations

   NFEV - the number of MYFUNCT function evaluations performed.

   NITER - the number of iterations completed.

   NOCOVAR - set this keyword to prevent the calculation of the
             covariance matrix before returning (see COVAR)

   NPRINT - The frequency with which ITERPROC is called.  A value of
            1 indicates that ITERPROC is called with every iteration,
            while 2 indicates every other iteration, etc.  Note that
            several Levenberg-Marquardt attempts can be made in a
            single iteration.
            Default value: 1

   PARINFO - Provides a mechanism for more sophisticated constraints
             to be placed on parameter values.  When PARINFO is not
             passed, then it is assumed that all parameters are free
             and unconstrained.  Values in PARINFO are never 
             modified during a call to MPFIT.

             See description above for the structure of PARINFO.

             Default value:  all parameters are free and unconstrained.

   PERROR - The formal 1-sigma errors in each parameter, computed
            from the covariance matrix.  If a parameter is held
            fixed, or if it touches a boundary, then the error is
            reported as zero.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.  *If* you can assume that the true reduced
            chi-squared value is unity -- meaning that the fit is
            implicitly assumed to be of good quality -- then the
            estimated parameter uncertainties can be computed by
            scaling PERROR by the measured chi-squared value.

              DOF     = N_ELEMENTS(Z) - N_ELEMENTS(PARMS) ; deg of freedom
              PCERROR = PERROR * SQRT(BESTNORM / DOF)   ; scaled uncertainties

   QUIET - set this keyword when no textual output should be printed
           by MPFIT

   STATUS - an integer status code is returned.  All values other
            than zero can represent success.  It can have one of the
            following values:

	   0  improper input parameters.
         
	   1  both actual and predicted relative reductions
	      in the sum of squares are at most FTOL.
         
	   2  relative error between two consecutive iterates
	      is at most XTOL
         
	   3  conditions for STATUS = 1 and STATUS = 2 both hold.
         
	   4  the cosine of the angle between fvec and any
	      column of the jacobian is at most GTOL in
	      absolute value.
         
	   5  the maximum number of iterations has been reached
         
	   6  FTOL is too small. no further reduction in
	      the sum of squares is possible.
         
	   7  XTOL is too small. no further improvement in
	      the approximate solution x is possible.
         
	   8  GTOL is too small. fvec is orthogonal to the
	      columns of the jacobian to machine precision.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  If WEIGHTS is specified then the ERR
             parameter is ignored.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Z-MYFUNCT(X,Y,P))^2 * ABS(WEIGHTS) )

             Here are common values of WEIGHTS:

                1D/ERR^2 - Normal weighting (ERR is the measurement error)
                1D/Z     - Poisson weighting (counting statistics)
                1D       - Unweighted

   XTOL - a nonnegative input variable. Termination occurs when the
          relative error between two consecutive iterates is at most
          XTOL (and STATUS is accordingly set to 2 or 3).  Therefore,
          XTOL measures the relative error desired in the approximate
          solution.  Default: 1D-10

   YFIT - the best-fit model function, as returned by MYFUNCT.

 EXAMPLE:

   p  = [2.2D, -0.7D, 1.4D, 3000.D]
   x  = (dindgen(200)*0.1 - 10.) # (dblarr(200) + 1)
   y  = (dblarr(200) + 1) # (dindgen(200)*0.1 - 10.)
   zi = gauss2(x, y, p)
   sz = sqrt(zi>1)
   z  = zi + randomn(seed, 200, 200) * sz

   p0 = [0D, 0D, 1D, 10D]
   p = mpfit2dfun('GAUSS2', x, y, z, sz, p0)
   
   Generates a synthetic data set with a Gaussian peak, and Poisson
   statistical uncertainty.  Then the same function (but different
   starting parameters) is fitted to the data to see how close we can
   get.

   It is especially worthy to notice that the X and Y values are
   created as full images, so that a coordinate is attached to each
   pixel independently.  This is the format that GAUSS2 accepts, and
   the easiest for you to use in your own functions.


 COMMON BLOCKS:

   COMMON MPFIT_ERROR, ERROR_CODE

     User routines may stop the fitting process at any time by
     setting an error condition.  This condition may be set in either
     the user's model computation routine (MYFUNCT), or in the
     iteration procedure (ITERPROC).

     To stop the fitting, the above common block must be declared,
     and ERROR_CODE must be set to a negative number.  After the user
     procedure or function returns, MPFIT checks the value of this
     common block variable and exits immediately if the error
     condition has been set.  By default the value of ERROR_CODE is
     zero, indicating a successful function/procedure call.


 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:
   Written, transformed from MPFITFUN, 26 Sep 1999, CM
   Alphabetized documented keywords, 02 Oct 1999, CM
   Added example, 02 Oct 1999, CM
   Tried to clarify definitions of X and Y, 29 Oct 1999, CM
   Added QUERY keyword and query checking of MPFIT, 29 Oct 1999, CM
   Check to be sure that X, Y and Z are present, 02 Nov 1999, CM
   Documented PERROR for unweighted fits, 03 Nov 1999, CM
   Changed to ERROR_CODE for error condition, 28 Jan 2000, CM
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Propagated improvements from MPFIT, 17 Dec 2000, CM
   Documented RELSTEP field of PARINFO (!!), CM, 25 Oct 2002
   Add DOF keyword to return degrees of freedom, CM, 23 June 2003
   Minor documentation adjustment, 03 Feb 2004, CM
   Fix the example to prevent zero errorbars, 28 Mar 2005, CM
   Defend against users supplying strangely dimensioned X and Y, 29
     Jun 2005, CM
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   Move STRICTARR compile option inside each function/procedure, 9 Oct 2006
   Add COMPATIBILITY section, CM, 13 Dec 2007

  $Id: mpfit2dfun.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFIT2DPEAK

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFIT2DPEAK

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Fit a gaussian, lorentzian or Moffat model to data

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   yfit = MPFIT2DPEAK(Z, A [, X, Y, /TILT ...] )

 DESCRIPTION:

   MPFIT2DPEAK fits a gaussian, lorentzian or Moffat model using the
   non-linear least squares fitter MPFIT.  MPFIT2DPEAK is meant to be
   a drop-in replacement for IDL's GAUSS2DFIT function (and requires
   MPFIT and MPFIT2DFUN).

   The choice of the fitting function is determined by the keywords
   GAUSSIAN, LORENTZIAN and MOFFAT.  By default the gaussian model
   function is used.  [ The Moffat function is a modified Lorentzian
   with variable power law index. ]  The two-dimensional peak has
   independent semimajor and semiminor axes, with an optional
   rotation term activated by setting the TILT keyword.  The baseline
   is assumed to be a constant.

      GAUSSIAN      A[0] + A[1]*exp(-0.5*u)
      LORENTZIAN    A[0] + A[1]/(u + 1)
      MOFFAT        A[0] + A[1]/(u + 1)^A[7]

      u = ( (x-A[4])/A[2] )^2 + ( (y-A[5])/A[3] )^2

         where x and y are cartesian coordinates in rotated
         coordinate system if TILT keyword is set.

   The returned parameter array elements have the following meanings:

      A[0]   Constant baseline level
      A[1]   Peak value
      A[2]   Peak half-width (x) -- gaussian sigma or half-width at half-max
      A[3]   Peak half-width (y) -- gaussian sigma or half-width at half-max
      A[4]   Peak centroid (x)
      A[5]   Peak centroid (y)
      A[6]   Rotation angle (radians) if TILT keyword set
      A[7]   Moffat power law index if MOFFAT keyword set

   By default the initial starting values for the parameters A are
   estimated from the data.  However, explicit starting values can be
   supplied using the ESTIMATES keyword.  Also, error or weighting
   values can optionally be provided; otherwise the fit is
   unweighted.

 RESTRICTIONS:

   If no starting parameter ESTIMATES are provided, then MPFIT2DPEAK
   attempts to estimate them from the data.  This is not a perfect
   science; however, the author believes that the technique
   implemented here is more robust than the one used in IDL's
   GAUSS2DFIT.  The author has tested cases of strong peaks, noisy
   peaks and broad peaks, all with success.


 COMPATIBILITY

  This function is designed to work with IDL 5.0 or greater.
  
  Because TIED parameters rely on the EXECUTE() function, they cannot
  be used with the free version of the IDL Virtual Machine.


 INPUTS:

   Z - Two dimensional array of "measured" dependent variable values.
       Z should be of the same type and dimension as (X # Y).

   X - Optional vector of x positions for a single row of Z.

          X[i] should provide the x position of Z[i,*]

       Default: X values are integer increments from 0 to NX-1

   Y - Optional vector of y positions for a single column of Z.

          Y[j] should provide the y position of Z[*,j]

       Default: Y values are integer increments from 0 to NY-1

 OUTPUTS:
   A - Upon return, an array of best fit parameter values.  See the
       table above for the meanings of each parameter element.


 RETURNS:

   Returns the best fitting model function as a 2D array.

 KEYWORDS:

   ** NOTE ** Additional keywords such as PARINFO, BESTNORM, and
              STATUS are accepted by MPFIT2DPEAK but not documented
              here.  Please see the documentation for MPFIT for the
              description of these advanced options.

   CHISQ - the value of the summed squared residuals for the
           returned parameter values.

   CIRCULAR - if set, then the peak profile is assumed to be
              azimuthally symmetric.  When set, the parameters A[2)
              and A[3) will be identical and the TILT keyword will
              have no effect.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).

   ERROR - upon input, the measured 1-sigma uncertainties in the "Z"
           values.  If no ERROR or WEIGHTS are given, then the fit is
           unweighted.

   ESTIMATES - Array of starting values for each parameter of the
               model.  If ESTIMATES is not set, then the starting
               values are estimated from the data directly, before
               fitting.  (This also means that PARINFO.VALUES is
               ignored.)
               Default: not set - parameter values are estimated from data.

   GAUSSIAN - if set, fit a gaussian model function.  The Default.
   LORENTZIAN - if set, fit a lorentzian model function.
   MOFFAT - if set, fit a Moffat model function.

   MEASURE_ERRORS - synonym for ERRORS, for consistency with built-in
                    IDL fitting routines.

   NEGATIVE - if set, and ESTIMATES is not provided, then MPFIT2DPEAK
              will assume that a negative peak is present -- a
              valley.  Specifying this keyword is not normally
              required, since MPFIT2DPEAK can determine this
              automatically.

   NFREE - the number of free parameters in the fit.  This includes
           parameters which are not FIXED and not TIED, but it does
           include parameters which are pegged at LIMITS.

   PERROR - upon return, the 1-sigma uncertainties of the parameter
            values A.  These values are only meaningful if the ERRORS
            or WEIGHTS keywords are specified properly.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.  

            *If* you can assume that the true reduced chi-squared
            value is unity -- meaning that the fit is implicitly
            assumed to be of good quality -- then the estimated
            parameter uncertainties can be computed by scaling PERROR
            by the measured chi-squared value.

              DOF     = N_ELEMENTS(Z) - N_ELEMENTS(A)   ; deg of freedom
              PCERROR = PERROR * SQRT(BESTNORM / DOF)   ; scaled uncertainties

   QUIET - if set then diagnostic fitting messages are suppressed.
           Default: QUIET=1 (i.e., no diagnostics)

   SIGMA - synonym for PERROR (1-sigma parameter uncertainties), for
           compatibility with GAUSSFIT.  Do not confuse this with the
           Gaussian "sigma" width parameter.

   TILT - if set, then the major and minor axes of the peak profile
          are allowed to rotate with respect to the image axes.
          Parameter A[6] will be set to the clockwise rotation angle
          of the A[2] axis in radians.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  If WEIGHTS is specified then the ERR
             parameter is ignored.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Z-MYFUNCT(X,Y,P))^2 * ABS(WEIGHTS) )

             Here are common values of WEIGHTS:

                1D/ERR^2 - Normal weighting (ERR is the measurement error)
                1D/Y     - Poisson weighting (counting statistics)
                1D       - Unweighted

             The ERROR keyword takes precedence over any WEIGHTS
             keyword values.  If no ERROR or WEIGHTS are given, then
             the fit is unweighted.


 EXAMPLE:

 ; Construct a sample gaussian surface in range [-5,5] centered at [2,-3]
   x = findgen(100)*0.1 - 5. & y = x
   xx = x # (y*0 + 1)
   yy = (x*0 + 1) # y
   rr = sqrt((xx-2.)^2 + (yy+3.)^2)

 ; Gaussian surface with sigma=0.5, peak value of 3, noise with sigma=0.2
   z = 3.*exp(-(rr/0.5)^2) + randomn(seed,100,100)*.2

 ; Fit gaussian parameters A
   zfit = mpfit2dpeak(z, a, x, y)

 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:

   New algorithm for estimating starting values, CM, 31 Oct 1999
   Documented, 02 Nov 1999
   Small documentation fixes, 02 Nov 1999
   Documented PERROR for unweighted fits, 03 Nov 1999, CM
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Small cosmetic changes, 21 Sep 2000, CM
   Corrected bug introduced by cosmetic changes, 11 Oct 2000, CM :-)
   Added POSITIVE keyword, 17 Nov 2000, CM
   Removed TILT in common, in favor of FUNCTARGS approach, 23 Nov
     2000, CM
   Added SYMMETRIC keyword, documentation for TILT, and an example,
     24 Nov 2000, CM
   Changed SYMMETRIC to CIRCULAR, 17 Dec 2000, CM
   Really change SYMMETRIC to CIRCULAR!, 13 Sep 2002, CM
   Add error messages for SYMMETRIC and CIRCLE, 08 Nov 2002, CM
   Make more consistent with comparable IDL routines, 30 Jun 2003, CM
   Defend against users supplying strangely dimensioned X and Y, 29
     Jun 2005, CM
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   Move STRICTARR compile option inside each function/procedure, 9 Oct 2006
   Add COMPATIBILITY section, CM, 13 Dec 2007
   Clarify documentation regarding what happens when ESTIMATES is not
     set, CM, 14 Dec 2008

  $Id: mpfit2dpeak.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFITELLIPSE

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFITELLIPSE

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Approximate fit to points forming an ellipse

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   parms = MPFITELLIPSE(X, Y, start_parms, [/TILT, WEIGHTS=wts, ...])

 DESCRIPTION:

   MPFITELLIPSE fits a closed elliptical or circular curve to a two
   dimensional set of data points.  The user specifies the X and Y
   positions of the points, and an optional set of weights.  The
   ellipse may also be tilted at an arbitrary angle.

   IMPORTANT NOTE: this fitting program performs simple ellipse
   fitting.  It will not work well for ellipse data with high
   eccentricity.  More robust answers can usually be obtained with
   "orthogonal distance regression."  (See FORTRAN package ODRPACK on
   netlib.org for more information).

   The best fitting ellipse parameters are returned from by
   MPFITELLIPSE as a vector, whose values are:

      P[0]   Ellipse semi axis 1
      P[1]   Ellipse semi axis 2   ( = P[0] if CIRCLE keyword set)
      P[2]   Ellipse center - x value
      P[3]   Ellipse center - y value
      P[4]   Ellipse rotation angle (radians) if TILT keyword set

   If the TILT keyword is set, then the P[0] is meant to be the
   semi-major axis, and P[1] is the semi-minor axis, and P[4]
   represents the tilt of the semi-major axis with respect to the X
   axis.  If the TILT keyword is not set, the P[0] and P[1] represent
   the ellipse semi-axes in the X and Y directions, respectively.
   The returned semi-axis lengths should always be positive.

   The user may specify an initial set of trial parameters, but by
   default MPFITELLIPSE will estimate the parameters automatically.

   Users should be aware that in the presence of large amounts of
   noise, namely when the measurement error becomes significant
   compared to the ellipse axis length, then the estimated parameters
   become unreliable.  Generally speaking the computed axes will
   overestimate the true axes.  For example when (SIGMA_R/R) becomes
   0.5, the radius of the ellipse is overestimated by about 40%.

   This unreliability is also pronounced if the ellipse has high
   eccentricity, as noted above.

   Users can weight their data as they see appropriate.  However, the
   following prescription for the weighting may serve as a good
   starting point, and appeared to produce results comparable to the
   typical chi-squared value.

     WEIGHTS = 0.75/(SIGMA_X^2 + SIGMA_Y^2)

   where SIGMA_X and SIGMA_Y are the measurement error vectors in the
   X and Y directions respectively.  However, this has not been
   robustly tested, and it should be pointed out that this weighting
   may only be appropriate for a set of points whose measurement
   errors are comparable.  If a more robust estimation of the
   parameter values is needed, the so-called orthogonal distance
   regression package should be used (ODRPACK, available in FORTRAN
   at www.netlib.org).

 INPUTS:

   X - measured X positions of the points in the ellipse.
   Y - measured Y positions of the points in the ellipse.

   START_PARAMS - an array of starting values for the ellipse
                  parameters, as described above.  This parameter is
                  optional; if not specified by the user, then the
                  ellipse parameters are estimated automatically from
                  the properties of the data.

 RETURNS:

   Returns the best fitting model ellipse parameters.  Returned
   values are undefined if STATUS indicates an error condition.

 KEYWORDS:

   ** NOTE ** Additional keywords such as PARINFO, BESTNORM, and
              STATUS are accepted by MPFITELLIPSE but not documented
              here.  Please see the documentation for MPFIT for the
              description of these advanced options.

   CIRCULAR - if set, then the curve is assumed to be a circle
              instead of ellipse.  When set, the parameters P[0] and
              P[1] will be identical and the TILT keyword will have
              no effect.

   PERROR - upon return, the 1-sigma uncertainties of the returned
            ellipse parameter values.  These values are only
            meaningful if the WEIGHTS keyword is specified properly.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.

            If STATUS indicates an error condition, then PERROR is
            undefined.

   QUIET - if set then diagnostic fitting messages are suppressed.
           Default: QUIET=1 (i.e., no diagnostics]

   STATUS - an integer status code is returned.  All values greater
            than zero can represent success (however STATUS EQ 5 may
            indicate failure to converge).  Please see MPFIT for
            the definitions of status codes.

   TILT - if set, then the major and minor axes of the ellipse
          are allowed to rotate with respect to the data axes.
          Parameter P[4] will be set to the clockwise rotation angle
          of the P[0] axis in radians, as measured from the +X axis.
          P[4] should be in the range 0 to !dpi.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Z-MYFUNCT(X,Y,P))^2 * ABS(WEIGHTS)^2 )

             Users may wish to follow the guidelines for WEIGHTS
             described above.


 EXAMPLE:

 ; Construct a set of points on an ellipse, with some noise
   ph0 = 2*!pi*randomu(seed,50)
   x =  50. + 32.*cos(ph0) + 4.0*randomn(seed, 50)
   y = -75. + 65.*sin(ph0) + 0.1*randomn(seed, 50)

 ; Compute weights function
   weights = 0.75/(4.0^2 + 0.1^2)

 ; Fit ellipse and plot result
   p = mpfitellipse(x, y)
   phi = dindgen(101)*2D*!dpi/100
   plot, x, y, psym=1
   oplot, p[2]+p[0]*cos(phi), p[3]+p[1]*sin(phi), color='ff'xl

 ; Fit ellipse and plot result - WITH TILT
   p = mpfitellipse(x, y, /tilt)
   phi = dindgen(101)*2D*!dpi/100
   ; New parameter P[4] gives tilt of ellipse w.r.t. coordinate axes
   ; We must rotate a standard ellipse to this new orientation
   xm = p[2] + p[0]*cos(phi)*cos(p[4]) + p[1]*sin(phi)*sin(p[4])
   ym = p[3] - p[0]*cos(phi)*sin(p[4]) + p[1]*sin(phi)*cos(p[4])

   plot, x, y, psym=1
   oplot, xm, ym, color='ff'xl

 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:

   Ported from MPFIT2DPEAK, 17 Dec 2000, CM
   More documentation, 11 Jan 2001, CM
   Example corrected, 18 Nov 2001, CM
   Change CIRCLE keyword to the correct CIRCULAR keyword, 13 Sep
      2002, CM
   Add error messages for SYMMETRIC and CIRCLE, 08 Nov 2002, CM
   Found small error in computation of _EVAL (when CIRCULAR) was set;
      sanity check when CIRCULAR is set, 21 Jan 2003, CM
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   Move STRICTARR compile option inside each function/procedure, 9
     Oct 2006
   Add disclaimer about the suitability of this program for fitting
     ellipses, 17 Sep 2007, CM
   Clarify documentation of TILT angle; make sure output contains
    semi-major axis first, followed by semi-minor; make sure that
    semi-axes are always positive (and can handle negative inputs)
      17 Sep 2007, CM
   Output tilt angle is now in range 0 to !DPI, 20 Sep 2007, CM
   Some documentation clarifications, including to remove reference
     to the "ERR" keyword, which does not exist, 17 Jan 2008, CM
   Swapping of P[0] and P[1] only occurs if /TILT is set, 06 Nov
     2009, CM
   Document an example of how to plot a tilted ellipse, 09 Nov 2009, CM
   Check for MPFIT error conditions and return immediately, 23 Jan 2010, CM

  $Id: mpfitellipse.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFITEXPR

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFITEXPR

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Perform Levenberg-Marquardt least-squares fit to arbitrary expression

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   MYFUNCT = 'X*(1-X)+3'
   parms = MPFITEXPR(MYFUNCT, XVAL, YVAL, ERR, start_parms, ...)

 DESCRIPTION:

  MPFITEXPR fits a user-supplied model -- in the form of an arbitrary IDL
  expression -- to a set of user-supplied data.  MPFITEXPR calls
  MPFIT, the MINPACK-1 least-squares minimizer, to do the main
  work.

  Given the data and their uncertainties, MPFITEXPR finds the best set
  of model parameters which match the data (in a least-squares
  sense) and returns them in an array.
  
  The user must supply the following items:
   - An array of independent variable values ("X").
   - An array of "measured" *dependent* variable values ("Y").
   - An array of "measured" 1-sigma uncertainty values ("ERR").
   - A text IDL expression which computes Y given X.
   - Starting guesses for all of the parameters ("START_PARAMS").

  There are very few restrictions placed on X, Y or the expression of
  the model.  Simply put, the expression must map the "X" values into
  "Y" values given the model parameters.  The "X" values may
  represent any independent variable (not just Cartesian X), and
  indeed may be multidimensional themselves.  For example, in the
  application of image fitting, X may be a 2xN array of image
  positions.

  Some rules must be obeyed in constructing the expression.  First,
  the independent variable name *MUST* be "X" in the expression,
  regardless of the name of the variable being passed to MPFITEXPR.
  This is demonstrated in the above calling sequence, where the X
  variable passed in is called "XVAL" but the expression still refers
  to "X".  Second, parameter values must be referred to as an array
  named "P".

  If you do not pass in starting values for the model parameters,
  MPFITEXPR will attempt to determine the number of parameters you
  intend to have (it does this by looking for references to the array
  variable named "P").  When no starting values are passed in, the
  values are assumed to start at zero.

  MPFITEXPR carefully avoids passing large arrays where possible to
  improve performance.

  See below for an example of usage.

 EVALUATING EXPRESSIONS

  This source module also provides a function called MPEVALEXPR.  You
  can use this function to evaluate your expression, given a list of
  parameters.  This is one of the easier ways to compute the model
  once the best-fit parameters have been found.  Here is an example:

       YMOD = MPEVALEXPR(MYFUNCT, XVAL, PARMS)

  where MYFUNCT is the expression (see MYFUNCT below), XVAL is the
  list of "X" values, and PARMS is an array of parameters.  The
  returned array YMOD contains the expression MYFUNCT evaluated at
  each point in XVAL.

 PASSING PRIVATE DATA TO AN EXPRESSION

  The most complicated optimization problems typically involve other
  external parameters, in addition to the fitted parameters.  While
  it is extremely easy to rewrite an expression dynamically, in case
  one of the external parameters changes, the other possibility is to
  use the PRIVATE data structure.

  The user merely passes a structure to the FUNCTARGS keyword.  The
  user expression receives this value as the variable PRIVATE.
  MPFITEXPR nevers accesses this variable so it can contain any
  desired values.  Usually it would be an IDL structure so that any
  named external parameters can be passed to the expression.


 CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD

  The behavior of MPFIT can be modified with respect to each
  parameter to be fitted.  A parameter value can be fixed; simple
  boundary constraints can be imposed; limitations on the parameter
  changes can be imposed; properties of the automatic derivative can
  be modified; and parameters can be tied to one another.

  These properties are governed by the PARINFO structure, which is
  passed as a keyword parameter to MPFIT.

  PARINFO should be an array of structures, one for each parameter.
  Each parameter is associated with one element of the array, in
  numerical order.  The structure can have the following entries
  (none are required):
  
     .VALUE - the starting parameter value (but see the START_PARAMS
              parameter for more information).
  
     .FIXED - a boolean value, whether the parameter is to be held
              fixed or not.  Fixed parameters are not varied by
              MPFIT, but are passed on to MYFUNCT for evaluation.
  
     .LIMITED - a two-element boolean array.  If the first/second
                element is set, then the parameter is bounded on the
                lower/upper side.  A parameter can be bounded on both
                sides.  Both LIMITED and LIMITS must be given
                together.
  
     .LIMITS - a two-element float or double array.  Gives the
               parameter limits on the lower and upper sides,
               respectively.  Zero, one or two of these values can be
               set, depending on the values of LIMITED.  Both LIMITED
               and LIMITS must be given together.
  
     .PARNAME - a string, giving the name of the parameter.  The
                fitting code of MPFIT does not use this tag in any
                way.  However, the default ITERPROC will print the
                parameter name if available.
  
     .STEP - the step size to be used in calculating the numerical
             derivatives.  If set to zero, then the step size is
             computed automatically.  Ignored when AUTODERIVATIVE=0.
             This value is superceded by the RELSTEP value.

     .RELSTEP - the *relative* step size to be used in calculating
                the numerical derivatives.  This number is the
                fractional size of the step, compared to the
                parameter value.  This value supercedes the STEP
                setting.  If the parameter is zero, then a default
                step size is chosen.

     .MPSIDE - the sidedness of the finite difference when computing
               numerical derivatives.  This field can take four
               values:

                  0 - one-sided derivative computed automatically
                  1 - one-sided derivative (f(x+h) - f(x)  )/h
                 -1 - one-sided derivative (f(x)   - f(x-h))/h
                  2 - two-sided derivative (f(x+h) - f(x-h))/(2*h)

              Where H is the STEP parameter described above.  The
              "automatic" one-sided derivative method will chose a
              direction for the finite difference which does not
              violate any constraints.  The other methods do not
              perform this check.  The two-sided method is in
              principle more precise, but requires twice as many
              function evaluations.  Default: 0.

     .MPMAXSTEP - the maximum change to be made in the parameter
                  value.  During the fitting process, the parameter
                  will never be changed by more than this value in
                  one iteration.

                  A value of 0 indicates no maximum.  Default: 0.
  
     .TIED - a string expression which "ties" the parameter to other
             free or fixed parameters as an equality constraint.  Any
             expression involving constants and the parameter array P
             are permitted.
             Example: if parameter 2 is always to be twice parameter
             1 then use the following: parinfo[2].tied = '2 * P[1]'.
             Since they are totally constrained, tied parameters are
             considered to be fixed; no errors are computed for them.
             [ NOTE: the PARNAME can't be used in a TIED expression. ]

     .MPPRINT - if set to 1, then the default ITERPROC will print the
                parameter value.  If set to 0, the parameter value
                will not be printed.  This tag can be used to
                selectively print only a few parameter values out of
                many.  Default: 1 (all parameters printed)

     .MPFORMAT - IDL format string to print the parameter within
                 ITERPROC.  Default: '(G20.6)'  (An empty string will
                 also use the default.)

  Future modifications to the PARINFO structure, if any, will involve
  adding structure tags beginning with the two letters "MP".
  Therefore programmers are urged to avoid using tags starting with
  "MP", but otherwise they are free to include their own fields
  within the PARINFO structure, which will be ignored by MPFIT.
  
  PARINFO Example:
  parinfo = replicate({value:0.D, fixed:0, limited:[0,0], $
                       limits:[0.D,0]}, 5)
  parinfo[0].fixed = 1
  parinfo[4].limited[0] = 1
  parinfo[4].limits[0]  = 50.D
  parinfo[*].value = [5.7D, 2.2, 500., 1.5, 2000.]
  
  A total of 5 parameters, with starting values of 5.7,
  2.2, 500, 1.5, and 2000 are given.  The first parameter
  is fixed at a value of 5.7, and the last parameter is
  constrained to be above 50.


 COMPATIBILITY

  This function is designed to work with IDL 5.0 or greater.  Because
  this function uses the IDL EXECUTE() function, it will not work
  with the free version of the IDL Virtual machine.
  

 INPUTS:
   MYFUNCT - a string variable containing an IDL expression.  The
             only restriction is that the independent variable *must*
             be referred to as "X" and model parameters *must* be
             referred to as an array called "P".  Do not use symbol
             names beginning with the underscore, "_".

             The expression should calculate "model" Y values given
             the X values and model parameters.  Using the vector
             notation of IDL, this can be quite easy to do.  If your
             expression gets complicated, you may wish to make an IDL
             function which will improve performance and readibility.

             The resulting array should be of the same size and
             dimensions as the "measured" Y values.

   X - Array of independent variable values.

   Y - Array of "measured" dependent variable values.  Y should have
       the same data type as X.  The function MYFUNCT should map
       X->Y.

   ERR - Array of "measured" 1-sigma uncertainties.  ERR should have
         the same data type as Y.  ERR is ignored if the WEIGHTS
         keyword is specified.

   START_PARAMS - An array of starting values for each of the
                  parameters of the model.  The number of parameters
                  should be fewer than the number of measurements.
                  Also, the parameters should have the same data type
                  as the measurements (double is preferred).

                  This parameter is optional if the PARINFO keyword
                  is used (see MPFIT).  The PARINFO keyword provides
                  a mechanism to fix or constrain individual
                  parameters.  If both START_PARAMS and PARINFO are
                  passed, then the starting *value* is taken from
                  START_PARAMS, but the *constraints* are taken from
                  PARINFO.

                  If no parameters are given, then MPFITEXPR attempts
                  to determine the number of parameters by scanning
                  the expression.  Parameters determined this way are
                  initialized to zero.  This technique is not fully
                  reliable, so users are advised to pass explicit
                  parameter starting values.
 

 RETURNS:

   Returns the array of best-fit parameters.


 KEYWORD PARAMETERS:

   BESTNORM - the value of the summed, squared, weighted residuals
              for the returned parameter values, i.e. the chi-square value.

   COVAR - the covariance matrix for the set of parameters returned
           by MPFIT.  The matrix is NxN where N is the number of
           parameters.  The square root of the diagonal elements
           gives the formal 1-sigma statistical errors on the
           parameters IF errors were treated "properly" in MYFUNC.
           Parameter errors are also returned in PERROR.

           To compute the correlation matrix, PCOR, use this:
           IDL> PCOR = COV * 0
           IDL> FOR i = 0, n-1 DO FOR j = 0, n-1 DO $
                PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j])

           If NOCOVAR is set or MPFIT terminated abnormally, then
           COVAR is set to a scalar with value !VALUES.D_NAN.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).

   ERRMSG - a string error or warning message is returned.

   FTOL - a nonnegative input variable. Termination occurs when both
          the actual and predicted relative reductions in the sum of
          squares are at most FTOL (and STATUS is accordingly set to
          1 or 3).  Therefore, FTOL measures the relative error
          desired in the sum of squares.  Default: 1D-10

   FUNCTARGS - passed directly to the expression as the variable
               PRIVATE.  Any user-private data can be communicated to
               the user expression using this keyword.
               Default: PRIVATE is undefined in user expression

   GTOL - a nonnegative input variable. Termination occurs when the
          cosine of the angle between fvec and any column of the
          jacobian is at most GTOL in absolute value (and STATUS is
          accordingly set to 4). Therefore, GTOL measures the
          orthogonality desired between the function vector and the
          columns of the jacobian.  Default: 1D-10

   ITERARGS - The keyword arguments to be passed to ITERPROC via the
              _EXTRA mechanism.  This should be a structure, and is
              similar in operation to FUNCTARGS.
              Default: no arguments are passed.

   ITERPROC - The name of a procedure to be called upon each NPRINT
              iteration of the MPFIT routine.  It should be declared
              in the following way:

              PRO ITERPROC, MYFUNCT, p, iter, fnorm, FUNCTARGS=fcnargs, $
                PARINFO=parinfo, QUIET=quiet, ...
                ; perform custom iteration update
              END
         
              ITERPROC must either accept all three keyword
              parameters (FUNCTARGS, PARINFO and QUIET), or at least
              accept them via the _EXTRA keyword.
          
              MYFUNCT is the user-supplied function to be minimized,
              P is the current set of model parameters, ITER is the
              iteration number, and FUNCTARGS are the arguments to be
              passed to MYFUNCT.  FNORM should be the
              chi-squared value.  QUIET is set when no textual output
              should be printed.  See below for documentation of
              PARINFO.

              In implementation, ITERPROC can perform updates to the
              terminal or graphical user interface, to provide
              feedback while the fit proceeds.  If the fit is to be
              stopped for any reason, then ITERPROC should set the
              common block variable ERROR_CODE to negative value (see
              MPFIT_ERROR common block below).  In principle,
              ITERPROC should probably not modify the parameter
              values, because it may interfere with the algorithm's
              stability.  In practice it is allowed.

              Default: an internal routine is used to print the
                       parameter values.

   MAXITER - The maximum number of iterations to perform.  If the
             number is exceeded, then the STATUS value is set to 5
             and MPFIT returns.
             Default: 200 iterations

   NFEV - the number of MYFUNCT function evaluations performed.

   NFREE - the number of free parameters in the fit.  This includes
           parameters which are not FIXED and not TIED, but it does
           include parameters which are pegged at LIMITS.

   NITER - the number of iterations completed.

   NOCOVAR - set this keyword to prevent the calculation of the
             covariance matrix before returning (see COVAR)

   NPEGGED - the number of free parameters which are pegged at a
             LIMIT.

   NPRINT - The frequency with which ITERPROC is called.  A value of
            1 indicates that ITERPROC is called with every iteration,
            while 2 indicates every other iteration, etc.  Note that
            several Levenberg-Marquardt attempts can be made in a
            single iteration.
            Default value: 1

   PARINFO - Provides a mechanism for more sophisticated constraints
             to be placed on parameter values.  When PARINFO is not
             passed, then it is assumed that all parameters are free
             and unconstrained.  Values in PARINFO are never 
             modified during a call to MPFIT.

             See description above for the structure of PARINFO.

             Default value:  all parameters are free and unconstrained.

   PERROR - The formal 1-sigma errors in each parameter, computed
            from the covariance matrix.  If a parameter is held
            fixed, or if it touches a boundary, then the error is
            reported as zero.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.  

            *If* you can assume that the true reduced chi-squared
            value is unity -- meaning that the fit is implicitly
            assumed to be of good quality -- then the estimated
            parameter uncertainties can be computed by scaling PERROR
            by the measured chi-squared value.

              DOF     = N_ELEMENTS(X) - N_ELEMENTS(PARMS) ; deg of freedom
              PCERROR = PERROR * SQRT(BESTNORM / DOF)   ; scaled uncertainties

   QUIET - set this keyword when no textual output should be printed
           by MPFIT

   STATUS - an integer status code is returned.  All values other
            than zero can represent success.  It can have one of the
            following values:

	   0  improper input parameters.
         
	   1  both actual and predicted relative reductions
	      in the sum of squares are at most FTOL.
         
	   2  relative error between two consecutive iterates
	      is at most XTOL
         
	   3  conditions for STATUS = 1 and STATUS = 2 both hold.
         
	   4  the cosine of the angle between fvec and any
	      column of the jacobian is at most GTOL in
	      absolute value.
         
	   5  the maximum number of iterations has been reached
         
	   6  FTOL is too small. no further reduction in
	      the sum of squares is possible.
         
	   7  XTOL is too small. no further improvement in
	      the approximate solution x is possible.
         
	   8  GTOL is too small. fvec is orthogonal to the
	      columns of the jacobian to machine precision.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  If WEIGHTS is specified then the ERR
             parameter is ignored.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Y-MYFUNCT(X,P))^2 * ABS(WEIGHTS) )

             Here are common values of WEIGHTS:

                1D/ERR^2 - Normal weighting (ERR is the measurement error)
                1D/Y     - Poisson weighting (counting statistics)
                1D       - Unweighted

   XTOL - a nonnegative input variable. Termination occurs when the
          relative error between two consecutive iterates is at most
          XTOL (and STATUS is accordingly set to 2 or 3).  Therefore,
          XTOL measures the relative error desired in the approximate
          solution.  Default: 1D-10

   YFIT - the best-fit model function, as returned by MYFUNCT.


 EXAMPLE:

   ; First, generate some synthetic data
   x  = dindgen(200) * 0.1 - 10.                   ; Independent variable 
   yi = gauss1(x, [2.2D, 1.4, 3000.]) + 1000       ; "Ideal" Y variable
   y  = yi + randomn(seed, 200) * sqrt(yi)         ; Measured, w/ noise
   sy = sqrt(y)                                    ; Poisson errors

   ; Now fit a Gaussian to see how well we can recover
   expr = 'P[0] + GAUSS1(X, P[1:3])'               ; fitting function
   p0 = [800.D, 1.D, 1., 500.]                     ; Initial guess
   p = mpfitexpr(expr, x, y, sy, p0)               ; Fit the expression
   print, p

   plot, x, y                                      ; Plot data
   oplot, x, mpevalexpr(expr, x, p)                ; Plot model

   Generates a synthetic data set with a Gaussian peak, and Poisson
   statistical uncertainty.  Then a model consisting of a constant
   plus Gaussian is fit to the data.


 COMMON BLOCKS:

   COMMON MPFIT_ERROR, ERROR_CODE

     User routines may stop the fitting process at any time by
     setting an error condition.  This condition may be set in either
     the user's model computation routine (MYFUNCT), or in the
     iteration procedure (ITERPROC).

     To stop the fitting, the above common block must be declared,
     and ERROR_CODE must be set to a negative number.  After the user
     procedure or function returns, MPFIT checks the value of this
     common block variable and exits immediately if the error
     condition has been set.  By default the value of ERROR_CODE is
     zero, indicating a successful function/procedure call.


 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:
   Written, Apr-Jul 1998, CM
   Added PERROR keyword, 04 Aug 1998, CM
   Added COVAR keyword, 20 Aug 1998, CM
   Added NITER output keyword, 05 Oct 1998
      D.L Windt, Bell Labs, windt@bell-labs.com;
   Added ability to return model function in YFIT, 09 Nov 1998
   Parameter values can be tied to others, 09 Nov 1998
   Added MPEVALEXPR utility function, 09 Dec 1998
   Cosmetic documentation updates, 16 Apr 1999, CM
   More cosmetic documentation updates, 14 May 1999, CM
   Made sure to update STATUS value, 25 Sep 1999, CM
   Added WEIGHTS keyword, 25 Sep 1999, CM
   Changed from handles to common blocks, 25 Sep 1999, CM
     - commons seem much cleaner and more logical in this case.
   Alphabetized documented keywords, 02 Oct 1999, CM
   Added QUERY keyword and query checking of MPFIT, 29 Oct 1999, CM
   Check to be sure that X and Y are present, 02 Nov 1999, CM
   Documented PERROR for unweighted fits, 03 Nov 1999, CM
   Removed ITERPROC='' when quiet EQ 1, 10 Jan 2000, CM
   Changed to ERROR_CODE for error condition, 28 Jan 2000, CM
   Updated the EXAMPLE, 26 Mar 2000, CM
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Propagated improvements from MPFIT, 17 Dec 2000, CM
   Correct reference to _WTS in MPFITEXPR_EVAL, 25 May 2001, CM
      (thanks to Mark Fardal)
   Added useful FUNCTARGS behavior (as yet undocumented), 04 Jul
      2002, CM
   Documented FUNCTARGS/PRIVATE behavior, 22 Jul 2002, CM
   Added NFREE and NPEGGED keywords, 13 Sep 2002, CM
   Documented RELSTEP field of PARINFO (!!), CM, 25 Oct 2002
   Add DOF keyword, CM, 31 Jul 2003
   Add FUNCTARGS keyword to MPEVALEXPR, CM 08 Aug 2003
   Minor documentation adjustment, 03 Feb 2004, CM
   Move STRICTARR compile option inside each function/procedure, 9 Oct 2006
   Clarify documentation on user-function, derivatives, and PARINFO,
     27 May 2007
   Add COMPATIBILITY section, CM, 13 Dec 2007

  $Id: mpfitexpr.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFITFUN

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFITFUN

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Perform Levenberg-Marquardt least-squares fit to IDL function

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   parms = MPFITFUN(MYFUNCT, X, Y, ERR, start_params, ...)

 DESCRIPTION:

  MPFITFUN fits a user-supplied model -- in the form of an IDL
  function -- to a set of user-supplied data.  MPFITFUN calls
  MPFIT, the MINPACK-1 least-squares minimizer, to do the main
  work.

  Given the data and their uncertainties, MPFITFUN finds the best set
  of model parameters which match the data (in a least-squares
  sense) and returns them in an array.
  
  The user must supply the following items:
   - An array of independent variable values ("X").
   - An array of "measured" *dependent* variable values ("Y").
   - An array of "measured" 1-sigma uncertainty values ("ERR").
   - The name of an IDL function which computes Y given X ("MYFUNCT").
   - Starting guesses for all of the parameters ("START_PARAMS").

  There are very few restrictions placed on X, Y or MYFUNCT.  Simply
  put, MYFUNCT must map the "X" values into "Y" values given the
  model parameters.  The "X" values may represent any independent
  variable (not just Cartesian X), and indeed may be multidimensional
  themselves.  For example, in the application of image fitting, X
  may be a 2xN array of image positions.

  Data values of NaN or Infinity for "Y", "ERR" or "WEIGHTS" will be
  ignored as missing data if the NAN keyword is set.  Otherwise, they
  may cause the fitting loop to halt with an error message.  Note
  that the fit will still halt if the model function, or its
  derivatives, produces infinite or NaN values.

  MPFITFUN carefully avoids passing large arrays where possible to
  improve performance.

  See below for an example of usage.

 USER FUNCTION

  The user must define a function which returns the model value.  For
  applications which use finite-difference derivatives -- the default
  -- the user function should be declared in the following way:

    FUNCTION MYFUNCT, X, P
     ; The independent variable is X
     ; Parameter values are passed in "P"
     YMOD = ... computed model values at X ...
     return, YMOD
    END

  The returned array YMOD must have the same dimensions and type as
  the "measured" Y values.

  User functions may also indicate a fatal error condition
  using the ERROR_CODE common block variable, as described
  below under the MPFIT_ERROR common block definition.

  MPFIT by default calculates derivatives numerically via a finite
  difference approximation.  However, the user function *may*
  calculate the derivatives if desired, but only if the model
  function is declared with an additional position parameter, DP, as
  described below.

  To enable explicit derivatives for all parameters, set
  AUTODERIVATIVE=0.

  When AUTODERIVATIVE=0, the user function is responsible for
  calculating the derivatives of the user function with respect to
  each parameter.  The user function should be declared as follows:

    ;
    ; MYFUNCT - example user function
    ;   P - input parameter values (N-element array)
    ;   DP - upon input, an N-vector indicating which parameters
    ;          to compute derivatives for; 
    ;        upon output, the user function must return
    ;          an ARRAY(M,N) of derivatives in this keyword
    ;   (keywords) - any other keywords specified by FUNCTARGS
    ; RETURNS - function values
    ;
    FUNCTION MYFUNCT, x, p, dp [, (additional keywords if desired)]
     model = F(x, p)         ;; Model function
     
     if n_params() GT 2 then begin
       ; Create derivative and compute derivative array
       requested = dp   ; Save original value of DP
       dp = make_array(n_elements(x), n_elements(p), value=x[0]*0)

       ; Compute derivative if requested by caller
       for i = 0, n_elements(p)-1 do if requested(i) NE 0 then $
         dp(*,i) = FGRAD(x, p, i)
     endif
    
     return, resid
    END

  where FGRAD(x, p, i) is a model function which computes the
  derivative of the model F(x,p) with respect to parameter P(i) at X.

  Derivatives should be returned in the DP array. DP should be an
  ARRAY(m,n) array, where m is the number of data points and n is the
  number of parameters.  DP[i,j] is the derivative of the ith
  function value with respect to the jth parameter.

  MPFIT may not always request derivatives from the user function.
  In those cases, the parameter DP is not passed.  Therefore
  functions can use N_PARAMS() to indicate whether they must compute
  the derivatives or not.

  For additional information about explicit derivatives, including
  additional settings and debugging options, see the discussion under
  "EXPLICIT DERIVATIVES" and AUTODERIVATIVE in MPFIT.PRO.

 CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD

  The behavior of MPFIT can be modified with respect to each
  parameter to be fitted.  A parameter value can be fixed; simple
  boundary constraints can be imposed; limitations on the parameter
  changes can be imposed; properties of the automatic derivative can
  be modified; and parameters can be tied to one another.

  These properties are governed by the PARINFO structure, which is
  passed as a keyword parameter to MPFIT.

  PARINFO should be an array of structures, one for each parameter.
  Each parameter is associated with one element of the array, in
  numerical order.  The structure can have the following entries
  (none are required):
  
     .VALUE - the starting parameter value (but see the START_PARAMS
              parameter for more information).
  
     .FIXED - a boolean value, whether the parameter is to be held
              fixed or not.  Fixed parameters are not varied by
              MPFIT, but are passed on to MYFUNCT for evaluation.
  
     .LIMITED - a two-element boolean array.  If the first/second
                element is set, then the parameter is bounded on the
                lower/upper side.  A parameter can be bounded on both
                sides.  Both LIMITED and LIMITS must be given
                together.
  
     .LIMITS - a two-element float or double array.  Gives the
               parameter limits on the lower and upper sides,
               respectively.  Zero, one or two of these values can be
               set, depending on the values of LIMITED.  Both LIMITED
               and LIMITS must be given together.
  
     .PARNAME - a string, giving the name of the parameter.  The
                fitting code of MPFIT does not use this tag in any
                way.  However, the default ITERPROC will print the
                parameter name if available.
  
     .STEP - the step size to be used in calculating the numerical
             derivatives.  If set to zero, then the step size is
             computed automatically.  Ignored when AUTODERIVATIVE=0.
             This value is superceded by the RELSTEP value.

     .RELSTEP - the *relative* step size to be used in calculating
                the numerical derivatives.  This number is the
                fractional size of the step, compared to the
                parameter value.  This value supercedes the STEP
                setting.  If the parameter is zero, then a default
                step size is chosen.

     .MPSIDE - the sidedness of the finite difference when computing
               numerical derivatives.  This field can take four
               values:

                  0 - one-sided derivative computed automatically
                  1 - one-sided derivative (f(x+h) - f(x)  )/h
                 -1 - one-sided derivative (f(x)   - f(x-h))/h
                  2 - two-sided derivative (f(x+h) - f(x-h))/(2*h)

              Where H is the STEP parameter described above.  The
              "automatic" one-sided derivative method will chose a
              direction for the finite difference which does not
              violate any constraints.  The other methods do not
              perform this check.  The two-sided method is in
              principle more precise, but requires twice as many
              function evaluations.  Default: 0.

     .MPMAXSTEP - the maximum change to be made in the parameter
                  value.  During the fitting process, the parameter
                  will never be changed by more than this value in
                  one iteration.

                  A value of 0 indicates no maximum.  Default: 0.
  
     .TIED - a string expression which "ties" the parameter to other
             free or fixed parameters as an equality constraint.  Any
             expression involving constants and the parameter array P
             are permitted.
             Example: if parameter 2 is always to be twice parameter
             1 then use the following: parinfo[2].tied = '2 * P[1]'.
             Since they are totally constrained, tied parameters are
             considered to be fixed; no errors are computed for them.
             [ NOTE: the PARNAME can't be used in a TIED expression. ]

     .MPPRINT - if set to 1, then the default ITERPROC will print the
                parameter value.  If set to 0, the parameter value
                will not be printed.  This tag can be used to
                selectively print only a few parameter values out of
                many.  Default: 1 (all parameters printed)

     .MPFORMAT - IDL format string to print the parameter within
                 ITERPROC.  Default: '(G20.6)'  (An empty string will
                 also use the default.)

  Future modifications to the PARINFO structure, if any, will involve
  adding structure tags beginning with the two letters "MP".
  Therefore programmers are urged to avoid using tags starting with
  "MP", but otherwise they are free to include their own fields
  within the PARINFO structure, which will be ignored by MPFIT.
  
  PARINFO Example:
  parinfo = replicate({value:0.D, fixed:0, limited:[0,0], $
                       limits:[0.D,0]}, 5)
  parinfo[0].fixed = 1
  parinfo[4].limited[0] = 1
  parinfo[4].limits[0]  = 50.D
  parinfo[*].value = [5.7D, 2.2, 500., 1.5, 2000.]
  
  A total of 5 parameters, with starting values of 5.7,
  2.2, 500, 1.5, and 2000 are given.  The first parameter
  is fixed at a value of 5.7, and the last parameter is
  constrained to be above 50.

 COMPATIBILITY

  This function is designed to work with IDL 5.0 or greater.
  
  Because TIED parameters rely on the EXECUTE() function, they cannot
  be used with the free version of the IDL Virtual Machine.


 INPUTS:
   MYFUNCT - a string variable containing the name of an IDL function.
             This function computes the "model" Y values given the
             X values and model parameters, as desribed above.

   X - Array of independent variable values.

   Y - Array of "measured" dependent variable values.  Y should have
       the same data type as X.  The function MYFUNCT should map
       X->Y.
         NOTE: the following special cases apply:
                * if Y is NaN or Infinite, and the NAN keyword is
                  set, then the corresponding data point is ignored

   ERR - Array of "measured" 1-sigma uncertainties.  ERR should have
         the same data type as Y.  ERR is ignored if the WEIGHTS
         keyword is specified.
         NOTE: the following special cases apply:
                * if ERR is zero, then the corresponding data point
                  is ignored
                * if ERR is NaN or Infinite, and the NAN keyword is
                  set, then the corresponding data point is ignored
                * if ERR is negative, then the absolute value of 
                  ERR is used.

   START_PARAMS - An array of starting values for each of the
                  parameters of the model.  The number of parameters
                  should be fewer than the number of measurements.
                  Also, the parameters should have the same data type
                  as the measurements (double is preferred).

                  This parameter is optional if the PARINFO keyword
                  is used (see MPFIT).  The PARINFO keyword provides
                  a mechanism to fix or constrain individual
                  parameters.  If both START_PARAMS and PARINFO are
                  passed, then the starting *value* is taken from
                  START_PARAMS, but the *constraints* are taken from
                  PARINFO.
 

 RETURNS:

   Returns the array of best-fit parameters.


 KEYWORD PARAMETERS:

   BESTNORM - the value of the summed squared residuals for the
              returned parameter values.

   BEST_FJAC - upon return, BEST_FJAC contains the Jacobian, or
               partial derivative, matrix for the best-fit model.
               The values are an array,
               ARRAY(N_ELEMENTS(DEVIATES),NFREE) where NFREE is the
               number of free parameters.  This array is only
               computed if /CALC_FJAC is set, otherwise BEST_FJAC is
               undefined.

               The returned array is such that BEST_FJAC[I,J] is the
               partial derivative of the model with respect to
               parameter PARMS[PFREE_INDEX[J]].

   BEST_RESID - upon return, an array of best-fit deviates,
                normalized by the weights or errors.

   COVAR - the covariance matrix for the set of parameters returned
           by MPFIT.  The matrix is NxN where N is the number of
           parameters.  The square root of the diagonal elements
           gives the formal 1-sigma statistical errors on the
           parameters IF errors were treated "properly" in MYFUNC.
           Parameter errors are also returned in PERROR.

           To compute the correlation matrix, PCOR, use this example:
                  PCOR = COV * 0
                  FOR i = 0, n-1 DO FOR j = 0, n-1 DO $
                    PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j])
           or equivalently, in vector notation,
                  PCOR = COV / (PERROR # PERROR)

           If NOCOVAR is set or MPFIT terminated abnormally, then
           COVAR is set to a scalar with value !VALUES.D_NAN.

   CASH - when set, the fit statistic is changed to a derivative of
          the CASH statistic.  The model function must be strictly
          positive. WARNING: this option is incomplete and untested.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).  It also does not account for data points which
         are assigned zero weight, for example if :
           * WEIGHTS[i] EQ 0, or
           * ERR[i] EQ infinity, or 
           * any of the values is "undefined" and /NAN is set.

   ERRMSG - a string error or warning message is returned.

   FTOL - a nonnegative input variable. Termination occurs when both
          the actual and predicted relative reductions in the sum of
          squares are at most FTOL (and STATUS is accordingly set to
          1 or 3).  Therefore, FTOL measures the relative error
          desired in the sum of squares.  Default: 1D-10

   FUNCTARGS - A structure which contains the parameters to be passed
               to the user-supplied function specified by MYFUNCT via
               the _EXTRA mechanism.  This is the way you can pass
               additional data to your user-supplied function without
               using common blocks.

               By default, no extra parameters are passed to the
               user-supplied function.

   GTOL - a nonnegative input variable. Termination occurs when the
          cosine of the angle between fvec and any column of the
          jacobian is at most GTOL in absolute value (and STATUS is
          accordingly set to 4). Therefore, GTOL measures the
          orthogonality desired between the function vector and the
          columns of the jacobian.  Default: 1D-10

   ITERARGS - The keyword arguments to be passed to ITERPROC via the
              _EXTRA mechanism.  This should be a structure, and is
              similar in operation to FUNCTARGS.
              Default: no arguments are passed.

   ITERPROC - The name of a procedure to be called upon each NPRINT
              iteration of the MPFIT routine.  It should be declared
              in the following way:

              PRO ITERPROC, MYFUNCT, p, iter, fnorm, FUNCTARGS=fcnargs, $
                PARINFO=parinfo, QUIET=quiet, ...
                ; perform custom iteration update
              END
         
              ITERPROC must either accept all three keyword
              parameters (FUNCTARGS, PARINFO and QUIET), or at least
              accept them via the _EXTRA keyword.
          
              MYFUNCT is the user-supplied function to be minimized,
              P is the current set of model parameters, ITER is the
              iteration number, and FUNCTARGS are the arguments to be
              passed to MYFUNCT.  FNORM should be the
              chi-squared value.  QUIET is set when no textual output
              should be printed.  See below for documentation of
              PARINFO.

              In implementation, ITERPROC can perform updates to the
              terminal or graphical user interface, to provide
              feedback while the fit proceeds.  If the fit is to be
              stopped for any reason, then ITERPROC should set the
              common block variable ERROR_CODE to negative value (see
              MPFIT_ERROR common block below).  In principle,
              ITERPROC should probably not modify the parameter
              values, because it may interfere with the algorithm's
              stability.  In practice it is allowed.

              Default: an internal routine is used to print the
                       parameter values.

   MAXITER - The maximum number of iterations to perform.  If the
             number of calculation iterations exceeds MAXITER, then
             the STATUS value is set to 5 and MPFIT returns.  

             If MAXITER EQ 0, then MPFIT does not iterate to adjust
             parameter values; however, the user function is evaluated
             and parameter errors/covariance/Jacobian are estimated
             before returning.
             Default: 200 iterations

   NAN - ignore infinite or NaN values in the Y, ERR or WEIGHTS
         parameters.  These values will be treated as missing data.
         However, the fit will still halt with an error condition
         if the model function becomes infinite.

   NFEV - the number of MYFUNCT function evaluations performed.

   NFREE - the number of free parameters in the fit.  This includes
           parameters which are not FIXED and not TIED, but it does
           include parameters which are pegged at LIMITS.

   NITER - the number of iterations completed.

   NOCOVAR - set this keyword to prevent the calculation of the
             covariance matrix before returning (see COVAR)

   NPEGGED - the number of free parameters which are pegged at a
             LIMIT.

   NPRINT - The frequency with which ITERPROC is called.  A value of
            1 indicates that ITERPROC is called with every iteration,
            while 2 indicates every other iteration, etc.  Be aware
            that several Levenberg-Marquardt attempts can be made in
            a single iteration.  Also, the ITERPROC is *always*
            called for the final iteration, regardless of the
            iteration number.
            Default value: 1

   PARINFO - A one-dimensional array of structures.
             Provides a mechanism for more sophisticated constraints
             to be placed on parameter values.  When PARINFO is not
             passed, then it is assumed that all parameters are free
             and unconstrained.  Values in PARINFO are never 
             modified during a call to MPFIT.

             See description above for the structure of PARINFO.

             Default value:  all parameters are free and unconstrained.

   PERROR - The formal 1-sigma errors in each parameter, computed
            from the covariance matrix.  If a parameter is held
            fixed, or if it touches a boundary, then the error is
            reported as zero.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.  

            *If* you can assume that the true reduced chi-squared
            value is unity -- meaning that the fit is implicitly
            assumed to be of good quality -- then the estimated
            parameter uncertainties can be computed by scaling PERROR
            by the measured chi-squared value.

              DOF     = N_ELEMENTS(X) - N_ELEMENTS(PARMS) ; deg of freedom
              PCERROR = PERROR * SQRT(BESTNORM / DOF)   ; scaled uncertainties

   PFREE_INDEX - upon return, PFREE_INDEX contains an index array
                 which indicates which parameter were allowed to
                 vary.  I.e. of all the parameters PARMS, only
                 PARMS[PFREE_INDEX] were varied.

   QUERY - if set, then MPFIT() will return immediately with one of
           the following values:
                 1 - if MIN_VERSION is not set
                 1 - if MIN_VERSION is set and MPFIT satisfies the minimum
                 0 - if MIN_VERSION is set and MPFIT does not satisfy it
           Default: not set.

   QUIET - set this keyword when no textual output should be printed
           by MPFIT

   STATUS - an integer status code is returned.  All values greater
            than zero can represent success (however STATUS EQ 5 may
            indicate failure to converge).  It can have one of the
            following values:

        -18  a fatal execution error has occurred.  More information
             may be available in the ERRMSG string.

        -16  a parameter or function value has become infinite or an
             undefined number.  This is usually a consequence of
             numerical overflow in the user's model function, which
             must be avoided.

        -15 to -1 
             these are error codes that either MYFUNCT or ITERPROC
             may return to terminate the fitting process (see
             description of MPFIT_ERROR common below).  If either
             MYFUNCT or ITERPROC set ERROR_CODE to a negative number,
             then that number is returned in STATUS.  Values from -15
             to -1 are reserved for the user functions and will not
             clash with MPFIT.

	   0  improper input parameters.
         
	   1  both actual and predicted relative reductions
	      in the sum of squares are at most FTOL.
         
	   2  relative error between two consecutive iterates
	      is at most XTOL
         
	   3  conditions for STATUS = 1 and STATUS = 2 both hold.
         
	   4  the cosine of the angle between fvec and any
	      column of the jacobian is at most GTOL in
	      absolute value.
         
	   5  the maximum number of iterations has been reached
         
	   6  FTOL is too small. no further reduction in
	      the sum of squares is possible.
         
	   7  XTOL is too small. no further improvement in
	      the approximate solution x is possible.
         
	   8  GTOL is too small. fvec is orthogonal to the
	      columns of the jacobian to machine precision.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  If WEIGHTS is specified then the ERR
             parameter is ignored.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Y-MYFUNCT(X,P))^2 * ABS(WEIGHTS) )

             Here are common values of WEIGHTS for standard weightings:

                1D/ERR^2 - Normal weighting (ERR is the measurement error)
                1D/Y     - Poisson weighting (counting statistics)
                1D       - Unweighted

         NOTE: the following special cases apply:
                * if WEIGHTS is zero, then the corresponding data point
                  is ignored
                * if WEIGHTS is NaN or Infinite, and the NAN keyword is
                  set, then the corresponding data point is ignored
                * if WEIGHTS is negative, then the absolute value of 
                  WEIGHTS is used.

   XTOL - a nonnegative input variable. Termination occurs when the
          relative error between two consecutive iterates is at most
          XTOL (and STATUS is accordingly set to 2 or 3).  Therefore,
          XTOL measures the relative error desired in the approximate
          solution.  Default: 1D-10

   YFIT - the best-fit model function, as returned by MYFUNCT.

   
 EXAMPLE:

   ; First, generate some synthetic data
   npts = 200
   x  = dindgen(npts) * 0.1 - 10.                  ; Independent variable 
   yi = gauss1(x, [2.2D, 1.4, 3000.])              ; "Ideal" Y variable
   y  = yi + randomn(seed, npts) * sqrt(1000. + yi); Measured, w/ noise
   sy = sqrt(1000.D + y)                           ; Poisson errors

   ; Now fit a Gaussian to see how well we can recover
   p0 = [1.D, 1., 1000.]                   ; Initial guess (cent, width, area)
   p = mpfitfun('GAUSS1', x, y, sy, p0)    ; Fit a function
   print, p

   Generates a synthetic data set with a Gaussian peak, and Poisson
   statistical uncertainty.  Then the same function is fitted to the
   data (with different starting parameters) to see how close we can
   get.


 COMMON BLOCKS:

   COMMON MPFIT_ERROR, ERROR_CODE

     User routines may stop the fitting process at any time by
     setting an error condition.  This condition may be set in either
     the user's model computation routine (MYFUNCT), or in the
     iteration procedure (ITERPROC).

     To stop the fitting, the above common block must be declared,
     and ERROR_CODE must be set to a negative number.  After the user
     procedure or function returns, MPFIT checks the value of this
     common block variable and exits immediately if the error
     condition has been set.  By default the value of ERROR_CODE is
     zero, indicating a successful function/procedure call.

 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:
   Written, Apr-Jul 1998, CM
   Added PERROR keyword, 04 Aug 1998, CM
   Added COVAR keyword, 20 Aug 1998, CM
   Added ITER output keyword, 05 Oct 1998
      D.L Windt, Bell Labs, windt@bell-labs.com;
   Added ability to return model function in YFIT, 09 Nov 1998
   Analytical derivatives allowed via AUTODERIVATIVE keyword, 09 Nov 1998
   Parameter values can be tied to others, 09 Nov 1998
   Cosmetic documentation updates, 16 Apr 1999, CM
   More cosmetic documentation updates, 14 May 1999, CM
   Made sure to update STATUS, 25 Sep 1999, CM
   Added WEIGHTS keyword, 25 Sep 1999, CM
   Changed from handles to common blocks, 25 Sep 1999, CM
     - commons seem much cleaner and more logical in this case.
   Alphabetized documented keywords, 02 Oct 1999, CM
   Added QUERY keyword and query checking of MPFIT, 29 Oct 1999, CM
   Corrected EXAMPLE (offset of 1000), 30 Oct 1999, CM
   Check to be sure that X and Y are present, 02 Nov 1999, CM
   Documented PERROR for unweighted fits, 03 Nov 1999, CM
   Changed to ERROR_CODE for error condition, 28 Jan 2000, CM
   Corrected errors in EXAMPLE, 26 Mar 2000, CM
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Propagated improvements from MPFIT, 17 Dec 2000, CM
   Added CASH statistic, 10 Jan 2001
   Added NFREE and NPEGGED keywords, 11 Sep 2002, CM
   Documented RELSTEP field of PARINFO (!!), CM, 25 Oct 2002
   Add DOF keyword to return degrees of freedom, CM, 23 June 2003
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   Move STRICTARR compile option inside each function/procedure, 9
     Oct 2006
   Add NAN keyword, to ignore non-finite data values, 28 Oct 2006, CM
   Clarify documentation on user-function, derivatives, and PARINFO,
     27 May 2007
   Fix bug in handling of explicit derivatives with errors/weights
     (the weights were not being applied), CM, 03 Sep 2007
   Add COMPATIBILITY section, CM, 13 Dec 2007
   Add documentation about NAN behavior, CM, 30 Mar 2009
   Add keywords BEST_RESIDS, CALC_FJAC, BEST_FJAC, PFREE_INDEX;
     update some documentation that had become stale, CM, 2010-10-28
   Documentation corrections, CM, 2011-08-26
   Additional documentation about explicit derivatives, CM, 2012-07-23

  $Id: mpfitfun.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFITPEAK

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFITPEAK

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Fit a gaussian, lorentzian or Moffat model to data

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   yfit = MPFITPEAK(X, Y, A, NTERMS=nterms, ...)

 DESCRIPTION:

   MPFITPEAK fits a gaussian, lorentzian or Moffat model using the
   non-linear least squares fitter MPFIT.  MPFITPEAK is meant to be a
   drop-in replacement for IDL's GAUSSFIT function (and requires
   MPFIT and MPFITFUN).

   The choice of the fitting function is determined by the keywords
   GAUSSIAN, LORENTZIAN and MOFFAT.  By default the gaussian model
   function is used.  [ The Moffat function is a modified Lorentzian
   with variable power law index. (Moffat, A. F. J. 1969, Astronomy &
   Astrophysics, v. 3, p. 455-461) ]

   The functional form of the baseline is determined by NTERMS and
   the function to be fitted.  NTERMS represents the total number of
   parameters, A, to be fitted.  The functional forms and the
   meanings of the parameters are described in this table:

                 GAUSSIAN#          Lorentzian#         Moffat#

   Model     A[0]*exp(-0.5*u^2)   A[0]/(u^2 + 1)   A[0]/(u^2 + 1)^A[3]

   A[0]         Peak Value          Peak Value        Peak Value
   A[1]        Peak Centroid       Peak Centroid     Peak Centroid
   A[2]       Gaussian Sigma           HWHM%             HWHM%
   A[3]         + A[3]    *          + A[3]   *      Moffat Index
   A[4]         + A[4]*x  *          + A[4]*x *         + A[4]   *
   A[5]                                                 + A[5]*x *

   Notes: # u = (x - A[1])/A[2]
          % Half-width at half maximum
          * Optional depending on NTERMS

   By default the initial starting values for the parameters A are
   estimated from the data.  However, explicit starting values can be
   supplied using the ESTIMATES keyword.  Also, error or weighting
   values can optionally be provided; otherwise the fit is
   unweighted.

   MPFITPEAK fits the peak value of the curve.  The area under a
   gaussian peak is A[0]*A[2]*SQRT(2*!DPI); the area under a
   lorentzian peak is A[0]*A[2]*!DPI.

  Data values of NaN or Infinity for "Y", "ERROR" or "WEIGHTS" will
  be ignored as missing data if the NAN keyword is set.  Otherwise,
  they may cause the fitting loop to halt with an error message.
  Note that the fit will still halt if the model function, or its
  derivatives, produces infinite or NaN values, or if an "X" value is
  missing.

 RESTRICTIONS:

   If no starting parameter ESTIMATES are provided, then MPFITPEAK
   attempts to estimate them from the data.  This is not a perfect
   science; however, the author believes that the technique
   implemented here is more robust than the one used in IDL's
   GAUSSFIT.  The author has tested cases of strong peaks, noisy
   peaks and broad peaks, all with success.

   Users should be aware that if the baseline term contains a strong
   linear component then the automatic estimation may fail.  For
   automatic estimation to work the peak amplitude should dominate
   over the the maximum baseline.

 COMPATIBILITY

  This function is designed to work with IDL 5.0 or greater.
  
  Because TIED parameters rely on the EXECUTE() function, they cannot
  be used with the free version of the IDL Virtual Machine.


 INPUTS:
   X - Array of independent variable values, whose values should
       monotonically increase.

   Y - Array of "measured" dependent variable values.  Y should have
       the same data type and dimension as X.
         NOTE: the following special cases apply:
                * if Y is NaN or Infinite, and the NAN keyword is
                  set, then the corresponding data point is ignored

 OUTPUTS:
   A - Upon return, an array of NTERMS best fit parameter values.
       See the table above for the meanings of each parameter
       element.


 RETURNS:

   Returns the best fitting model function.

 KEYWORDS:

   ** NOTE ** Additional keywords such as PARINFO, BESTNORM, and
              STATUS are accepted by MPFITPEAK but not documented
              here.  Please see the documentation for MPFIT for the
              description of these advanced options.

   AUTODERIV - Set to 1 to have MPFIT compute the derivatives numerically.
          Default is 0 -  derivatives are computed analytically, which is 
              generally faster.    (Prior to Jan 2011, the default was 1)

   CHISQ - the value of the summed squared residuals for the
           returned parameter values.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).

   ERROR - upon input, the measured 1-sigma uncertainties in the "Y"
           values.  If no ERROR or WEIGHTS are given, then the fit is
           unweighted.
         NOTE: the following special cases apply:
                * if ERROR is zero, then the corresponding data point
                  is ignored
                * if ERROR is NaN or Infinite, and the NAN keyword is
                  set, then the corresponding data point is ignored
                * if ERROR is negative, then the absolute value of 
                  ERROR is used.

   ESTIMATES - Array of starting values for each parameter of the
               model.  The number of parameters should at least be
               three (four for Moffat), and if less than NTERMS, will
               be extended with zeroes.  If ESTIMATES is not set,
               then the starting values are estimated from the data
               directly, before fitting.  (This also means that
               PARINFO.VALUES is ignored.)
               Default: not set - parameter values are estimated from data.

   GAUSSIAN - if set, fit a gaussian model function.  The Default.
   LORENTZIAN - if set, fit a lorentzian model function.
   MOFFAT - if set, fit a Moffat model function.

   MEASURE_ERRORS - synonym for ERRORS, for consistency with built-in
                    IDL fitting routines.

   NAN - ignore infinite or NaN values in the Y, ERR or WEIGHTS
         parameters.  These values will be treated as missing data.
         However, the fit will still halt with an error condition if
         the model function becomes infinite, or if X has missing
         values.

   NEGATIVE / POSITIVE - if set, and ESTIMATES is not provided, then
                         MPFITPEAK will assume that a
                         negative/positive peak is present.
                         Default: determined automatically

   NFREE - the number of free parameters in the fit.  This includes
           parameters which are not FIXED and not TIED, but it does
           include parameters which are pegged at LIMITS.

   NO_FIT - if set, then return only the initial estimates without
            fitting.  Useful to find out what the estimates the
            automatic guessing algorithm produced.  If NO_FIT is set,
            then SIGMA and CHISQ values are not produced.  The
            routine returns, NAN, and STATUS=5.

   NTERMS - An integer describing the number of fitting terms.
            NTERMS must have a minimum value, but can optionally be
            larger depending on the desired baseline.  

            For gaussian and lorentzian models, NTERMS must be three
            (zero baseline), four (constant baseline) or five (linear
            baseline).  Default: 4

            For the Moffat model, NTERMS must be four (zero
            baseline), five (constant baseline), or six (linear
            baseline).  Default: 5

   PERROR - upon return, the 1-sigma uncertainties of the parameter
            values A.  These values are only meaningful if the ERRORS
            or WEIGHTS keywords are specified properly.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.  

            *If* you can assume that the true reduced chi-squared
            value is unity -- meaning that the fit is implicitly
            assumed to be of good quality -- then the estimated
            parameter uncertainties can be computed by scaling PERROR
            by the measured chi-squared value.

              DOF     = N_ELEMENTS(X) - N_ELEMENTS(PARMS) ; deg of freedom
              PCERROR = PERROR * SQRT(BESTNORM / DOF)   ; scaled uncertainties

   QUIET - if set then diagnostic fitting messages are suppressed.
           Default: QUIET=1 (i.e., no diagnostics)

   SIGMA - synonym for PERROR (1-sigma parameter uncertainties), for
           compatibility with GAUSSFIT.  Do not confuse this with the
           Gaussian "sigma" width parameter.

   WEIGHTS - Array of weights to be used in calculating the
             chi-squared value.  If WEIGHTS is specified then the ERROR
             keyword is ignored.  The chi-squared value is computed
             as follows:

                CHISQ = TOTAL( (Y-MYFUNCT(X,P))^2 * ABS(WEIGHTS) )

             Here are common values of WEIGHTS:

                1D/ERR^2 - Normal weighting (ERR is the measurement error)
                1D/Y     - Poisson weighting (counting statistics)
                1D       - Unweighted

             The ERROR keyword takes precedence over any WEIGHTS
             keyword values.  If no ERROR or WEIGHTS are given, then
             the fit is unweighted.
         NOTE: the following special cases apply:
                * if WEIGHTS is zero, then the corresponding data point
                  is ignored
                * if WEIGHTS is NaN or Infinite, and the NAN keyword is
                  set, then the corresponding data point is ignored
                * if WEIGHTS is negative, then the absolute value of 
                  WEIGHTS is used.

   YERROR - upon return, the root-mean-square variance of the
            residuals.


 EXAMPLE:

   ; First, generate some synthetic data
   npts = 200
   x  = dindgen(npts) * 0.1 - 10.                  ; Independent variable 
   yi = gauss1(x, [2.2D, 1.4, 3000.]) + 1000       ; "Ideal" Y variable
   y  = yi + randomn(seed, npts) * sqrt(1000. + yi); Measured, w/ noise
   sy = sqrt(1000.D + y)                           ; Poisson errors

   ; Now fit a Gaussian to see how well we can recover the original
   yfit = mpfitpeak(x, y, a, error=sy)
   print, p

   Generates a synthetic data set with a Gaussian peak, and Poisson
   statistical uncertainty.  Then the same function is fitted to the
   data.

 REFERENCES:

   MINPACK-1, Jorge More', available from netlib (www.netlib.org).
   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.

 MODIFICATION HISTORY:

   New algorithm for estimating starting values, CM, 31 Oct 1999
   Documented, 02 Nov 1999
   Small documentation fixes, 02 Nov 1999
   Slight correction to calculation of dx, CM, 02 Nov 1999
   Documented PERROR for unweighted fits, 03 Nov 1999, CM
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Change requirements on # elements in X and Y, 20 Jul 2000, CM
      (thanks to David Schlegel )
   Added documentation on area under curve, 29 Aug 2000, CM
   Added POSITIVE and NEGATIVE keywords, 17 Nov 2000, CM
   Added reference to Moffat paper, 10 Jan 2001, CM
   Added usage message, 26 Jul 2001, CM
   Documentation clarification, 05 Sep 2001, CM
   Make more consistent with comparable IDL routines, 30 Jun 2003, CM
   Assumption of sorted data was removed, CM, 06 Sep 2003, CM
   Add some defensive code against divide by zero, 30 Nov 2005, CM
   Add some defensive code against all Y values equal to each other,
     17 Apr 2005, CM
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   Move STRICTARR compile option inside each function/procedure, 9 Oct 2006
   Add COMPATIBILITY section, CM, 13 Dec 2007
   Missed some old IDL 4 () array syntax, now corrected, 13 Jun 2008
   Slightly more error checking for pathalogical case, CM, 11 Nov 2008
   Clarify documentation regarding what happens when ESTIMATES is not
     set, CM, 14 Dec 2008
   Add the NAN keyword, document how NAN, WEIGHTS and ERROR interact,
     CM, 30 Mar 2009
   Correct one case of old IDL 4 () array syntax (thanks to I. Urra),
     CM, 25 Jan 2010
  Improve performance by analytic derivative computation, added AUTODERIV 
      keyword, W. Landsman, 2011-01-21
  Move estimation code to its own function; allow the user to compute
    only the estimate and return immediately without fitting,
    C. Markwardt, 2011-07-12

  $Id: mpfitpeak.pro,v 1.2 2014/02/24 22:26:01 bdavis Exp $


MPFIT

[Previous Routine] [Next Routine] [List of Routines]
 NAME:
   MPFIT

 AUTHOR:
   Craig B. Markwardt, NASA/GSFC Code 662, Greenbelt, MD 20770
   craigm@lheamail.gsfc.nasa.gov
   UPDATED VERSIONs can be found on my WEB PAGE: 
      http://cow.physics.wisc.edu/~craigm/idl/idl.html

 PURPOSE:
   Perform Levenberg-Marquardt least-squares minimization (MINPACK-1)

 MAJOR TOPICS:
   Curve and Surface Fitting

 CALLING SEQUENCE:
   parms = MPFIT(MYFUNCT, start_parms, FUNCTARGS=fcnargs, NFEV=nfev,
                 MAXITER=maxiter, ERRMSG=errmsg, NPRINT=nprint, QUIET=quiet, 
                 FTOL=ftol, XTOL=xtol, GTOL=gtol, NITER=niter, 
                 STATUS=status, ITERPROC=iterproc, ITERARGS=iterargs,
                 COVAR=covar, PERROR=perror, BESTNORM=bestnorm,
                 PARINFO=parinfo)

 DESCRIPTION:

  MPFIT uses the Levenberg-Marquardt technique to solve the
  least-squares problem.  In its typical use, MPFIT will be used to
  fit a user-supplied function (the "model") to user-supplied data
  points (the "data") by adjusting a set of parameters.  MPFIT is
  based upon MINPACK-1 (LMDIF.F) by More' and collaborators.

  For example, a researcher may think that a set of observed data
  points is best modelled with a Gaussian curve.  A Gaussian curve is
  parameterized by its mean, standard deviation and normalization.
  MPFIT will, within certain constraints, find the set of parameters
  which best fits the data.  The fit is "best" in the least-squares
  sense; that is, the sum of the weighted squared differences between
  the model and data is minimized.

  The Levenberg-Marquardt technique is a particular strategy for
  iteratively searching for the best fit.  This particular
  implementation is drawn from MINPACK-1 (see NETLIB), and seems to
  be more robust than routines provided with IDL.  This version
  allows upper and lower bounding constraints to be placed on each
  parameter, or the parameter can be held fixed.

  The IDL user-supplied function should return an array of weighted
  deviations between model and data.  In a typical scientific problem
  the residuals should be weighted so that each deviate has a
  gaussian sigma of 1.0.  If X represents values of the independent
  variable, Y represents a measurement for each value of X, and ERR
  represents the error in the measurements, then the deviates could
  be calculated as follows:

    DEVIATES = (Y - F(X)) / ERR

  where F is the function representing the model.  You are
  recommended to use the convenience functions MPFITFUN and
  MPFITEXPR, which are driver functions that calculate the deviates
  for you.  If ERR are the 1-sigma uncertainties in Y, then

    TOTAL( DEVIATES^2 ) 

  will be the total chi-squared value.  MPFIT will minimize the
  chi-square value.  The values of X, Y and ERR are passed through
  MPFIT to the user-supplied function via the FUNCTARGS keyword.

  Simple constraints can be placed on parameter values by using the
  PARINFO keyword to MPFIT.  See below for a description of this
  keyword.

  MPFIT does not perform more general optimization tasks.  See TNMIN
  instead.  MPFIT is customized, based on MINPACK-1, to the
  least-squares minimization problem.

 USER FUNCTION

  The user must define a function which returns the appropriate
  values as specified above.  The function should return the weighted
  deviations between the model and the data.  For applications which
  use finite-difference derivatives -- the default -- the user
  function should be declared in the following way:

    FUNCTION MYFUNCT, p, X=x, Y=y, ERR=err
     ; Parameter values are passed in "p"
     model = F(x, p)
     return, (y-model)/err
    END

  See below for applications with explicit derivatives.

  The keyword parameters X, Y, and ERR in the example above are
  suggestive but not required.  Any parameters can be passed to
  MYFUNCT by using the FUNCTARGS keyword to MPFIT.  Use MPFITFUN and
  MPFITEXPR if you need ideas on how to do that.  The function *must*
  accept a parameter list, P.
  
  In general there are no restrictions on the number of dimensions in
  X, Y or ERR.  However the deviates *must* be returned in a
  one-dimensional array, and must have the same type (float or
  double) as the input arrays.

  See below for error reporting mechanisms.


 CHECKING STATUS AND HANNDLING ERRORS

  Upon return, MPFIT will report the status of the fitting operation
  in the STATUS and ERRMSG keywords.  The STATUS keyword will contain
  a numerical code which indicates the success or failure status.
  Generally speaking, any value 1 or greater indicates success, while
  a value of 0 or less indicates a possible failure.  The ERRMSG
  keyword will contain a text string which should describe the error
  condition more fully.

  By default, MPFIT will trap fatal errors and report them to the
  caller gracefully.  However, during the debugging process, it is
  often useful to halt execution where the error occurred.  When you
  set the NOCATCH keyword, MPFIT will not do any special error
  trapping, and execution will stop whereever the error occurred.

  MPFIT does not explicitly change the !ERROR_STATE variable
  (although it may be changed implicitly if MPFIT calls MESSAGE).  It
  is the caller's responsibility to call MESSAGE, /RESET to ensure
  that the error state is initialized before calling MPFIT.

  User functions may also indicate non-fatal error conditions using
  the ERROR_CODE common block variable, as described below under the
  MPFIT_ERROR common block definition (by setting ERROR_CODE to a
  number between -15 and -1).  When the user function sets an error
  condition via ERROR_CODE, MPFIT will gracefully exit immediately
  and report this condition to the caller.  The ERROR_CODE is
  returned in the STATUS keyword in that case.


 EXPLICIT DERIVATIVES
 
  In the search for the best-fit solution, MPFIT by default
  calculates derivatives numerically via a finite difference
  approximation.  The user-supplied function need not calculate the
  derivatives explicitly.  However, the user function *may* calculate
  the derivatives if desired, but only if the model function is
  declared with an additional position parameter, DP, as described
  below.  If the user function does not accept this additional
  parameter, MPFIT will report an error.  As a practical matter, it
  is often sufficient and even faster to allow MPFIT to calculate the
  derivatives numerically, but this option is available for users who
  wish more control over the fitting process.

  There are two ways to enable explicit derivatives.  First, the user
  can set the keyword AUTODERIVATIVE=0, which is a global switch for
  all parameters.  In this case, MPFIT will request explicit
  derivatives for every free parameter.  

  Second, the user may request explicit derivatives for specifically
  selected parameters using the PARINFO.MPSIDE=3 (see "CONSTRAINING
  PARAMETER VALUES WITH THE PARINFO KEYWORD" below).  In this
  strategy, the user picks and chooses which parameter derivatives
  are computed explicitly versus numerically.  When PARINFO[i].MPSIDE
  EQ 3, then the ith parameter derivative is computed explicitly.

  The keyword setting AUTODERIVATIVE=0 always globally overrides the
  individual values of PARINFO.MPSIDE.  Setting AUTODERIVATIVE=0 is
  equivalent to resetting PARINFO.MPSIDE=3 for all parameters.

  Even if the user requests explicit derivatives for some or all
  parameters, MPFIT will not always request explicit derivatives on
  every user function call.

 EXPLICIT DERIVATIVES - CALLING INTERFACE

  When AUTODERIVATIVE=0, the user function is responsible for
  calculating the derivatives of the *residuals* with respect to each
  parameter.  The user function should be declared as follows:

    ;
    ; MYFUNCT - example user function
    ;   P - input parameter values (N-element array)
    ;   DP - upon input, an N-vector indicating which parameters
    ;          to compute derivatives for; 
    ;        upon output, the user function must return
    ;          an ARRAY(M,N) of derivatives in this keyword
    ;   (keywords) - any other keywords specified by FUNCTARGS
    ; RETURNS - residual values
    ;
    FUNCTION MYFUNCT, p, dp, X=x, Y=y, ERR=err
     model = F(x, p)         ;; Model function
     resid = (y - model)/err ;; Residual calculation (for example)
     
     if n_params() GT 1 then begin
       ; Create derivative and compute derivative array
       requested = dp   ; Save original value of DP
       dp = make_array(n_elements(x), n_elements(p), value=x[0]*0)

       ; Compute derivative if requested by caller
       for i = 0, n_elements(p)-1 do if requested(i) NE 0 then $
         dp(*,i) = FGRAD(x, p, i) / err
     endif
    
     return, resid
    END

  where FGRAD(x, p, i) is a model function which computes the
  derivative of the model F(x,p) with respect to parameter P(i) at X.

  A quirk in the implementation leaves a stray negative sign in the
  definition of DP.  The derivative of the *residual* should be
  "-FGRAD(x,p,i) / err" because of how the residual is defined
  ("resid = (data - model) / err").  **HOWEVER** because of the
  implementation quirk, MPFIT expects FGRAD(x,p,i)/err instead,
  i.e. the opposite sign of the gradient of RESID.

  Derivatives should be returned in the DP array. DP should be an
  ARRAY(m,n) array, where m is the number of data points and n is the
  number of parameters.  -DP[i,j] is the derivative of the ith
  residual with respect to the jth parameter (note the minus sign
  due to the quirk described above).

  As noted above, MPFIT may not always request derivatives from the
  user function.  In those cases, the parameter DP is not passed.
  Therefore functions can use N_PARAMS() to indicate whether they
  must compute the derivatives or not.
  
  The derivatives with respect to fixed parameters are ignored; zero
  is an appropriate value to insert for those derivatives.  Upon
  input to the user function, DP is set to a vector with the same
  length as P, with a value of 1 for a parameter which is free, and a
  value of zero for a parameter which is fixed (and hence no
  derivative needs to be calculated).  This input vector may be
  overwritten as needed.  In the example above, the original DP
  vector is saved to a variable called REQUESTED, and used as a mask
  to calculate only those derivatives that are required.

  If the data is higher than one dimensional, then the *last*
  dimension should be the parameter dimension.  Example: fitting a
  50x50 image, "dp" should be 50x50xNPAR.

 EXPLICIT DERIVATIVES - TESTING and DEBUGGING

  For reasonably complicated user functions, the calculation of
  explicit derivatives of the correct sign and magnitude can be
  difficult to get right.  A simple sign error can cause MPFIT to be
  confused.  MPFIT has a derivative debugging mode which will compute
  the derivatives *both* numerically and explicitly, and compare the
  results.

  It is expected that during production usage, derivative debugging
  should be disabled for all parameters.

  In order to enable derivative debugging mode, set the following
  PARINFO members for the ith parameter.
      PARINFO[i].MPSIDE = 3          ; Enable explicit derivatives
      PARINFO[i].MPDERIV_DEBUG = 1   ; Enable derivative debugging mode
      PARINFO[i].MPDERIV_RELTOL = ?? ; Relative tolerance for comparison
      PARINFO[i].MPDERIV_ABSTOL = ?? ; Absolute tolerance for comparison
  Note that these settings are maintained on a parameter-by-parameter
  basis using PARINFO, so the user can choose which parameters
  derivatives will be tested.

  When .MPDERIV_DEBUG is set, then MPFIT first computes the
  derivative explicitly by requesting them from the user function.
  Then, it computes the derivatives numerically via finite
  differencing, and compares the two values.  If the difference
  exceeds a tolerance threshold, then the values are printed out to 
  alert the user.  The tolerance level threshold contains both a
  relative and an absolute component, and is expressed as,

     ABS(DERIV_U - DERIV_N) GE (ABSTOL + RELTOL*ABS(DERIV_U))

  where DERIV_U and DERIV_N are the derivatives computed explicitly
  and numerically, respectively.  Appropriate values
  for most users will be: 

      PARINFO[i].MPDERIV_RELTOL = 1d-3 ;; Suggested relative tolerance 
      PARINFO[i].MPDERIV_ABSTOL = 1d-7 ;; Suggested absolute tolerance

  although these thresholds may have to be adjusted for a particular
  problem.  When the threshold is exceeded, users can expect to see a
  tabular report like this one:

    FJAC DEBUG BEGIN
    #        IPNT       FUNC    DERIV_U    DERIV_N   DIFF_ABS   DIFF_REL
    FJAC PARM 2
               80    -0.7308    0.04233    0.04233 -5.543E-07 -1.309E-05
               99      1.370    0.01417    0.01417 -5.518E-07 -3.895E-05
              118    0.07187   -0.01400   -0.01400 -5.566E-07  3.977E-05
              137      1.844   -0.04216   -0.04216 -5.589E-07  1.326E-05
    FJAC DEBUG END

  The report will be bracketed by FJAC DEBUG BEGIN/END statements.
  Each parameter will be delimited by the statement FJAC PARM n,
  where n is the parameter number.  The columns are,

      IPNT - data point number  (0 ... M-1)
      FUNC - function value at that point
      DERIV_U - explicit derivative value at that point
      DERIV_N - numerical derivative estimate at that point
      DIFF_ABS - absolute difference = (DERIV_U - DERIV_N)
      DIFF_REL - relative difference = (DIFF_ABS)/(DERIV_U)

  When prints appear in this report, it is most important to check
  that the derivatives computed in two different ways have the same
  numerical sign and the same order of magnitude, since these are the
  most common programming mistakes.

  A line of this form may also appear 

   # FJAC_MASK = 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 1 

  This line indicates for which parameters explicit derivatives are
  expected.  A list of all-1s indicates all explicit derivatives for
  all parameters are requested from the user function.
    
  
 CONSTRAINING PARAMETER VALUES WITH THE PARINFO KEYWORD

  The behavior of MPFIT can be modified with respect to each
  parameter to be fitted.  A parameter value can be fixed; simple
  boundary constraints can be imposed; limitations on the parameter
  changes can be imposed; properties of the automatic derivative can
  be modified; and parameters can be tied to one another.

  These properties are governed by the PARINFO structure, which is
  passed as a keyword parameter to MPFIT.

  PARINFO should be an array of structures, one for each parameter.
  Each parameter is associated with one element of the array, in
  numerical order.  The structure can have the following entries
  (none are required):
  
     .VALUE - the starting parameter value (but see the START_PARAMS
              parameter for more information).
  
     .FIXED - a boolean value, whether the parameter is to be held
              fixed or not.  Fixed parameters are not varied by
              MPFIT, but are passed on to MYFUNCT for evaluation.
  
     .LIMITED - a two-element boolean array.  If the first/second
                element is set, then the parameter is bounded on the
                lower/upper side.  A parameter can be bounded on both
                sides.  Both LIMITED and LIMITS must be given
                together.
  
     .LIMITS - a two-element float or double array.  Gives the
               parameter limits on the lower and upper sides,
               respectively.  Zero, one or two of these values can be
               set, depending on the values of LIMITED.  Both LIMITED
               and LIMITS must be given together.
  
     .PARNAME - a string, giving the name of the parameter.  The
                fitting code of MPFIT does not use this tag in any
                way.  However, the default ITERPROC will print the
                parameter name if available.
  
     .STEP - the step size to be used in calculating the numerical
             derivatives.  If set to zero, then the step size is
             computed automatically.  Ignored when AUTODERIVATIVE=0.
             This value is superceded by the RELSTEP value.

     .RELSTEP - the *relative* step size to be used in calculating
                the numerical derivatives.  This number is the
                fractional size of the step, compared to the
                parameter value.  This value supercedes the STEP
                setting.  If the parameter is zero, then a default
                step size is chosen.

     .MPSIDE - selector for type of derivative calculation. This
               field can take one of five possible values:

                  0 - one-sided derivative computed automatically
                  1 - one-sided derivative (f(x+h) - f(x)  )/h
                 -1 - one-sided derivative (f(x)   - f(x-h))/h
                  2 - two-sided derivative (f(x+h) - f(x-h))/(2*h)
                  3 - explicit derivative used for this parameter

              In the first four cases, the derivative is approximated
              numerically by finite difference, with step size
              H=STEP, where the STEP parameter is defined above.  The
              last case, MPSIDE=3, indicates to allow the user
              function to compute the derivative explicitly (see
              section on "EXPLICIT DERIVATIVES").  AUTODERIVATIVE=0
              overrides this setting for all parameters, and is
              equivalent to MPSIDE=3 for all parameters.  For
              MPSIDE=0, the "automatic" one-sided derivative method
              will chose a direction for the finite difference which
              does not violate any constraints.  The other methods
              (MPSIDE=-1 or MPSIDE=1) do not perform this check.  The
              two-sided method is in principle more precise, but
              requires twice as many function evaluations.  Default:
              0.

     .MPDERIV_DEBUG - set this value to 1 to enable debugging of
              user-supplied explicit derivatives (see "TESTING and
              DEBUGGING" section above).  In addition, the
              user must enable calculation of explicit derivatives by
              either setting AUTODERIVATIVE=0, or MPSIDE=3 for the
              desired parameters.  When this option is enabled, a
              report may be printed to the console, depending on the
              MPDERIV_ABSTOL and MPDERIV_RELTOL settings.
              Default: 0 (no debugging)

     
     .MPDERIV_ABSTOL, .MPDERIV_RELTOL - tolerance settings for
              print-out of debugging information, for each parameter
              where debugging is enabled.  See "TESTING and
              DEBUGGING" section above for the meanings of these two
              fields.


     .MPMAXSTEP - the maximum change to be made in the parameter
                  value.  During the fitting process, the parameter
                  will never be changed by more than this value in
                  one iteration.

                  A value of 0 indicates no maximum.  Default: 0.
  
     .TIED - a string expression which "ties" the parameter to other
             free or fixed parameters as an equality constraint.  Any
             expression involving constants and the parameter array P
             are permitted.
             Example: if parameter 2 is always to be twice parameter
             1 then use the following: parinfo[2].tied = '2 * P[1]'.
             Since they are totally constrained, tied parameters are
             considered to be fixed; no errors are computed for them,
             and any LIMITS are not obeyed.
             [ NOTE: the PARNAME can't be used in a TIED expression. ]

     .MPPRINT - if set to 1, then the default ITERPROC will print the
                parameter value.  If set to 0, the parameter value
                will not be printed.  This tag can be used to
                selectively print only a few parameter values out of
                many.  Default: 1 (all parameters printed)

     .MPFORMAT - IDL format string to print the parameter within
                 ITERPROC.  Default: '(G20.6)'  (An empty string will
                 also use the default.)

  Future modifications to the PARINFO structure, if any, will involve
  adding structure tags beginning with the two letters "MP".
  Therefore programmers are urged to avoid using tags starting with
  "MP", but otherwise they are free to include their own fields
  within the PARINFO structure, which will be ignored by MPFIT.
  
  PARINFO Example:
  parinfo = replicate({value:0.D, fixed:0, limited:[0,0], $
                       limits:[0.D,0]}, 5)
  parinfo[0].fixed = 1
  parinfo[4].limited[0] = 1
  parinfo[4].limits[0]  = 50.D
  parinfo[*].value = [5.7D, 2.2, 500., 1.5, 2000.]
  
  A total of 5 parameters, with starting values of 5.7,
  2.2, 500, 1.5, and 2000 are given.  The first parameter
  is fixed at a value of 5.7, and the last parameter is
  constrained to be above 50.


 RECURSION

  Generally, recursion is not allowed.  As of version 1.77, MPFIT has
  recursion protection which does not allow a model function to
  itself call MPFIT.  Users who wish to perform multi-level
  optimization should investigate the 'EXTERNAL' function evaluation
  methods described below for hard-to-evaluate functions.  That
  method places more control in the user's hands.  The user can
  design a "recursive" application by taking care.

  In most cases the recursion protection should be well-behaved.
  However, if the user is doing debugging, it is possible for the
  protection system to get "stuck."  In order to reset it, run the
  procedure:
     MPFIT_RESET_RECURSION
  and the protection system should get "unstuck."  It is save to call
  this procedure at any time.


 COMPATIBILITY

  This function is designed to work with IDL 5.0 or greater.
  
  Because TIED parameters and the "(EXTERNAL)" user-model feature use
  the EXECUTE() function, they cannot be used with the free version
  of the IDL Virtual Machine.


 DETERMINING THE VERSION OF MPFIT

  MPFIT is a changing library.  Users of MPFIT may also depend on a
  specific version of the library being present.  As of version 1.70
  of MPFIT, a VERSION keyword has been added which allows the user to
  query which version is present.  The keyword works like this:

    RESULT = MPFIT(/query, VERSION=version)

  This call uses the /QUERY keyword to query the version number
  without performing any computations.  Users of MPFIT can call this
  method to determine which version is in the IDL path before
  actually using MPFIT to do any numerical work.  Upon return, the
  VERSION keyword contains the version number of MPFIT, expressed as
  a string of the form 'X.Y' where X and Y are integers.

  Users can perform their own version checking, or use the built-in
  error checking of MPFIT.  The MIN_VERSION keyword enforces the
  requested minimum version number.  For example,

    RESULT = MPFIT(/query, VERSION=version, MIN_VERSION='1.70')

  will check whether the accessed version is 1.70 or greater, without
  performing any numerical processing.

  The VERSION and MIN_VERSION keywords were added in MPFIT
  version 1.70 and later.  If the caller attempts to use the VERSION
  or MIN_VERSION keywords, and an *older* version of the code is
  present in the caller's path, then IDL will throw an 'unknown
  keyword' error.  Therefore, in order to be robust, the caller, must
  use exception handling.  Here is an example demanding at least
  version 1.70.

    MPFIT_OK = 0  & VERSION = ''
    CATCH, CATCHERR
    IF CATCHERR EQ 0 THEN MPFIT_OK = MPFIT(/query, VERSION=version, $
                                         MIN_VERSION='1.70')
    CATCH, /CANCEL

    IF NOT MPFIT_OK THEN $
      MESSAGE, 'ERROR: you must have MPFIT version 1.70 or higher in '+$
             'your path (found version '+version+')'

  Of course, the caller can also do its own version number
  requirements checking.


 HARD-TO-COMPUTE FUNCTIONS: "EXTERNAL" EVALUATION

  The normal mode of operation for MPFIT is for the user to pass a
  function name, and MPFIT will call the user function multiple times
  as it iterates toward a solution.

  Some user functions are particularly hard to compute using the
  standard model of MPFIT.  Usually these are functions that depend
  on a large amount of external data, and so it is not feasible, or
  at least highly impractical, to have MPFIT call it.  In those cases
  it may be possible to use the "(EXTERNAL)" evaluation option.

  In this case the user is responsible for making all function *and
  derivative* evaluations.  The function and Jacobian data are passed
  in through the EXTERNAL_FVEC and EXTERNAL_FJAC keywords,
  respectively.  The user indicates the selection of this option by
  specifying a function name (MYFUNCT) of "(EXTERNAL)".  No
  user-function calls are made when EXTERNAL evaluation is being
  used.

  ** SPECIAL NOTE ** For the "(EXTERNAL)" case, the quirk noted above
     does not apply.  The gradient matrix, EXTERNAL_FJAC, should be
     comparable to "-FGRAD(x,p)/err", which is the *opposite* sign of
     the DP matrix described above.  In other words, EXTERNAL_FJAC
     has the same sign as the derivative of EXTERNAL_FVEC, and the
     opposite sign of FGRAD.

  At the end of each iteration, control returns to the user, who must
  reevaluate the function at its new parameter values.  Users should
  check the return value of the STATUS keyword, where a value of 9
  indicates the user should supply more data for the next iteration,
  and re-call MPFIT.  The user may refrain from calling MPFIT
  further; as usual, STATUS will indicate when the solution has
  converged and no more iterations are required.

  Because MPFIT must maintain its own data structures between calls,
  the user must also pass a named variable to the EXTERNAL_STATE
  keyword.  This variable must be maintained by the user, but not
  changed, throughout the fitting process.  When no more iterations
  are desired, the named variable may be discarded.


 INPUTS:
   MYFUNCT - a string variable containing the name of the function to
             be minimized.  The function should return the weighted
             deviations between the model and the data, as described
             above.

             For EXTERNAL evaluation of functions, this parameter
             should be set to a value of "(EXTERNAL)".

   START_PARAMS - An one-dimensional array of starting values for each of the
                  parameters of the model.  The number of parameters
                  should be fewer than the number of measurements.
                  Also, the parameters should have the same data type
                  as the measurements (double is preferred).

                  This parameter is optional if the PARINFO keyword
                  is used (but see PARINFO).  The PARINFO keyword
                  provides a mechanism to fix or constrain individual
                  parameters.  If both START_PARAMS and PARINFO are
                  passed, then the starting *value* is taken from
                  START_PARAMS, but the *constraints* are taken from
                  PARINFO.
 
 RETURNS:

   Returns the array of best-fit parameters.
   Exceptions: 
      * if /QUERY is set (see QUERY).


 KEYWORD PARAMETERS:

   AUTODERIVATIVE - If this is set, derivatives of the function will
                    be computed automatically via a finite
                    differencing procedure.  If not set, then MYFUNCT
                    must provide the explicit derivatives.
                    Default: set (=1) 
                    NOTE: to supply your own explicit derivatives,
                      explicitly pass AUTODERIVATIVE=0

   BESTNORM - upon return, the value of the summed squared weighted
              residuals for the returned parameter values,
              i.e. TOTAL(DEVIATES^2).

   BEST_FJAC - upon return, BEST_FJAC contains the Jacobian, or
               partial derivative, matrix for the best-fit model.
               The values are an array,
               ARRAY(N_ELEMENTS(DEVIATES),NFREE) where NFREE is the
               number of free parameters.  This array is only
               computed if /CALC_FJAC is set, otherwise BEST_FJAC is
               undefined.

               The returned array is such that BEST_FJAC[I,J] is the
               partial derivative of DEVIATES[I] with respect to
               parameter PARMS[PFREE_INDEX[J]].  Note that since
               deviates are (data-model)*weight, the Jacobian of the
               *deviates* will have the opposite sign from the
               Jacobian of the *model*, and may be scaled by a
               factor.

   BEST_RESID - upon return, an array of best-fit deviates.

   CALC_FJAC - if set, then calculate the Jacobian and return it in
               BEST_FJAC.  If not set, then the return value of
               BEST_FJAC is undefined.

   COVAR - the covariance matrix for the set of parameters returned
           by MPFIT.  The matrix is NxN where N is the number of
           parameters.  The square root of the diagonal elements
           gives the formal 1-sigma statistical errors on the
           parameters IF errors were treated "properly" in MYFUNC.
           Parameter errors are also returned in PERROR.

           To compute the correlation matrix, PCOR, use this example:
                  PCOR = COV * 0
                  FOR i = 0, n-1 DO FOR j = 0, n-1 DO $
                    PCOR[i,j] = COV[i,j]/sqrt(COV[i,i]*COV[j,j])
           or equivalently, in vector notation,
                  PCOR = COV / (PERROR # PERROR)

           If NOCOVAR is set or MPFIT terminated abnormally, then
           COVAR is set to a scalar with value !VALUES.D_NAN.

   DOF - number of degrees of freedom, computed as
             DOF = N_ELEMENTS(DEVIATES) - NFREE
         Note that this doesn't account for pegged parameters (see
         NPEGGED).  It also does not account for data points which
         are assigned zero weight by the user function.

   ERRMSG - a string error or warning message is returned.

   EXTERNAL_FVEC - upon input, the function values, evaluated at
                   START_PARAMS.  This should be an M-vector, where M
                   is the number of data points.

   EXTERNAL_FJAC - upon input, the Jacobian array of partial
                   derivative values.  This should be a M x N array,
                   where M is the number of data points and N is the
                   number of parameters.  NOTE: that all FIXED or
                   TIED parameters must *not* be included in this
                   array.

   EXTERNAL_STATE - a named variable to store MPFIT-related state
                    information between iterations (used in input and
                    output to MPFIT).  The user must not manipulate
                    or discard this data until the final iteration is
                    performed.

   FASTNORM - set this keyword to select a faster algorithm to
              compute sum-of-square values internally.  For systems
              with large numbers of data points, the standard
              algorithm can become prohibitively slow because it
              cannot be vectorized well.  By setting this keyword,
              MPFIT will run faster, but it will be more prone to
              floating point overflows and underflows.  Thus, setting
              this keyword may sacrifice some stability in the
              fitting process.
              
   FTOL - a nonnegative input variable. Termination occurs when both
          the actual and predicted relative reductions in the sum of
          squares are at most FTOL (and STATUS is accordingly set to
          1 or 3).  Therefore, FTOL measures the relative error
          desired in the sum of squares.  Default: 1D-10

   FUNCTARGS - A structure which contains the parameters to be passed
               to the user-supplied function specified by MYFUNCT via
               the _EXTRA mechanism.  This is the way you can pass
               additional data to your user-supplied function without
               using common blocks.

               Consider the following example:
                if FUNCTARGS = { XVAL:[1.D,2,3], YVAL:[1.D,4,9],
                                 ERRVAL:[1.D,1,1] }
                then the user supplied function should be declared
                like this:
                FUNCTION MYFUNCT, P, XVAL=x, YVAL=y, ERRVAL=err

               By default, no extra parameters are passed to the
               user-supplied function, but your function should
               accept *at least* one keyword parameter.  [ This is to
               accomodate a limitation in IDL's _EXTRA
               parameter-passing mechanism. ]

   GTOL - a nonnegative input variable. Termination occurs when the
          cosine of the angle between fvec and any column of the
          jacobian is at most GTOL in absolute value (and STATUS is
          accordingly set to 4). Therefore, GTOL measures the
          orthogonality desired between the function vector and the
          columns of the jacobian.  Default: 1D-10

   ITERARGS - The keyword arguments to be passed to ITERPROC via the
              _EXTRA mechanism.  This should be a structure, and is
              similar in operation to FUNCTARGS.
              Default: no arguments are passed.

   ITERPRINT - The name of an IDL procedure, equivalent to PRINT,
               that ITERPROC will use to render output.  ITERPRINT
               should be able to accept at least four positional
               arguments.  In addition, it should be able to accept
               the standard FORMAT keyword for output formatting; and
               the UNIT keyword, to redirect output to a logical file
               unit (default should be UNIT=1, standard output).
               These keywords are passed using the ITERARGS keyword
               above.  The ITERPRINT procedure must accept the _EXTRA
               keyword.  
               NOTE: that much formatting can be handled with the 
                     MPPRINT and MPFORMAT tags.
               Default: 'MPFIT_DEFPRINT' (default internal formatter)

   ITERPROC - The name of a procedure to be called upon each NPRINT
              iteration of the MPFIT routine.  ITERPROC is always
              called in the final iteration.  It should be declared
              in the following way:

              PRO ITERPROC, MYFUNCT, p, iter, fnorm, FUNCTARGS=fcnargs, $
                PARINFO=parinfo, QUIET=quiet, DOF=dof, PFORMAT=pformat, $
                UNIT=unit, ...
                ; perform custom iteration update
              END
         
              ITERPROC must either accept all three keyword
              parameters (FUNCTARGS, PARINFO and QUIET), or at least
              accept them via the _EXTRA keyword.
          
              MYFUNCT is the user-supplied function to be minimized,
              P is the current set of model parameters, ITER is the
              iteration number, and FUNCTARGS are the arguments to be
              passed to MYFUNCT.  FNORM should be the chi-squared
              value.  QUIET is set when no textual output should be
              printed.  DOF is the number of degrees of freedom,
              normally the number of points less the number of free
              parameters.  See below for documentation of PARINFO.
              PFORMAT is the default parameter value format.  UNIT is
              passed on to the ITERPRINT procedure, and should
              indicate the file unit where log output will be sent
              (default: standard output).

              In implementation, ITERPROC can perform updates to the
              terminal or graphical user interface, to provide
              feedback while the fit proceeds.  If the fit is to be
              stopped for any reason, then ITERPROC should set the
              common block variable ERROR_CODE to negative value
              between -15 and -1 (see MPFIT_ERROR common block
              below).  In principle, ITERPROC should probably not
              modify the parameter values, because it may interfere
              with the algorithm's stability.  In practice it is
              allowed.

              Default: an internal routine is used to print the
                       parameter values.

   ITERSTOP - Set this keyword if you wish to be able to stop the
              fitting by hitting the predefined ITERKEYSTOP key on
              the keyboard.  This only works if you use the default
              ITERPROC.

   ITERKEYSTOP - A keyboard key which will halt the fit (and if
                 ITERSTOP is set and the default ITERPROC is used).
                 ITERSTOPKEY may either be a one-character string
                 with the desired key, or a scalar integer giving the
                 ASCII code of the desired key.  
                 Default: 7b (control-g)

                 NOTE: the default value of ASCI 7 (control-G) cannot
                 be read in some windowing environments, so you must
                 change to a printable character like 'q'.

   MAXITER - The maximum number of iterations to perform.  If the
             number of calculation iterations exceeds MAXITER, then
             the STATUS value is set to 5 and MPFIT returns.  

             If MAXITER EQ 0, then MPFIT does not iterate to adjust
             parameter values; however, the user function is evaluated
             and parameter errors/covariance/Jacobian are estimated
             before returning.
             Default: 200 iterations

   MIN_VERSION - The minimum requested version number.  This must be
                 a scalar string of the form returned by the VERSION
                 keyword.  If the current version of MPFIT does not
                 satisfy the minimum requested version number, then,
                    MPFIT(/query, min_version='...') returns 0
                    MPFIT(...) returns NAN
                 Default: no version number check
                 NOTE: MIN_VERSION was added in MPFIT version 1.70

   NFEV - the number of MYFUNCT function evaluations performed.

   NFREE - the number of free parameters in the fit.  This includes
           parameters which are not FIXED and not TIED, but it does
           include parameters which are pegged at LIMITS.

   NITER - the number of iterations completed.

   NOCATCH - if set, then MPFIT will not perform any error trapping.
             By default (not set), MPFIT will trap errors and report
             them to the caller.  This keyword will typically be used
             for debugging.

   NOCOVAR - set this keyword to prevent the calculation of the
             covariance matrix before returning (see COVAR)

   NPEGGED - the number of free parameters which are pegged at a
             LIMIT.

   NPRINT - The frequency with which ITERPROC is called.  A value of
            1 indicates that ITERPROC is called with every iteration,
            while 2 indicates every other iteration, etc.  Be aware
            that several Levenberg-Marquardt attempts can be made in
            a single iteration.  Also, the ITERPROC is *always*
            called for the final iteration, regardless of the
            iteration number.
            Default value: 1

   PARINFO - A one-dimensional array of structures.
             Provides a mechanism for more sophisticated constraints
             to be placed on parameter values.  When PARINFO is not
             passed, then it is assumed that all parameters are free
             and unconstrained.  Values in PARINFO are never 
             modified during a call to MPFIT.

             See description above for the structure of PARINFO.

             Default value:  all parameters are free and unconstrained.

   PERROR - The formal 1-sigma errors in each parameter, computed
            from the covariance matrix.  If a parameter is held
            fixed, or if it touches a boundary, then the error is
            reported as zero.

            If the fit is unweighted (i.e. no errors were given, or
            the weights were uniformly set to unity), then PERROR
            will probably not represent the true parameter
            uncertainties.  

            *If* you can assume that the true reduced chi-squared
            value is unity -- meaning that the fit is implicitly
            assumed to be of good quality -- then the estimated
            parameter uncertainties can be computed by scaling PERROR
            by the measured chi-squared value.

              DOF     = N_ELEMENTS(X) - N_ELEMENTS(PARMS) ; deg of freedom
              PCERROR = PERROR * SQRT(BESTNORM / DOF)   ; scaled uncertainties

   PFREE_INDEX - upon return, PFREE_INDEX contains an index array
                 which indicates which parameter were allowed to
                 vary.  I.e. of all the parameters PARMS, only
                 PARMS[PFREE_INDEX] were varied.

   QUERY - if set, then MPFIT() will return immediately with one of
           the following values:
                 1 - if MIN_VERSION is not set
                 1 - if MIN_VERSION is set and MPFIT satisfies the minimum
                 0 - if MIN_VERSION is set and MPFIT does not satisfy it
           The VERSION output keyword is always set upon return.
           Default: not set.

   QUIET - set this keyword when no textual output should be printed
           by MPFIT

   RESDAMP - a scalar number, indicating the cut-off value of
             residuals where "damping" will occur.  Residuals with
             magnitudes greater than this number will be replaced by
             their logarithm.  This partially mitigates the so-called
             large residual problem inherent in least-squares solvers
             (as for the test problem CURVI, http://www.maxthis.com/-
             curviex.htm).  A value of 0 indicates no damping.
             Default: 0

             Note: RESDAMP doesn't work with AUTODERIV=0

   STATUS - an integer status code is returned.  All values greater
            than zero can represent success (however STATUS EQ 5 may
            indicate failure to converge).  It can have one of the
            following values:

        -18  a fatal execution error has occurred.  More information
             may be available in the ERRMSG string.

        -16  a parameter or function value has become infinite or an
             undefined number.  This is usually a consequence of
             numerical overflow in the user's model function, which
             must be avoided.

        -15 to -1 
             these are error codes that either MYFUNCT or ITERPROC
             may return to terminate the fitting process (see
             description of MPFIT_ERROR common below).  If either
             MYFUNCT or ITERPROC set ERROR_CODE to a negative number,
             then that number is returned in STATUS.  Values from -15
             to -1 are reserved for the user functions and will not
             clash with MPFIT.

	   0  improper input parameters.
         
	   1  both actual and predicted relative reductions
	      in the sum of squares are at most FTOL.
         
	   2  relative error between two consecutive iterates
	      is at most XTOL
         
	   3  conditions for STATUS = 1 and STATUS = 2 both hold.
         
	   4  the cosine of the angle between fvec and any
	      column of the jacobian is at most GTOL in
	      absolute value.
         
	   5  the maximum number of iterations has been reached
         
	   6  FTOL is too small. no further reduction in
	      the sum of squares is possible.
         
	   7  XTOL is too small. no further improvement in
	      the approximate solution x is possible.
         
	   8  GTOL is too small. fvec is orthogonal to the
	      columns of the jacobian to machine precision.

          9  A successful single iteration has been completed, and
             the user must supply another "EXTERNAL" evaluation of
             the function and its derivatives.  This status indicator
             is neither an error nor a convergence indicator.

   VERSION - upon return, VERSION will be set to the MPFIT internal
             version number.  The version number will be a string of
             the form "X.Y" where X is a major revision number and Y
             is a minor revision number.
             NOTE: the VERSION keyword was not present before 
               MPFIT version number 1.70, therefore, callers must 
               use exception handling when using this keyword.

   XTOL - a nonnegative input variable. Termination occurs when the
          relative error between two consecutive iterates is at most
          XTOL (and STATUS is accordingly set to 2 or 3).  Therefore,
          XTOL measures the relative error desired in the approximate
          solution.  Default: 1D-10


 EXAMPLE:

   p0 = [5.7D, 2.2, 500., 1.5, 2000.]
   fa = {X:x, Y:y, ERR:err}
   p = mpfit('MYFUNCT', p0, functargs=fa)

   Minimizes sum of squares of MYFUNCT.  MYFUNCT is called with the X,
   Y, and ERR keyword parameters that are given by FUNCTARGS.  The
   resulting parameter values are returned in p.


 COMMON BLOCKS:

   COMMON MPFIT_ERROR, ERROR_CODE

     User routines may stop the fitting process at any time by
     setting an error condition.  This condition may be set in either
     the user's model computation routine (MYFUNCT), or in the
     iteration procedure (ITERPROC).

     To stop the fitting, the above common block must be declared,
     and ERROR_CODE must be set to a negative number.  After the user
     procedure or function returns, MPFIT checks the value of this
     common block variable and exits immediately if the error
     condition has been set.  This value is also returned in the
     STATUS keyword: values of -1 through -15 are reserved error
     codes for the user routines.  By default the value of ERROR_CODE
     is zero, indicating a successful function/procedure call.

   COMMON MPFIT_PROFILE
   COMMON MPFIT_MACHAR
   COMMON MPFIT_CONFIG

     These are undocumented common blocks are used internally by
     MPFIT and may change in future implementations.

 THEORY OF OPERATION:

   There are many specific strategies for function minimization.  One
   very popular technique is to use function gradient information to
   realize the local structure of the function.  Near a local minimum
   the function value can be taylor expanded about x0 as follows:

      f(x) = f(x0) + f'(x0) . (x-x0) + (1/2) (x-x0) . f''(x0) . (x-x0)
             -----   ---------------   -------------------------------  (1)
     Order    0th          1st                      2nd

   Here f'(x) is the gradient vector of f at x, and f''(x) is the
   Hessian matrix of second derivatives of f at x.  The vector x is
   the set of function parameters, not the measured data vector.  One
   can find the minimum of f, f(xm) using Newton's method, and
   arrives at the following linear equation:

      f''(x0) . (xm-x0) = - f'(x0)                            (2)

   If an inverse can be found for f''(x0) then one can solve for
   (xm-x0), the step vector from the current position x0 to the new
   projected minimum.  Here the problem has been linearized (ie, the
   gradient information is known to first order).  f''(x0) is
   symmetric n x n matrix, and should be positive definite.

   The Levenberg - Marquardt technique is a variation on this theme.
   It adds an additional diagonal term to the equation which may aid the
   convergence properties:

      (f''(x0) + nu I) . (xm-x0) = -f'(x0)                  (2a)

   where I is the identity matrix.  When nu is large, the overall
   matrix is diagonally dominant, and the iterations follow steepest
   descent.  When nu is small, the iterations are quadratically
   convergent.

   In principle, if f''(x0) and f'(x0) are known then xm-x0 can be
   determined.  However the Hessian matrix is often difficult or
   impossible to compute.  The gradient f'(x0) may be easier to
   compute, if even by finite difference techniques.  So-called
   quasi-Newton techniques attempt to successively estimate f''(x0)
   by building up gradient information as the iterations proceed.

   In the least squares problem there are further simplifications
   which assist in solving eqn (2).  The function to be minimized is
   a sum of squares:

       f = Sum(hi^2)                                         (3)

   where hi is the ith residual out of m residuals as described
   above.  This can be substituted back into eqn (2) after computing
   the derivatives:

       f'  = 2 Sum(hi  hi')     
       f'' = 2 Sum(hi' hj') + 2 Sum(hi hi'')                (4)

   If one assumes that the parameters are already close enough to a
   minimum, then one typically finds that the second term in f'' is
   negligible [or, in any case, is too difficult to compute].  Thus,
   equation (2) can be solved, at least approximately, using only
   gradient information.

   In matrix notation, the combination of eqns (2) and (4) becomes:

        hT' . h' . dx = - hT' . h                          (5)

   Where h is the residual vector (length m), hT is its transpose, h'
   is the Jacobian matrix (dimensions n x m), and dx is (xm-x0).  The
   user function supplies the residual vector h, and in some cases h'
   when it is not found by finite differences (see MPFIT_FDJAC2,
   which finds h and hT').  Even if dx is not the best absolute step
   to take, it does provide a good estimate of the best *direction*,
   so often a line minimization will occur along the dx vector
   direction.

   The method of solution employed by MINPACK is to form the Q . R
   factorization of h', where Q is an orthogonal matrix such that QT .
   Q = I, and R is upper right triangular.  Using h' = Q . R and the
   ortogonality of Q, eqn (5) becomes

        (RT . QT) . (Q . R) . dx = - (RT . QT) . h
                     RT . R . dx = - RT . QT . h         (6)
                          R . dx = - QT . h

   where the last statement follows because R is upper triangular.
   Here, R, QT and h are known so this is a matter of solving for dx.
   The routine MPFIT_QRFAC provides the QR factorization of h, with
   pivoting, and MPFIT_QRSOL;V provides the solution for dx.
   
 REFERENCES:

   Markwardt, C. B. 2008, "Non-Linear Least Squares Fitting in IDL
     with MPFIT," in proc. Astronomical Data Analysis Software and
     Systems XVIII, Quebec, Canada, ASP Conference Series, Vol. XXX, eds.
     D. Bohlender, P. Dowler & D. Durand (Astronomical Society of the
     Pacific: San Francisco), p. 251-254 (ISBN: 978-1-58381-702-5)
       http://arxiv.org/abs/0902.2850
       Link to NASA ADS: http://adsabs.harvard.edu/abs/2009ASPC..411..251M
       Link to ASP: http://aspbooks.org/a/volumes/table_of_contents/411

   Refer to the MPFIT website as:
       http://purl.com/net/mpfit

   MINPACK-1 software, by Jorge More' et al, available from netlib.
     http://www.netlib.org/

   "Optimization Software Guide," Jorge More' and Stephen Wright, 
     SIAM, *Frontiers in Applied Mathematics*, Number 14.
     (ISBN: 978-0-898713-22-0)

   More', J. 1978, "The Levenberg-Marquardt Algorithm: Implementation
     and Theory," in Numerical Analysis, vol. 630, ed. G. A. Watson
     (Springer-Verlag: Berlin), p. 105 (DOI: 10.1007/BFb0067690 )

 MODIFICATION HISTORY:
   Translated from MINPACK-1 in FORTRAN, Apr-Jul 1998, CM
   Fixed bug in parameter limits (x vs xnew), 04 Aug 1998, CM
   Added PERROR keyword, 04 Aug 1998, CM
   Added COVAR keyword, 20 Aug 1998, CM
   Added NITER output keyword, 05 Oct 1998
      D.L Windt, Bell Labs, windt@bell-labs.com;
   Made each PARINFO component optional, 05 Oct 1998 CM
   Analytical derivatives allowed via AUTODERIVATIVE keyword, 09 Nov 1998
   Parameter values can be tied to others, 09 Nov 1998
   Fixed small bugs (Wayne Landsman), 24 Nov 1998
   Added better exception error reporting, 24 Nov 1998 CM
   Cosmetic documentation changes, 02 Jan 1999 CM
   Changed definition of ITERPROC to be consistent with TNMIN, 19 Jan 1999 CM
   Fixed bug when AUTDERIVATIVE=0.  Incorrect sign, 02 Feb 1999 CM
   Added keyboard stop to MPFIT_DEFITER, 28 Feb 1999 CM
   Cosmetic documentation changes, 14 May 1999 CM
   IDL optimizations for speed & FASTNORM keyword, 15 May 1999 CM
   Tried a faster version of mpfit_enorm, 30 May 1999 CM
   Changed web address to cow.physics.wisc.edu, 14 Jun 1999 CM
   Found malformation of FDJAC in MPFIT for 1 parm, 03 Aug 1999 CM
   Factored out user-function call into MPFIT_CALL.  It is possible,
     but currently disabled, to call procedures.  The calling format
     is similar to CURVEFIT, 25 Sep 1999, CM
   Slightly changed mpfit_tie to be less intrusive, 25 Sep 1999, CM
   Fixed some bugs associated with tied parameters in mpfit_fdjac, 25
     Sep 1999, CM
   Reordered documentation; now alphabetical, 02 Oct 1999, CM
   Added QUERY keyword for more robust error detection in drivers, 29
     Oct 1999, CM
   Documented PERROR for unweighted fits, 03 Nov 1999, CM
   Split out MPFIT_RESETPROF to aid in profiling, 03 Nov 1999, CM
   Some profiling and speed optimization, 03 Nov 1999, CM
     Worst offenders, in order: fdjac2, qrfac, qrsolv, enorm.
     fdjac2 depends on user function, qrfac and enorm seem to be
     fully optimized.  qrsolv probably could be tweaked a little, but
     is still <10% of total compute time.
   Made sure that !err was set to 0 in MPFIT_DEFITER, 10 Jan 2000, CM
   Fixed small inconsistency in setting of QANYLIM, 28 Jan 2000, CM
   Added PARINFO field RELSTEP, 28 Jan 2000, CM
   Converted to MPFIT_ERROR common block for indicating error
     conditions, 28 Jan 2000, CM
   Corrected scope of MPFIT_ERROR common block, CM, 07 Mar 2000
   Minor speed improvement in MPFIT_ENORM, CM 26 Mar 2000
   Corrected case where ITERPROC changed parameter values and
     parameter values were TIED, CM 26 Mar 2000
   Changed MPFIT_CALL to modify NFEV automatically, and to support
     user procedures more, CM 26 Mar 2000
   Copying permission terms have been liberalized, 26 Mar 2000, CM
   Catch zero value of zero a(j,lj) in MPFIT_QRFAC, 20 Jul 2000, CM
      (thanks to David Schlegel )
   MPFIT_SETMACHAR is called only once at init; only one common block
     is created (MPFIT_MACHAR); it is now a structure; removed almost
     all CHECK_MATH calls for compatibility with IDL5 and !EXCEPT;
     profiling data is now in a structure too; noted some
     mathematical discrepancies in Linux IDL5.0, 17 Nov 2000, CM
   Some significant changes.  New PARINFO fields: MPSIDE, MPMINSTEP,
     MPMAXSTEP.  Improved documentation.  Now PTIED constraints are
     maintained in the MPCONFIG common block.  A new procedure to
     parse PARINFO fields.  FDJAC2 now computes a larger variety of
     one-sided and two-sided finite difference derivatives.  NFEV is
     stored in the MPCONFIG common now.  17 Dec 2000, CM
   Added check that PARINFO and XALL have same size, 29 Dec 2000 CM
   Don't call function in TERMINATE when there is an error, 05 Jan
     2000
   Check for float vs. double discrepancies; corrected implementation
     of MIN/MAXSTEP, which I still am not sure of, but now at least
     the correct behavior occurs *without* it, CM 08 Jan 2001
   Added SCALE_FCN keyword, to allow for scaling, as for the CASH
     statistic; added documentation about the theory of operation,
     and under the QR factorization; slowly I'm beginning to
     understand the bowels of this algorithm, CM 10 Jan 2001
   Remove MPMINSTEP field of PARINFO, for now at least, CM 11 Jan
     2001
   Added RESDAMP keyword, CM, 14 Jan 2001
   Tried to improve the DAMP handling a little, CM, 13 Mar 2001
   Corrected .PARNAME behavior in _DEFITER, CM, 19 Mar 2001
   Added checks for parameter and function overflow; a new STATUS
     value to reflect this; STATUS values of -15 to -1 are reserved
     for user function errors, CM, 03 Apr 2001
   DAMP keyword is now a TANH, CM, 03 Apr 2001
   Added more error checking of float vs. double, CM, 07 Apr 2001
   Fixed bug in handling of parameter lower limits; moved overflow
     checking to end of loop, CM, 20 Apr 2001
   Failure using GOTO, TERMINATE more graceful if FNORM1 not defined,
     CM, 13 Aug 2001
   Add MPPRINT tag to PARINFO, CM, 19 Nov 2001
   Add DOF keyword to DEFITER procedure, and print degrees of
     freedom, CM, 28 Nov 2001
   Add check to be sure MYFUNCT is a scalar string, CM, 14 Jan 2002
   Addition of EXTERNAL_FJAC, EXTERNAL_FVEC keywords; ability to save
     fitter's state from one call to the next; allow '(EXTERNAL)'
     function name, which implies that user will supply function and
     Jacobian at each iteration, CM, 10 Mar 2002
   Documented EXTERNAL evaluation code, CM, 10 Mar 2002
   Corrected signficant bug in the way that the STEP parameter, and
     FIXED parameters interacted (Thanks Andrew Steffl), CM, 02 Apr
     2002
   Allow COVAR and PERROR keywords to be computed, even in case of
     '(EXTERNAL)' function, 26 May 2002
   Add NFREE and NPEGGED keywords; compute NPEGGED; compute DOF using
     NFREE instead of n_elements(X), thanks to Kristian Kjaer, CM 11
     Sep 2002
   Hopefully PERROR is all positive now, CM 13 Sep 2002
   Documented RELSTEP field of PARINFO (!!), CM, 25 Oct 2002
   Error checking to detect missing start pars, CM 12 Apr 2003
   Add DOF keyword to return degrees of freedom, CM, 30 June 2003
   Always call ITERPROC in the final iteration; add ITERKEYSTOP
     keyword, CM, 30 June 2003
   Correct bug in MPFIT_LMPAR of singularity handling, which might
     likely be fatal for one-parameter fits, CM, 21 Nov 2003
     (with thanks to Peter Tuthill for the proper test case)
   Minor documentation adjustment, 03 Feb 2004, CM
   Correct small error in QR factorization when pivoting; document
     the return values of QRFAC when pivoting, 21 May 2004, CM
   Add MPFORMAT field to PARINFO, and correct behavior of interaction
     between MPPRINT and PARNAME in MPFIT_DEFITERPROC (thanks to Tim
     Robishaw), 23 May 2004, CM
   Add the ITERPRINT keyword to allow redirecting output, 26 Sep
     2004, CM
   Correct MAXSTEP behavior in case of a negative parameter, 26 Sep
     2004, CM
   Fix bug in the parsing of MINSTEP/MAXSTEP, 10 Apr 2005, CM
   Fix bug in the handling of upper/lower limits when the limit was
     negative (the fitting code would never "stick" to the lower
     limit), 29 Jun 2005, CM
   Small documentation update for the TIED field, 05 Sep 2005, CM
   Convert to IDL 5 array syntax (!), 16 Jul 2006, CM
   If MAXITER equals zero, then do the basic parameter checking and
     uncertainty analysis, but do not adjust the parameters, 15 Aug
     2006, CM
   Added documentation, 18 Sep 2006, CM
   A few more IDL 5 array syntax changes, 25 Sep 2006, CM
   Move STRICTARR compile option inside each function/pro