;+ ; SINGLECONTOUR generates a Postscript 1-D contour plot. ; See the full procedure
; @examples
;  A simple call to SINGLECONTOUR is:
;    x    = -50. + FINDGEN(101)
;    y    = 100. + FINDGEN(51)
;    xx   = x # (1.+FLTARR(51))
;    yy   = (1.+FLTARR(101)) # y
;    f    = 5*(SIN(0.08*xx)*SIN(0.12*yy))^2+5*(SIN(0.05*(xx+yy)))^2 + 0.3*RANDOMN(seed,101,51)
;    SINGLECONTOUR, "test10a.ps", {f:f}
;  See the jmaplot tutorial for additional examples. 
; @version v. 3.1, 11 May 2013.
; @history
                                                        
;
;  v0.1: The difference between xmin,xmax and ymin,ymax and yrange is     
;         introduced.                                                     
;        Variable step in xand y is allowed.                             
;        LINESTYLE and EXTERNAL are introduced.                           
;  v0.2: EXTXTICKS and EXTYTICKS are introduced.                          
;  v1.0: General cleanup.                                                 
;  v1.1: Axes which increase in the opposite direction allowed.           
;  v1.2: BACKGROUND added.                                                
;  v1.3: PSFONTS added.                                                   
;  v2.0: English version.                                                 
;  v2.1: IDLdoc documentation.
;        CTABLE problems from MULTIGRAPH eliminated.                          
;        Fix to the small font problem when using MULTIGRAPH (NPX).
;  v2.2: OPENHTML introduced.
;        Upgrade to IDLdoc documentation. 
;        Contour color control transferred from CTEXT to C_COLORS.  
;        Additional keywords can be passed to CONTOUR using _REF_EXTRA.
;  v2.3: To ensure compatibility, use _EXTRA instead of _REF_EXTRA.
;        Windows compatibility enhanced.
;  v2.4: CELL_BLANK keyword added. 
;  v2.5: Version system update.
;        QUIET flag added.             
;        REVERSE bug fixed.   
;  v3.0: Global rewritting.
;        Most KEYWORDS eliminated with input converted into structures.
;        Assimilation to SINGLEPLOT changes.
;        Legend types eliminated.
;        New grid, thick, and linestyle options for axes.
;        Colors for lines introduced.
;        THICK and LINESTYLE added for the lines.
;        MYDEVICE eliminated.     
;        CMYK PS output added.
;        HTML pages moved to local directory.
;        TEST eliminated. 
; v3.1:  NOBORDER added to LEGEND.  
; @author Jesús Maíz Apellániz, IAA
; @param psname {in}{required}{type=string} Postscript file name. ; If '' is passed, the Postscript file is ; neither opened nor closed (this option is intended to be used ; from MULTIGRAPH).
; @param v1 {in}{required}{type=structure} Data structure. Possible tags:
;           F:         Function to be plotted (required).
;           G:         Masking function.
;           G_CRIT:    Masking critical value.
;           G_CELL:    Flag for masking with CELL_FILL.
;           X:         x values for f (and g).
;           Y:         y values for f (and g).
;           NOLINES:   Flag for not drawing contour lines.
;           NOFILL:    Flag for not filling contours.
;           C:         Contour values.         
;           CN:        Number of contour values (superseded by c).         
;           CMIN:      Value for minimum contour (superseded by c).         
;           CMAX:      Value for maximum contour (superseded by c).         
;           CLOG:      Flag for logarithmic spacing of contours (superseded by c).         
;           COLOR:     Color index (fill if NOFILL not activated, contours otherwise).
;           LINESTYLE: IDL line style.
;           THICK:     Line thicknesses.  
; @keyword BACKGROUND {in}{optional}{type=byte array} Background image of ; dimensions (nx,ny) or (nx,ny,3).
; @keyword XAXISL {in}{optional}{type=structure} Lower x-axis structure with the ; following possible tags:
;           RANGE:     2-element float array with minimum and maximum.
;           EXTRA:     If -1.0, it increases the x range by 10%. If not 1.0, it
;                       increases the natural x range by that fraction. RANGE
;                       supersedes it.
;           STYLE:     Axis type, -2 (nothing), -1 (lines), 0 (lines and
;                       ticks), and 1 (lines, ticks, and text). 
;           TITLE:     Axis title.                       
;           THICK:     Line thickness.                   
;           LINESTYLE: Line style.                
;           TICKNAME:  Text for the tick marks.            
;           CHARSIZE:  Text size (also affected by PLOT.CHARSIZE).
;           TICKV:     Values for the tick marks.            
;           TICKLEN:   Scale factor for the tick lengths.
;           LESSTICKS: Flag for using less tick marks (ignored if TICKV given).
;           MORETICKS: Flag for using more tick marks (ignored if TICKV given).
;           MINORN:    Number of minor tick marks per major ones, counting major 
;                       ones as minor (ignored if LOG is activated). 
; @keyword YAXISL {in}{optional}{type=structure} Lower y-axis structure. See XAXISL ; for the possible tags:
; @keyword XAXISU {in}{optional}{type=structure} Upper x-axis structure. See XAXISL ; for the possible tags:
; @keyword YAXISU {in}{optional}{type=structure} Upper y-axis structure. See XAXISL ; for the possible tags:
; @keyword PLOT {in}{optional}{type=structure} Plot structure with the ; following possible tags:
;           XSIZE:     X size (in normal coordinates) of the plot.
;           YSIZE:     Y size (in normal coordinates) of the plot.
;           XC:        X position (in normal coordinates) of the center of the plot.
;           YC:        Y position (in normal coordinates) of the center of the plot.
;           CHARSIZE:  Global text size.
;           CHARTHICK: Global text thickness.
;           PSASPECT:  Aspect ratio of the Postscript file.
;           PSXSIZE:   X size (in cm) of the Postscript file.
;           LANDSCAPE: Flag for landscape mode.
;           FONT:      -1 (Vector-drawn), 0 (PS), 1 (TrueType).
;           CMYK:      Flag to generate CMYK PS output.
;           TITLE:     Main title.  
; @keyword CFILE {in}{optional}{type=structure} Color table structure with ; the following possible tags:
;           NAME:      File name.                                  
;           DIR:       Directory name.                             
;           TABLE:     Color table.                                
;           DEF:       Default color. 
;           WHITE:     White color. 
; @keyword LEGEND {in}{optional}{type=structure} Legend structure with the ; following possible tags:
;           DRAW:      Flag to to do legend (unnecesary if any other tag is
;                       specified).
;           CLEAR:     Flag to clear the legend background.
;           XLEFT:     Left border of the legend box in plot-normalized
;                       coordinates (default: 0.05).
;           YDOWN:     Lower border of the legend box in plot-normalized
;                       coordinates (default: 0.05).
;           XSIZE:     Horizontal size of the legend box in plot-normalized
;                       coordinates (default: 0.25).
;           YSIZE:     Horizontal size of the legend box in plot-normalized
;                       coordinates (default: 0.15). 
;           NOBORDER:  Flag not to draw a border around the legend.
; @keyword SPANISH {in}{optional}{type=boolean}{default=FALSE} Flag to use ; decimal commas instead of decimal points.
; @keyword PREEXTERNAL {in}{optional}{type=string array} String(s) with commands ; to be executed before the plots are drawn.
; @keyword EXTERNAL {in}{optional}{type=string array} String(s) with commands ; to be executed after the plots are drawn.
; @keyword QUIET {in}{optional}{default=FALSE} Flag to supress informational messages.
; @keyword IN {in}{optional}{type=structure} Input structure to pass ; the structures produced by out.
; @keyword OUT {out}{optional}{type=structure} Output structure. ; @keyword VAR {in}{optional}{type=structure} Input structure to pass ; additional variables.
; @keyword ENTRANCE {in}{optional}{type=integer} Entrance point for ; sequential calls from MULTIGRAPH. ; @keyword EXIT {in}{optional}{type=integer} Exit point for sequential ; calls from MULTIGRAPH. ; @keyword _EXTRA {in}{optional}{type=string} As of IDL 6.3, the following additional ; keywords can be passed to CONTOUR here:
; C_ANNOTATION
; C_CHARSIZE
; C_CHARTHICK
; C_LABELS
; C_ORIENTATION
; C_SPACING
; CLOSED
; DOWNHILL
; FOLLOW
; MIN_VALUE
; MAX_VALUE
; PATH_DATA_COORDS
; PATH_DOUBLE
; PATH_INFO
; PATH_XY
; See the IDL manual for descriptions of these keywords. Also, ; note that not all of them have been tested with SINGLECONTOUR. ; If you encounter an error or detect an unexpected behavior ; while using them, please send me an ; e-mail. ;- ;
PRO SINGLECONTOUR, psname, v1, $ ; xmin, xmax, ymin, ymax, $
                   BACKGROUND=background, $
		   XAXISL=xaxisl, YAXISL=yaxisl, $
		   XAXISU=xaxisu, YAXISU=yaxisu, $
		   PLOT=plot, CFILE=cfile, LEGEND=legend, $	   
                   SPANISH=spanish, $
                   PREEXTERNAL=preexternal, EXTERNAL=external, $
		   QUIET=quiet, $
		   IN=in, OUT=out, VAR=var, $
		   ENTRANCE=entrance, EXIT=exit, $
		   _EXTRA=extra
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          (a) Inicialización general                                          ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
COMMON vv,            v,  vv2,  vv3,  vv4,  vv5,  vv6,  vv7,  vv8,  vv9, vv10, $
                   vv11, vv12, vv13, vv14, vv15, vv16, vv17, vv18, vv19, vv20, $
                   vv21, vv22, vv23, vv24, vv25, vv26, vv27, vv28, vv29, vv30, $
                   vv31, vv32, vv33, vv34, vv35, vv36, vv37, vv38, vv39, vv40, $
                   vv41, vv42, vv43, vv44, vv45, vv46, vv47, vv48, vv49, vv50, $
                   vv51, vv52, vv53, vv54, vv55, vv56, vv57, vv58, vv59, vv60
