PRO SET_UTPLOT,xrange=x,labelpar=lbl,utbase=base,error_range=error_range,$
	err_format=err_format,tick_unit=tick_unit,minors=minors,xstyle=xstyle, $
	year=year
!quiet=1
;+
; NAME:
;	SET_UTPLOT
; PURPOSE:
;	Allows user flexibility in setting up time axis labelling.
;	Prepares IDL system variables (!X.RANGE, !X.TICKV, !X.TICKNAME, 
;	and !X.TICKNAME) for plotting X vs Y with Universal time labels 
;	on bottom X axis.  After calling SET_UTPLOT, user calls the 
;	standard IDL PLOT routine to draw the plot. 
;	SET_UTPLOT is normally called by UTPLOT, and is transparent to 
;	the user.
; CATEGORY:
; CALLING SEQUENCE:
;	SET_UTPLOT,XRANGE=X,LABELPAR=LBL,UTBASE=BASE,ERROR_RANGE=ERROR_RANGE,
;	   ERR_FORMAT=ERR_FORMAT,TICK_UNIT=TICK_UNIT,MINORS=MINORS,
;	   XSTYLE=XSTYLE
; INPUT PARAMETERS:
;	X - 	X array to plot (seconds relative to base time).
;	LBL - 	2 element vector selecting substring from publication format
;	   	of ASCII time (YY/MM/DD, HH:MM:SS.XXX).  For example, 
;	   	LBL=[11,18] would select the HH:MM:SS part of the string.
;	BASE - 	ASCII string containing base time for X axis. Format for
;	   	time is YY/MM/DD,HHMM:SS.XXX.  If this parameter isn't present
;          	and hasn't been set yet (by a previous call to UTPLOT, via 
;		routine SETUTBASE, or directly), user is prompted for base time.
;	ERROR_RANGE - = 0/1. If set to 1, the X array is outside of the
;	   	limits defined by start and end times selected by user.
;	ERR_FORMAT - =0/1. If set to 1, there was an error in the ASCII time
;	   	format for the base time.
;	TICK_UNIT - Time between Major tick marks is forced to TICK_UNIT
;		    Has no effect for axis longer than 62 days.
;	MINORS	  - Number of minor tick marks is forced to MINORS
;	XSTYLE    - Same meaning as in PLOT, if SET xaxis is exact
; COMMON BLOCKS:
;	COMMON UTCOMMON, UTBASE, UTSTART, UTEND = base, start, and 
;	end time for X axis in double precision variables containing
;	seconds since 79/1/1, 00:00.
;       COMMON CLEARCOMMON,XOLD,YOLD,CLEARSET = holding area for previous
;	!x and !y structures if clearset=1
; RESTRICTIONS:
;	Cannot be used for times before 79/1/1 or after 99/1/1.
; MODIFICATION HISTORY:
;	Written by Richard Schwartz 91/02/17
;	Modified 91/03/27, RAS
;		Clears all !x vectors which will be set.
;	Modified 91/05/02, RAS
;		New Keywords Tick_unit, and Minors		
;	Modified 91/10/18, RAS
;		if xstyle is set then utstart and utend are set by limits of x
;	26-Aug-92 (MDM) - Added keyword YEAR - put year on tick labels
;	18-Mar-93 (MDM) - Removed the modification made 91/10/18 since it was
;			  causing problems on subsequent plots (giving a
;			  error_range error)
;-
common utcommon,utbase,utstart,utend
common clearcommon,xold,yold,clearset
;INITIALIZE UTCOMMON VALUES
checkvar,utstart,0. ;utstart or 0. if undefined
checkvar,utend,0.
checkvar,base,'-1'
	checkvar,utbase,base ;Is UTBASE defined?
	 ;if no then prompt for base time
try_again:
err_format=0
	if (utbase eq '-1') then setutbase,err=err_format
	if err_format then goto,try_again
	 ;set utbase to base
	if (base ne '-1') then setut,utbase=base,err=err_format
	if err_format then return
;************
;DETERMINE LIMITS ON X AXIS
checkvar,clearset,1
if clearset then begin ;save !x and !y in clearcommon
	xold=!x
	yold=!y
	clearset=0
endif
	xstyle_in = !x.style
	!x.style=fcheck(xstyle, !x.style)