ON_ERROR, 1
jmaplot_path = JMAPLOTPATH(JMAPLOT_VERSION=jmaplot_version)
nplots  = N_PARAMS()-1
IF nplots EQ -1 THEN BEGIN
 OPENHTML, jmaplot_path + 'html/singlecontour.html'
 RETURN
ENDIF
IF N_ELEMENTS(IN) NE 0 THEN BEGIN
 IF TAG_EXIST(in,'v1')      EQ 0 THEN MESSAGE, 'v1 not supplied for SINGLECONTOUR call'
 nplots = 1
 v1     = in.v1
 IF TAG_EXIST(in,'background')   THEN background  = in.background
 IF TAG_EXIST(in,'spanish'   )   THEN spanish     = in.spanish 
 IF TAG_EXIST(in,'preexternal')  THEN preexternal = in.preexternal
 IF TAG_EXIST(in,'external')     THEN external    = in.external
 IF TAG_EXIST(in,'var')          THEN var         = in.var
 IF TAG_EXIST(in,'extra')        THEN extra       = in.extra
ENDIF ELSE BEGIN
 IF N_ELEMENTS(v1)          EQ 0 THEN MESSAGE, 'v1 not supplied for SINGLECONTOUR call'
ENDELSE
xsv     = !X
ysv     = !Y
psv     = !P
IF KEYWORD_SET(BACKGROUND)  EQ 0 THEN background  = 0
IF KEYWORD_SET(SPANISH)     EQ 0 THEN spanish     = 0
IF KEYWORD_SET(PREEXTERNAL) EQ 0 THEN preexternal = ''
IF KEYWORD_SET(EXTERNAL)    EQ 0 THEN external    = ''
IF KEYWORD_SET(VAR)         EQ 0 THEN var         = {dummy:0}
IF KEYWORD_SET(ENTRANCE)    EQ 0 THEN entrance    = 0
IF KEYWORD_SET(EXIT)        EQ 0 THEN exit        = 0
IF N_ELEMENTS(EXTRA)        EQ 0 THEN extra = {dummy:0} $
	                         ELSE COPY_STRUC, extra, extra, EXCEPT_TAGS='dummy', STRUC_ADD={dummy:0}
IF KEYWORD_SET(CFILE)       EQ 0 THEN cfileo      = ''     ELSE $
	                              cfileo      = cfile
IF KEYWORD_SET(LEGEND)      EQ 0 THEN legendo     = ''     ELSE $
	                              legendo     = legend
v      = v1
;
; Parte en común con SINGLEPLOT
;
COMMONSINGLE, xxl, yyl, xxu, yyu, pplot, nplots, v, $
              BACKGROUND=background, $
	      XAXISL=xaxisl, YAXISL=yaxisl, $
	      XAXISU=xaxisu, YAXISU=yaxisu, $
	      PLOT=plot, CFILE=cfile, LEGEND=legend, QUIET=quiet, IN=in, $
	      DAXIS=daxis, XRANGE=xrange, YRANGE=yrange, $
	      PSASPECT=psaspect, PSXSIZE=psxsize, $
	      LANDSCAPE=landscape, PSFONTS=psfonts
IF entrance EQ 1 THEN GOTO, ENTRANCE1
IF entrance EQ 2 THEN GOTO, ENTRANCE2
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          (b) Inicialización de datos y propiedades                           ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; f, nx, ny, valores "tontos"
;
IF SIZE(v,/TNAME) NE 'STRUCT' THEN $
 MESSAGE, 'This version of SINGLECONTOUR requires v to be a structure'
IF TAG_EXIST(v,'f')       EQ 0 THEN MESSAGE, 'Structure without f tag'
IF SIZE(v.f, /N_DIM)      NE 2 THEN MESSAGE, 'Structure with invalid f dimensions (not a 2-D array)'
aux = SIZE(v.f, /DIM)
COPY_STRUC, v, v, EXCEPT_TAGS=['nx','ny'], STRUC_ADD={nx:aux[0], ny:aux[1]}
COPY_STRUC, v, v, EXCEPT_TAGS=['f','nplots','sxm','sxp','sym','syp','dx','dy'], $
	          STRUC_ADD={f:DOUBLE(v.f), nplots:1, sxm:0.0, sxp:0.0, sym:0.0, syp:0.0, dx:0.0, dy:0.0}
;
; g, g_crit, g_flag, g_cell
;
IF TAG_EXIST(v,'g')       EQ 0 THEN BEGIN
 COPY_STRUC, v, v, EXCEPT_TAGS=['g','g_crit','g_flag'], STRUC_ADD={g:v.f*0., g_crit:-1., g_cell:0, g_flag:0}
ENDIF ELSE BEGIN
 IF SIZE(v.g, /N_DIM)     NE 2 THEN MESSAGE, 'Structure with invalid g dimensions (not a 2-D array)'
 aux = SIZE(v.g, /DIM)
 IF aux[0] NE v.nx OR aux[1] NE v.ny THEN MESSAGE, 'Structure with invalid g dimensions (nx and/or ny different from f)'
 IF TAG_EXIST(v,'g_crit') EQ 0 THEN v = CREATE_STRUCT(v, {g_crit:0.0})
 IF TAG_EXIST(v,'g_cell') EQ 0 THEN v = CREATE_STRUCT(v, {g_cell:  0})
 COPY_STRUC, v, v, EXCEPT_TAGS=['g','g_crit','g_cell','g_flag'], $
	     STRUC_ADD={g:DOUBLE(v.g), g_crit:DOUBLE(v.g_crit), g_cell:1*(v.g_cell NE 0), g_flag:1}
ENDELSE
;
; x, y
;
IF TAG_EXIST(v,'x')       EQ 0 THEN BEGIN
 v = CREATE_STRUCT(v, {x:FINDGEN(v.nx)})
ENDIF ELSE BEGIN
 IF SIZE(v.x, /N_DIM)     NE 1 THEN MESSAGE, 'Structure with invalid x dimensions (not a 1-D array)'
 aux = N_ELEMENTS(v.x)
 IF aux EQ 2    THEN COPY_STRUC, v, v, EXCEPT_TAGS=['x'], STRUC_ADD={x:v.x[0] + (v.x[1]-v.x[0])*DINDGEN(v.nx)/(v.nx-1)} ELSE $
 IF aux EQ v.nx THEN COPY_STRUC, v, v, EXCEPT_TAGS=['x'], STRUC_ADD={x:DOUBLE(v.x)                                    } ELSE $
                     MESSAGE, 'Structure with invalid x dimensions (# of elements is not 2 or equal to the # of x points of f)'