S_X=SIZE(X) ;IS X PASSED?
IF S_X(1) NE 0 THEN BEGIN ;IF1 BEGIN
	CSAVE=!C
;	xmin=min(x) &xmax=max(x)	;mdm removed 21-Aug-92 to allow reverse UTPLOTs
	if (n_elements(x) eq 2) then begin	;assume passed XRANGE
		xmin = x(0)
		xmax = x(1)
	end else begin
		xmin=min(x)
		xmax=max(x)
	end
	!C=CSAVE
	if (!x.style and 1b) eq 1 then begin
;;		utstart = xmin + utbase		;removed 18-Mar-93 by MDM
;;		utend   = xmax + utbase		;removed 18-Mar-93 by MDM
	endif
ENDIF ELSE BEGIN	  ;IF1 ELSE
	xmin=!x.crange(0)
	xmax=!x.crange(1)
ENDELSE		          ;IF1 CLOSE
;************
error_range=0 ;logical for x-data out of range
if utstart ne 0. then xmin=(utstart-utbase)
if utend   ne 0. then xmax=(utend-utbase)
;;IF XMAX LE XMIN THEN BEGIN ;IF2 BEGIN
;;	PRINT,'Error - end time is less than or equal to start time.'
;;	error_range=1
;;	RETURN ;EXIT
;;ENDIF			   ;IF2 CLOSE
IF XMAX+UTBASE GT 9.466848D8 THEN BEGIN
	PRINT,'Error - end time is greater than year 1999.'
	error_range=1
	RETURN
ENDIF
;clear old plot parameters prior to DUMMYPLOT, 91/03/27, RAS *****************
	!x.crange=0.
	!x.range=0.
	!x.tickv=0.
	!x.ticks=0.
	!x.tickname=0.
;	xminor=!x.minor ;save input minor tick count
	!x.minor=0.
	!x.range=[xmin,xmax]
;***************************** end modification ******************************
;;wrange=where( (x le xmax) and (x ge xmin))
wrange=where( (x le max([xmin,xmax])) and (x ge min([xmin,xmax])))
if !err lt 2 then begin
	print,'Error, less than two data points within the range'
	error_range=1
	return
endif
;DUMMY PLOTS
DUMMYPLOTS,X=x ;SETS PLOTS RANGES WO PLOTTING
!x.style = xstyle_in ; 
;SET TICKMARKS
s_tick=size(tick_unit)
;checkvar,minors,xminor ;if minors is passed use it, 
checkvar,minors,0 ;if minors is passed use it, 
!x.range=!x.crange
;;drange=!x.crange(1)-!x.crange(0)
drange=abs(!x.crange(1)-!x.crange(0))
;FIND THE APPROPRIATE UNITS TO HAVE 2 TO 6 TICK INTERVALS
tick_units=[10^findgen(5)*1.0d-3,10^findgen(4)*.002,10^findgen(4)*.005,$
20.,30.,60.,60.*[2,4,5,6,10,15,20,30,60],3600.*[2.+findgen(5),8.,10.,12.],$
86400.*[findgen(6)+1.,10.,20.,30.,60.]]
;6)+1.,12.*(1.+findgen(10.))]]]
minor_units=[.0001,.0002,.001,.002,.01,.02,.1,.2,1.0,2.0,5.0,10.,20.,60.,$
	120.,300.,600.,3600.,7200.,14400.,3600.*[6.,12.],$
	86400.*[1.,2.,5.,10.]] ;possible time intervals between minor ticks
;the units should be selected so that there are from 2 to 6 tick intervals
if drange le 62*86400. then begin ;select from units lt month
if s_tick(1) eq 0 then begin ;find tick_unit if its not set already
	w_ok=where( (drange/tick_units lt 7) and (drange/tick_units ge 2)) 
	m_ok=max(drange/tick_units(w_ok)) &!C=0
	i_ok=w_ok(!c)
	tick_unit=tick_units(i_ok)
endif 
	!x.ticks=drange/tick_unit ;number of tick intervals
	;*****************
if minors eq 0 then begin
	wminors=where( tick_unit mod minor_units eq 0) ;which minors divide evenly
	;into major tick intervals
	nminors=tick_unit/minor_units(wminors) ;possible #minor intervals
	test_minors=min(abs(nminors-4)) ;get as close as possible to 4 sub-intervals
	!x.minor=nminors(!c) &!c=0 ;number of minor tick intervals