ENDELSE
IF TAG_EXIST(v,'y')       EQ 0 THEN BEGIN
 v = CREATE_STRUCT(v, {y:FINDGEN(v.ny)})
ENDIF ELSE BEGIN
 IF SIZE(v.y, /N_DIM)     NE 1 THEN MESSAGE, 'Structure with invalid y dimensions (not a 1-D array)'
 aux = N_ELEMENTS(v.y)
 IF aux EQ 2    THEN COPY_STRUC, v, v, EXCEPT_TAGS=['y'], STRUC_ADD={y:v.y[0] + (v.y[1]-v.y[0])*DINDGEN(v.ny)/(v.ny-1)} ELSE $
 IF aux EQ v.ny THEN COPY_STRUC, v, v, EXCEPT_TAGS=['y'], STRUC_ADD={y:DOUBLE(v.y)                                    } ELSE $
                     MESSAGE, 'Structure with invalid y dimensions (# of elements is not 2 or equal to the # of y points of f)'
ENDELSE
;
; nolines, nofill
;
IF TAG_EXIST(v,'nolines') EQ 0 THEN v = CREATE_STRUCT(v, {nolines:0})
IF v.nolines              NE 0 THEN  COPY_STRUC, v, v, EXCEPT_TAGS=['nolines'], STRUC_ADD={nolines:1}
IF TAG_EXIST(v,'nofill' ) EQ 0 THEN v = CREATE_STRUCT(v, { nofill:0})
IF v.nofill               NE 0 THEN  COPY_STRUC, v, v, EXCEPT_TAGS=['nofill' ], STRUC_ADD={ nofill:1}
IF v.nolines+v.nofill     EQ 2 THEN MESSAGE, 'You need to either draw lines or fill the contours'
;
; c, cn, cmin, cmax, clog
;
IF TAG_EXIST(v,'c')            THEN BEGIN ; Opción 1: Se dan los contornos
 aux = N_ELEMENTS(v.c)
 COPY_STRUC, v, v, EXCEPT_TAGS=['c','cn','cmin','cmax','clog'], $
	     STRUC_ADD={c:v.c[[INDGEN(aux)]], cn:aux, cmin:MIN(v.c), cmax:MAX(v.c), clog:0}
ENDIF ELSE BEGIN                          ; Opción 2: No se dan los contornos
 IF TAG_EXIST(v,'cn')     EQ 0 THEN v = CREATE_STRUCT(v, {cn:6})
 IF N_ELEMENTS(v.cn)      NE 1 THEN MESSAGE, 'Structure with invalid cn (not a scalar)'
 IF v.cn                  LT 1 THEN MESSAGE, 'Structure with invalid cn (must be >=2, for cn=1 define c directly)'
 aux = MOMENT(DOUBLE(v.f))
 IF TAG_EXIST(v,'cmin')   EQ 0 THEN v = CREATE_STRUCT(v, {cmin:aux[0]-1.5*SQRT(aux[1])})
 IF N_ELEMENTS(v.cmin)    NE 1 THEN MESSAGE, 'Structure with invalid cmin (not a scalar)'
 IF TAG_EXIST(v,'cmax')   EQ 0 THEN v = CREATE_STRUCT(v, {cmax:aux[0]+1.5*SQRT(aux[1])})
 IF N_ELEMENTS(v.cmax)    NE 1 THEN MESSAGE, 'Structure with invalid cmax (not a scalar)'
 IF v.cmin GT v.cmax           THEN MESSAGE, 'Structure with cmin > cmax'
 IF TAG_EXIST(v,'clog')   EQ 0 THEN v = CREATE_STRUCT(v, {clog:0})
 IF v.clog                NE 0 THEN  COPY_STRUC, v, v, EXCEPT_TAGS=['clog'], STRUC_ADD={clog:1}
 IF v.clog                EQ 0 THEN $
  v = CREATE_STRUCT(v, {c:v.cmin + (v.cmax-v.cmin)/   (v.cn-1.)*DINDGEN(v.cn) }) ELSE $
  v = CREATE_STRUCT(v, {c:v.cmin * (v.cmax/v.cmin)^(1/(v.cn-1.)*DINDGEN(v.cn))})
ENDELSE
IF v.nofill               EQ 0 THEN BEGIN
 vextra = MIN([2*v.cmin-v.cmax, MIN(v.f)-1.]) ; Corregimos el problema de IDL con el nivel inferior
 COPY_STRUC, v, v, EXCEPT_TAGS=['c','cn'], STRUC_ADD={c:[vextra,v.c], cn:v.cn+1}
ENDIF
IF MAX(ABS(SORT(v.c)-INDGEN(v.cn))) NE 0 THEN MESSAGE, 'Contour levels have to be in increasing order'
;
; color 
;
IF TAG_EXIST(v,'color')   EQ 0 THEN BEGIN
 v = CREATE_STRUCT(v, {color:INTARR(v.cn)})
 np     = v.cn/2
 IF 2*(v.cn/2) EQ v.cn THEN BEGIN
  center = v.cn/2 - 1
  nm     = np - 1   
 ENDIF ELSE BEGIN
  center = v.cn/2
  nm     = np
 ENDELSE
 v.color[center] = 130
 IF nm NE 0 THEN v.color[0:nm-1] = ROUND( 10 + 120/(nm+1.)*(1+FINDGEN(nm)))
 v.color[center+1:v.cn-1]        = ROUND(130 + 120/(np+1.)*(1+FINDGEN(np)))