endif else !x.minor=minors
;*****************
;*****************
;SET THE TICKVALUES AND NAMES
;;start_off=(utbase+!x.crange(0))/tick_unit mod 1.d0 ;looking for frac. 
start_off=(utbase+min(!x.crange))/tick_unit mod 1.d0 ;looking for frac. 
tic_n_range=((1.d0-start_off) mod 1. +findgen(!x.ticks+1))*tick_unit $
       + min(!x.crange) +utbase
;;       + !x.crange(0) +utbase
endif else begin ;range is at least two months 
;find yy/mm/01 and yy/01/01 within range
	ymd2sec,day=days_month,iut=iuty,/alt
if drange lt 1096.*86400. then begin ;LT 3 YEARS, 4-36 MONTHS
	tic_n_range=(86400.d0*days_month)#replicate(1.,1,21)+ $
	transpose( (iuty*86400.d0)#replicate(1.,1,12))
	for i=1,20,4 do tic_n_range(2,i)=tic_n_range(2:11,i)+86400.d0
	tick_unit=30.d0*86400.d0 ;approximately one month or more between
			 	 ;tick marks
	;array tic_n_range has all yy/mm/01 within allowed range
	endif else begin ;range is longer than 3 years
		tic_n_range=86400.d0*iuty; LONGER THAN 3 YEARS
		tick_unit=365.*86400.d0 ;about one year between tick marks
	endelse
endelse ;CLOSE LOOP FOR YEAR OR MONTH TICK MARKS
;Make sure ticks are within range by both methods of time selection
	tic_n_range=tic_n_range-utbase
;;	wyymm=where( (tic_n_range ge !x.crange(0)) and $
;; 		(tic_n_range le !x.crange(1))) ;how many possible ticks
	wyymm=where( (tic_n_range ge min(!x.crange)) and $
 		(tic_n_range le max(!x.crange))) ;how many possible ticks
	num_yymm=!err
	if drange gt 62*86400. then begin ; make sure minor tick marks lie close
					  ;to month boundaries
	        dticks=fix(num_yymm/6.1)+1 ;number of months/years between ticks
		if minors eq 0 then $
		!x.minor=dticks $;set minor tick marks close to months or years
		else !x.minor=minors
        	wyymm=wyymm(where(wyymm mod dticks eq 0));use only every dtick month/yr
	endif 
	!x.ticks=n_elements(wyymm)-1 ;
	xtickv=tic_n_range(wyymm)
;SET THE TICKNAME STRINGS
for i=0,n_elements(xtickv)-1 do $
	if (xtickv(i) le max(!x.crange)) then $
	!x.tickname(i)=atime(utbase+xtickv(i),/pub)
;DETERMINE PROPER LABEL FORMAT
if not keyword_set(lbl) then begin ;if no label format, select one
;SET LABEL FORMAT BASED ON SIZE OF UNITS
	;test_units=[365.*86400.,86400.,60.,1., .1, .01,.001]
	; Old Form yy/mm/dd, hh:mm:ss.xxx				;MDM
	;          0123456789012345678901				;MDM
	;rhs=       [4,          7,     17, 17, 19, 20, 21]		;MDM
	;lhs=       [0,          3,     10, 10, 13, 16, 16]		;MDM
;
test_units=[365/2.*86400.,86400.,60.,1., .1, .01,.001]			;MDM - changed to if tick is 6 month
; New Form dd-mmm-yy hh:mm:ss.xxx
;          0123456789012345678901
;
;	    * mmm-yy
;			* dd-mmm
;				* hh:mm
;					* mm:ss.x
;					    * ss.xx
;						* ss.xxx
rhs=       [8,          5,     14, 17, 19, 20, 21]			;MDM
lhs=       [3,          0,     10, 10, 13, 16, 16]			;MDM
if (keyword_set(year)) then rhs(1)=8	;MDM added 26-Aug-92

wtest=where( tick_unit ge test_units)
lbl=[lhs(wtest(0)) ,rhs(wtest(0))]
endif ;LABEL FORMAT SELECTED
!x.tickname=strmid(!x.tickname,lbl(0),lbl(1)-lbl(0)+1)
!x.tickv=xtickv
return
end