ENDIF
v_n2 = N_ELEMENTS(v.color    )
IF v_n2 EQ 1 THEN COPY_STRUC, v, v, EXCEPT_TAGS='color',     STRUC_ADD={    color:v.color     + INTARR(v.cn)} $
 ELSE IF v_n2 NE v.cn THEN MESSAGE, 'The number of colors (' + STRTRIM(v_n2,2) + $
                                    ') is not equal to the number of contours (' + STRTRIM(v.cn,2) + '). ' + $
                                    'Note that SINGLECONTOUR internally increases the number of contours by one unless nofill is activated.'
;
; linestyle, thick
;
IF TAG_EXIST(v,'linestyle') EQ 0 THEN v = CREATE_STRUCT(v, {linestyle:INTARR(v.cn) + 0  })
v_n2 = N_ELEMENTS(v.linestyle)
IF v_n2 EQ 1 THEN COPY_STRUC, v, v, EXCEPT_TAGS='linestyle', STRUC_ADD={linestyle:v.linestyle + INTARR(v.cn)} $
 ELSE IF v_n2 NE v.cn THEN MESSAGE, 'The number of linestyles (' + STRTRIM(v_n2,2) + $
                                    ') is not equal to the number of contours (' + STRTRIM(v.cn,2) + '). '
IF TAG_EXIST(v,'thick'    ) EQ 0 THEN v = CREATE_STRUCT(v, {    thick:FLTARR(v.cn) + 1.0})
v_n2 = N_ELEMENTS(v.thick)
IF v_n2 EQ 1 THEN COPY_STRUC, v, v, EXCEPT_TAGS='thick'    , STRUC_ADD={    thick:v.thick     + FLTARR(v.cn)} $
 ELSE IF v_n2 NE v.cn THEN MESSAGE, 'The number of thick (' + STRTRIM(v_n2,2) + $
                                    ') is not equal to the number of contours (' + STRTRIM(v.cn,2) + '). '
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;   (c) Inicialización y cálculo de ejes (XAXISL, YAXISL, XAXISU, YAXISU)      ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
DOAXIS, xxl, 'xl',         SPANISH=spanish
DOAXIS, yyl, 'yl',         SPANISH=spanish
DOAXIS, xxu, 'xu', VL=xxl, SPANISH=spanish
DOAXIS, yyu, 'yu', VL=yyl, SPANISH=spanish
COPY_STRUC, xxl, xxl, EXCEPT_TAGS=['tickname'], STRUC_ADD={tickname:xxl.tickname2} ; This has to be done here to
COPY_STRUC, yyl, yyl, EXCEPT_TAGS=['tickname'], STRUC_ADD={tickname:yyl.tickname2} ; allow for separate upper/lower
COPY_STRUC, xxu, xxu, EXCEPT_TAGS=['tickname'], STRUC_ADD={tickname:xxu.tickname2} ; axis behavior and for corrections
COPY_STRUC, yyu, yyu, EXCEPT_TAGS=['tickname'], STRUC_ADD={tickname:yyu.tickname2} ; done to OUT
IF xxl.log NE 0 OR xxu.log NE 0 OR yyl.log NE 0 OR yyu.log NE 0 THEN $
 MESSAGE, 'Logarithmic axes not allowed in SINGLECONTOUR'
;
; Corregimos el caso que IDL no identifica correctamente en el que los
;  ejes aumentan en sentido negativo
;
COPY_STRUC, v, v, EXCEPT_TAGS=['ff','gg'], STRUC_ADD={ff:v.f, gg:v.g}
;IF xxl.range[1] LT xxl.range[0] THEN BEGIN
; v.ff = REVERSE(v.ff,1)
; v.gg = REVERSE(v.gg,1)
;ENDIF
;IF yyl.range[1] LT yyl.range[0] THEN BEGIN
; v.ff = REVERSE(v.ff,2)
; v.gg = REVERSE(v.gg,2)
;ENDIF
IF exit EQ 1 THEN GOTO, WRAPUP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          (d) Inicialización de la gráfica (PLOT y CTABLE)                    ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ENTRANCE1:
;
; Etiquetas no-PS de PLOT
;
IF TAG_EXIST(pplot,'xsize')     EQ 0 THEN pplot = CREATE_STRUCT(pplot, {    xsize:              0.0})
IF N_ELEMENTS(pplot.xsize)      NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.xsize'
IF SIZE(pplot.xsize,/TYPE)      NE 4 AND $
   SIZE(pplot.xsize,/TYPE)      NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='xsize',     STRUC_ADD={    xsize:FLOAT(v.xsize    )}
IF TAG_EXIST(pplot,'ysize')     EQ 0 THEN pplot = CREATE_STRUCT(pplot, {    ysize:              0.0})
IF N_ELEMENTS(pplot.ysize)      NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.ysize'
IF SIZE(pplot.ysize,/TYPE)      NE 4 AND $
   SIZE(pplot.ysize,/TYPE)      NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='ysize',     STRUC_ADD={    ysize:FLOAT(v.ysize    )}
IF TAG_EXIST(pplot,'xc')        EQ 0 THEN pplot = CREATE_STRUCT(pplot, {       xc:              0.0})
IF N_ELEMENTS(pplot.xc)         NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.xc'
IF SIZE(pplot.xc,/TYPE)         NE 4 AND $
   SIZE(pplot.xc,/TYPE)         NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='xc',        STRUC_ADD={       xc:FLOAT(v.xc       )}
IF TAG_EXIST(pplot,'yc')        EQ 0 THEN pplot = CREATE_STRUCT(pplot, {       yc:              0.0})
IF N_ELEMENTS(pplot.yc)         NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.yc'
IF SIZE(pplot.yc,/TYPE)         NE 4 AND $
   SIZE(pplot.yc,/TYPE)         NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='yc',        STRUC_ADD={       yc:FLOAT(v.yc       )}
IF TAG_EXIST(pplot,'ngx')       EQ 0 THEN pplot = CREATE_STRUCT(pplot, {      ngx:                1})
IF N_ELEMENTS(pplot.ngx)        NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.ngx'
IF TAG_EXIST(pplot,'title')     EQ 0 THEN pplot = CREATE_STRUCT(pplot, {    title:               ''})
IF N_ELEMENTS(pplot.title)      NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.title'
IF TAG_EXIST(pplot,'charsize')  EQ 0 THEN pplot = CREATE_STRUCT(pplot, { charsize:              0.0})
IF N_ELEMENTS(pplot.charsize)   NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.charsize'
IF SIZE(pplot.charsize,/TYPE)   NE 4 AND $
   SIZE(pplot.charsize,/TYPE)   NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='charsize',  STRUC_ADD={ charsize:FLOAT(v.charsize )}
IF TAG_EXIST(pplot,'charthick') EQ 0 THEN pplot = CREATE_STRUCT(pplot, {charthick:              0.0})
IF N_ELEMENTS(pplot.charthick)  NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.charthick'
IF SIZE(pplot.charthick,/TYPE)  NE 4 AND $
   SIZE(pplot.charthick,/TYPE)  NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='charthick', STRUC_ADD={charthick:FLOAT(v.charthick)}
IF TAG_EXIST(pplot,'box')       EQ 0 THEN pplot = CREATE_STRUCT(pplot, {      box:[0.0,0.0,1.0,1.0]})
IF N_ELEMENTS(pplot.box)        NE 4 THEN MESSAGE, 'Incorrect dimensions for plot.charthick'
IF SIZE(pplot.charthick,/TYPE)  NE 4 AND $
   SIZE(pplot.charthick,/TYPE)  NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='box'      , STRUC_ADD={      box:FLOAT(v.box      )}
;
; CFILE
;
IF N_TAGS(cfile) NE 5 OR TAG_EXIST(cfile,'name') EQ 0 THEN BEGIN ; Se especifica parcialmente cfile
 IF TAG_EXIST(cfile,'name' ) EQ 0 THEN cfile = CREATE_STRUCT(cfile, { name:'colorjma.tbl'})
 IF TAG_EXIST(cfile,'name' ) EQ 0 AND $
    cfile.name EQ 'colorjma.tbl'  THEN cfile = CREATE_STRUCT(cfile, {  dir:jmaplot_path  })
 IF TAG_EXIST(cfile,'dir'  ) EQ 0 THEN BEGIN
  cpath = FILE_SEARCH(STRSPLIT(!DIR + '/resource/colors/:' + !PATH, PATH_SEP(/SEARCH_PATH),/EXTRACT) + '/' + cfile.name)
  IF STRLEN(cpath[0]) EQ 0 THEN STOP, cfile.name + ' not found in the path'
  cfile = CREATE_STRUCT(cfile, {dir:STRMID(cpath[0],0,STRLEN(cpath[0])-STRLEN(cfile.name))})
 ENDIF
 IF TAG_EXIST(cfile,'table') EQ 0 AND $
    cfile.name EQ 'colorjma.tbl'  THEN cfile = CREATE_STRUCT(cfile, {table:            37})
 IF TAG_EXIST(cfile,'table') EQ 0 THEN cfile = CREATE_STRUCT(cfile, {table:             0})
 IF TAG_EXIST(cfile,'def'  ) EQ 0 THEN BEGIN
  IF cfile.name  EQ 'colorjma.tbl' AND $
     cfile.table EQ 38            THEN cfile = CREATE_STRUCT(cfile, {  def:           254}) $
                                  ELSE cfile = CREATE_STRUCT(cfile, {  def:             0})
 ENDIF
 IF TAG_EXIST(cfile,'white') EQ 0 THEN cfile = CREATE_STRUCT(cfile, {white:           255})
ENDIF ELSE IF N_TAGS(cfile) NE 5 THEN BEGIN                      ; No se especifica nada de cfile
 IF cfile.name EQ 'colorjma.tbl' THEN cfile = CREATE_STRUCT(cfile, {dir:jmaplot_path, table:37, def:0, white:255}) $
                                 ELSE cfile = CREATE_STRUCT(cfile, {dir:jmaplot_path, table:0,  def:0, white:255})
ENDIF
OPENR, unit, cfile.dir + cfile.name, /GET_LUN, ERROR=err
IF err EQ 0 THEN BEGIN
 CLOSE, unit
 FREE_LUN, unit
ENDIF ELSE BEGIN
 MESSAGE, cfile.name + ' not found in ' + cfile.dir
ENDELSE
;
; Etiquetas PS de PLOT
;
IF TAG_EXIST(pplot,'psxsize')   EQ 0 THEN $
 IF KEYWORD_SET(PSXSIZE)             THEN pplot = CREATE_STRUCT(pplot, {  psxsize:psxsize  }) ELSE $
                                          pplot = CREATE_STRUCT(pplot, {  psxsize:      0.0})
IF N_ELEMENTS(pplot.psxsize)    NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.psxsize'
IF SIZE(pplot.psxsize,/TYPE)    NE 4 AND $
   SIZE(pplot.psxsize,/TYPE)    NE 5 THEN COPY_STRUC, pplot, pplot, EXCEPT_TAGS='psxsize', STRUC_ADD={psxsize:FLOAT(pplot.psxsize)}
IF TAG_EXIST(pplot,'font')      EQ 0 THEN  pplot = CREATE_STRUCT(pplot, {     font:        0})
; IF KEYWORD_SET(PSFONTS)             THEN pplot = CREATE_STRUCT(pplot, {     font:        0}) ELSE $
;                                          pplot = CREATE_STRUCT(pplot, {     font:       -1})
IF N_ELEMENTS(pplot.font)       NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.psfonts'
IF TAG_EXIST(pplot,'landscape') EQ 0 THEN $
 IF KEYWORD_SET(LANDSCAPE)           THEN pplot = CREATE_STRUCT(pplot, {landscape:landscape}) ELSE $
                                          pplot = CREATE_STRUCT(pplot, {landscape:        0})
IF N_ELEMENTS(pplot.landscape)  NE 1 THEN MESSAGE, 'Incorrect dimensions for plot.landscape'
IF psname NE '' THEN BEGIN
 IF pplot.psaspect              EQ 0 THEN pplot.psaspect = ABS(yyl.delta/xxl.delta)
 PREPPS, psname, pplot, cfile, QUIET=quiet
ENDIF ELSE BEGIN
 IF pplot.psxsize  EQ 0 THEN MESSAGE,  'psxsize has to be set from multigraph'
 IF pplot.psaspect EQ 0 THEN MESSAGE, 'psaspect has to be set from multigraph'
 COPY_STRUC, pplot, pplot, EXCEPT_TAGS='psysize', STRUC_ADD={psysize:pplot.psxsize*pplot.psaspect}
ENDELSE
;
; Fijamos el tamaño y posición de la gráfica.
;
GRPOS, pplot, xxl, yyl, xxu, yyu, QUIET=quiet
IF exit EQ 2 THEN GOTO, WRAPUP
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          (e) Representación de gráficas.                                     ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
ENTRANCE2:
LOADCT, cfile.table, FILE=cfile.dir+cfile.name, SILENT=quiet
!X.CHARSIZE = xxl.charsize
!Y.CHARSIZE = yyl.charsize
!P.POSITION = pplot.box + [pplot.extraxl,pplot.extrayl,-pplot.extraxu,-pplot.extrayu]
!P.CHARSIZE = pplot.charsize
!X.RANGE    = xxl.range
!Y.RANGE    = yyl.range
PLOT, [xxl.range[0]+2*(xxl.range[1]-xxl.range[0])], $
      [yyl.range[0]+2*(yyl.range[1]-yyl.range[0])], $
      XRANGE=xxl.range, YRANGE=yyl.range,           $
      XLOG=xxl.log2, YLOG=yyl.log2,                 $
      XSTYLE=5, YSTYLE=5, /NOERASE
IF KEYWORD_SET(PREEXTERNAL) THEN FOR j=0,N_ELEMENTS(preexternal)-1 DO tmp = EXECUTE(preexternal[j])
IF KEYWORD_SET(BACKGROUND) THEN BEGIN
 sizeback = SIZE(background)
 IF sizeback[0] EQ 2 THEN BEGIN
  TV, background, !P.POSITION[0]*pplot.psxsize, !P.POSITION[1]*pplot.psysize, $
  XSIZE=(!P.POSITION[2]-!P.POSITION[0])*pplot.psxsize, $
  YSIZE=(!P.POSITION[3]-!P.POSITION[1])*pplot.psysize, $
  /CENTIMETERS
 ENDIF ELSE BEGIN
  LOADCT, 0, SILENT=quiet
  TV, $
  [[[background[*,*,0]]],[[background[*,*,1]]],[[background[*,*,2]]]], $
  TRUE=3, !P.POSITION[0]*pplot.psxsize, !P.POSITION[1]*pplot.psysize, $
  XSIZE=(!P.POSITION[2]-!P.POSITION[0])*pplot.psxsize, $
  YSIZE=(!P.POSITION[3]-!P.POSITION[1])*pplot.psysize, $
  /CENTIMETERS
  LOADCT, cfile.table, FILE=cfile.dir+cfile.name, SILENT=quiet
 ENDELSE
ENDIF
COPY_STRUC, extra, extra2, EXCEPT_TAGS=['C_ORIENTATION','C_SPACING','C_THICK','C_LINESTYLE']
IF v.nofill  EQ 0                   THEN                         $ ; Relleno
	 CONTOUR, v.ff, v.x, v.y, LEVELS=v.c,                    $
         /FILL, /NOERASE, C_COLORS=v.color, XSTYLE=5, YSTYLE=5,  $
	 _EXTRA=extra
IF v.nolines EQ 0 AND v.nofill NE 1 THEN                         $ ; Líneas negras
	 CONTOUR, v.ff, v.x, v.y, LEVELS=v.c,                    $
         /NOERASE, C_COLORS=cfile.def, XSTYLE=5, YSTYLE=5,       $
         C_LINESTYLE=v.linestyle, C_THICK=v.thick, _EXTRA=extra2
IF v.nolines EQ 0 AND v.nofill EQ 1 THEN                         $ ; Líneas de colores
	 CONTOUR, v.ff, v.x, v.y, LEVELS=v.c,                    $
         /NOERASE, C_COLORS=v.color, XSTYLE=5, YSTYLE=5,         $
         C_LINESTYLE=v.linestyle, C_THICK=v.thick, _EXTRA=extra2
IF v.g_flag  EQ 1 AND v.g_cell EQ 0 THEN                         $ ; Máscara
	 CONTOUR, v.gg, v.x, v.y, LEVELS=v.g_crit,               $
         C_COLORS=cfile.white, COLOR=cfile.def, /FILL,           $
	 /NOERASE, XSTYLE=5, YSTYLE=5
IF v.g_flag  EQ 1 AND v.g_cell EQ 1 THEN                         $ ; Máscara alternativa
	 CONTOUR, v.gg, v.x, v.y, LEVELS=v.g_crit,               $
         C_COLORS=cfile.white, COLOR=cfile.def, /CELL_FILL,      $
	 /NOERASE, XSTYLE=5, YSTYLE=5
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          (f) Representación de ejes, marcas, títulos y leyendas.             ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;
; Ponemos los títulos y los ejes
;
IF xxl.style NE -2 THEN AXIS2, pplot, xxl, yyl, cfile
IF yyl.style NE -2 THEN AXIS2, pplot, yyl, xxl, cfile
IF xxu.style NE -2 THEN AXIS2, pplot, xxu, yyl, cfile
IF yyu.style NE -2 THEN AXIS2, pplot, yyu, xxl, cfile
IF pplot.title NE '' THEN BEGIN
 titlen = strlen(pplot.title)
 IF titlen LE 60 THEN titsize=1.3*pplot.charsize ELSE titsize=1.1*pplot.charsize
 XYOUTS, 0.5*(!P.POSITION(0)+!P.POSITION(2)),                          $
         !P.POSITION(3)+pplot.extrayu-0.60*pplot.unitl/pplot.psaspect, $
	 pplot.title,                                                  $
         FONT=pplot.font, CHARSIZE=titsize, ALIGNMENT=0.5, /NORMAL, COLOR=cfile.def
ENDIF
;
; Comprobamos si se quiere escribir leyenda o no
;
IF legend.draw EQ 1 THEN BEGIN
 IF TAG_EXIST(legend,'clear') EQ 0 THEN legend = CREATE_STRUCT(legend, {clear:     0})
 IF TAG_EXIST(legend,'xleft') EQ 0 THEN legend = CREATE_STRUCT(legend, {xleft:  0.05})
 IF TAG_EXIST(legend,'ydown') EQ 0 THEN legend = CREATE_STRUCT(legend, {ydown:  0.05})
 IF TAG_EXIST(legend,'xsize') EQ 0 THEN legend = CREATE_STRUCT(legend, {xsize:  0.25})
 IF TAG_EXIST(legend,'ysize') EQ 0 THEN legend = CREATE_STRUCT(legend, {ysize:  0.15})
 IF N_ELEMENTS(legend.xleft)  NE 1 THEN MESSAGE, 'Incorrect dimensions for legend.xleft'
 IF N_ELEMENTS(legend.ydown)  NE 1 THEN MESSAGE, 'Incorrect dimensions for legend.ydown'
 IF N_ELEMENTS(legend.xsize)  NE 1 THEN MESSAGE, 'Incorrect dimensions for legend.xsize'
 IF N_ELEMENTS(legend.ysize)  NE 1 THEN MESSAGE, 'Incorrect dimensions for legend.ysize'
 COPY_STRUC, legend, legend, EXCEPT_TAGS=['xleft','ydown','xsize','ysize'],  $
       STRUC_ADD={xleft:FLOAT(legend.xleft),ydown:FLOAT(legend.ydown), $
                  xsize:FLOAT(legend.xsize),ysize:FLOAT(legend.ysize)}
 IF v.nofill EQ 0 THEN aux = v.c[1:v.cn-1] ELSE aux = v.c
 vleg        = FTICKS(aux, SPANISH=spanish, /NOTRIM)
 vleg        = ' ' + vleg
 flag        = 1
 WHILE flag EQ 1 DO BEGIN
  vleg       = STRMID(vleg,1,999)
  FOR i=0,N_ELEMENTS(vleg)-1 DO IF STRMID(vleg[i],0,1) NE ' ' THEN flag = 0
 ENDWHILE
 leglen      = MAX(STRLEN(vleg))
 vleg2       = STRARR(v.cn,3) + STRJOIN(STRARR(leglen) + ' ')
 IF v.nofill EQ 0 THEN BEGIN
  vleg2[*,0] = [vleg2[0,0], vleg                                ]
  vleg2[*,1] = [       '<', STRARR(v.cn-2) + '-',            '<']
  vleg2[*,2] = [vleg                            ,vleg2[v.cn-1,2]]
 ENDIF ELSE BEGIN
  vleg2[*,2] = vleg
 ENDELSE
 COPY_STRUC, legend, legend, EXCEPT_TAGS=['text'], STRUC_ADD={text:vleg2}
 psym        = v.color*0 + 10 + 1*(v.nofill EQ 0 AND v.nolines EQ 1) + 2*(v.nofill EQ 0 AND v.nolines EQ 0)
 symsize     = v.color*0 + 2.0
 nofill      = v.color*0
 ert         = v.color*0
 LEGEND, legend, pplot, cfile, v.color, v.linestyle, psym, symsize, v.thick, nofill, ert
ENDIF
IF KEYWORD_SET(EXTERNAL) THEN FOR i=0,N_ELEMENTS(external)-1 DO tmp = EXECUTE(external[i])
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
;          (g) Cierre del fichero PostScript.                                  ;
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
IF psname NE '' THEN CLOSEPS
WRAPUP:
out    = {v1:v, nplots:nplots, xaxisl:xxl, yaxisl:yyl, xaxisu:xxu, yaxisu:yyu, plot:pplot, cfile:cfile, legend:legend, $
          background:background, spanish:spanish, preexternal:preexternal, external:external, var:var, extra:extra}
cfile  = cfileo
legend = legendo
!X     = xsv
!Y     = ysv
!P     = psv
END
;